Menu
CoddyTech

抽象方法

本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 44 课,共 110 课。

抽象方法是在抽象类中声明且没有方法体的方法。它定义了方法签名,但将实现留给每个子类。任何继承抽象类的类都必须重写所有抽象方法,否则该类也会成为抽象类。

abstract class Animal {
  // 抽象方法:没有方法体,必须由子类实现
  String makeSound();

  // 具体方法:有方法体,所有子类共用
  void breathe() {
    print('Breathing...');
  }
}

class Dog extends Animal {
  @override
  String makeSound() {
    return 'Woof!';  // 必须提供具体实现
  }
}

class Cat extends Animal {
  @override
  String makeSound() {
    return 'Meow!';  // 实现方式不同,方法签名相同
  }
}

如果子类忘记实现抽象方法,Dart 会给你一个编译错误。这正是抽象方法的意义所在:它们强制遵守契约。每个子类都一定有这个方法,因此你可以放心地在抽象类型的任何实例上调用它。

// 你可以把抽象类型用作变量的类型
Animal a = Dog();
print(a.makeSound());  // 汪!

Animal b = Cat();
print(b.makeSound());  // 喵!

抽象类中的抽象方法与具体方法不同。具体方法有方法体,并会原样继承。抽象方法没有方法体,必须重写。

你可以在同一个抽象类中混合使用这两种方法,共享部分行为,同时强制子类为其他行为定义自己的方法。

特性抽象方法具体方法
是否有方法体否是
是否必须重写是否
用途强制遵守约定共享行为
适用位置仅限抽象类任何类
challenge icon

挑战

简单

让我们来构建一个形状计算器,演示抽象方法的实际用法。你将定义一个包含抽象方法的抽象类,每种形状都必须以不同方式实现这些方法,然后通过一个通用接口使用这些形状。

你将把代码组织到 4 个文件中:

  • shape.dart:定义一个抽象类 Shape,包含一个 final 字段 color(String)和一个用于初始化它的构造函数。声明两个抽象方法:double area() 和 double perimeter()。再添加一个具体方法 describe(),用于打印 A [color] shape with area: [area] and perimeter: [perimeter]。由于 area() 和 perimeter() 是抽象方法,每个子类都会提供自己的计算方式,但 describe() 无需重写就能用于所有子类。
  • circle.dart:创建一个继承 Shape 的 Circle 类。它包含一个 final 字段 radius(double)。它的构造函数接收 color 和 radius,并将 color 传递给 super。实现 area(),使其返回 3.14 * radius * radius;实现 perimeter(),使其返回 2 * 3.14 * radius。
  • rectangle.dart:创建一个继承 Shape 的 Rectangle 类。它包含 final 字段 width 和 height(两者都是 double)。它的构造函数接收 color、width 和 height,并将 color 传递给 super。实现 area(),使其返回 width * height;实现 perimeter(),使其返回 2 * (width + height)。
  • main.dart:导入所有文件。创建一个颜色为 'red'、半径为 5.0 的 Circle,再创建一个颜色为 'blue'、宽度为 4.0、高度为 6.0 的 Rectangle。对每个形状调用 describe()。然后创建一个包含这两个形状的 List<Shape>,遍历这个列表,并为每个形状打印 Area: [area]。

预期输出:

A red shape with area: 78.5 and perimeter: 31.400000000000002
A blue shape with area: 24.0 and perimeter: 20.0
Area: 78.5
Area: 24.0

亲手试试

import 'shape.dart';
import 'circle.dart';
import 'rectangle.dart';

void main() {
  // TODO: 创建一个颜色为 'red'、半径为 5.0 的 Circle

  // TODO: 创建一个颜色为 'blue'、宽度为 4.0、高度为 6.0 的 Rectangle

  // TODO: 对圆形调用 describe()

  // TODO: 对矩形调用 describe()

  // TODO: 创建一个包含这两个形状的 List<Shape>

  // TODO: 遍历列表,为每个形状打印 "Area: [area]"
}
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: Dart 在线编译器