dart3.0中令人迷糊的各种类修饰符与组合,我真的没搞清楚!

277 阅读2分钟

abstract、interface、final、base、mixin、以及它们的各种组合,各种代表啥?有啥用?

先上一个令人迷糊的,这是官网的示例

image.png 它说Car不能继承Vehicle,但是我复制代码到一个测试文件里,它并没有报错:

image.png

我有那么一瞬间认为官网的搞错了!后来才发现,它这个跟_是一个玩法:都要区分文件。这样改为2个文件就能正常报错了:

image.png

image.png

回到标题,鉴于太懒不想写,直接贴官网的表格:

DeclarationConstruct?Extend?Implement?Mix in?Exhaustive?
classYesYesYesNoNo
base classYesYesNoNoNo
interface classYesNoYesNoNo
final classYesNoNoNoNo
sealed classNoNoNoNoYes
abstract classNoYesYesNoNo
abstract base classNoYesNoNoNo
abstract interface classNoNoYesNoNo
abstract final classNoNoNoNoNo
mixin classYesYesYesYesNo
base mixin classYesYesNoYesNo
abstract mixin classNoYesYesYesNo
abstract base mixin classNoYesNoYesNo
mixinNoNoYesYesNo
base mixinNoNoNoYesNo

这表格如此之大咱也不能硬背啊(主要是咱人老了记忆力不行了)!!!这里我只做几个总结帮助大家快速记忆和区分:

  1. 只要带有interface的就表示他是一个接口(废话),它就能被实现且不能被继承!
  2. 只要带有abstract的就不能有构造方法,同时也就拥有了添加抽象成员的能力。
  3. 只有带mixin的才能混入。
  4. 封闭类有且只有一个:sealed class

interface classabstract interface class的区别是:后者是一个更纯粹的接口,意思是说它更像Java之前的对接口含义的定义。前者不能定义抽象成员,所有的成员都必须自己实现一遍(可空实现),感觉失去了接口定义的含义了。

再看一下mixinmixin 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的修饰后,也约束了它一些能力。比如:
    • 只能是一个无参的构造函数(这个函数默认也有,可以不用显示定义)
    • 不能有成员变量
    • 它仍然能被继承(个人感觉理解上有点怪)