Menu
CoddyTech

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 更灵活。你可以在想要定义没有实现的接口时使用抽象类,也可以在合适时使用普通类作为接口。下一课将更详细地介绍“隐式接口”这一概念的工作原理。

challenge icon

挑战

简单

让我们构建一个媒体播放器系统,演示 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')
  
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Dart 在线编译器