Flutter中Mixin的一些理解

使用Mixin前先复习一下继承与实现

1.extends + implements

abstract class First {
  void doPrint() {
    print('First');
  }
}

abstract class Second {
  void doPrint() {
    print('Second');
  }
}

class Father {
  void doPrint() {
    print('Father');
  }
}

class Son1 extends Father implements First,Second {

}

调用:
 Son1 son = Son1();
       son.doPrint();
打印:Father

如果Second或者First中再加入一个方法

abstract class Second {
  void doPrint() {
    print('Second');
  }

  void test(){
    print('test');
  }
}

就会报错

Error: The non-abstract class 'Son1' is missing implementations for these members:
 - Second.test
Try to either
 - provide an implementation,
 - inherit an implementation from a superclass or mixin,
 - mark the class as abstract, or
 - provide a 'noSuchMethod' implementation.
 

提示Son1中需要实现test()方法,说明implements关键字只是声明要实现接口方法,abstract相当于interface,而doPrint()方法具体实现是在extend继承的Father中实现了,所以接口声明的方法要在Son中或者Father中实现。

 

 

2.extends + with

abstract class First {
  void doPrint() {
    print('First');
  }
}

abstract class Second {
  void doPrint() {
    print('Second');
  }
}

class Father {
  void doPrint() {
    print('Father');
  }
}

class Son1 extends Father with First,Second {

}

调用:
Son1 son = Son1();
       son.doPrint();
打印:
Second

with关键字能够实现mixin,可以想象成多继承,而且是以类似于栈的形式实现,同一方法调用最外边的Second

 

3.extends + with + implements

abstract class First {
  void doPrint() {
    print('First');
  }
}

abstract class Second {
  void doPrint() {
    print('Second');
  }
}

class Father {
  void doPrint() {
    print('Father');
  }
}

class Son1 extends Father with First implements Second {

}

调用:
Son1 son = Son1();
       son.doPrint();
打印:
First

说明Second是接口,with关键字依旧遵守上边例子中的性质,首先实现First中的方法,如果把First中的doPrint()方法注释掉,打印Father

4.mixin关键字的使用

一般情况下,mixin与on关键字结合使用,如果不与on关键字一起使用,作用类似于abstract。所以着重看下与on关键字配合的例子

class Father {
  void init() {
    print('Father init');
  }
}
//当使用on关键字,则表示该mixin只能在那个类的子类使用了,
// 那么结果显然的,mixin中可以调用那个类定义的方法、属性
mixin FirstMixin on Father {
  void init() {
    print('FirstMixin init start');
    super.init();
    print('FirstMixin init end');
  }
}

mixin SecondMixin on Father {
  void init() {
    print('SecondMixin init start');
    super.init();
    print('SecondMixin init end');
  }
}


class Son2 extends Father with FirstMixin, SecondMixin {

  @override
  void init() {
    print('Son2 init start');
    super.init();
    print('Son2 init end');

  }
}

调用:
  Son2().init();

打印:
flutter: Son2 init start
flutter: SecondMixin init start
flutter: FirstMixin init start
flutter: Father init
flutter: FirstMixin init end
flutter: SecondMixin init end
flutter: Son2 init end

与例子2一样,但是,这里super调用会发现,with关键字把FirstMixin和SecondMixin以及Father自动关联为父子,这一切都是基于on关键字,且对Father这个家族(可以理解为整个家族)增加束缚,Son2这个类也只能继承Father,如果增加其他家族的mixin,就会报错。

如:

class OtherFamily{
  void init(){
    print('其他家族');
  }
}

mixin OtherFamilyMixin on OtherFamily{
@override
  void init() {
    // TODO: implement init
    super.init();
  }
}

class Son2 extends Father with FirstMixin, SecondMixin ,OtherFamilyMixin{
  @override
  void init() {
    // TODO: implement init
    super.init();
  }
}

报错:
 Error: '_Son2&Father&FirstMixin&SecondMixin' doesn't implement 'OtherFamily' so it can't be used with 'OtherFamilyMixin'.
 - 'Father with FirstMixin, SecondMixin' is from 'package:github_app/common/page/HomePage.dart' ('lib/common/page/HomePage.dart').
 - 'OtherFamily' is from 'package:github_app/common/page/HomePage.dart' ('lib/common/page/HomePage.dart').
 - 'OtherFamilyMixin' is from 'package:github_app/common/page/HomePage.dart' ('lib/common/page/HomePage.dart').
class Son2 extends Father with FirstMixin, SecondMixin ,OtherFamilyMixin{

如果把OtherFamilyMixin改成OtherFamily,那么Son也改换门庭了

class OtherFamily{
  void init(){
    print('其他家族');
  }
}

mixin OtherFamilyMixin on OtherFamily{
@override
  void init() {
    // TODO: implement init
    super.init();
  }
}

class Son2 extends Father with FirstMixin, SecondMixin ,OtherFamily{

  @override
  void init() {
    print('Son2 init start');
    super.init();
    print('Son2 init end');

  }


}

打印:
flutter: Son2 init start
flutter: 其他家族
flutter: Son2 init end

看看,连他爸爸都不要了,super直接指向OtherFamily,但是他又不忘记继承的Father,还是依旧能调用Father里的方法,比如在Father里加入eat方法

 class Father {
  void init() {
    print('Father init');
  }

  void eat(){
    print('eat food');
  }

}

调用:
Son2().init();
Son2().eat();

打印:
flutter: Son2 init start
flutter: 其他家族
flutter: Son2 init end
flutter: eat food

真的是脚踏两只船,就像段誉,血脉上是段延庆,可以用段延庆的血脉,然后武功上用着段正淳的一阳指,好乱啊。

 

5.on关键字

on关键字后边不止可以跟一个类,再加一个类会出现什么情况

class Father{
  void init() {
    print('Father init');
  }
  
}

abstract class Mother{
  void initMother();
}
//当使用on关键字,则表示该mixin只能在那个类的子类使用了,
// 那么结果显然的,mixin中可以调用那个类定义的方法、属性
mixin FirstMixin on Father {
  void init() {
    print('FirstMixin init start');
    super.init();
    print('FirstMixin init end');
  }
}

mixin SecondMixin on Father,Mother {
  void init() {
    print('SecondMixin init start');
    super.init();
    print('SecondMixin init end');
  }

  
}


class Son2 extends Father with FirstMixin, SecondMixin{

  @override
  void init() {
    print('Son2 init start');
    super.init();
    print('Son2 init end');

  }


}

跑项目执行报错

打印:
Error: The non-abstract class 'Son2' is missing implementations for these members:
 - Mother.initMother
Try to either

Error: '_Son2&Father&FirstMixin' doesn't implement 'Mother' so it can't be used with 'SecondMixin'.

说是需要实现initMother方法,好吧我们在Son2中实现该方法

class Son2 extends Father with FirstMixin, SecondMixin{

  @override
  void init() {
    print('Son2 init start');
    super.init();
    print('Son2 init end');

  }
  
  @override
  void initMother() {
    // TODO: implement initMother
  }


}

打印:
Error: '_Son2&Father&FirstMixin' doesn't implement 'Mother' so it can't be used with 'SecondMixin'.

好吧,我们继续实现,在FirstMixin中实现

//当使用on关键字,则表示该mixin只能在那个类的子类使用了,
// 那么结果显然的,mixin中可以调用那个类定义的方法、属性
mixin FirstMixin on Father implements Mother{
  void init() {
    print('FirstMixin init start');
    super.init();
    print('FirstMixin init end');
  }
  
  @override
  void initMother() {
    // TODO: implement initMother
  }
}

成功了!!

然后我又把Sons中的initMother实现注释掉,还是可以成功!然后把FirstMixin中的实现去掉,只在Father中实现initMother

class Father implements Mother{
  void init() {
    print('Father init');
  }

  @override
  void initMother() {
    // TODO: implement initMother
  }
}

class Mother{
  void initMother(){

  }
}
//当使用on关键字,则表示该mixin只能在那个类的子类使用了,
// 那么结果显然的,mixin中可以调用那个类定义的方法、属性
mixin FirstMixin on Father{
  void init() {
    print('FirstMixin init start');
    super.init();
    print('FirstMixin init end');
  }
  
}

mixin SecondMixin on Father,Mother {
  void init() {
    print('SecondMixin init start');
    super.init();
    print('SecondMixin init end');
  }


}


class Son2 extends Father with FirstMixin, SecondMixin{

  @override
  void init() {
    print('Son2 init start');
    super.init();
    print('Son2 init end');

  }
  
}

还是可以成功!!

这时,有个大胆的想法,是不是遵循例子2,with关键字依次往前推,只要某个mixin实现Mother就行?

SecondMixin->FirstMixin->Father

 

然后把on Father,Mother的mixin放到倒数第二个,在倒数第一个实现


class Father{
  void init() {
    print('Father init');
  }
}

class Mother{
  void initMother(){

  }
}
//当使用on关键字,则表示该mixin只能在那个类的子类使用了,
// 那么结果显然的,mixin中可以调用那个类定义的方法、属性
mixin FirstMixin on Father{
  void init() {
    print('FirstMixin init start');
    super.init();
    print('FirstMixin init end');
  }

}

mixin SecondMixin on Father,Mother {
  void init() {
    print('SecondMixin init start');
    super.init();
    print('SecondMixin init end');
  }


}


class Son2 extends Father with SecondMixin,FirstMixin{

  @override
  void init() {
    print('Son2 init start');
    super.init();
    print('Son2 init end');

  }

}

打印:
 Error: The non-abstract class 'Son2' is missing implementations for these members:
 - Mother.initMother
Try to either

Error: 'Father' doesn't implement 'Mother' so it can't be used with 'SecondMixin'.

失败!!

注意看,第二个Error由之前的 '_Son2&Father&FirstMixin'变成了具体的Father,说明是往前推得。

既然这样,再来验证一下,我们添加一个ThirdMixin,把on Mother,Father的SecondMixin放在中间

mixin ThirdMixin on Father {
  void init() {
    print('ThirdMixin init start');
    super.init();
    print('ThirdMixin init end');
  }


}

class Son2 extends Father with ThirdMixin,SecondMixin,FirstMixin{

  @override
  void init() {
    print('Son2 init start');
    super.init();
    print('Son2 init end');

  }

}

打印:
 Error: The non-abstract class 'Son2' is missing implementations for these members:
- Mother.initMother
Error: '_Son2&Father&ThirdMixin' doesn't implement 'Mother' so it can't be used with 'SecondMixin'.

果然不出所料!打印又成了_Son2&Father&ThirdMixin

 

既然这样,也不能在Father中实现啊!

我们就把Mother放到Son中的with后边,而且要放到SecondMixin的前边

class Son2 extends Father with Mother,ThirdMixin,SecondMixin,FirstMixin{

  @override
  void init() {
    print('Son2 init start');
    super.init();
    print('Son2 init end');

  }

}

这样就OK了,可以试验一下把Mother放SecondMixin后边,又会报错,这样体现了mixin的约束性,强制Son必须继承Mother这个类。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值