在开发flutter项目的时候,发现mixins对于我来说是一个新的概念。在项目中是常用到的,比如AutomaticKeepAliveClientMixin和在使用动画时常用到SingleTickerProviderStateMixin等等情况。那么mixins究竟是什么呢?有什么用呢?
语法:
这是通过普通类的声明隐式定义Mixins
class Bird {
void fly() {
print("I'm flying");
}
}
如果你不希望mixins被继承或者实例化(instantiate), 可以这么做:
abstract class Bird {
factory Bird._() => null;
void fly() {
print("I'm flying");
}
}
利用关键字“with”来使用mixins:
class Crow extends Animal with Bird {}
class Crow extends Animal with Bird, plane {}
具体使用:
class A {
String getMessage() => 'A';
}
class B {
String getMessage() => 'B';
}
class P {
String getMessage() => 'P';
}
class AB extends P with A, B {}
class BA extends P with B, A {}
void main() {
String result = '';
AB ab = AB();
result += ab.getMessage();
BA ba = BA();
result += ba.getMessage();
print(result);
}
这一段代码最后的输出结果是什么呢?
答案是:BA
知道是什么原因吗?原理是什么?
线性化(Linearization)
'Dart中的Mixins通过创建一个新类来实现,该类将mixin的实现层叠在一个超类之上以创建一个新类 ,它不是“在超类中”,而是在超类的“顶部”,因此如何解决查找问题不会产生歧义。 -- Lasse R. H. Nielsen on StackOverflow.
- Mixins不是一种在经典意义上获得多重继承的方法。
- Mixins是一种抽象和重用一系列操作和状态的方法。
- 它类似于扩展类所获得的重用,但它与单继承兼容,因为它是线性的。
— Lasse R. H. Nielsen on StackOverflow.
线性化决定了每次执行的是最上层超类的方法。
原理告诉我们一个非常重要的事情:声明mixins的顺序决定了继承链,即决定了最上层到底层的超类(superclass)的排序
类型:
使用了mixins实例化后会是什么类型呢?
class A {
String getMessage() => 'A';
}
class B {
String getMessage() => 'B';
}
class P {
String getMessage() => 'P';
}
class AB extends P with A, B {}
class BA extends P with B, A {}
void main() {
AB ab = AB();
print(ab is P);
print(ab is A);
print(ab is B);
BA ba = BA();
print(ba is P);
print(ba is A);
print(ba is B);
}
所有打印的结果都会是true.
有什么用?
我们来看一个例子:
abstract class Super {
void method() {
print("Super");
}
}
class MySuper implements Super { //注意这里是implements
void method() {
print("MySuper");
}
}
mixin Mixin on Super {
void method() {
super.method();
print("Sub");
}
}
class Client extends MySuper with Mixin {}
void main() {
Client().method();
}
- 输出的结果是?
MySuper
Sub
这个最简单直白的理解,就是把Mixin实现的method方法内部实现放在Client里执行了,所以super.method()调用的就是client的父类。
- 第7行代码为什么用implements?用extends可不可以?
可以用extends,用了extends好处是不用实现method方法。这也解释了为什么需要mixins:- dart不能多继承
- 使用implements需要实现方法的内部实现,不利于代码复用
对mixins的理解已经介绍完了,如果有问题,欢迎向我反馈。
本文参考了这篇英文文章:Dart: What are mixins?--Romain Rastel
网友评论