4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DartのMixin

Last updated at Posted at 2014-12-31

Mixinについて大分混乱したのでメモ。

Dartのクラス

Dartのクラスには2種類ある。

  1. 普通のクラス(class
  2. 抽象クラス(abstract class
    抽象クラスは全てのメソッドに実装を与える必要がないが、newによるインスタンス生成ができない。

Dartの継承

Dartの継承には2種類ある。

  1. extendsによる継承
  2. implementsによる継承
    extendsは継承元のインターフェースと実装を全て継承先に引き継ぐ。普通継承といえばこれ。あるクラスがextendsできるのは一つのクラスだけ。
    implementsは継承元のインターフェースを全て継承先に引き継ぐ。継承先からは継承元の実装を使うことができない。あるクラスから複数のクラスをimplementsできる。
    どちらも継承元の型を継承先の型で置き換えることができる。つまり、継承先の型は継承元の型のサブクラスになっている。

Mixin

DartにはMixin(クラスの合成)という機構がある。
Mixinは指定したクラスからインターフェースと実装を引き継ぐ(extendsによる継承と同じ)。
extendsと異なるのは、あるクラスから複数のクラスをMixinできるということ。
しかし、Mixinされる(インターフェースと実装を提供する)側のクラスはObject以外から実装を継承することができない。
ここがミソで、Mixinされるクラスでもインターフェースはいくらでも継承できる。
したがって、Mixinされることを目的としたクラスで(型の観点から)親クラスを持ちたい場合はimplementsによる継承をすれば良い。

class A {
  void hoge() => print('A');
}

// BはAのインターフェースのみを継承する
abstract class B implements A {
  void foo() => print('foo');
}

// CはBの実装とインターフェースを継承するが、
// BではA.hogeの実装が与えられていないので
// Cでhogeの実装を与える必要がある。
class C extends Object with B {
  void hoge() => print('C');
}

main() {
  C c = new C();
  c.hoge(); // => 'C'  Aの実装は使えない
  c.foo(); // => 'foo'  Bの実装は使える

  A a = c; // CはAのサブクラスとして扱われる
  B b = c; // CはBのサブクラスとして扱われる
}

参考:Dartのクラス継承、Implicit Interface、Mix-inについて

4
2
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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?