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