Dart 中的接口
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 45 课,共 110 课。
与许多使用专门的 interface 关键字的语言不同,Dart 采用了不同的方式。在 Dart 中,每个类都会自动定义一个接口。这个接口由该类声明的所有公共成员(方法和属性)组成。
如果你希望一个类承诺提供某些功能,但不继承实现,可以使用 implements 关键字:
class Printer {
void printDocument(String content) {
print('Printing: $content');
}
}
class Scanner {
void scan() {
print('Scanning document');
}
}
// MultiFunctionDevice 必须实现这两个类的所有方法
class MultiFunctionDevice implements Printer, Scanner {
@override
void printDocument(String content) {
print('MFD printing: $content');
}
@override
void scan() {
print('MFD scanning');
}
}与 extends 的主要区别在于,implements 不会继承任何代码。你必须为接口中定义的每个方法和属性提供自己的实现。这是一份契约,你承诺自己的类具备这些能力,但具体如何实现由你决定。
这种方式让 Dart 更灵活。你可以在想要定义没有实现的接口时使用抽象类,也可以在合适时使用普通类作为接口。下一课将更详细地介绍“隐式接口”这一概念的工作原理。
挑战
简单让我们构建一个媒体播放器系统,演示 Dart 中 implements 关键字的作用。你将创建充当接口的类,然后在一个具备多种功能的设备类中实现这些接口。
你会把代码分成两个文件:
media.dart:在这里定义接口类和实现类:- 一个
AudioPlayer类,其中包含一个方法playAudio(String track),用于输出Playing audio: [track] - 一个
VideoPlayer类,其中包含一个方法playVideo(String title),用于输出Playing video: [title] - 一个同时实现
AudioPlayer和VideoPlayer的SmartTV类。由于implements不会继承任何代码,你必须为这两个方法都提供自己的实现。对于音频,SmartTV应输出SmartTV audio: [track];对于视频,应输出SmartTV video: [title]
- 一个
main.dart:导入媒体文件,并演示一个类如何实现多个接口:- 创建一个
SmartTV实例 - 调用
playAudio('Jazz Collection') - 调用
playVideo('Nature Documentary')
- 创建一个
请注意,SmartTV 必须为两个接口中的每个方法都提供自己的实现,它不会从 AudioPlayer 或 VideoPlayer 继承原有实现。这就是 implements 和 extends 的关键区别。
预期输出:
SmartTV audio: Jazz Collection
SmartTV video: Nature Documentary亲手试试
import 'media.dart';
void main() {
// TODO: 创建一个 SmartTV 实例
// TODO: 调用 playAudio('Jazz Collection')
// TODO: 调用 playVideo('Nature Documentary')
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器