#头条创作挑战赛#
本文同步本人掘金平台的文章:
https://juejin.cn/post/7128957843314573349
推荐使用线上编辑器 dartpad.cn 进行学习,测试~
Mixin 是一种在多重继承中复用某个类中代码的方法模式。使用 with 关键字并在其后跟上 Mixin 类的名字来使用 Mixin 模式:
class Dog extends Animal with Walk, Bark { // ...}复制代码
实现一个 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.') }}复制代码
我们举个例子:
// 手机类class Phone { void startUp() { print('start up'); } void shutDown() { print('shut down'); }}// sms - wechatclass Wechat { void sms() { print('install wechat'); }}// sms - facebookclass 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 - wechatmixin Wechat { void sms() { print('install wechat'); }}// sms - facebookmixin 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 呢?这就涉及到了重名方法处理。
通过上面的代码示例,我们知道:
void main() { IosPhone nameJimmy = new IosPhone(); nameJimmy.startUp(); // ios phone can start up nameJimmy.sms(); // I have mine}// sms - facebookmixin 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 类的方法,则调用距离 with 最远的 Mixin 类方法;否则,调用重写的方法。
如果读者觉得文章还可以,不防一键三连:关注➕点赞➕收藏