Menu
CoddyTech

构造函数与继承

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

子类继承父类时,必须调用父类的构造函数,才能正确初始化继承的字段。Dart 提供了灵活的方式,可以通过初始化列表使用 super 来处理。

如果父类有带参数的构造函数,子类必须显式调用它:

class Person {
  String name;
  int age;
  
  Person(this.name, this.age);
}

class Student extends Person {
  String school;
  
  Student(String name, int age, this.school) : super(name, age);
}

Dart 2.17 引入了super 参数,这是一种更简洁的语法,可以将参数直接传递给父类构造函数:

class Student extends Person {
  String school;
  
  // super.name 和 super.age 会直接传给 Person 的构造函数
  Student(super.name, super.age, this.school);
}

使用命名构造函数时,你需要指定要调用哪个父类构造函数:

class Employee extends Person {
  String department;
  
  Employee(super.name, super.age, this.department);
  
  Employee.intern(String name, this.department) : super(name, 18);
}

关键规则很简单:必须先完全初始化父类,然后子类才能添加自己的属性。无论你使用传统的 super() 调用,还是较新的 super 参数,Dart 都会确保继承链从父类到子类正确构建。

challenge icon

挑战

简单

让我们构建一个产品库存系统,演示构造函数如何与继承配合使用。你将创建一个层级结构,让不同的产品类型扩展基础产品类,并通过父类构造函数正确初始化。

你要将代码分成两个文件:

  • product.dart:在这里定义产品层级结构:
    • 一个 Product 类,包含 String name 和 double price 属性、一个接收这两个值的构造函数,以及一个用于打印 [name]: $[price] 的 info() 方法
    • 一个扩展 Product 的 Book 类,并添加 String author 属性。使用 super 参数将 name 和 price 传递给父类构造函数
    • 一个扩展 Product 的 Electronics 类,并添加 int warranty 属性(单位为月)。在初始化列表中使用传统的 super() 调用,将值传递给父类
  • main.dart:导入产品文件,并演示这两种构造函数继承方式:
    • 创建一个 Book,名称为 'Dart Essentials',价格为 29.99,作者为 'Jane Smith'
    • 调用它的 info() 方法,然后打印 Author: [author]
    • 打印一个空行
    • 创建一个 Electronics,名称为 'Wireless Mouse',价格为 45.50,保修期为 24 个月
    • 调用它的 info() 方法,然后打印 Warranty: [warranty] months

这两个子类都会继承 Product 的 info() 方法,无需重写。关键区别在于调用父类构造函数的方式:Book 使用更简洁的 super 参数语法,而 Electronics 则使用在初始化列表中调用 super() 的传统方式。

预期输出:

Dart Essentials: $29.99
Author: Jane Smith

Wireless Mouse: $45.5
Warranty: 24 months

亲手试试

import 'product.dart';

void main() {
  // TODO: 创建一个 Book 对象,属性如下:
  // - name: 'Dart Essentials'
  // - price: 29.99
  // - author: 'Jane Smith'

  // TODO: 调用 book 的 info() 方法

  // TODO: 打印 "Author: [author]"

  // TODO: 打印一个空行

  // TODO: 创建一个 Electronics 对象,属性如下:
  // - name: 'Wireless Mouse'
  // - price: 45.50
  // - warranty: 24

  // TODO: 调用 electronics 的 info() 方法

  // TODO: 打印 "Warranty: [warranty] months"
}
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: Dart 在线编译器