Dart 知識點 - 混入 Mixin

語言: CN / TW / HK

攜手創作,共同成長!這是我參與「掘金日新計劃 · 8 月更文挑戰」的第12天,點選檢視活動詳情

推薦使用線上編輯器 dartpad.cn 進行學習,測試~

什麼是混入 Mixin

Mixin 是一種在多重繼承中複用某個類中程式碼的方法模式。使用 with 關鍵字並在其後跟上 Mixin 類的名字來使用 Mixin 模式:

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

怎麼使用混入 Mixin

實現一個 Mixin 類,要建立一個繼承自 Object 其沒有宣告建構函式的類。

bash mixin Walk { bool canWalk = true; // 注意,沒有建構函式 void walk() { print('I can walk.') } }

我們使用關鍵字 mixin 來代替 class 實現混入類。

on關鍵字(格式:on className),指定哪些類可以使用該 Mixin 類。我們改寫下上面的程式碼,如下:

bash // 表明 Walk 類只能被 Animal 類使用 mixin Walk on Animal { bool canWalk = true; // 注意,沒有建構函式 void walk() { print('I can walk.') } }

混入 Mixin 有什麼應用場景

我們舉個例子:

```bash // 手機類 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 的手機,裡面有 WechatFacebook,我們使用 extends 來實現,比如:

bash class Phone extends Wechat, Facebook {} ❌

明顯不行,拋開 手機繼承功能 這個語義話的問題,語法上是不允許多繼承的。Dart 允許單繼承

我們可以考慮使用混入 Mixin。我們來改寫下程式碼:

```bash 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'); } } ```

細心的讀者應該發現了,WechatFacebook 上都有 sms 的功能,為什麼 nameIvy.sms() 中打印出來的是 install wechat 呢?這就涉及到了重名方法處理

重名方法處理

通過上面的程式碼示例,我們知道:

  • with 後面的類會覆蓋前面的類的同名函式

```bash 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 類方法;否則,呼叫重寫的方法。

往期精彩推薦

如果讀者覺得文章還可以,不防一鍵三連:關注➕點贊➕收藏