创建混入
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 51 课,共 110 课。
现在你已经了解了混入是什么,接下来看看如何正确创建它们。声明混入时要使用 mixin 关键字,而不是 class。
mixin Logging {
void log(String message) {
print('[LOG] $message');
}
void logError(String error) {
print('[ERROR] $error');
}
}混入可以包含方法、属性,甚至获取器和设置器,就像类一样。不过,有一条重要规则:混入不能有构造函数。混入的目的是被“混入”到其他类中,而不是直接实例化,因此不需要初始化逻辑。
mixin Timestamped {
DateTime createdAt = DateTime.now();
String get formattedTime => createdAt.toString();
void printTimestamp() {
print('Created at: $formattedTime');
}
}
class Document with Timestamped {
String title;
Document(this.title);
}
void main() {
var doc = Document('Report');
doc.printTimestamp(); // 使用 mixin 的方法
print(doc.createdAt); // 使用 mixin 的属性
}使用 with 应用混入时,它的所有成员都会成为你的类的一部分。这个类可以直接使用这些成员,任何拥有该类实例的代码也可以使用它们。这样,混入就成了一种简洁的方式,可以添加可重复使用的功能,而不必处理复杂的继承层次结构。
挑战
简单让我们构建一个消息系统,展示如何创建包含方法、属性和 getter 的 mixin。你将设计一个 mixin,为不同类型的消息添加格式化功能。
你将把代码整理到两个文件中:
messaging.dart:在这里定义 mixin 和消息类:- 一个
Formattablemixin,其中包含:- 一个初始值为
'>>>'的String prefix属性 - 一个返回
' | '的 getterseparator - 一个方法
format(String text),返回字符串[prefix][separator][text] - 一个方法
formatBold(String text),返回**[text]**
- 一个初始值为
- 一个使用
Formattablemixin 的TextMessage类。添加一个带有构造函数的String sender属性。再添加一个方法send(String content),打印使用[sender]: [content]调用format()的结果。 - 一个同样使用
Formattablemixin 的AlertMessage类。添加一个带有构造函数的String level属性。再添加一个方法alert(String content),打印使用[[level]] [formatBold(content)]调用format()的结果。
- 一个
main.dart:导入消息文件,并演示这两种消息类型如何通过 mixin 获得格式化功能:- 创建一个发送者为
'Alice'的TextMessage - 创建一个级别为
'WARNING'的AlertMessage - 在文本消息上调用
send('Hello there!') - 在警报消息上调用
alert('System overload')
- 创建一个发送者为
你的 mixin 展示了 mixin 可以包含具有默认值的属性、用于计算值的 getter,以及多个甚至可以相互调用的方法。只需使用 with 关键字,这两个消息类就能获得所有这些功能。
预期输出:
>>> | Alice: Hello there!
>>> | [WARNING] **System overload**亲手试试
import 'messaging.dart';
void main() {
// TODO:创建一个发送者为 'Alice' 的 TextMessage
// TODO:创建一个级别为 'WARNING' 的 AlertMessage
// TODO:在文本消息上调用 send('Hello there!')
// TODO:在警报消息上调用 alert('System overload')
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器