Menu
CoddyTech

可调用类

本课属于 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.
}

当你需要将类似函数的行为与状态或配置结合起来时,可调用类就很有用。它们常用于创建可重复使用的操作、验证器或转换器,并且需要在多次调用之间记住设置。

challenge icon

挑战

简单

让我们使用可调用类来构建一个文本格式化系统!你将创建可以像函数一样调用的对象,以不同方式转换文本,同时保留各自的配置设置。

你将把代码整理到两个文件中:

  • 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,再打印最终结果
  
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Dart 在线编译器