类 - Part II

类的知识点较多,所以分成两节进行讲解,本节是Part II,上一节是Part I


本节继续讲解类的知识点,主要包括抽象类/方法,接口,mixin以及枚举。

抽象类和抽象方法

没有函数体的方法,即只声明而不实现的方法被称为抽象方法,它只能出现在抽象类中。抽象类是使用abstract关键字修饰的类,它可以包含非抽象方法,可以被继承但不能被实例化。

  1. // 大剑抽象类
  2. abstract class GreatSword {
  3. // 抽象方法
  4. upgrade();
  5. // 非抽象方法
  6. use() {
  7. print('attack');
  8. }
  9. }
  10. // 混种大剑继承大剑
  11. class BastardSword extends GreatSword {
  12. // 实现父类的抽象方法
  13. upgrade() {
  14. print('upgrade');
  15. }
  16. // 重写且使用父类已有的实现
  17. use() {
  18. super.use();
  19. }
  20. }

接口

Dart 支持接口,但没有定义接口的关键字。Dart 的每个类都隐含定义了一个接口,该接口包含当前类所有的实例变量和方法(包含通过继承和实现其他类而得来的)。通常使用抽象类来定义接口,而接口的实现是通过implements关键字,多个接口之间使用逗号分隔。

  1. // 轻攻击接口
  2. abstract class Light {
  3. lightAttack();
  4. }
  5. // 重攻击接口
  6. abstract class Heavy {
  7. heavyAttack();
  8. }
  9. // 大剑同时实现了轻重攻击
  10. class GreatSword implements Light, Heavy {
  11. lightAttack() {
  12. print('Light attack!');
  13. }
  14. heavyAttack() {
  15. print('Heavy attack!!!');
  16. }
  17. }

mixin

mixin是一种特殊的专门用于复用的类,Dart 不直接支持多继承(子类继承多个父类),但通过mixin可以实现类似于多继承的效果。

mixin有两种书写方式,一种是使用class声明一个没有父类和构造函数的类,另一种是直接使用mixin关键字(从Dart 2.1开始引入,为了代码的明确性,笔者倾向于直接使用mixin关键字)。

在声明其他类时,使用with关键字指定一个或多个mixin,这些mixin的属性和方法就都被”混入”到当前类中,即实现了类的复用。

如果需要限定mixin只能被特定类型使用,可以使用on关键字(只适用于mixin关键字),on后跟随逗号分隔的多个父类,只有这些父类的子类才能使用当前mixin。

  1. // 使用class方式声明的轻攻击mixin
  2. class LightAttack {
  3. lightAttack() {
  4. print('Light attack!');
  5. }
  6. }
  7. // 使用mixin声明的重攻击mixin
  8. mixin HeavyAttack {
  9. heavyAttack() {
  10. print('Heavy attack!');
  11. }
  12. }
  13. // 特殊攻击方式mixin,使用on限定能够使用的类型为Weapon的子类
  14. mixin SpecialAttack on Weapon {
  15. specialAttack() {
  16. print('Special attack!');
  17. }
  18. }
  19. // 武器基类Weapon
  20. abstract class Weapon {
  21. }
  22. // 大剑继承Weapon而且复用了LightAttack, HeavyAttack, SpecialAttack实现的方法
  23. class GreatSword extends Weapon with LightAttack, HeavyAttack, SpecialAttack {
  24. attack() {
  25. lightAttack();
  26. heavyAttack();
  27. specialAttack();
  28. }
  29. }

枚举

枚举也是一种特殊的类,它专门用于表示固定数量的常量值,枚举使用关键字enum进行声明。

枚举内的值是有序的,它们的索引可以通过index属性获取,而values属性则将它们输出为一个列表(List)。

枚举不能被继承、实现和实例化,也不能被用作mixin。枚举可用于switch语句和for...in循环。

  1. // 方向枚举:东南西北
  2. enum Direction { north, east, south, west }
  3. printDirection() {
  4. // 通过for...in遍历values列表并打印所有方向的索引
  5. for (Direction direction in Direction.values) {
  6. print(direction.index);
  7. }
  8. }