abstract、interface、final、base、mixin、以及它们的各种组合,各种代表啥?有啥用?
先上一个令人迷糊的,这是官网的示例:
它说
Car不能继承Vehicle,但是我复制代码到一个测试文件里,它并没有报错:
我有那么一瞬间认为官网的搞错了!后来才发现,它这个跟_是一个玩法:都要区分文件。这样改为2个文件就能正常报错了:
回到标题,鉴于太懒不想写,直接贴官网的表格:
| Declaration | Construct? | Extend? | Implement? | Mix in? | Exhaustive? |
|---|---|---|---|---|---|
class | Yes | Yes | Yes | No | No |
base class | Yes | Yes | No | No | No |
interface class | Yes | No | Yes | No | No |
final class | Yes | No | No | No | No |
sealed class | No | No | No | No | Yes |
abstract class | No | Yes | Yes | No | No |
abstract base class | No | Yes | No | No | No |
abstract interface class | No | No | Yes | No | No |
abstract final class | No | No | No | No | No |
mixin class | Yes | Yes | Yes | Yes | No |
base mixin class | Yes | Yes | No | Yes | No |
abstract mixin class | No | Yes | Yes | Yes | No |
abstract base mixin class | No | Yes | No | Yes | No |
mixin | No | No | Yes | Yes | No |
base mixin | No | No | No | Yes | No |
这表格如此之大咱也不能硬背啊(主要是咱人老了记忆力不行了)!!!这里我只做几个总结帮助大家快速记忆和区分:
- 只要带有
interface的就表示他是一个接口(废话),它就能被实现且不能被继承! - 只要带有
abstract的就不能有构造方法,同时也就拥有了添加抽象成员的能力。 - 只有带
mixin的才能混入。 - 封闭类有且只有一个:
sealed class
interface class与abstract interface class的区别是:后者是一个更纯粹的接口,意思是说它更像Java之前的对接口含义的定义。前者不能定义抽象成员,所有的成员都必须自己实现一遍(可空实现),感觉失去了接口定义的含义了。
再看一下mixin与mixin class:
先看代码↓
void main(List<String> arguments) {
final aBu = ABu();
aBu.hello();
final aNiu = ANiu();
aNiu.hello();
}
abstract interface class Animal {
String get name;
}
mixin CatMixin implements Animal {
void yell() {
print('$name is yelling');
}
}
mixin class CatMixinClass implements Animal {
/// 可以有一个无参构造函数
CatMixinClass();
/// 但是必须要实现这个Animal的name getter
@override
String get name => 'Cat';
void yell() {
print('$name is yelling');
}
}
class ABu with CatMixin {
@override
String get name => 'A Bu';
void hello() {
yell();
}
}
class ANiu with CatMixinClass {
void hello() {
yell();
}
}
运行后输出:
A Bu is yelling
Cat is yelling
简单总结:虽然2者都可以都可以被混入,不过概念上还是有点区别:
mixin是一个纯粹的混入,它是无状态的- 而
mixin class本质上还是一个类,但是它经过mixin的修饰后,也约束了它一些能力。比如:- 只能是一个无参的构造函数(这个函数默认也有,可以不用显示定义)
- 不能有成员变量
- 它仍然能被继承(个人感觉理解上有点怪)