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 理解为“使用父类的版本”,无论它是构造函数、方法还是属性。
挑战
简单我们来构建一个消息系统,演示 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() 方法
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器