Dart 知識點 - 混入 Mixin
攜手創作,共同成長!這是我參與「掘金日新計劃 · 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
的手機,裡面有 Wechat
和 Facebook
,我們使用 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'); } } ```
細心的讀者應該發現了,Wechat
和 Facebook
上都有 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 類方法;否則,呼叫重寫的方法。
往期精彩推薦
如果讀者覺得文章還可以,不防一鍵三連:關注➕點贊➕收藏
- 前端開發中 5 個很讚的資源
- 懂點心理學 - 馬太效應
- Flutter 構建一個 todo list 應用
- Dart 知識點 - 資料型別
- Dart 知識點 - 混入 Mixin
- Dart 知識點 - 集合 List, Set, Map
- Flutter - 使用 push(), pop() 和路由進行導航
- Dart 知識點 - 面向物件基礎
- Flutter: Stateful 掛件 vs Stateless 掛件
- Flutter 實現登入 UI
- Dart 知識點 - 抽象類和介面
- 自 2020 年以來全球的開源商業化軟體融資情況
- IstioCon 2022 回顧及錄影、PPT 分享
- 網頁實現 1CM 物理長度
- Flutter 開發出現的那些 Bugs 和解決方案「持續更新... 」
- 仿寫新聞客戶端
- Beyond Istio OSS —— Istio 服務網格的現狀及未來
- 在外企的工作生活「年中總結」
- 如何在 Istio 中整合 SPRIRE?
- Javascript尾遞迴程式設計