DEV Community

Cover image for Dart - Mixin Vs Class
HyperRedStart
HyperRedStart

Posted on • Edited on

Dart - Mixin Vs Class

在 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();
}
Enter fullscreen mode Exit fullscreen mode

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 {}
Enter fullscreen mode Exit fullscreen mode

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 {}
Enter fullscreen mode Exit fullscreen mode

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 {}
Enter fullscreen mode Exit fullscreen mode

Output

A Construct
-->MixMC.getMessage()
-->MixMB.getMessage()
-->B.getMessage()
-->MixMB
-->MixMC

Conclusion

Dart 中使用 Mixin 可以讓我們的物件重用性更高,更能減少我們程式碼重複部份,但邏輯上可能就會便得更加的複雜,使用上不可不謹慎!

後續會增加更多 Dart/Flutter 的開發介紹,歡迎大家持續關注!

Top comments (0)