關(guān)于Dart Mixin 的一些理解
Mixin are a way of reusing code in multiple class hierarchies.
mixin 是什么?
維基百科中這樣定義 mixin:
in object-oriented programming languages, a Mixin is a class that contains methods for use by other class without having to be the parent class of those other classes.
即,mixin是個普通類,我們可以在不繼承這個類的情況下,從這個類借用方法和變量
Support for the mixin keyword was introduced in Dart 2.1. Code in earlier releases usually used abstract class instead.
從這個角度講,mixin不過是abstract class 。
Java tries to make up for this by using Interfaces, but that is not as useful or flexible as mixins .
小結(jié)
- mixin 有點類似 abstract class
- minxin 有點類似 interface
- mixin 不能繼承
on 的用法
The keyword on is used to restrict our mixin's use to only classes which either extends or implements the class it is declared on . In order to use the on keyword, you must declare your mixin using the mixin keyword.
class Z {}
mixin Y on Z {
void hi() {
print ('hi');
}
}
class Q with Y {}
則有如下錯誤提示:
'Y' can't be mixed onto 'Object' because 'Object' doesn't implement 'Z'.
on 關(guān)鍵字限制了Y的使用范圍: Y只能用于繼承或?qū)崿F(xiàn)了Z 的類。修復(fù)方式是讓Q 繼承 自Z:
class Q extends Z with Y {}
mixin 解決什么問題
mixin解決了多重繼承中的Deadly Diamond of Death(DDD) 問題
多重繼承問題簡單描述。各個類的繼承關(guān)系如下:

class Performer {
abstract void perform();
}
class Dancer extends Performer {
void perform();
}
class Singer extends Performer {
void perform();
}
class Musician extends Dancer, Singer {
}
問題來了,當(dāng)調(diào)用 Musician.perform() 時,到底會調(diào)用哪個 perform() 方法是模糊的。
來看 mixin 如何解決這個問題。
class Performer {
abstract void perform();
}
mixin Dancer {
void perform() {}
}
mixin Singer {
void perform() {}
}
class Musician extends Performer with Dancer, Singer {
}
現(xiàn)在,當(dāng)調(diào)用 Musician.perform() 時,到底會調(diào)用哪個 perform() 方法是確定的。在這里是調(diào)用 Singer.perform()。
mixin 有一套明確的機制來選擇調(diào)用哪個方法。

假設(shè) Musician 類使用多個 mixin (Dancer, Singer)。該類有個方法名為 perform(),Musician 類繼承自 Performer 類。
- 首先,將 Performer 類置于棧頂
- 其次,后聲明的 mixin 優(yōu)先于后聲明的 mixin。按順序?qū)?mixin 置于棧中,在這里分別是 Dancer, Singer
- 最后,將 Musician 類自己置于棧中。Musician 類中的 perform() 被優(yōu)先調(diào)用
Dart 使用的是單重繼承 (Java 也是單重繼承,C++ 是多重繼承)。多重繼承更為強大,但會引起 Deadly Diamond of Death(DDD) 問題。
Java 使用接口(interface)來部分實現(xiàn)多重繼承。多重繼承的問題是需要在每個類中實現(xiàn)接口(interface),所以并不是一個好的方案。(實際上 Java 已經(jīng)通過默認方法修復(fù)了這個問題)
所以 Dart 中就有了 mixin。
理解 mixin
Mixins in Dart work by creating a new class that layers the implementation of the mixin on top of a superclass to create a new class — it is not “on the side” but “on top” of the superclass, so there is no ambiguity in how to resolve lookups.
Mixins is not a way to get multiple inheritance in the classical sense. Mixins is a way to abstract and reuse a family of operations and state. It is similar to the reuse you get from extending a class, but it is compatible with single-inheritance because it is linear.
StackOverflow