理解Dart的Mixin
Mixin是面向对象程序设计语言中的类,提供了方法的实现。其它类可以访问mixin类的方法而不必成为其子类。Mixin有时被称作"included(包含)"而不是"inherited(继承)"。mixin为使用它的class提供额外的功能
Mixin是面向对象程序设计语言中的类,提供了方法的实现。其它类可以访问mixin类的方法而不必成为其子类。Mixin有时被称作"included(包含)"而不是"inherited(继承)"。mixin为使用它的class提供额外的功能,但自身却不单独使用(不能单独生成实例对象,属于抽象类)。因为有以上限制,Mixin类通常作为功能模块使用,在需要该功能时“混入”,而且不会使类的关系变得复杂
Mixin有利于代码复用,又避免了多继承的复杂。使用Mixin享有单一继承的单纯性和多重继承的共有性。接口与mixin相同的地方是都可以多继承,不同的地方在于 mixin 是带实现的。Mixin也可以看作是带实现的interface。这种设计模式实现了依赖反转的原则
如果你没有类的基础,请先阅读我们的Dart中的类,理解Dart的继承,接口,再看本文章
可能你会觉得上面说的太复杂,下面以一个真实的示例,看看Mixin在什么时候使用,以及加入了Mixin的类中的代码优先执行顺序,我们来看看下面的类继承图
我们有一个超类Animal,它有三个子类(Mammal, Bird, 和 Fish),三个子类下还有多个子类,这多个子类旁边的小方块代表其行为,比如蓝色小方块表示一个类的实例行为是游泳,灰色表示飞行,黄色表示行走
某些动物可能会共享某一些行为,比如Bat,Dove,Duck,Flying Fish都是会飞行的。但是这些行为与此分类正交,因此我们无法在父类中实现这些行为。
如果一个类可以有多个父类,这将会变得非常简单,我们只需要让第三层动物Cat,Bat等继承多个类的行为,就可以实现。但是Dart只允许继承一个父类
如何在不是在继承基础上在Bat,Cat等类中实现行走,飞行等行为。我们可以找到第二个方案就是将这些行为的类都作为接口来实现,但是这样还差一步没有实现我们的目标,这还会导致很多重复代码,因为你需要在Cat,Bat等类中实现这些动物的行为,比如行走,每个Cat,Bat类都实现一次
我们需要一种在多个类层次结构中重用类的代码的方法,,就是mixin
Mixins are a way of reusing a class’s code in multiple class hierarchies.
这看起来很容易😁,首先我们看看Dart如何定义mixin,下面是一个简单定义的mixin
mixin Musical {
bool canPlayPiano = false;
void entertainMe() {
// code
}
}
要使用mixin,请使用with关键字后跟一个或多个mixin名称。以下示例显示了两个使用mixins的类
class Musician extends Performer with Musical,Demented {
// ···
}
现在我们知道基本的语法,下面我们以代码的方式实现上面的案例,首先将行走,飞行等行为定义为mixin,其它的行为都是用以下的方式来定义
mixin Walker {
void walk() {
print("I'm walking");
}
}
注意mixin是不能被实例化的,也不能被继承,如果你要实例化请使用正常的类
下面是这个示例的完整代码
abstract class Animal {}
abstract class Mammal extends Animal {}
abstract class Bird extends Animal {}
abstract class Fish extends Animal {}
mixin Walker {
void walk() {
print("I'm walking");
}
}
mixin Swimmer {
void swim() {
print("I'm swimming");
}
}
mixin Flyer {
void fly() {
print("I'm flying");
}
}
class Dolphin extends Mammal with Swimmer {}
class Bat extends Mammal with Walker, Flyer {}
class Cat extends Mammal with Walker {}
class Dove extends Bird with Walker, Flyer {}
class Duck extends Bird with Walker, Swimmer, Flyer {}
class Shark extends Fish with Swimmer {}
class FlyingFish extends Fish with Swimmer, Flyer {}
main(List<String> arguments) {
Cat cat = Cat();
Dove dove = Dove();
// cat可以行走.
cat.walk();
// dove可以飞行.
dove.walk();
dove.fly();
// cat不能飞行.
// cat.fly();
}
现在你可以会过头来理解顶部描述,如果你能看明白顶部说明你基本理解了Mixin,下面我们继续深入理解Mixin
为了加深理解对理解,我还需要知道使用多个Mixin时那个方法会先被执行,参考以下代码,大家可以留言猜测result的结果是什么
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);
}
Mixin如此强大,并且规范不断在变化,以后继续更新详细Mixin执行过程