密封类(Dart 3)
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 85 课,共 110 课。
Dart 3 引入了密封类,它们会限制哪些类可以继承或实现它们。当你将一个类标记为 sealed 时,只有同一文件中的类才能成为它的直接子类型。这样就创建了一个已知子类型的封闭集合。
sealed class Result {}
class Success extends Result {
final String data;
Success(this.data);
}
class Failure extends Result {
final String error;
Failure(this.error);
}密封类的强大之处在于穷尽性检查。当你对密封类型使用 switch 时,编译器知道所有可能的子类型,并确保你处理了每一种:
String handleResult(Result result) {
return switch (result) {
Success(data: var d) => 'Got: $d',
Failure(error: var e) => 'Error: $e',
};
// 不需要 default:编译器知道所有情况都已覆盖!
}
void main() {
var success = Success('Hello');
var failure = Failure('Not found');
print(handleResult(success)); // Got: Hello
print(handleResult(failure)); // Error: Not found
}如果你向密封类添加新的子类型,编译器会标记所有未处理该子类型的 switch 语句。因此,密封类非常适合用于建模状态、结果,或任何具有固定变体集合的场景。与抽象类不同,密封类可以确保外部代码无法添加意料之外的子类型。
挑战
简单让我们使用密封类来构建一个网络请求处理器!你将创建一个类型安全的系统,用来表示网络响应的不同状态,确保妥善处理每一种可能的结果。
你将把代码整理到两个文件中:
response.dart:创建一个密封类层次结构,用来表示网络响应的所有可能状态:- 创建一个名为
NetworkResponse的密封类,作为所有响应类型的基类 - 创建一个继承
NetworkResponse的Loading类,其中包含一个String message字段(例如,"Fetching data...") - 创建一个继承
NetworkResponse的Success类,其中包含一个String data字段和一个int statusCode字段 - 创建一个继承
NetworkResponse的Error类,其中包含一个String errorMessage字段和一个int errorCode字段
- 创建一个名为
main.dart:导入响应文件,并创建一个使用 switch 表达式处理所有响应类型的函数:- 创建一个名为
handleResponse(NetworkResponse response)的函数,返回值类型为String - 使用带模式匹配的 switch 表达式处理每种情况:
- 对于
Loading:返回Status: [message] - 对于
Success:返回Success ([statusCode]): [data] - 对于
Error:返回Error ([errorCode]): [errorMessage]
- 对于
- 创建三个响应实例,并打印分别处理它们的结果:
- 创建一个消息为
Please wait...的Loading - 创建一个数据为
User profile loaded、状态码为200的Success - 创建一个错误消息为
Not found、错误码为404的Error
- 创建一个消息为
- 创建一个名为
密封类的优点在于,编译器会确保你处理每一种可能的响应类型,因此不需要默认情况!
预期输出:
Status: Please wait...
Success (200): User profile loaded
Error (404): Not found亲手试试
import 'response.dart';
// TODO: 创建函数 handleResponse(NetworkResponse response)
// 返回一个 String
// 使用带模式匹配的 switch 表达式处理每种情况:
// - 对于 Loading:返回 "Status: [message]"
// - 对于 Success:返回 "Success ([statusCode]): [data]"
// - 对于 Error:返回 "Error ([errorCode]): [errorMessage]"
void main() {
// TODO: 创建一个 Loading 实例,message 为 "Please wait..."
// TODO: 创建一个 Success 实例,data 为 "User profile loaded",状态码为 200
// TODO: 创建一个 Error 实例,错误消息为 "Not found",错误码为 404
// TODO: 打印处理每个响应的结果
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器