Menu
CoddyTech

扩展方法

本课属于 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 指的是调用该方法的实例。扩展是一种简洁的方式,可以增强现有类型,同时让代码保持整洁、易读。

challenge icon

挑战

简单

使用扩展方法为 Dart 内置类型添加实用功能吧!你将创建扩展,为 String 和 List 类型添加实用方法,然后在主文件中使用它们。

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

  • extensions.dart:创建两个扩展,为现有类型添加新功能:
    • 在 String 上创建名为 StringUtils 的扩展,其中包含:
      • 一个 countVowels() 方法,用于返回字符串中的元音字母数量(a、e、i、o、u,不区分大小写)
      • 一个 initials getter,用于获取每个单词的首字母(按空格拆分),将它们连在一起并转为大写。例如,"hello world" 会变成 "HW"
    • 在 List<T> 上创建名为 ListUtils<T> 的扩展,其中包含:
      • 一个 safeGet(int index) 方法,如果该索引存在,则返回对应元素;如果索引越界,则返回 null
      • 一个 hasMultiple getter,如果列表中的元素多于一个,则返回 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]
}
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: Dart 在线编译器