泛型类
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 65 课,共 110 课。
你已经了解了 Dart 内置集合如何使用类型参数,例如 List<String>。现在,该创建你自己的泛型类了,它们可以处理你指定的任何类型。
泛型类使用类型参数(通常是 T)作为占位符,在创建实例时提供实际类型:
class Box<T> {
T content;
Box(this.content);
T getContent() => content;
}
void main() {
var stringBox = Box<String>('Hello');
var intBox = Box<int>(42);
print(stringBox.getContent()); // Hello
print(intBox.getContent()); // 42
}T 充当类型变量。当你创建 Box<String> 时,类中的每个 T 都会变成 String。这样,你无需为每种类型分别编写类,也能确保类型安全。
当你的类需要处理多种类型时,可以使用多个类型参数:
class Pair<K, V> {
K first;
V second;
Pair(this.first, this.second);
}
void main() {
var pair = Pair<String, int>('age', 25);
print('${pair.first}: ${pair.second}'); // age: 25
}泛型类是编写可复用、类型安全代码的基础。使用泛型,你无需为不同类型重复编写逻辑,也不会像使用 dynamic 那样丢失类型信息,还能编写灵活且可由编译器验证的代码。
挑战
简单我们来构建一个礼物包装系统,使用泛型类为不同类型的物品创建灵活的容器。你将创建一个可以包装任意类型内容的泛型 Wrapper 类,以及一个带有两个类型参数、用于将礼物和卡片留言配对的 GiftBox 类。
你将把代码组织到两个文件中:
wrapper.dart:在这里定义泛型类:- 定义泛型类
Wrapper<T>,包含一个T content属性和一个构造函数。添加一个返回内容的方法unwrap(),以及一个用于打印Wrapped: [content]的方法describe() - 定义泛型类
GiftBox<G, C>,包含两个属性:G gift和C card。添加一个构造函数和一个方法open(),该方法在一行中打印Gift: [gift],并在下一行打印Card: [card]
- 定义泛型类
main.dart:导入包装器文件,并用不同类型演示这些泛型类:- 创建一个包含
'Chocolate'的Wrapper<String>,并调用describe() - 创建一个包含
42的Wrapper<int>,并调用describe() - 创建一个包含
3.14的Wrapper<double>,并调用describe() - 打印一个空行
- 创建一个
GiftBox<String, String>,礼物为'Teddy Bear',卡片为'Happy Birthday!',然后调用open() - 打印一个空行
- 创建一个
GiftBox<int, String>,礼物为100(表示礼品卡金额),卡片为'Congratulations!',然后调用open()
- 创建一个包含
注意,同一个 Wrapper 类可以轻松处理字符串、整数和双精度浮点数。GiftBox 类展示了如何使用两个类型参数将不同类型配对:礼物可以是任意类型,而卡片留言始终是字符串。
预期输出:
Wrapped: Chocolate
Wrapped: 42
Wrapped: 3.14
Gift: Teddy Bear
Card: Happy Birthday!
Gift: 100
Card: Congratulations!亲手试试
import 'wrapper.dart';
void main() {
// TODO: 创建一个包含 'Chocolate' 的 Wrapper<String>,并调用 describe()
// TODO: 创建一个包含 42 的 Wrapper<int>,并调用 describe()
// TODO: 创建一个包含 3.14 的 Wrapper<double>,并调用 describe()
// TODO: 打印一个空行
// TODO: 创建一个 GiftBox<String, String>,礼物为 'Teddy Bear'
// 卡片为 'Happy Birthday!',然后调用 open()
// TODO: 打印一个空行
// TODO: 创建一个 GiftBox<int, String>,礼物为 100
// 卡片为 'Congratulations!',然后调用 open()
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器