天天看點

Dart的mixin詳解

mixin 是什麼?

Mixin 是一種在多個類層次結構中重用代碼的方法。它是Dart裡的新特性。

mixin的用途

mixin是面向對象程式設計語言中的類,提供了方法的實作。其他類可以通路mixin類的方法、變量而不必成為其子類。Mixin的作用就是在多個類層次結構中重用類的代碼,在類中混入其他功能,來增強代碼的複用能力。

你可以将多個mixins放入同一個類中,而且dart對這個數量沒有作任何限制。

mixin的使用

使用with關鍵字将mixin加入到class中。用一個很簡單的例子來說明其使用方法:

1、聲明

聲明一個mixin

mixin Eat {
    void eat() {
        print('eating');
    }
}

mixin Speak {
    void speak() {
        print('speaking');
    }
}
           

2、混入到類中(使用with關鍵字)

abstract class Animal {
    void breath() {
        print('breath');
    }
}

class People extends Animal with Eat Speak  {

}
           

People這個類繼承自Animal類但是混入了Eat和Speak。People 這個類就有了Eat和Speak的屬性。

mixin的使用注意事項

  • 作為mixins的類隻能繼承自Object,不能繼承其他類
  • 作為mixins的類不能有構造函數

mixin的深入了解

可以使用關鍵字 on 來指定哪些類可以使用該 Mixin 類。

當聲明一個 mixin 時,on後面的類是使用這個mixin的父類限制。也就是說一個類若是要 with 這個 mixin,則這個類必須繼承或實作這個 mixin 的父類限制。

比如有 Mixin 類 A,但是 A 隻能被 B 類使用,則可以這樣定義 A:

class Musician {
  // ...
}
mixin MusicalPerformer on Musician {
  // ...
}
class SingerDancer extends Musician with MusicalPerformer {
  // ...
}
           

在這個例子中,隻有擴充或實作音樂家類的類才能使用mixin MusicalPerformer。

mixin 的順序決定了同名方法的調用關系

它類似于擴充類所獲得的重用,但它與單繼承相容,因為它是線性的。線性化決定了每次執行的是最上層超類的方法。

原理告訴我們一個非常重要的事情:聲明mixins的順序決定了繼承鍊,即決定了最上層到底層的超類(superclass)的排序。mixin 可以了解為對類的一種“增強”,但它與單繼承相容,因為它的繼承關系是線性的。

簡單來說with 後面的類會覆寫前面的類的同名方法。看下面這個例子

class A {
  String getMessage() => 'A';
}

class B {
  String getMessage() => 'B';
}

class P {
  String getMessage() => 'P';
}

class AB extends P with A, B {}

class BA extends P with B, A {}

void main() {
  String result = '';

  AB ab = AB();
  result += ab.getMessage();

  BA ba = BA();
  result += ba.getMessage();

  print(result);
}
           

結果是:BA

class A {
  printMessage() => print('A');
}

mixin B on A {
  printMessage() {
    super.printMessage();
    print('B');
  }
}

mixin C on B {
  printMessage() {
    super.printMessage();
    print('C');
  }
}

class D with A, B, C {
  printMessage() => super.printMessage();
}

void main() {
  D().printMessage();
}
           

輸出結果:

A

B

C

在看下面這個例子

class A {
  printMessage() => print('A');
}

class B {
  printMessage() => print('B');
}

mixin C on A {
  printMessage() {
    super.printMessage();
    print('C');
  }
}

class D with A, B, C {
  printMessage() => super.printMessage();
}

void main() {
  D().printMessage();
}
           

結果是:

B

C

是不是以為是

A

C

思考題

abstract class A {
  void method() {
    print("I am A");
  }
}

class B extends A{ 
  void method() {
    print("I am B");
  }
}

mixin Mixin on A {
  void method() {
    super.method();
    print("Mixin");
  }
}

class Test extends B with Mixin {}


void main() {
    Test cli = new Test();
    cli.method();
}