@override 注解
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 39 课,共 110 课。
@override 注解是一种最佳实践标记,用来告诉 Dart(以及其他开发者),你有意重写父类中的方法。虽然不使用它也能重写方法,但使用 @override 可以增加一道重要的安全保障。
class Animal {
String name;
Animal(this.name);
void speak() {
print('$name makes a sound');
}
}
class Dog extends Animal {
Dog(String name) : super(name);
@override
void speak() {
print('$name barks: Woof!');
}
}这个注解有两个重要好处。首先,它能清楚地说明你的意图,让任何阅读代码的人都能立即知道这个方法存在于父类中。其次,如果父类中实际上不存在该方法,Dart 的分析器会发出警告,从而及早发现拼写错误和重构错误。
想一想,如果不写 @override,却把方法名称拼错了,会发生什么:
class Cat extends Animal {
Cat(String name) : super(name);
void speek() { // 拼写错误!没有 @override 就不会收到警告。
print('$name meows');
}
}如果没有这个注解,Dart 会认为你正在创建一个名为 speek() 的新方法。使用 @override 后,分析器会立即指出父类中不存在这个方法。这个简单的注解可以避免一些不易察觉、以后很难排查的 bug。
挑战
简单我们来构建一个媒体播放器系统,展示自定义继承行为时 @override 注解的重要性。你将创建不同的媒体类型,让它们各自以不同的方式播放内容。
你将把代码分成两个文件:
media.dart:在这里定义媒体类层次结构:- 创建一个
Media类,包含String title属性、一个接收标题的构造函数,以及一个会打印Playing: [title]的方法play() - 创建一个继承
Media的Song类,并添加String artist属性。使用@override注解重写play(),打印Playing song: [title] by [artist] - 创建一个继承
Media的Video类,并添加int duration属性(单位为秒)。使用@override注解重写play(),先通过super.play()调用父类的版本,然后打印Duration: [duration] seconds
- 创建一个
main.dart:导入媒体文件,并演示重写后的方法:- 创建一个标题为
'Generic Content'的Media对象,并调用play() - 打印一个空行
- 创建一个标题为
'Imagine'、艺术家为'John Lennon'的Song,然后调用play() - 打印一个空行
- 创建一个标题为
'Dart Tutorial'、时长为360秒的Video,然后调用play()
- 创建一个标题为
@override 注解可以说明你的意图,并帮助你发现错误。如果你不小心把 play() 拼错成 plya(),这个注解会提醒你父类中不存在这样的方法。
预期输出:
Playing: Generic Content
Playing song: Imagine by John Lennon
Playing: Dart Tutorial
Duration: 360 seconds亲手试试
import 'media.dart';
void main() {
// TODO: 创建一个 title 为 'Generic Content' 的 Media 对象,并调用 play()
// TODO: 打印一个空行
// TODO: 创建一个 title 为 'Imagine'、artist 为 'John Lennon' 的 Song 对象,然后调用 play()
// TODO: 打印一个空行
// TODO: 创建一个 title 为 'Dart Tutorial'、duration 为 360 的 Video 对象,然后调用 play()
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器