Mixin

Last updated: ... / Reads: 42 Edit

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 可以访问它所依赖的任何接口。


Comments

Make a comment