複数のMixinの使用
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 52/110。
複数のインターフェースを実装できるのと同様に、1つのクラスに複数のミックスインを適用することもできます。withキーワードの後に、カンマで区切ってそれらを並べるだけです。
mixin Swimming {
void swim() => print('Swimming');
}
mixin Flying {
void fly() => print('Flying');
}
mixin Walking {
void walk() => print('Walking');
}
class Duck with Swimming, Flying, Walking {
void quack() => print('Quack!');
}
void main() {
var duck = Duck();
duck.swim(); // Swimming mixinから
duck.fly(); // Flying mixinから
duck.walk(); // Walking mixinから
duck.quack(); // Duckクラスから
}ミキシンに同じ名前のメソッドがある場合、ミキシンの順序が重要になります。リストの最後のミキシンが優先されます:
mixin A {
void greet() => print('Hello from A');
}
mixin B {
void greet() => print('Hello from B');
}
class MyClass with A, B {}
void main() {
MyClass().greet(); // 出力: Hello from B
}B は A の後に来るため、その greet() メソッドが優先されます。このレイヤリング動作により、複雑な継承階層を介さずに、複数のソースからの機能を組み合わせて、必要な機能を正確に備えたクラスを構成できます。
チャレンジ
簡単ミックスインを通じて複数の機能を組み合わせるスマートホームデバイスシステムを構築しましょう。さまざまなスマート機能を表す異なるミックスインを作成し、それらすべてを組み合わせて使用するデバイスを構築します。
コードを2つのファイルに整理します:
smart_features.dart: 異なるスマートホーム機能を提供する3つのミックスインを定義します:VoiceControlミックスイン:Voice: [command]と出力するvoiceCommand(String command)メソッドを持ちます。WiFiEnabledミックスイン:Connected to [network]と出力するconnectWiFi(String network)メソッドを持ちます。PowerSaverミックスイン:Entering sleep mode...と出力するenterSleepMode()メソッドと、Waking up!と出力するwakeUp()メソッドを持ちます。
SmartSpeakerクラスを作成します。コンストラクタを持つString nameプロパティを追加し、[name] playing: [song]と出力するplayMusic(String song)メソッドを含めます。main.dart: スマート機能ファイルをインポートし、スピーカーがすべての機能をどのように組み合わせるかを実演します:'Echo'という名前のSmartSpeakerを作成します。connectWiFi('HomeNetwork')を呼び出します。voiceCommand('Play jazz')を呼び出します。playMusic('Smooth Jazz Mix')を呼び出します。enterSleepMode()を呼び出します。wakeUp()を呼び出します。
SmartSpeaker は、単一の with 句によって3つのミックスインすべてからメソッドを取得します。これは、複数のミックスインを使用することで、複雑な継承を行うことなく、必要な機能を正確に構成できることを示しています。
期待される出力:
Connected to HomeNetwork
Voice: Play jazz
Echo playing: Smooth Jazz Mix
Entering sleep mode...
Waking up!チートシート
クラスは、withキーワードの後にカンマで区切ってリストすることで、複数のミックスインを適用できます。
mixin Swimming {
void swim() => print('Swimming');
}
mixin Flying {
void fly() => print('Flying');
}
class Duck with Swimming, Flying {
void quack() => print('Quack!');
}
void main() {
var duck = Duck();
duck.swim(); // Swimmingミックスインから
duck.fly(); // Flyingミックスインから
duck.quack(); // Duckクラスから
}複数のミックスインが同じ名前のメソッドを持っている場合、リストの最後のミックスインが優先されます:
mixin A {
void greet() => print('Hello from A');
}
mixin B {
void greet() => print('Hello from B');
}
class MyClass with A, B {}
void main() {
MyClass().greet(); // 出力: Hello from B
}自分で試してみよう
import 'smart_features.dart';
void main() {
// TODO: 'Echo'という名前のSmartSpeakerを作成する
// TODO: connectWiFi('HomeNetwork')を呼び出す
// TODO: voiceCommand('Play jazz')を呼び出す
// TODO: playMusic('Smooth Jazz Mix')を呼び出す
// TODO: enterSleepMode()を呼び出す
// TODO: wakeUp()を呼び出す
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ