Dart - 类(扩展、枚举、Mixin)
扩展
Dart 2.7 中引入的 Extension 方法是向现有库添加功能的一种方式。
这里是一个在 String 中使用 extension 方法的样例,我们取名为 parseInt(),它定义为:
extension NumberParsing on String {
int parseInt() {
return int.parse(this);
}
double parseDouble() {
return double.parse(this);
}
}
下面我们就可以使用了:
import string_apis.dart';
...
print('42'.padLeft(5)); // Use a String method.
print('42'.parseInt()); // Use an extension method.
更多关于 extension
可以参考doc。
枚举
使用关键字 enum 来定义枚举类型:
enum Color { red, green, blue }
每一个枚举值都有一个名为 index 成员变量的 Getter 方法,该方法将会返回以 0 为基准索引的位置值。例如,第一个枚举值的索引是 0 ,第二个枚举值的索引是 1。以此类推。
assert(Color.red.index == 0);
assert(Color.green.index == 1);
assert(Color.blue.index == 2);
可以使用枚举类的 values 方法获取一个包含所有枚举值的列表:
List<Color> colors = Color.values;
assert(colors[2] == Color.blue);
你可以在 Switch 语句中使用枚举,但是需要注意的是必须处理枚举值的每一种情况,即每一个枚举值都必须成为一个 case 子句,不然会出现警告:
var aColor = Color.blue;
switch (aColor) {
case Color.red:
print('红如玫瑰!');
break;
case Color.green:
print('绿如草原!');
break;
default: // 没有该语句会出现警告。
print(aColor); // 'Color.blue'
}
枚举类型有如下两个限制:
- 枚举不能成为子类,也不可以
mix in
(后面开始讲),你也不可以实现一个枚举。 - 不能显式地实例化一个枚举类。
Mixin
Mixin
是一种在多重继承中复用某个类中代码的方法模式。
使用 with
关键字并在其后跟上 Mixin 类
的名字来使用 Mixin 模式
:
class Musician extends Performer with Musical {
// ···
}
class Maestro extends Person
with Musical, Aggressive, Demented {
Maestro(String maestroName) {
name = maestroName;
canConduct = true;
}
}
定义一个类继承自 Object 并且不为该类定义构造函数,这个类就是 Mixin 类,除非你想让该类与普通的类一样可以被正常地使用,否则可以使用关键字 mixin 替代 class 让其成为一个单纯的 Mixin 类:
mixin Musical {
bool canPlayPiano = false;
bool canCompose = false;
bool canConduct = false;
void entertainMe() {
if (canPlayPiano) {
print('Playing piano');
} else if (canConduct) {
print('Waving hands');
} else {
print('Humming to self');
}
}
}
可以使用关键字 on 来指定哪些类可以使用该 Mixin 类,比如有 Mixin 类 A,但是 A 只能被 B 类使用,则可以这样定义 A:
mixin MusicalPerformer on Musician {
// ···
}
关于mixin,Dart 鼓励代码重用,mixin可以被视为具有实现方法的接口。这样一来,不仅可以解决 Dart 缺少对多重继承的支持问题,还能够避免由于多重继承可能导致的歧义(菱形问题)。
备注:继承歧义,也叫菱形问题,是支持多继承的编程语言中一个相当棘手的问题。当 B 类和 C 类继承自 A 类,而 D 类继承自 B 类和 C 类时会产生歧义。如果 A 中有一个方法在 B 和 C 中已经覆写,而 D 没有覆写它,那么 D 继承的方法的版本是 B 类,还是 C 类的呢?