docs

TOP(About this memo)) > 一覧(Dart) > ミックスイン

mixin

class C1 extends A2 with M2 {
  // M1がonをしているA2を継承する必要がある。
  
  // M2がM1をonしているがM1.a()を実装していないため、こちらで実装する必要がある。
  void a(){}
}
mixin M1 {
  void a(); 
}
class A2 {
  void ab() {}
}
mixin M2 on A2 implements M1 {// mixinをimplementsすることもできる。
  // onで指定したクラス・mixinの任意のメソッドをオーバーライドできる。
  // 実装しなくてもエラーとはならないが、withをするclassの方で実装する必要がある。
  @override
  void ab() {}
}

mixin M3 on M1, M2 {// mixinに対してもonができる。
  void d();
}

class C2 with M4,M5 {}// M5がonをしているM4を継承している必要があるが、M4はmixinのためwithにする。
mixin M4 {}
mixin M5 on M4{}

// このあたりまで複雑になると筆者も良くわからない。
class C3 extends C1 with M3 {
  @override
  void ab() {}
  @override
  void a() {}
  @override
  void d() {}
}
class C1 {
  f() => print("C1");
}
class C2 extends C1 with M1 {
  // 同名のメソッドが存在する場合は、オーバライドされる。
  // この場合、C1のメソッドf()と同名のメソッドがM1に存在するため上書きされる。
  // C2.f()のsuper.f()はこのオーバーライドされたM1の方のf()になる。
  f() { 
    print("C2");
    super.f();
  }
}
mixin M1 {
  f() => print("M1");
}
void main() => C2().f();
// C2
// M1

mixin class

複数のmixinが同名のメソッドをオーバーライドした場合

void main() => C2();
abstract class C1 {
  C1() {
    f();
  }
  void f() => print("C1");
}
class C2 extends C1 with M1, M2 {
  C2() {
    print("C2 constructor");
  }
}
mixin M1 on C1{
  @override
  void f() {
    print("M1");
    super.f();
  }
}
mixin M2 on C1{
  @override
  void f() {
    print("M2");
    super.f();
  }
}
/*
M2
M1
C1
C2 constructor
*/

(参考) Flutterの ensureInitialized()メソッド

余談