扩展方法
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 83 课,共 110 课。
有时,你想为自己不拥有的类添加功能,比如 Dart 内置的 String 或 int 类型。你无法修改它们的源代码,而对于 final 类,继承也无济于事。这时就可以使用扩展方法。
扩展可以让你为现有类型添加新方法,而无需修改这些类型或创建子类:
extension StringExtras on String {
String reverse() {
return split('').reversed.join('');
}
bool get isPalindrome {
var cleaned = toLowerCase().replaceAll(' ', '');
return cleaned == cleaned.split('').reversed.join('');
}
}
void main() {
print('hello'.reverse()); // olleh
print('radar'.isPalindrome); // true
}语法是 extension ExtensionName on Type。在扩展内部,你可以像在普通类中一样定义方法和获取器。定义后,这些方法会出现在该类型的所有实例上,就像它们是内置的一样。
扩展适用于任何类型,包括你自己的类和泛型类型:
extension IntExtras on int {
int squared() => this * this;
}
extension ListExtras<T> on List<T> {
T? get secondOrNull => length >= 2 ? this[1] : null;
}
void main() {
print(5.squared()); // 25
print([1, 2, 3].secondOrNull); // 2
}请注意,在扩展中,this 指的是调用该方法的实例。扩展是一种简洁的方式,可以增强现有类型,同时让代码保持整洁、易读。
挑战
简单使用扩展方法为 Dart 内置类型添加实用功能吧!你将创建扩展,为 String 和 List 类型添加实用方法,然后在主文件中使用它们。
你将把代码整理到两个文件中:
extensions.dart:创建两个扩展,为现有类型添加新功能:- 在
String上创建名为StringUtils的扩展,其中包含:- 一个
countVowels()方法,用于返回字符串中的元音字母数量(a、e、i、o、u,不区分大小写) - 一个
initialsgetter,用于获取每个单词的首字母(按空格拆分),将它们连在一起并转为大写。例如,"hello world"会变成"HW"
- 一个
- 在
List<T>上创建名为ListUtils<T>的扩展,其中包含:- 一个
safeGet(int index)方法,如果该索引存在,则返回对应元素;如果索引越界,则返回null - 一个
hasMultiplegetter,如果列表中的元素多于一个,则返回true
- 一个
- 在
main.dart:导入你的扩展并演示它们的用法:- 创建字符串
"Object Oriented Programming",并按以下格式打印其中的元音字母数量:Vowels: [count] - 按以下格式打印同一字符串的首字母:
Initials: [initials] - 创建整数列表
[10, 20, 30] - 按以下格式打印
safeGet(1)的结果:Element at 1: [value] - 按以下格式打印
safeGet(5)的结果:Element at 5: [value] - 按以下格式打印列表是否包含多个元素:
Has multiple: [true/false]
- 创建字符串
请记住,在扩展内部,this 指的是调用该方法的实例。你的扩展会让这些类型看起来像是内置了这些方法!
预期输出:
Vowels: 9
Initials: OOP
Element at 1: 20
Element at 5: null
Has multiple: true亲手试试
import 'extensions.dart';
void main() {
// 创建字符串
String text = "Object Oriented Programming";
// TODO:使用 countVowels() 输出元音数量
// 格式:Vowels: [count]
// TODO:使用 initials getter 输出首字母
// 格式:Initials: [initials]
// 创建整数列表
List<int> numbers = [10, 20, 30];
// TODO:输出 safeGet(1) 的结果
// 格式:Element at 1: [value]
// TODO:输出 safeGet(5) 的结果
// 格式:Element at 5: [value]
// TODO:输出列表是否包含多个元素
// 格式:Has multiple: [true/false]
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器