Menu
CoddyTech

隐式接口

本课属于 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 的代码,都可以与实现了该接口的任意类协同工作,而不受其内部实现方式的影响。

challenge icon

挑战

简单

我们来构建一个通知系统,演示具体类如何充当隐式接口。你将创建一个基础通知类,然后用完全不同的方式实现它,从而展示 implements 要求你自己提供所有成员。

你将把代码整理到两个文件中:

  • notification.dart:在这里定义通知类:
    • 创建一个 Notification 类,其中包含一个值为 'default' 的 String channel 属性、一个会打印 [channel]: [message] 的 send(String message) 方法,以及一个返回字符串 'Notification ready' 的 getStatus() 方法。
    • 创建一个 EmailNotification 类,让它 implements Notification。由于你使用了 implements,必须自行提供 channel 属性(将它设为 'email')、会打印 Sending email: [message] 的 send() 方法,以及返回 'Email service active' 的 getStatus() 方法。
    • 创建一个 PushNotification 类,让它 implements Notification。将它的 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'
  
}
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: Dart 在线编译器