Menu
Coddy logo textTech

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 がないと、ミックスインは namebreathe() が存在することを知ることができません。

制限された mixin を互換性のないクラスで使用しようとすると、Dart はコンパイル時エラーを発生させます:

class Robot with Swimming {}  // エラー!RobotはAnimalを継承していません

この制約は、ミックスインの機能がベースクラスの特定の機能に依存している場合に役立ちます。これにより、より安全な契約が作成されます。ミックスインは特定の振る舞いを約束しますが、それは正しく動作するために必要な基盤がある場合に限られます。

challenge icon

チャレンジ

簡単

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() を呼び出します。

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のメンバーにアクセスできることを保証します。これがないと、ミックスインはnamebreathe()が存在することを知ることができません。

制限されたミックスインを互換性のないクラスで使用しようとすると、コンパイルエラーが発生します:

class Robot with Swimming {}  // エラー!RobotはAnimalを継承していません

この制約は、ミックスインの機能がベースクラスの特定の機能に依存している場合に便利で、ミックスインとそれを使用するクラスとの間により安全な規約(コントラクト)を作成します。

自分で試してみよう

import 'vehicles.dart';

void main() {
  // TODO: モデル 'Ferrari'、速度 320、色 'Red' で SportsCar を作成する
  
  // TODO: showOff() を呼び出す
  
  // TODO: activateTurbo() を呼び出す
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン