0
点赞
收藏
分享

微信扫一扫

Dart 知识点 - 混入 Mixin

什么是混入 Mixin

​Mixin​​​ 是一种在多重继承中复用某个类中代码的方法模式。使用 ​​with​​​ 关键字并在其后跟上 ​​Mixin​​​ 类的名字来使用 ​​Mixin​​ 模式:

class Dog extends Animal with Walk, Bark {
// ...
}

怎么使用混入 Mixin

实现一个 ​​Mixin​​​ 类,要创建一个继承自 ​​Object​​ 其没有声明构造函数的类。

mixin Walk {
bool canWalk = true;
// 注意,没有构造函数
void walk() {
print('I can walk.')
}
}

我们使用关键字 ​​mixin​​​ 来代替 ​​class​​ 实现混入类。

​on​​​关键字(格式:​​on className​​​),指定哪些类可以使用该 ​​Mixin​​ 类。我们改写下上面的代码,如下:

// 表明 Walk 类只能被 Animal 类使用
mixin Walk on Animal {
bool canWalk = true;
// 注意,没有构造函数
void walk() {
print('I can walk.')
}
}

混入 Mixin 有什么应用场景

我们举个例子:

// 手机类
class Phone {
void startUp() {
print('start up');
}
void shutDown() {
print('shut down');
}
}

// sms - wechat
class Wechat {
void sms() {
print('install wechat');
}
}

// sms - facebook
class Facebook {
void sms() {
print('install facebook');
}
}

// ios 手机
class IosPhone extends Phone {
@override
void startUp() {
print('ios phone can start up');
}
}

// android 手机
class AndroidPhone extends Phone {
@override
void startUp() {
print('android phone can start up');
}
}

假设现在我有一台 ​​iPhone​​​ 的手机,里面有 ​​Wechat​​​ 和 ​​Facebook​​​,我们使用 ​​extends​​ 来实现,比如:

class Phone extends Wechat, Facebook {} ❌

明显不行,抛开 ​​手机继承功能​​​ 这个语义话的问题,语法上是不允许多继承的。​Dart 允许单继承

我们可以考虑使用混入 ​​Mixin​​。我们来改写下代码:

void main() {
IosPhone nameJimmy = new IosPhone();
nameJimmy.startUp(); // ios phone can start up
nameJimmy.sms(); // install facebook

AndroidPhone nameIvy = new AndroidPhone();
nameIvy.startUp(); // android phone can start up
nameIvy.sms(); // install wechat
nameIvy.specialFn(); // facebook special function
}

// 手机类
class Phone {
void startUp() {
print('start up');
}
void shutDown() {
print('shut down');
}
}

// sms - wechat
mixin Wechat {
void sms() {
print('install wechat');
}
}

// sms - facebook
mixin Facebook {
void sms() {
print('install facebook');
}

void specialFn() {
print('facebook special function');
}
}

// ios 手机
class IosPhone extends Phone with Facebook {
@override
void startUp() {
print('ios phone can start up');
}
}

// android 手机
class AndroidPhone extends Phone with Facebook, Wechat {
@override
void startUp() {
print('android phone can start up');
}
}

细心的读者应该发现了,​​Wechat​​​ 和 ​​Facebook​​​ 上都有 ​​sms​​​ 的功能,为什么 ​​nameIvy.sms()​​​ 中打印出来的是 ​​install wechat​​ 呢?这就涉及到了重名方法处理

重名方法处理

通过上面的代码示例,我们知道:

  • with 后面的类会覆盖前面的类的同名函数

void main() {
IosPhone nameJimmy = new IosPhone();
nameJimmy.startUp(); // ios phone can start up
nameJimmy.sms(); // I have mine
}

// sms - facebook
mixin Facebook {
void sms() {
print('install facebook');
}
}

// ios 手机
class IosPhone with Facebook {
@override
void startUp() {
print('ios phone can start up');
}

@override
void sms() {
print('I have mine');
}
}

我们现在重写 ​​sms​​​ 的方法,然后调用的时候,会调用 ​​IosPhone​​ 的重写方法。那么我们可以得到:

  • 类中重写了 Mixin 类中的方法,调用类自己的方法

我们总结一下:​​如果当前使用的类没有重写 Mixin 类的方法,则调用距离 with 最远的 Mixin 类方法;否则,调用重写的方法。​

如果读者觉得文章还可以,不防一键三连:关注➕点赞➕收藏


举报

相关推荐

0 条评论