Menu
CoddyTech

方法重写

本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 38 课,共 110 课。

当子类为父类中已有的方法提供自己的实现时,就称为方法重写。这样,子类就能自定义继承的行为,同时保留相同的方法签名。

当你在子类中定义一个与父类中的方法同名且参数相同的方法时,子类中的版本会取代父类中的版本:

class Animal {
  String name;
  
  Animal(this.name);
  
  void speak() {
    print('$name makes a sound');
  }
}

class Dog extends Animal {
  Dog(String name) : super(name);
  
  void speak() {
    print('$name barks: Woof!');
  }
}

void main() {
  var animal = Animal('Generic');
  var dog = Dog('Buddy');
  
  animal.speak();  // Generic 发出声音
  dog.speak();     // Buddy 叫道:汪!
}

在 Dog 实例上调用 speak() 时,Dart 会执行 Dog 的版本,而不是 Animal 的版本。子类重写了父类的方法。

你也可以将重写与 super 结合起来,以扩展而不是替换父类的行为:

class Cat extends Animal {
  Cat(String name) : super(name);
  
  void speak() {
    super.speak();  // 先调用父类的方法
    print('$name also purrs');
  }
}

这种模式可以让你在现有功能的基础上进行扩展。关键规则很简单:子类中的方法名称和参数与父类相同,那么在子类实例上调用时,就会替代父类的实现。

challenge icon

挑战

简单

让我们来构建一个通知系统,展示子类如何重写父类方法来自定义行为。你将创建不同类型的通知,每种通知都会以独特的方式发送消息。

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

  • notification.dart:在这里定义通知类的层级结构:
    • 创建一个 Notification 类(父类),包含 String title 和 String message。添加一个接收这两个值的构造函数,以及一个用于打印 Notification: [title] - [message] 的 send() 方法。
    • 创建一个继承 Notification 的 EmailNotification 类,并添加一个 String recipient 属性。重写 send() 方法,使其打印 Sending email to [recipient]: [title] - [message]。
    • 创建一个继承 Notification 的 PushNotification 类,并添加一个 String deviceId 属性。重写 send() 方法,先使用 super 调用父类的 send(),然后在下一行打印 Pushed to device: [deviceId]。
  • main.dart:导入通知文件,并演示方法重写的实际效果:
    • 创建一个基础的 Notification,标题为 'Alert',消息为 'System update available'。
    • 调用它的 send() 方法。
    • 打印一个空行。
    • 创建一个 EmailNotification,标题为 'Welcome',消息为 'Thanks for signing up!',收件人为 'user@example.com'。
    • 调用它的 send() 方法。
    • 打印一个空行。
    • 创建一个 PushNotification,标题为 'Reminder',消息为 'Meeting in 10 minutes',deviceId 为 'DEVICE-001'。
    • 调用它的 send() 方法。

注意,EmailNotification 会完全替换父类的行为,而 PushNotification 会先调用 super.send(),再扩展父类的行为。这两种方法都是重写方法的有效方式,具体取决于你的需求。

预期输出:

Notification: Alert - System update available

Sending email to user@example.com: Welcome - Thanks for signing up!

Notification: Reminder - Meeting in 10 minutes
Pushed to device: DEVICE-001

亲手试试

import 'notification.dart';

void main() {
  // TODO: 创建一个基础 Notification,title 为 'Alert',message 为 'System update available'
  // 调用它的 send() 方法

  // TODO: 打印一个空行

  // TODO: 创建一个 EmailNotification,包含:
  // - title: 'Welcome'
  // - message: 'Thanks for signing up!'
  // - recipient: 'user@example.com'
  // 调用它的 send() 方法

  // TODO: 打印一个空行

  // TODO: 创建一个 PushNotification,包含:
  // - title: 'Reminder'
  // - message: 'Meeting in 10 minutes'
  // - deviceId: 'DEVICE-001'
  // 调用它的 send() 方法
}
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: Dart 在线编译器