Flutter mixins 探究
mixins
作為Flutter的重要特性,值得好好研究一下
0x01 mixins的定義
mixins
的中文意思是混入,就是在類中混入其他功能。
Dart中的定義是:
Mixins are a way of reusing a class’s code in multiple class hierarchies. 複製程式碼
Mixins是一種在多個類層次結構中重用類程式碼的方法。
可以看出Mixins最重要的功能是重用程式碼,我們先看下JAVA,重用程式碼的方式有哪些:
-
繼承
子類可以複用父類的方法和屬性,但是JAVA裡的繼承只能單繼承。
-
組合
將要重用的程式碼,封裝成類A,讓其他類持有A的例項,看上去貌似解決了重用程式碼的問題,但是一方面,每個類持有的A的例項是不同的,有多少個類,就總共有多少個A的例項,而且另一方面,即使A使用單例,使用起來也很不方便。
-
介面 定義一個介面interface,類實現interface,這樣雖然介面是同一個,但是實現卻是分散的,能重用的程式碼是有限的。
所以在JAVA裡想要重用程式碼,限制是很多的。
這就有了mixins
的概念,mixins
最早的根源來自於Lisp,因為Dart也受到smalltakk的影響,所以Dart引入了mixins
的概念,
在維基百科中有對mixins
最準確的定義:
在面向物件的語言中,mixins類是一個可以把自己的方法提供給其他類使用,但卻不需要成為其他類的父類。 複製程式碼
mixins
要重用的程式碼,不是方法或者是介面,而是類!
這裡舉個例子,有一個類A,A中有一個方法a(),還有一個方法B,也想使用a()方法,那麼這時候就需要用到mixins,類A就是mixins類(混入類),類B就是要被mixins的類,對應的Dart程式碼如下:
class A { String content = 'A Class'; void a(){ print("a"); } } class B with A{ } B b = new B(); print(b.content); b.a(); 複製程式碼
輸出是:
A Class a 複製程式碼
將類Amixins 到 B,B可以使用A的屬性和方法,B就具備了A的功能,但是需要強調的是:
-
mixins的物件是類
-
mixins絕不是繼承,也不是介面,而是一種全新的特性
0x02 with
mixins要用到的關鍵字 with
怎麼來理解with
呢?很簡單:
繼承 -> extends
mixins -> with
繼承和mixins是一樣的,是語言的特性,with和extends是關鍵字。
0x03 使用mixins的條件
因為mixins使用的條件,隨著Dart版本一直在變,這裡講的是Dart2.1中使用mixins的條件:
on
0x04 一個類可以mixins多個mixins類
看下面程式碼:
class A { void a(){ print("a"); } } class A1 { void a1(){ print("a1"); } } class B with A,A1{ } B b = new B(); b.a(); b.a1(); 複製程式碼
輸出是:
a a1 複製程式碼
但是,如果A和A1的方法相同,而且調換A和A1的順序,在被mixins的類中實現同一個方法呢,看下面的程式碼:
class A { void a(){ print("a"); } } class A1 { void a(){ print("a1"); } } class B with A,A1{ } class B1 with A1,A{ } class B2 with A,A1{ void a(){ print("b2"); } } class C { void a(){ print("a1"); } } class B3 extends C with A,A1{ } class B4 extends C with A1,A{ } class B5 extends C with A,A1{ void a(){ print("b5"); } } B b = new B(); B1 b1 = new B1(); B2 b2 = new B2(); B3 b3 = new B3(); B4 b4 = new B4(); B5 b5 = new B5(); b.a(); b1.a(); b2.a(); b3.a(); b4.a(); b5.a(); 複製程式碼
會是什麼樣的結果呢?
0x05 mixins的實現原理
Mixins in Dart work by creating a new class that layers the implementation of the mixin on top of a superclass to create a new class — it is not “on the side” but “on top” of the superclass, so there is no ambiguity in how to resolve lookups. 複製程式碼
以
class B3 extends C with A,A1{ } 複製程式碼
為例,可以分解為:
class CA = C with A; class CAA1 = CA with A1; class B3 extends CAA1{ } 複製程式碼
mixins不是多繼承
Mixins is not a way to get multiple inheritance in the classical sense. Mixins is a way to abstract and reuse a family of operations and state. It is similar to the reuse you get from extending a class, but it is compatible with single-inheritance because it is linear. 複製程式碼
所以輸出結果是:
a1 a b2 a1 a b5 複製程式碼