Menu
CoddyTech

基本继承

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

继承允许一个类获得另一个类的属性和方法。你不必重写相同的代码,而是创建一个基于现有类的新类。原来的类称为父类(或超类),新类称为子类(或派生类)。

在 Dart 中,你可以使用 extends 关键字从父类继承:

class Animal {
  String name;
  
  Animal(this.name);
  
  void eat() {
    print('$name is eating');
  }
}

class Dog extends Animal {
  Dog(String name) : super(name);
  
  void bark() {
    print('$name says woof!');
  }
}

void main() {
  var dog = Dog('Buddy');
  dog.eat();   // 继承自 Animal
  dog.bark();  // 在 Dog 中定义
}

Dog 类会自动拥有 Animal 的 name 属性和 eat() 方法,以及自己的 bark() 方法。这建立了一种“是一种”的关系,也就是说,Dog 是一种 Animal。

子类可以添加新的属性和方法,但会继承父类的所有公共成员。请注意,私有成员(带有 _ 的成员)无法在不同库中的子类里直接访问,不过它们仍然存在于继承得到的对象中。

challenge icon

挑战

简单

我们来构建一个车辆系统,演示继承如何让子类重用并扩展父类的功能。你将创建一个通用车辆的父类,以及一个特定车辆类型的子类。

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

  • vehicle.dart:在这里定义你的类:
    • 一个 Vehicle 类(父类),包含一个 String brand 属性、一个接收品牌的构造函数,以及一个会打印 [brand] engine starting... 的 start() 方法
    • 一个继承自 Vehicle 的 Motorcycle 类。它应包含一个额外的 int cc 属性(发动机排量)、一个同时接收品牌和 cc 的构造函数(使用 super 将品牌传给父类),以及一个会打印 [brand] is doing a wheelie! 的自有方法 wheelie()
  • main.dart:导入车辆文件,并演示继承的实际效果:
    • 创建一个品牌为 'Toyota' 的 Vehicle
    • 调用它的 start() 方法
    • 创建一个品牌为 'Harley'、cc 为 1200 的 Motorcycle
    • 调用摩托车的 start() 方法(从 Vehicle 继承而来)
    • 调用摩托车的 wheelie() 方法(在 Motorcycle 中定义)
    • 打印 Motorcycle engine: [cc]cc,以显示子类自己的属性

注意,Motorcycle 类会自动获得 Vehicle 类的 brand 属性和 start() 方法,同时也拥有自己独有的 cc 属性和 wheelie() 方法。这就是继承的强大之处:在现有代码的基础上进行扩展。

预期输出:

Toyota engine starting...
Harley engine starting...
Harley is doing a wheelie!
Motorcycle engine: 1200cc

亲手试试

import 'vehicle.dart';

void main() {
  // TODO: 创建一个品牌为 'Toyota' 的 Vehicle 对象
  
  // TODO: 调用 vehicle 的 start() 方法
  
  // TODO: 创建一个品牌为 'Harley'、cc 为 1200 的 Motorcycle 对象
  
  // TODO: 调用 motorcycle 的 start() 方法(继承自 Vehicle)
  
  // TODO: 调用 motorcycle 的 wheelie() 方法
  
  // TODO: 使用 motorcycle 的 cc 属性打印 'Motorcycle engine: [cc]cc'
}
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: Dart 在线编译器