原文引用 大专栏 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 { 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 { 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 { }
class WhoCanTeach extends Human { }
mixin Teach on WhoCanTeach { 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 { }
class Driver extends Human with Teach, Drive { }
class Driver extends Human with Drive { }
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); }
|
输出: