通俗的讲,mixin(mix-in)是一种新的语言特性,表面类似多继承,使用with关键字对类添加一些功能。官话mixin是在多个类层次结构中重用类代码的一种方法。mixin(mix-in)是为面向对象程序设计语言中的类提供了方法的实现。其他类可以访问mixin类的方法、变量而不必成为其子类。Mixin 的作用就是在多个类层次结构中重用类的代码,很好的解决了单继承带来的代码冗余问题。
Dart 1.12或更低版本使用Mixin时必须继承至Object,并且不能调用super()方法。
Dart 1.13或更高版本支持继承至Object以外的类并使用Mixin,并且可以调用super.method()。这项支持仅在DartVM中默认开启,并且在标志后面的Analyzer中才能够使用。更具体地说,它位于命令行分析器中的--supermixin标志之后。它也可以在分析服务器中,在客户端可配置选项后面。Dart2js和dartdevc不支持SuperMixin。
Dart 2.1.0添加了mixin
关键字,用于显式声明mixin。为了兼容起见,Dart仍然允许您混入未使用定义的类mixin
。但是,这是有风险的。如果该类的作者不希望将该类用作混入,则他们可能会以打破混入限制的方式更改该类。例如,如果他们添加一个构造函数,则您的mixin将无法使用(The class 'xxx' can't be used as a mixin because it declares a constructor.)
先举个栗子,我想在杏树上嫁接梨树代码如下:
void main() {
Apricot().flower();
}
/**
* 杏树
*/
class Apricot with Pair {
}
/**
* 梨树
* class 可以用mixin代替
*/
class Pair{
void flower() {
print('梨花');
}
}
这样的话,杏树上就开了梨花。mixin可以理解成嫁接,就像是你嫁接在我身上之后,我继承了你的功能,我俩合体了,这属于捆绑的关系,并不是父子的关系。
为什么dart语言的设计者,不设计出可以多继承的语法,而要设计mixin来替代多继承,是因为多继承会导致菱形问题,所以一直都是单继承。
4.1 mixin之间的线性化
概述里讲到with后面如果有多个mixin,且有相同的函数,只会用离with最远的那个mixin里面的方法。即mixin的线性化。如下代码:
void main() {
Apricot().flower();
}
/**
* 杏树
*/
class Apricot with Pair , Peach{
}
/**
* 梨树
*/
mixin Pair{
void flower() {
print('梨花');
}
}
/**
* 桃树
*/
mixin Peach{
void flower() {
print('桃花');
}
}
如果本体里面如果有相同的函数,只会调用本体里面的方法。代码如下:
void main() {
Apricot().flower();
}
/**
* 杏树
*/
class Apricot with Pair{
void flower() {
print('杏花');
}
}
/**
* 梨树
*/
mixin Pair{
void flower() {
print('梨花');
}
}
4.2 mixin与extends之间的优先级
void main() {
Apricot().flower();
}
/**
* 杏树
*/
class Apricot extends Peach with Pair implements Apple{
}
abstract class Apple {
void flower();
}
/**
* 桃树
*/
class Peach{
void flower() {
print('桃花');
}
}
/**
* 梨树
*/
mixin Pair {
void flower() {
print('梨花');
}
}
相同方法的调用顺序:本体>with>extends>implements
限定符on主要是用于对mixin进行使用限定,当一个mixin后面跟着on xxClass(这里可以是类、接口、抽象类),那么使用这个mixin的宿主必须继承这个xxClass。如下:
/**
* 果树
*/
class Fruiter {
}
/**
* 杏树
*/
class Apricot extends Fruiter with Pair, Peach {
}
/**
* 桃树
*/
class Peach {
void flower() {
print('桃花');
}
}
/**
* 梨树
*/
mixin Pair on Fruiter {
void flower() {
print('梨花');
}
}
而on又有点像extends,比如:
abstract class Super {
void create() {
print("Super");
}
}
class Clazz implements Super {
void create() {
print("Create Clazz");
}
}
mixin Mixin on Super {
void create() {
super.create();
print("Create Mixin");
}
}
class Clazzz extends Clazz with Mixin {
}
void main() {
Clazzz().create();
}
Mixin类中可以使用super.create()函数,
被mixin定义的类不能实例化,不能有构造器
mixin不能使用extends继续其他类
一个类可以混入多个mixin
mixin可以使用implements实现接口
使用混入mixin,这不是继承关系