混入是定義可以在多個類別層級中重複使用的程式碼的一種方式。它們旨在大量提供成員實作。

若要使用混入,請使用 with 關鍵字,後接一個或多個混入名稱。下列範例顯示兩個使用混入的類別

dart
class Musician extends Performer with Musical {
  // ···
}

class Maestro extends Person with Musical, Aggressive, Demented {
  Maestro(String maestroName) {
    name = maestroName;
    canConduct = true;
  }
}

若要定義混合,請使用 mixin 宣告。在罕見的情況下,當您需要同時定義混合和類別時,可以使用 mixin class 宣告

混合和混合類別不能有 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');
    }
  }
}

有時您可能想要限制可以使用混合的類型。例如,混合可能依賴於能夠呼叫混合未定義的方法。如下列範例所示,您可以使用 on 關鍵字來指定所需的超類別,以限制混合的使用

dart
class Musician {
  // ...
}

mixin MusicalPerformer on Musician {
  // ...
}
class SingerDancer extends Musician with MusicalPerformer {
  // ...
}

在上述程式碼中,只有延伸或實作 Musician 類別的類別才能使用混合 MusicalPerformer。由於 SingerDancer 延伸 Musician,因此 SingerDancer 可以混合 MusicalPerformer

classmixinmixin class

#

mixin 宣告定義混合。class 宣告定義 類別mixin class 宣告定義一個類別,可以用作一般類別和混合,名稱和類型相同。

適用於類別或混合的任何限制也適用於混合類別

  • 混合不能有 extendswith 子句,因此 mixin class 也不能有。
  • 類別不能有 on 子句,因此 mixin class 也不能有。

抽象混合類別

#

您可以針對混合類別達成類似於 on 指令的行為。讓混合類別成為 abstract,並定義其行為依賴的抽象方法

dart
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 混合為抽象,您可以強制使用它的任何類型定義其行為依賴的抽象方法。

這類似於 on 指令如何透過指定該介面的超類別,來確保混合可以存取它依賴的任何介面。