可调用类
本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 84 课,共 110 课。
在 Dart 中,你可以通过实现 call() 方法,让类的实例像函数一样可调用。这样你就可以使用函数调用语法,也就是直接在实例后面加上括号来使用对象。
class Multiplier {
final int factor;
Multiplier(this.factor);
int call(int value) {
return value * factor;
}
}
void main() {
var double = Multiplier(2);
var triple = Multiplier(3);
print(double(5)); // 10:像调用函数一样调用对象
print(triple(5)); // 15
}当你写下 double(5) 时,Dart 会自动调用 call() 方法,并将 5 作为参数。这个对象的行为就像函数,同时仍会保留自己的状态(factor 字段)。
call() 方法可以有任意函数签名,包含多个参数、可选参数,甚至返回不同类型的值:
class Greeter {
final String greeting;
Greeter(this.greeting);
String call(String name, {String punctuation = '!'}) {
return '$greeting, $name$punctuation';
}
}
void main() {
var hello = Greeter('Hello');
print(hello('Alice')); // Hello, Alice!
print(hello('Bob', punctuation: '.')); // Hello, Bob.
}当你需要将类似函数的行为与状态或配置结合起来时,可调用类就很有用。它们常用于创建可重复使用的操作、验证器或转换器,并且需要在多次调用之间记住设置。
挑战
简单让我们使用可调用类来构建一个文本格式化系统!你将创建可以像函数一样调用的对象,以不同方式转换文本,同时保留各自的配置设置。
你将把代码整理到两个文件中:
formatters.dart:创建两个用于转换文本的可调用类:- 创建一个
Wrapper类,用前缀和后缀包裹文本。它应存储一个String prefix和一个String suffix,调用时接收String text参数,并返回用前缀和后缀包裹的文本。 - 创建一个
Repeater类,按指定次数重复文本。它应存储一个int times值,调用时接收String text参数,并返回重复指定次数的文本,每次重复之间用空格隔开。
- 创建一个
main.dart:导入格式化器,并演示可调用类的用法:- 创建一个前缀为
"["、后缀为"]"的Wrapper - 再创建一个前缀为
"***"、后缀为"***"的Wrapper - 创建一个重复 3 次的
Repeater - 用
"Hello"调用第一个包装器,并打印结果 - 用
"Important"调用第二个包装器,并打印结果 - 用
"Go"调用重复器,并打印结果 - 最后,将它们组合起来:用调用重复器并传入
"Dart"后得到的结果调用第一个包装器,并打印结果
- 创建一个前缀为
注意,每个格式化器对象都会记住自己的配置,而且可以像函数一样直接用括号调用!
预期输出:
[Hello]
***Important***
Go Go Go
[Dart Dart Dart]亲手试试
import 'formatters.dart';
void main() {
// TODO: 创建一个 Wrapper,前缀为 "[",后缀为 "]"
// TODO: 再创建一个 Wrapper,前缀和后缀都是 "***"
// TODO: 创建一个重复 3 次的 Repeater
// TODO: 用 "Hello" 调用第一个 Wrapper,并打印结果
// TODO: 用 "Important" 调用第二个 Wrapper,并打印结果
// TODO: 用 "Go" 调用 Repeater,并打印结果
// TODO: 组合它们:用以下结果调用第一个 Wrapper,
// 先用 "Dart" 调用 Repeater,再打印最终结果
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器