关于Dart Mixin 的一些理解
Mixin are a way of reusing code in multiple class hierarchies.
mixin 是什么?
维基百科中这样定义 mixin:
in object-oriented programming languages, a Mixin is a class that contains methods for use by other class without having to be the parent class of those other classes.
即,mixin是个普通类,我们可以在不继承这个类的情况下,从这个类借用方法和变量
Support for the mixin keyword was introduced in Dart 2.1. Code in earlier releases usually used abstract class instead.
从这个角度讲,mixin不过是abstract class 。
Java tries to make up for this by using Interfaces, but that is not as useful or flexible as mixins .
小结
- mixin 有点类似 abstract class
- minxin 有点类似 interface
- mixin 不能继承
on 的用法
The keyword on is used to restrict our mixin's use to only classes which either extends or implements the class it is declared on . In order to use the on keyword, you must declare your mixin using the mixin keyword.
class Z {}
mixin Y on Z {
void hi() {
print ('hi');
}
}
class Q with Y {}
则有如下错误提示:
'Y' can't be mixed onto 'Object' because 'Object' doesn't implement 'Z'.
on 关键字限制了Y的使用范围: Y只能用于继承或实现了Z 的类。修复方式是让Q 继承 自Z:
class Q extends Z with Y {}
mixin 解决什么问题
mixin解决了多重继承中的Deadly Diamond of Death(DDD) 问题
多重继承问题简单描述。各个类的继承关系如下:
class Performer {
abstract void perform();
}
class Dancer extends Performer {
void perform();
}
class Singer extends Performer {
void perform();
}
class Musician extends Dancer, Singer {
}
问题来了,当调用 Musician.perform() 时,到底会调用哪个 perform() 方法是模糊的。
来看 mixin 如何解决这个问题。
class Performer {
abstract void perform();
}
mixin Dancer {
void perform() {}
}
mixin Singer {
void perform() {}
}
class Musician extends Performer with Dancer, Singer {
}
现在,当调用 Musician.perform() 时,到底会调用哪个 perform() 方法是确定的。在这里是调用 Singer.perform()。
mixin 有一套明确的机制来选择调用哪个方法。
假设 Musician 类使用多个 mixin (Dancer, Singer)。该类有个方法名为 perform(),Musician 类继承自 Performer 类。
- 首先,将 Performer 类置于栈顶
- 其次,后声明的 mixin 优先于后声明的 mixin。按顺序将 mixin 置于栈中,在这里分别是 Dancer, Singer
- 最后,将 Musician 类自己置于栈中。Musician 类中的 perform() 被优先调用
Dart 使用的是单重继承 (Java 也是单重继承,C++ 是多重继承)。多重继承更为强大,但会引起 Deadly Diamond of Death(DDD) 问题。
Java 使用接口(interface)来部分实现多重继承。多重继承的问题是需要在每个类中实现接口(interface),所以并不是一个好的方案。(实际上 Java 已经通过默认方法修复了这个问题)
所以 Dart 中就有了 mixin。
理解 mixin
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.
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.
StackOverflow