Mixinにおけるonキーワード
CoddyのDartジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 53/110。
ミックスインが、ミックスイン先のクラスのメソッドやプロパティを使用する必要がある場合があります。on キーワードを使用すると、特定の型を継承するクラスに対してのみミックスインを使用できるように制限できます。
class Animal {
String name;
Animal(this.name);
void breathe() => print('$name is breathing');
}
mixin Swimming on Animal {
void swim() {
print('$name is swimming'); // Animal から 'name' にアクセスできます
breathe(); // Animal のメソッドを呼び出すことができます
}
}
class Fish extends Animal with Swimming {
Fish(String name) : super(name);
}on Animal 宣言は、このミックスインが Animal を継承するクラスにのみ適用できることを意味します。これにより、ミックスインが Animal のメンバにアクセスできることが保証されます。on がないと、ミックスインは name や breathe() が存在することを知ることができません。
制限された mixin を互換性のないクラスで使用しようとすると、Dart はコンパイル時エラーを発生させます:
class Robot with Swimming {} // エラー!RobotはAnimalを継承していませんこの制約は、ミックスインの機能がベースクラスの特定の機能に依存している場合に役立ちます。これにより、より安全な契約が作成されます。ミックスインは特定の振る舞いを約束しますが、それは正しく動作するために必要な基盤がある場合に限られます。
チャレンジ
簡単on キーワードを使用して、ミックスインを特定のベースクラスでのみ動作するように制限する方法を示す車両システムを構築しましょう。ターボブースト機能を追加するミックスインを作成しますが、これは Vehicle ベースクラスを継承するクラスでのみ使用できるように制限します。
コードを2つのファイルに整理します:
vehicles.dart: ここでベースクラス、制限付きミックスイン、および車両タイプを定義します:String modelプロパティとint speedプロパティを持つVehicleクラス。両方の値を受け取るコンストラクタを含めます。[model] accelerating to [speed] km/hと出力するaccelerate()メソッドを追加します。onキーワードを使用してVehicleに制限されたTurboBoostミックスイン。このミックスインには、[model] TURBO ACTIVATED!と出力し、その後にaccelerate()を呼び出すactivateTurbo()メソッドを持たせる必要があります(これらはon Vehicle制約によりアクセス可能です)。Vehicleを継承し、TurboBoostミックスインを使用するSportsCarクラス。String colorプロパティを追加します。コンストラクタは model、speed、color を受け取る必要があります。[color] [model] ready to race!と出力するshowOff()メソッドを含めます。
main.dart: vehicles ファイルをインポートし、制限付きミックスインがどのように機能するかを示します:- model が
'Ferrari'、speed が320、color が'Red'のSportsCarを作成します。 showOff()を呼び出します。activateTurbo()を呼び出します。
- model が
TurboBoost ミックスインは、on Vehicle 宣言によって Vehicle を継承するクラスにのみミックスされることが保証されているため、model にアクセスし、accelerate() を呼び出すことができます。これにより、ミックスインが利用可能な機能を正確に把握できる安全なコントラクトが作成されます。
期待される出力:
Red Ferrari ready to race!
Ferrari TURBO ACTIVATED!
Ferrari accelerating to 320 km/hチートシート
onキーワードは、ミックスインを特定の型を継承するクラスのみで使用できるように制限します。これにより、ミックスインはベースクラスのメソッドやプロパティに安全にアクセスできるようになります。
class Animal {
String name;
Animal(this.name);
void breathe() => print('$name is breathing');
}
mixin Swimming on Animal {
void swim() {
print('$name is swimming'); // Animalの'name'にアクセス可能
breathe(); // Animalのメソッドを呼び出し可能
}
}
class Fish extends Animal with Swimming {
Fish(String name) : super(name);
}on Animal宣言は、ミックスインがAnimalのメンバーにアクセスできることを保証します。これがないと、ミックスインはnameやbreathe()が存在することを知ることができません。
制限されたミックスインを互換性のないクラスで使用しようとすると、コンパイルエラーが発生します:
class Robot with Swimming {} // エラー!RobotはAnimalを継承していませんこの制約は、ミックスインの機能がベースクラスの特定の機能に依存している場合に便利で、ミックスインとそれを使用するクラスとの間により安全な規約(コントラクト)を作成します。
自分で試してみよう
import 'vehicles.dart';
void main() {
// TODO: モデル 'Ferrari'、速度 320、色 'Red' で SportsCar を作成する
// TODO: showOff() を呼び出す
// TODO: activateTurbo() を呼び出す
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4Null Safety
Null Safety 入門Nullable と Non-Nullable? 演算子と ! 演算子late キーワードと Null SafetyNull-Aware 演算子クラスにおける Null Safetyまとめ:ユーザープロフィールシステム10コレクションとジェネリクス
List, Set, Map の概要型安全なコレクションジェネリッククラスジェネリックメソッドジェネリクスの制約Iterable と Iteratorまとめ:ジェネリックなストレージ