Mixin 是一种定义可在多个类层次结构中重用的代码的方法。它们旨在集体提供成员实现。
要使用 mixin,请使用 with 关键字,后跟一个或多个 mixin 名称。以下示例显示了两个使用 mixin 的类:
class Musician extends Performer with Musical {
// ···
}
class Maestro extends Person with Musical, Aggressive, Demented {
Maestro(String maestroName) {
name = maestroName;
canConduct = true;
}
}
要定义 mixin,请使用 mixin 声明。在极少数情况下,您需要同时定义 mixin 和类,您可以使用 mixin class 声明。
Mixins 和 mixin 类不能有 extends 子句,并且不能声明任何生成构造函数。
例如:
mixin Musical {
bool canPlayPiano = false;
bool canCompose = false;
bool canConduct = false;
void entertainMe() {
if (canPlayPiano) {
print('Playing piano');
} else if (canConduct) {
print('Waving hands');
} else {
print('Humming to self');
}
}
有时您可能想限制可以使用 mixin 的类型。例如,mixin 可能依赖于能够调用 mixin 未定义的方法。如以下示例所示,您可以通过使用 on 关键字指定所需的超类来限制 mixin 的使用:
class Musician {
// ...
}
mixin MusicalPerformer on Musician {
// ...
}
class SingerDancer extends Musician with MusicalPerformer {
// ...
}
在上面的代码中,只有扩展或实现 Musician 类的类才能使用 mixin MusicalPerformer 。因为 SingerDancer 扩展了 Musician ,所以 SingerDancer 可以混合在 MusicalPerformer 中。
class 、 mixin 或 mixin class ?
mixin class 声明需要至少 3.0 的语言版本。
mixin 声明定义了一个 mixin。 class 声明定义一个类。 mixin class 声明定义了一个类,该类既可以用作常规类,也可以用作 mixin,并且具有相同的名称和类型。
适用于类或 mixin 的任何限制也适用于 mixin 类:
- Mixin 不能有 extends 或 with 子句,因此 mixin class 也不能。
- 类不能有 on 子句,因此也不能有 mixin class 。
abstract mixin class
您可以实现与 mixin 类的 on 指令类似的行为。创建 mixin 类 abstract 并定义其行为所依赖的抽象方法:
abstract mixin class Musician {
// No 'on' clause, but an abstract method that other types must define if
// they want to use (mix in or extend) Musician:
void playInstrument(String instrumentName);
void playPiano() {
playInstrument('Piano');
}
void playFlute() {
playInstrument('Flute');
}
}
class Virtuoso with Musician { // Use Musician as a mixin
void playInstrument(String instrumentName) {
print('Plays the $instrumentName beautifully');
}
}
class Novice extends Musician { // Use Musician as a class
void playInstrument(String instrumentName) {
print('Plays the $instrumentName poorly');
}
}
通过将 Musician mixin 声明为抽象,您可以强制使用它的任何类型定义其行为所依赖的抽象方法。
这类似于 on 指令通过指定接口的超类来确保 mixin 可以访问它所依赖的任何接口。