介绍
Mixin 是一种在多重继承中复用某个类中代码的方法模式。
Mixin 是面向对象程序设计语言中的类,提供了方法的实现。其他类可以访问mixin
类的方法、变量而不必成为其子类。
简单来说就是官方设计了一个种可以方便复用的类,不必去实现很多接口。
应用场景
比如说这里有一个Anmal的超类,下面有三个子类分别是Mammal、Bird、Fish,在其下还有更多的子类。
这里我们拿三个类来实例,分别是Duck、Cat、Dove,其中Duck三种方法都会,Cat会walk,Dove会walk和fly,如果要用继承来实现的话如下:
abstract class Animal{}
abstract class Swim{
void swim();
}
abstract class Walk{
void walk();
}
abstract class Fly{
void fly();
}
class Duck extends Animal implements Swim,Walk,Fly{
@override
void fly() => print("fly");
@override
void swim() => print("swim");
@override
void walk() => print("walk");
}
class Cat extends Animal implements Walk{
@override
void walk() => print("walk");
}
class Dove extends Animal implements Walk,Fly{
@override
void fly() => print("fly");
@override
void walk() => print("walk");
}
void main(){
Duck().swim();
Duck().walk();
Duck().fly();
Cat().walk();
Dove().fly();
Dove().walk();
}
输出的结果如下:
因为dart也是单继承语言,这种用法和java中是完全一样的,但是接口中所有的方法都要重写就很冗余,有没有一种办法我们可以复用接口里的方法呢,这时就可以来使用mixin了。
我们用mixin来代替接口,想要重用mixin类的方法只需要在类后面加上with关键字即可,如下:
abstract class Animal{}
mixin Swim{
void swim() => print("swim");
}
mixin Walk{
void walk() => print("walk");
}
mixin Fly{
void fly() => print("fly");
}
class Duck extends Animal with Swim,Walk,Fly{}
class Cat extends Animal with Walk{}
class Dove extends Animal with Walk,Fly{}
void main(){
Duck().swim();
Duck().walk();
Duck().fly();
Cat().walk();
Dove().fly();
Dove().walk();
}
最后打印出来的结果是上面完全一致的,想要实现类中特例的方法也和接口的使用方法是一样的,直接重写就行。
进阶用法
mixin的线性化特性
如果我们混入的类中,存在相同的方法,会怎么调用呢?比如在Person类和A类中都定义了run()方法,我们在Male类中调用试一试
class Person{ run() => print("person"); }
mixin A{ run() => print("A"); }
class Male extends Person with A{}
main(){
Male().run();
}
结果如下:
-------------------------------------------------------------------------------------------------------
A
这里只执行了A类中的run()方法,在dart中,有一种叫做线性化的语法特性
上面mixin的代码等同于
Class PersonA = Person with A
Class Male extends PersonA;
相当于Person类中的run()方法被A重写了,所以调用的是A类里的重写后的run()方法。
那我们有办法调用Person类中的方法吗?答案当然是可以的,而且很简单,既然是继承,我们直接调用父方法就行了,加上super.run()
class Person{ run() => print("person"); }
mixin A{
@override
run() {
super.run();
print("A");
}
}
class Male extends Person with A{}
main(){
Male().run();
}
输出结果为:
person
A
on
在使用mixin的时候可以用on关键字来限制,在混入该类的时候必须先继承或混入on后面的类
如:
class Person{ run() => print("person"); }
mixin A{ run() => print("A"); }
mixin C on Person{
@override
run() {
super.run();
print("C");
}
}
//这里还可以是
//class Femal extends Person with A,C{}
class Female with A,Person,C{} //混入时,Person类必须在C之前
main(){
Female().run();
}
最后输出
person
C
参考