隐式接口
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 46 课,共 110 课。
由于每个 Dart 类都会自动定义一个接口,因此你可以将任何类用作接口,甚至是包含完整实现的具体类。这就是我们所说的隐式接口。
考虑一个包含属性和方法的类:
class Logger {
String prefix = '[LOG]';
void log(String message) {
print('$prefix $message');
}
void clear() {
print('Clearing logs...');
}
}当另一个类实现 Logger 时,它必须为所有内容提供自己的实现,包括 prefix 属性:
class FileLogger implements Logger {
@override
String prefix = '[FILE]';
@override
void log(String message) {
print('$prefix Writing to file: $message');
}
@override
void clear() {
print('Deleting log file...');
}
}这是关键要点:使用 implements 时,你是在说“我的类会具有相同的结构”,也就是相同的方法和属性。你不会继承任何代码、构造函数或默认值。你只是承诺会匹配接口的结构。
这使得隐式接口在创建可互换的组件时非常强大。任何需要 Logger 的代码,都可以与实现了该接口的任意类协同工作,而不受其内部实现方式的影响。
挑战
简单我们来构建一个通知系统,演示具体类如何充当隐式接口。你将创建一个基础通知类,然后用完全不同的方式实现它,从而展示 implements 要求你自己提供所有成员。
你将把代码整理到两个文件中:
notification.dart:在这里定义通知类:- 创建一个
Notification类,其中包含一个值为'default'的String channel属性、一个会打印[channel]: [message]的send(String message)方法,以及一个返回字符串'Notification ready'的getStatus()方法。 - 创建一个
EmailNotification类,让它 implementsNotification。由于你使用了implements,必须自行提供channel属性(将它设为'email')、会打印Sending email: [message]的send()方法,以及返回'Email service active'的getStatus()方法。 - 创建一个
PushNotification类,让它 implementsNotification。将它的channel设为'push',让send()打印Push alert: [message],并让getStatus()返回'Push service connected'。
- 创建一个
main.dart:导入通知文件,并演示不同的类如何通过完全不同的行为实现同一个隐式接口:- 创建一个
EmailNotification和一个PushNotification。 - 对于每个通知,使用
getStatus()打印它的状态,然后调用send(),并传入消息'Hello World'。 - 在两个通知之间打印一个空行。
- 创建一个
请记住:使用 implements 时,你不会从 Notification 继承任何代码。你只是在承诺自己的类具有相同的结构,也就是相同的属性和方法。每个实现类都要提供自己的完整实现。
预期输出:
Email service active
Sending email: Hello World
Push service connected
Push alert: Hello World亲手试试
import 'notification.dart';
void main() {
// TODO: 创建一个 EmailNotification 实例
// TODO: 使用 getStatus() 打印邮件通知的状态
// TODO: 使用邮件通知发送消息 'Hello World'
// TODO: 打印一个空行
// TODO: 创建一个 PushNotification 实例
// TODO: 使用 getStatus() 打印推送通知的状态
// TODO: 使用推送通知发送消息 'Hello World'
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器