DEV Community

Cover image for Dart - Mixin Vs Class
HyperRedStart
HyperRedStart

Posted on • Edited on

3 2

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 的開發介紹,歡迎大家持續關注!

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay