C++启蒙课程:第13章 类继承
我们将揭开OOP最强大的特性:类继承!这就像让你的新机器人自动拥有父辈的全部技能,并能“形态变化”!
基因的传递:公有继承
学习 "is-a" 关系,以及“父子蓝图”如何通过构造函数传递特性。
形态变化:虚函数与多态
掌握 `virtual` 关键字,让“形态变化”的英雄能执行不同的 `Work()`。
架构设计:抽象基类
学习 `virtual ... = 0`“强制契约”,设计不能被实例化的通用接口。
课时一:基因的传递:公有继承与构造
(覆盖知识点 13.1.1 - 13.1.4)
“父子蓝图” (is-a 关系)
公有继承 (: public Base) 就像“基因传递”。子类 (Car) 自动获得父类 (Vehicle) 的所有公有特性。
“基类优先入场” (构造)
构造子类时,必须先调用父类的构造函数(使用 : 语法),把“基因”部分先组装好。
课时二:形态变化:虚函数与多态
(覆盖知识点 13.2.1 - 13.2.5)
“动态调度机器人” (虚函数)
`virtual` 关键字告诉C++进行“动态联编”。机器人 🤖 会在“运行时”检查指针的“实际形态”,并调用正确版本的函数。
💡 互动:
Employee* ptr = ?
📜 代码支撑:
课时三:抽象蓝图与继承适用性
(覆盖知识点 13.3 - 13.4)
13.3 “强制契约” (纯虚函数)
纯虚函数 (= 0) 是一个“强制契约”。任何包含它的类(ABC)都不能被实例化。派生类**必须**实现这个函数才能被创建。
Piano : public Instrument继承的“判断法则”
公有继承只适用于 **"is-a" (是一种)** 关系。如果只是“包含”关系 (has-a),应使用组合(成员对象)。
编程实践与作业
是时候检验你作为“OOP架构师”的实力了!
练习 1:Vehicle 与 Car (is-a 继承)
任务:
编写一个 Vehicle 基类(含 `wheels`),派生出 Car 类(新增 `passengers`)。实现 Car 的构造函数,确保它能正确调用基类构造函数。
点击查看参考答案
练习 2:虚函数与多态 (Employee)
任务:
编写 Employee 基类 (含 virtual void Work()),派生出 Manager 和 Technician。在 main 中使用基类指针数组 Employee* staff[2] 指向不同对象,演示多态。
点击查看参考答案
练习 3:抽象基类 (Instrument)
任务:
编写一个抽象基类 Instrument (含纯虚函数 Play())。派生 Piano 和 Guitar 类并实现 Play()。演示 ABC 无法实例化,但指针可以实现多态。
点击查看参考答案
本章知识点总结与复习
| 核心概念 | 解释/功能 | 关键用法/示例 |
|---|---|---|
| 公有继承 | 模拟 is-a 关系,派生类是基类的特例。 | class Derived : public Base {} |
| 派生构造函数 | 必须调用基类构造函数来初始化基类部分。 | Derived(...) : Base(...) { ... } |
| 多态性 | 相同的调用,导致依赖于对象类型的行为。 | ptr->Work(); |
| 虚函数 | 使用 `virtual` 关键字,启用多态(动态联编)。 | virtual void func() const; |
| 向上转换 | 允许将派生类指针/引用赋给基类指针/引用。 | Base * p = &derived_obj; |
| 抽象基类 (ABC) | 包含纯虚函数的类,不能被实例化。 | class Instrument { ... }; |
| 纯虚函数 | 虚函数声明后跟 `= 0`,强制派生类实现。 | virtual double Area() const = 0; |
| is-a vs. has-a | 继承 (is-a) vs. 组合 (has-a)。 | class Car { Engine m; }; |