通过接口实现多态
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 58 课,共 110 课。
在上一课中,你通过继承了解了多态,也就是使用父类类型来处理子类对象。不过,多态也可以通过接口实现,而且这种方式通常更灵活。
当类实现相同的接口时,即使它们之间没有继承关系,你也可以将它们视为多态对象:
abstract class Printable {
void printDetails();
}
class Invoice implements Printable {
@override
void printDetails() => print('Invoice #1234');
}
class Report implements Printable {
@override
void printDetails() => print('Monthly Report');
}
class Receipt implements Printable {
@override
void printDetails() => print('Receipt for purchase');
}
void printAll(List<Printable> items) {
for (var item in items) {
item.printDetails();
}
}
void main() {
var documents = [Invoice(), Report(), Receipt()];
printAll(documents);
}Invoice、Report 和 Receipt 是完全无关的类,它们没有共同的父类。不过,由于它们都实现了 Printable,我们可以将它们存储在同一个列表中,并对每个对象调用 printDetails()。
这很强大,因为它让你可以定义行为契约,而不必强制使用继承层次结构。任何类都可以实现接口,无论它继承自什么。这样一来,你的代码会更模块化,因为你可以添加新的可打印类型,而无需修改现有代码,只需实现接口即可。
挑战
简单让我们构建一个媒体播放器系统,通过接口展示多态。你将创建一个接口来定义“可播放”的含义,然后实现几种互不相关的媒体类型,让它们都遵循这个约定。这样一来,即使它们之间没有继承关系,也能用统一的方式处理。
你将把代码整理到两个文件中:
media.dart:在这里定义接口和媒体类:- 创建一个抽象类
Playable,其中包含两个抽象方法:play()和String getMediaType() - 创建一个实现
Playable的Song类。它应包含一个String title和一个String artist。它的play()方法会输出Playing song: [title] by [artist],而getMediaType()返回'Audio' - 创建一个实现
Playable的Video类。它应包含一个String title和一个int duration(分钟)。它的play()方法会输出Playing video: [title] ([duration] min),而getMediaType()返回'Video' - 创建一个实现
Playable的Podcast类。它应包含一个String title和一个int episode。它的play()方法会输出Playing podcast: [title] - Episode [episode],而getMediaType()返回'Podcast'
playAll(List<Playable> playlist),遍历列表,并为每个项目输出[Media Type]:,然后调用该项目的play()。- 创建一个抽象类
main.dart:导入媒体文件,并演示基于接口的多态:- 创建一个
List<Playable>,其中包含一个标题为'Imagine'、艺术家为'John Lennon'的Song,一个标题为'Dart Tutorial'、时长为15的Video,以及一个标题为'Tech Talk'、集数为42的Podcast - 将这个列表传递给
playAll()
- 创建一个
注意,Song、Video 和 Podcast 没有共同的父类,它们是完全互不相关的类型。但因为它们都实现了 Playable,你可以将它们存储在同一个列表中,并通过接口统一处理。
预期输出:
Audio:
Playing song: Imagine by John Lennon
Video:
Playing video: Dart Tutorial (15 min)
Podcast:
Playing podcast: Tech Talk - Episode 42亲手试试
import 'media.dart';
void main() {
// TODO: 创建一个 List<Playable>,包含:
// - 一个 Song,title 为 'Imagine',artist 为 'John Lennon'
// - 一个 Video,title 为 'Dart Tutorial',duration 为 15
// - 一个 Podcast,title 为 'Tech Talk',episode 为 42
// TODO: 将列表传给 playAll()
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器