LoginSignup
8
3

More than 3 years have passed since last update.

最近お気に入りのresocoderさんの、mixinに関する記事で学習しました。

Mixinが必要になるストーリー

単一継承でうまくいっているパターン

  • Mosquitoクラスが抽象クラスAirborneInsectを継承(extends)します。
  • AirborneInsectクラスはflutter()buzz()というメソッドを持っています。
  • Mosquitoクラスのインスタンスは flutter()呼び出せます!

単一継承でうまくいかないパターン

  • 昆虫だけでなく、鳥も扱うことになりました!
  • 抽象クラスBirdflutter()を持ちます。
  • Birdを継承したSwallowflutter()を呼び出せます!
  • しかしこのflutter()AirborneInsectBirdで重複しています!

複数の抽象クラスが同じメソッドを持つ重複を解決: mixin

ここで多重継承を可能にするmixinを使います。
以下のコードではFlutteringクラスを、AirborneInsectBird適用しています。

これでコードの重複がなくなりました!

実際のコード

mixin Fluttering {
  void flutter() {
    print('fluttering');
  }
}

abstract class Insect {
  void crawl() {
    print('crawling');
  }
}

abstract class AirborneInsect extends Insect with Fluttering {
  void buzz() {
    print('buzzing annoyingly');
  }
}

class Mosquito extends AirborneInsect {
  void doMosquitoThing() {
    crawl();
    flutter();
    buzz();
    print('sucking blood');
  }
}

abstract class Bird with Fluttering {
  void chirp() {
    print('chirp chirp');
  }
}

class Swallow extends Bird {
  void doSwallowThing() {
    chirp();
    flutter();
    print('eating a mosquito');
  }
}

Mixinの使い方

mixinで定義して、with句で適用します。
fieldとmethodを継承できます。また、複数mixinを適用できます。
またmixinは親クラスに適用され、新しい匿名クラスを生成しているようです。

// mixinの定義
mixin M1{
  int number = 42;
  void say() => print('M1!');
}
mixin M2{
  String name = 'M2';
  void hello() => print('hello!');
}

// mixinの適用
class C extends Object with M1, M2 {}

main() { 
  var c = C();
  c.say();          // M1!
  c.hello();        // hello!
  print(c.number);  // 42
  print(c.name);    // M2
}

まずはコードの重複をなくす目的で使ってみると良いと思います。

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3