目录

Mixin

mixin 是一种定义可在多个类层次结构中重用的代码的方式。它们旨在批量提供成员实现。

要使用 mixin,请使用 with 关键字,后跟一个或多个 mixin 名称。以下示例显示了两个使用(或作为子类)mixin 的类:

dart
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 声明

Mixin 和 mixin 类不能具有 extends 子句,并且不能声明任何生成式构造函数。

例如:

dart
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 不能使用构造函数参数来实例化它们自己的字段)。

以下部分介绍了确保 mixin 的任何子类都定义 mixin 的行为依赖的任何成员的不同策略。

在 mixin 中定义抽象成员

#

在 mixin 中声明抽象方法会强制使用该 mixin 的任何类型都定义其行为所依赖的抽象方法。

dart
mixin Musician {
  void playInstrument(String instrumentName); // 抽象方法。

  void playPiano() {
    playInstrument('Piano');
  }
  void playFlute() {
    playInstrument('Flute');
  }
}

class Virtuoso with Musician {

  @override
  void playInstrument(String instrumentName) { // 子类必须定义。
    print('Plays the $instrumentName beautifully');
  }  
}

访问 mixin 子类中的状态

#

声明抽象成员还可以通过调用在 mixin 上定义为抽象的 getter 来访问 mixin 子类上的状态:

dart
/// 可应用于具有 [name] 属性的任何类型,并根据它提供 [hashCode] 和运算符 `==` 的实现。
mixin NameIdentity {
  String get name;

  @override
  int get hashCode => name.hashCode;

  @override
  bool operator ==(other) => other is NameIdentity && name == other.name;
}

class Person with NameIdentity {
  final String name;

  Person(this.name);
}

实现接口

#

类似于声明 mixin 为抽象,在 mixin 上放置 implements 子句而不实际实现接口,也将确保为 mixin 定义任何成员依赖项。

dart
abstract interface class Tuner {
  void tuneInstrument();
}

mixin Guitarist implements Tuner {
  void playSong() {
    tuneInstrument();

    print('Strums guitar majestically.');
  }
}

class PunkRocker with Guitarist {

  @override
  void tuneInstrument() {
    print("Don't bother, being out of tune is punk rock.");
  }
}

使用 on 子句声明超类

#

on 子句用于定义 super 调用解析的目标类型。因此,只有当您需要在 mixin 中进行 super 调用时,才应使用它。

on 子句强制使用 mixin 的任何类也必须是 on 子句中类型的子类。如果 mixin 依赖于超类中的成员,这将确保在使用 mixin 的地方可以使用这些成员:

dart
class Musician {
  musicianMethod() {
    print('Playing music!');
  }
}

mixin MusicalPerformer on Musician {
  performerMethod() {
    print('Performing music!');
    super.musicianMethod();
  }
}

class SingerDancer extends Musician with MusicalPerformer { }

main() {
  SingerDancer().performerMethod();
}

在此示例中,只有扩展或实现 Musician 类的类才能使用 mixin MusicalPerformer 。因为 SingerDancer 扩展了 Musician ,所以 SingerDancer 可以混合使用 MusicalPerformer

classmixinmixin class

#

mixin 声明定义了一个 mixin。 class 声明定义了一个 mixin class 声明定义了一个可用作常规类和 mixin 的类,具有相同的名称和相同的类型。

dart
mixin class Musician {
  // ...
}

class Novice with Musician { // 使用 Musician 作为 mixin
  // ...
}

class Novice extends Musician { // 使用 Musician 作为类
  // ...
}

适用于类或 mixin 的任何限制也适用于 mixin 类:

  • Mixin 不能有 extendswith 子句,因此 mixin class 也不能有。
  • 类不能有 on 子句,因此 mixin class 也不能有。