Menu
CoddyTech

super 关键字

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

super 关键字让子类可以直接访问父类。你已经在构造函数中见过它,例如 super(name),但它在其他场景中也很有用。

需要调用父类的构造函数时,super 会沿着继承链向上传递参数:

class Vehicle {
  String brand;
  int year;
  
  Vehicle(this.brand, this.year);
}

class Car extends Vehicle {
  int doors;
  
  Car(String brand, int year, this.doors) : super(brand, year);
}

super 关键字还可以让你在子类中访问父类的方法和属性。当你想同时使用父类的行为和自己的行为时,这尤其有用:

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

class Cat extends Animal {
  Cat(String name) : super(name);
  
  void makeSound() {
    super.makeSound();  // 先调用父类的方法
    print('$name says meow!');
  }
}

调用 super.makeSound() 时,你是在显式调用父类版本的方法。如果不使用 super,调用 makeSound() 会指向当前类的方法,可能导致无限递归。

你可以把 super 理解为“使用父类的版本”,无论它是构造函数、方法还是属性。

challenge icon

挑战

简单

我们来构建一个消息系统,演示 super 关键字如何让子类访问并扩展父类的行为。你将创建一个类层次结构,让不同类型的消息基于一个基础消息类构建。

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

  • message.dart:在这里定义消息类:
    • 一个 Message 类(父类),包含 String sender 和 String content。添加一个接受这两个值的构造函数,以及一个会打印 From [sender]: [content] 的 display() 方法。
    • 一个继承 Message 的 UrgentMessage 类。它应有一个额外的 String priority 属性。构造函数接受 sender、content 和 priority,并使用 super 将前两个值传给父类。重写 display() 方法,先使用 super.display() 调用父类的方法,再在下一行打印 Priority: [priority]。
  • main.dart:导入消息文件,并演示 super 在构造函数和方法中的用法:
    • 创建一条普通的 Message,发送者为 'Alice',内容为 'Hello there!'。
    • 调用它的 display() 方法。
    • 打印一个空行作为分隔。
    • 创建一条 UrgentMessage,发送者为 'Bob',内容为 'Server is down!',优先级为 'HIGH'。
    • 调用它的 display() 方法。

注意,UrgentMessage 以两种方式使用 super:在构造函数中将数据传给父类,并在重写的方法中先包含父类的输出,再添加自己的输出。

预期输出:

From Alice: Hello there!

From Bob: Server is down!
Priority: HIGH

亲手试试

import 'message.dart';

void main() {
  // TODO:创建一个来自 'Alice'、内容为 'Hello there!' 的普通 Message 对象
  
  // TODO:调用该消息的 display() 方法
  
  // TODO:打印一个空行作为分隔
  
  // TODO:创建一个来自 'Bob'、内容为 'Server is down!'、优先级为 'HIGH' 的 UrgentMessage 对象
  
  // TODO:调用该紧急消息的 display() 方法
}
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: Dart 在线编译器