在 Dart 中有一較為特殊的關鍵字, Mixin 透過這個關鍵字可以讓我們實現多重繼承的關係,透過將關鍵字分離,可以更清楚在宣告時我們應該如何對此類別進行設計。
1.標準繼承
Class Child 繼承來至 Class A 在呼叫建構子的時候,進行呼叫 getMessage() ,沒意外的得到 A Construct -->A.getMessage() 的訊息。
abstract class A {
A() {
print('A Construct');
getMessage();
}
getMessage() {
print('-->A.getMessage()');
}
}
class Child extends A {}
void main() {
Child child = Child();
}
Output
A Construct
-->A.getMessage()
2.加入Mixin使用
增加 mixin MB 並於 混合於 Child 當中,MB Mixin 也是基於 A Class 所建構的,並透過 super 呼叫父類別的 getMessage 方法,也就是 -->A.getMessage() 。
mixin MB on A {
@override
getMessage() {
print('-->MixMB.getMessage()');
super.getMessage();
print('-->MixMB');
}
}
class Child extends A with MB {}
Output
A Construct
-->MixMB.getMessage()
-->A.getMessage()
-->MixMB
製造錯誤 🪲
我們嘗試把 class Child extends A with MB {} 。
Error: 'Object' doesn't implement 'A' so it can't be used with 'MB'.
此時編譯器提示錯誤,物件尚未實現 A 所以不可以混合 MB Mixin , 因為 MB 依賴著 Class A 所以如果混合 MB 時,類別未繼承制 A Class 就會得到提示,在使用上不可不留意!
3.再來一個Mix!
我們在替 Child Class 混合多一個類別, MC Mixin 程式與 MB Mixin 相同只是訊息部份從 MixMB 換成 MixMC 方便我們了解流程。
在MixMC中呼叫super.getMessage() 會先執行 MixMB 這邊Dart 使用堆疊的先進後出的方式,根據 with 後面的順序依序進行 pop 處理,就會看到我們的顯示結果!
mixin MC on A {
@override
getMessage() {
print('-->MixMC.getMessage()');
super.getMessage();
print('-->MixMC');
}
}
class Child extends A with MB, MC {}
Output
A Construct
-->MixMC.getMessage()
-->MixMB.getMessage()
-->A.getMessage()
-->MixMB
-->MixMC
4.再來一個Class!?
接著我們在替程式加上一個 Class B 並讓 MB 基於 A,B ,此時我們的Child 需要把B也跟著繼承,但是 extends 只能繼承一個Class 所以我們就把 B Class 用在 with 一起混入,執行後發現我們的 A Class 的getMessage 就被 B Class override 了,消失在我們的結果當中!
abstract class B {
getMessage() {
print('-->B.getMessage()');
}
}
mixin MB on A,B {
@override
getMessage() {
print('-->MixMB.getMessage()');
super.getMessage();
print('-->MixMB');
}
}
class Child extends A with B, MB, MC {}
Output
A Construct
-->MixMC.getMessage()
-->MixMB.getMessage()
-->B.getMessage()
-->MixMB
-->MixMC
Conclusion
Dart 中使用 Mixin 可以讓我們的物件重用性更高,更能減少我們程式碼重複部份,但邏輯上可能就會便得更加的複雜,使用上不可不謹慎!
後續會增加更多 Dart/Flutter 的開發介紹,歡迎大家持續關注!
Top comments (0)