Flutter mixin用法詳解

mixin是什麼

mixin應該怎麼理解呢,對Java系出身的我來講,這是一個新概念,各種資料的介紹也沒找到一個清晰的定義。從我的理解來看,能夠把它想象爲Kotlin中的接口(和Java的區別是能夠帶非抽象的屬性和方法),而多個mixin能夠相互覆蓋以實現組合,提供了很是大的靈活性,也能夠達到相似多重繼承的效果,本文將從簡單到複雜,演示mixin在Dart中的用法markdown

最簡單的mixin

mixin TestMixin {
  void test() {
    print('test');
  }
  int testInt = 1;
  void test2();
}

class Test with TestMixin {
  @override
  test2() {
    print('test2');
  }
}

void main() {
  Test().test();            // test
  print(Test().testInt);    // 1
  Test().test2();           // test2
}
複製代碼

mixin自己能夠是抽象的,能夠定義各類方法屬性,也能夠是抽象的,等後續類去實現ide

基於某個類型的mixin

class BaseObject {
  void method() {
    print('call method');
  }
}
mixin TestMixin on BaseObject{
  void test() {
    print('test');
  }
  int testInt = 1;
  void test2() {
    method();
  }
}

class Test extends BaseObject with TestMixin {
}

void main() {
  Test().test();            // test
  print(Test().testInt);    // 1
  Test().test2();           // call method
}
複製代碼

當使用on關鍵字,則表示該mixin只能在那個類的子類使用了,那麼結果顯然的,mixin中能夠調用那個類定義的方法、屬性ui

多個mixin

mixin TestMixin {
  void test() {
    print('test');
  }

  int testInt = 1;

  void test2();
}

mixin TestMixin2 {
  int testInt = 2;

  void test3() {
    print('test3');
  }
}

class Test with TestMixin, TestMixin2 {
  @override
  test2() {
    print('test2');
  }
}


void main() {
  Test().test();            // test
  print(Test().testInt);    // 2
  Test().test2();           // test2
  Test().test3();           // test3
}
複製代碼

若是把TestMixin和TestMixin2的前後順序改一下:spa

mixin TestMixin {
  void test() {
    print('test');
  }

  int testInt = 1;

  void test2();
}

mixin TestMixin2 {
  int testInt = 2;

  void test3() {
    print('test3');
  }
}

class Test with TestMixin2, TestMixin {
  @override
  test2() {
    print('test2');
  }
}

void main() {
  Test().test();            // test
  print(Test().testInt);    // 1
  Test().test2();           // test2
  Test().test3();           // test3
}
複製代碼

若是mixin存在衝突的部分,後面會覆蓋前面的,沒有衝突的則會保留,因此能夠存在後面的mixin修改了前面的mixin的一部分邏輯的狀況,不須要直接繼承便可實現覆蓋,避免了更復雜的繼承關係code

"多重繼承"

mixin TestMixin on BaseClass {
  void init() {
    print('TestMixin init start');
    super.init();
    print('TestMixin init end');
  }
}

mixin TestMixin2 on BaseClass {
  void init() {
    print('TestMixin2 init start');
    super.init();
    print('TestMixin2 init end');
  }
}

class BaseClass {
  void init() {
    print('Base init');
  }
  BaseClass() {
    init();
  }
}

class TestClass extends BaseClass with TestMixin, TestMixin2 {

  @override
  void init() {
    print('TestClass init start');
    super.init();
    print('TestClass init end');

  }
}

void main() {
  TestClass();
  /// TestClass init start
  /// TestMixin2 init start
  /// TestMixin init start
  /// Base init
  /// TestMixin init end
  /// TestMixin2 init end
  /// TestClass init end
}
複製代碼

稍微有點繞,能夠看到,這已經事實上達到多重繼承才能達到的效果了,寫起來比較麻煩,某種程度上也更不容易出錯(相對於C++)。。。源碼裏有最好也最複雜的例子—WidgetsFlutterBinding,它的定義以下:繼承

class WidgetsFlutterBinding extends BindingBase with GestureBinding, ServicesBinding, SchedulerBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding {}
複製代碼

具體WidgetsFlutterBinding的分析就沒啦,本身看源碼去吧~~接口

相關文章
相關標籤/搜索