search
LoginSignup
2

More than 1 year has passed since last update.

posted at

Dartのmixinを学んで見る

最近お気に入りの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
}

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

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
What you can do with signing up
2