浅谈Dart中的Mixin

原文引用 大专栏  https://www.dazhuanlan.com/2019/08/26/5d6335095dd24/


这篇本来要跟上一篇一起写

直到我发现Dart中Mixin的观念其实多到可以自成一篇QQ

观念

先来讲讲一些观念:

看完上述这几点,是不是心里只有 “马的,工三小?”

举个例子

接下来的话就来举个例子好了

现在有两种技能: Teach and Drive

而且有两种职业: Teacher and Driver

现在假设这两个职业都各持有Teach and Drive这两个技能

Java v.s. Dart

Java版本:

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
abstract class  {

}

interface Teach {
void canTeach();
}

interface Drive {
void canDrive();
}

class Teacher extends Human implements Teach, Drive {


public void canTeach() {
System.out.println("Yes, a human can teach.");
}

@Override
public void canDrive() {
System.out.println("Yes, a human can drive.");
}

}

class Driver extends Human implements Teach, Drive {

@Override
public void canTeach() {
System.out.println("Yes, a human can teach.");
}

@Override
public void canDrive() {
System.out.println("Yes, a human can drive.");
}

}

public static void main(String[] args) {

Teacher teacher = new Teacher();
teacher.canTeach();
teacher.canDrive();

Driver driver = new Driver();
driver.canTeach();
driver.canDrive();

}

Dart版本:

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
abstract class Human { 

}

class Teach {
void canTeach() {
print("Yes, a human can teach.");
}
}

class Drive {
void canDrive() {
print("Yes, a human can drive.");
}
}

class Teacher extends Human with Teach, Drive {}

class Driver extends Human with Teach, Drive {}

void main() {

Teacher teacher = new Teacher();
teacher.canTeach();
teacher.canDrive();

Driver driver = new Driver();
driver.canTeach();
driver.canDrive();

}

输出均为:

1
2
3
4
Yes, a human can teach.
Yes, a human can drive.
Yes, a human can teach.
Yes, a human can drive.

这里可以看到在Java版本的两个职业中,实践方法(技能)时出现重复的程序

而这里Dart版本中的Mixin类自带方法实现,从而解决了这个问题

(不过Java 8以上的default method也有同样的效果)

使Mixin类无法实例化

这里可以使用关键字mixin

1
2
3
4
5
6
mixin Teach {
// 这里就是一个标准的Mixin类,无法实例化
void canTeach() {
print("Yes, a human can teach.");
}
}

或者是改为abstract class

然后给定该类一个private constructor(dash代表私有),并设回传值为null

1
2
3
4
5
6
7
8
abstract class Drive {
// 这样一来Drive既不能扩充也不能实例化了
factory Drive._() => null;

void canDrive() {
print("Yes, a human can drive.");
}
}

mixin on

现在我们修改一下设定

假设说只有会教书的人能使用Teach这个技能呢?

这时我们可以用到mixin on这个关键字

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
abstract class Human {
// Some properties and methods...
}

class WhoCanTeach extends Human {
// 会教书的人
}

mixin Teach on WhoCanTeach {
// 这里就指定了只有extends WhoCanTeach或implements WhoCanTeach的类才能with Teach
void canTeach() {
print("Yes, a teacher can teach.");
}
}

abstract class Drive {
factory Drive._() => null;

void canDrive() {
print("Yes, a human can drive.");
}
}

class Teacher extends WhoCanTeach with Teach, Drive {
// Correct.
}

class Driver extends Human with Teach, Drive {
// Error: Driver does not implement WhoCanTeach.
}

class Driver extends Human with Drive {
// Correct.
}

void main() {

Teacher teacher = new Teacher();
teacher.canTeach();
teacher.canDrive();

Driver driver = new Driver();
driver.canDrive();

}

输出:

1
2
3
Yes, a teacher can teach.
Yes, a human can drive.
Yes, a human can drive.

线性化

看一下这个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Human {
String getStatus() => "Full of energy!";
}

class Student {
String getStatus() => "I'm tired!";
}

class Engineer {
String getStatus() => "I'm dying...";
}

class Me extends Human with Student, Engineer {}

void main() {

Me me = new Me();
print(me.getStatus());

}

好的,这里究竟会印出什么东西来呢?

答案是 “I’m dying…” QAQ

先讲结论: 越后面的Mixin类优先级别越高,等于是倒过来看啦~

拆解

上面的东西相当于这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Human {
String getStatus() => "Full of energy!";
}

class Student {
String getStatus() => "I'm tired!";
}

class Engineer {
String getStatus() => "I'm dying...";
}

class HumanWhoIsStudent extends Human with Student {}

class HumanWhoIsStudentAndEngineer extends HumanWhoIsStudent with Engineer {}

class Me extends HumanWhoIsStudentAndEngineer {}

void main() {

Me me = new Me();
print(me.getStatus());

}

简单来说,Mixin像是在实现一条线性的继承链

实例化后的类型

一样是上面的例子

1
2
3
4
5
6
7
8
9
void main() {

Me me = new Me();
print(me is Me);
print(me is Engineer);
print(me is Student);
print(me is Human);

}

输出:

1
2
3
4
true
true
true
true

猜你喜欢

转载自www.cnblogs.com/petewell/p/11410982.html
今日推荐