前言
Mixins 混入其中( ̄. ̄)!
是的,Flutter 使用的是 Dart 支持 Mixin ,而 Mixin 能够更好的解决 多继承 中容易出现的问题,如: 方法优先顺序混乱、参数冲突、类结构变得复杂化等等。
Mixin 的定义解释起来会比较绕,我们直接代码从中来解释。 Dart语言的解析可以使用在线 https://dartpad.dartlang.org/ 来解决。
With
如下代码所示,在 Dart 中 with 就是用于 mixins。可以看出,class G extends B with A, A2 ,在执行 G 的 a、b、c 方法后,输出了 A2.a()、A.b() 、B.c() 。所以结论上简单来说,就是
相同方法被覆盖了,并且 with 后面的会覆盖前面的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class A {
a() {
print("A.a()");
}
b() {
print("A.b()");
}
}
class A2 {
a() {
print("A2.a()");
}
}
class B {
a() {
print("B.a()");
}
b() {
print("B.b()");
}
c() {
print("B.c()");
}
}
class G extends B with A, A2 {
}
testMixins() {
G t = new G();
t.a();
t.b();
t.c();
}
/// ***********************输出***********************
///I/flutter (13627): A2.a()
///I/flutter (13627): A.b()
///I/flutter (13627): B.c()
接下来我们继续修改下代码。如下所示,我们定义了一个 Base
的抽象类,而 A、A2、B
都继承它,同时再 print
之后执行 super()
操作。
从最后的输入我们可以看出,A、A2、B
中的 所有方法都被执行了,且只执行了一次,同时执行的顺序也是和 with 的顺序有关。
如果你把下方代码中 class A.a() 方法的 super 去掉,那么你将看不到 B.a()
和 base a()
的输出,这表明with语法继承从右往左的顺序依次根据当前类是否有 super
来决定是否调用左边一个类的同名函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
abstract class Base {
a() {
print("base a()");
}
b() {
print("base b()");
}
c() {
print("base c()");
}
}
class A extends Base {
a() {
print("A.a()");
super.a();
}
b() {
print("A.b()");
super.b();
}
}
class A2 extends Base {
a() {
print("A2.a()");
super.a();
}
}
class B extends Base {
a() {
print("B.a()");
super.a();
}
b() {
print("B.b()");
super.b();
}
c() {
print("B.c()");
super.c();
}
}
class G extends B with A, A2 {
}
testMixins() {
G t = new G();
t.a();
t.b();
t.c();
}
/// ***********************输出***********************
///I/flutter (13627): A2.a()
///I/flutter (13627): A.a()
///I/flutter (13627): B.a()
///I/flutter (13627): base a()
///I/flutter (13627): A.b()
///I/flutter (13627): B.b()
///I/flutter (13627): base b()
///I/flutter (13627): B.c()
///I/flutter (13627): base c()
总结
上面的两种例子表明,Dart中的类继承的带有with的语法的构造顺序是从右往左的顺序执行的,with覆盖了相同的函数,即有with的情况下,相同的函数从右往左只会调用一次。
如果添加了 super
调用,则会以此按照从右往左的顺序把当前有 super
语法的父类的同名函数调用一遍。
比较直观的还是参看上面的两个例子来的更好理解。