final 类关键字
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 40 课,共 110 课。
有时,你可能想阻止一个类被扩展。将 final 关键字应用于类,可以阻止其他类继承它。
final class DatabaseConnection {
String connectionString;
DatabaseConnection(this.connectionString);
void connect() {
print('Connected to $connectionString');
}
}
// 这样会导致编译时错误:
// class CustomConnection extends DatabaseConnection { }当扩展一个类可能破坏其预期行为或安全保证时,将其标记为 final 会很有用。例如,管理敏感资源的类可能需要确保其方法不会以意料之外的方式被重写。
Dart 3 还引入了相关修饰符:base 强制子类使用 extends(而不是 implements),sealed 则将继承限制在同一个库中。现在,先重点了解 final,它是完全锁定一个类的最简单方式。
当你确定类的设计已经完善,而且继承只会带来问题时,使用 final 类。不过,不要过度使用它,大多数类保持开放以便扩展会更好。
挑战
简单让我们构建一个安全的配置系统,展示何时以及为何要阻止类被继承。你将创建一个 final 类来管理应用设置,确保它的行为不会因继承而改变。
你将把代码组织到两个文件中:
config.dart:在这里定义配置类:- 定义一个不能被继承的
final class AppConfig。它应有String appName和String version属性、一个接收这两个值的构造函数,以及一个会打印[appName] v[version]的display()方法。 - 定义一个普通的(非 final)
Feature类,它有String name和bool enabled属性、一个接收这两个值的构造函数,以及一个会打印[name]: [enabled ? 'ON' : 'OFF']的status()方法。 - 定义一个继承
Feature的ExperimentalFeature类,并添加String warning属性。使用@override重写status(),先调用父类的版本super.status(),然后打印Warning: [warning]。
- 定义一个不能被继承的
main.dart:导入配置文件,并展示 final 类与普通类的区别:- 创建一个
AppConfig,其中 appName 为'MyApp',version 为'2.0.1',然后调用display()。 - 打印一个空行。
- 创建一个
Feature,其中 name 为'Dark Mode',enabled 为true,然后调用status()。 - 打印一个空行。
- 创建一个
ExperimentalFeature,其中 name 为'AI Assistant',enabled 为false,warning 为'May be unstable',然后调用status()。
- 创建一个
注意,AppConfig 被标记为 final,因为它的配置行为应保持一致且安全,不应有子类能够改变设置的管理方式。与此同时,Feature 仍然可以被扩展,因此 ExperimentalFeature 能够添加专门的行为。
预期输出:
MyApp v2.0.1
Dark Mode: ON
AI Assistant: OFF
Warning: May be unstable亲手试试
import 'config.dart';
void main() {
// TODO:创建一个 AppConfig,将 appName 设为 'MyApp',version 设为 '2.0.1'
// 然后调用 display()
// TODO:输出一个空行
// TODO:创建一个 Feature,将 name 设为 'Dark Mode',enabled 设为 true
// 然后调用 status()
// TODO:输出一个空行
// TODO:创建一个 ExperimentalFeature,将 name 设为 'AI Assistant',
// enabled 设为 false,warning 设为 'May be unstable'
// 然后调用 status()
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器