kevinwu.cn/p/ae2ce64 上面这篇文章讲得很好,我总结一下。
如果class继承或者实现了多个类,同一个方法调用的时候,实际使用的是哪个方法优先级如下with>extend>implements
,如果with后面跟了多个类,后面的优先级大于前面的。
增加一种情况,代码如下:
abstract class Super {
void method() {
print("Super");
}
}
class MySuper implements Super {
void method() {
print("MySuper");//第8行
}
}
mixin MyMixin on Super {
void method() {
super.method();//第15行
print("Sub");
}
}
class Client extends MySuper with MyMixin {}
void main() {
Client().method();
}
复制代码
这种情况应该输出什么呢? 会输出
MySuper
Sub
复制代码
MyMixin on Super
意思是限定子类必须继承或实现Super,因为MyMixin使用了Super提供的功能。
第15行调用super.method()
会先查找MyMixin
中有没有对应的方法,发现有该方法,然后因为MyMixin
限定子类必须继承或实现Super
,所以第15行方法中的super.method()
会调用MyMixin
的子类所extend
的父类的method
方法,在这里就是MySuper
的method()
方法,所以输出MySuper
,然后输出Sub
。
然后把代码修改一下,搞复杂点
abstract class Super {
void method() {
print("Super");
}
}
class MySuper implements Super {
void method() {
print("MySuper"); //第9行
}
}
mixin MyMixin1 on Super {
void method() {
super.method(); //第15行
print("MyMixin1");
}
}
mixin MyMixin2 on Super {
void method() {
super.method(); //第22行
print("MyMixin2");
}
}
class Client extends MySuper with MyMixin1, MyMixin2 {}
void main() {
Client().method();
}
复制代码
这次你觉得能输出什么? 答案是
MySuper
MyMixin1
MyMixin2
复制代码
原因如下:
- Dart先找MyMixin2有没有method方法,发现有,就调用,然后22行会查找最后一个继承了Super的类,会找到MyMixin1的method方法
- MyMixin1再次寻找最后一个继承了Super的类,会找到MySuper
- 然后调用MySuper的method方法,输出MySuper
- 然后输出MyMixin1
- 再输出MyMixin2
理解mixin
有个重要的一点,就是不要看到mixin
类方法里的super
就觉得是调用这个mixin
类的父类的方法,mixin
里的on
不仅代表这个mixin
是on
后面的子类,也是一种约束关系,限定子类也必须继承on
后面的类。
拿上面的代码举例,MyMixin2 on Super
意思是你如果想继承MyMixin2
就必须是Super
的子类才可以,然后看到MyMixin2
里调用的super.method()
方法,应该在Client
的继承关系里从后往前查找第一个Super
的子类,发现MyMixin1
符合条件并且也有method
方法,然后就会调用MyMixin1
的method
方法。这样就能理解mixin
的用法了。