Dart 3.0 的 mixin

202 阅读2分钟

官方文档 Mixins

要使用混入的功能,代码必须是 mixin 关键字修饰的,有几种混入类型:

  • mixin
mixin Mixin {}
  • 混入类 mixin class
mixin class MixinClass {}
  • 抽象混入类 abstract mixin class
abstract mixin class AbstractMixinClass {}

要使用 mixin 功能,必须使用 with 关键字

/// 单混入
class Dog with Mixin {}
/// 多混入
class Dog with Mixin, MixinClass, AbstractMixinClass {}

关于 mixin

  • 不能有 constructor,构造函数。
  • 不能使用 extends with 关键字。
  • 可以使用 on 关键字,限制可以使用mixin的类型。

on 的类型:

  1. on 的类型 ,超类在混入时,有先后顺序,且实现没有实现的方法和属性
mixin Mixin {
  void test() {
    debugPrint('test');
  }

  /// 需要外部实现的方法
  void test1();

  /// 需要外部实现的属性
  String get name;
}
mixin Mixin1 on Mixin {}
/// 先混入 [Mixin],才能混入 [Mixin1]
class Cat with Mixin, Mixin1 {
  Cat();

  @override
  // TODO: implement name
  String get name => throw UnimplementedError();

  @override
  void test1() {
    // TODO: implement test1
  }
}
  1. on 的类型 classmixin class,超类必须继承
class Class {}
mixin class Class {}
mixin Mixin on Class {}
/// 因为要使用 [Mixin],必须继承 [Class]
class Dog extends Class with Mixin1 {}
  1. on 的类型 abstract classabstract mixin class,超类必须继承,且实现没有实现的方法和属性
abstract class Class {
  void test() {
    debugPrint('test');
  }

  /// 需要外部实现的方法
  void test1();

  /// 需要外部实现的属性
  String get name;
}
abstract mixin class Class {
  void test() {
    debugPrint('test');
  }

  /// 需要外部实现的方法
  void test1();

  /// 需要外部实现的属性
  String get name;
}
mixin Mixin on Class {}
/// 必须继承 [Class],且必须实现 [test1] [name]
class Cat extends Class with Mixin {
  Cat();

  @override
  // TODO: implement name
  String get name => throw UnimplementedError();

  @override
  void test1() {
    // TODO: implement test1
  }
}

关于 mixin class abstract mixin class

既可以当做 class or abstract class 使用,也可以当做 mixin 使用,它们拥有相同的名字和类型,同时也受到相同的约束。

  • 不能有构造函数,因为 mixin 不能使用。
  • 不能使用 extends with 关键字,因为 mixin 不能使用。
  • 不能使用 on 关键字,因为 class 不能使用。

补充: 如果需要实现类似 on 限制使用功能,可以使用混入 abstract mixin class,通过实现方法或属性,来确保必须实现的功能。

class Cat with AbstractMixinClass {
  Cat();

  // 超类必须实现的属性
  @override
  // TODO: implement name
  String get name => throw UnimplementedError();

  // 超类必须实现的方法
  @override
  void test1() {
    // TODO: implement test1
  }
}