考点频率:★★★★★(选择题必考,尤其爱考单继承与多继承的对比,以及 Java 与 C++ 的区别)
难度:⭐⭐
建议:重点理解“继承是为了复用”,但更要记住“继承不是万能的”
1️⃣ 继承像“遗传”,也像“抄作业”
上篇文章讲了封装——把数据和方法打包在一起,对外只暴露接口。
现在有一个新问题:你写了一个动物类,里面有属性年龄、体重,有方法吃()、睡()。现在你要写一个狗类和一个猫类。
如果从头写,你要在狗和猫里重复写一遍年龄、体重、吃()、睡()——代码冗余,而且如果吃()的逻辑要改,你得改两处。
继承解决的就是这个问题:
继承是在已有类的基础上创建新类的机制。新类(子类)自动拥有父类(基类)的属性和方法,并且可以增加新的属性和方法,或重写父类的方法。
2️⃣ 继承关系的核心概念
| 概念 | 含义 |
|---|---|
| 父类(基类/超类) | 被继承的类,代表“更一般”的概念 |
| 子类(派生类) | 继承父类的类,代表“更特殊”的概念 |
| 单继承 | 一个子类只能有一个直接父类 |
| 多重继承 | 一个子类可以有多个直接父类 |
关系语义:继承代表“is-a”关系。子类是父类的一种特殊类型。
狗是一种动物,所以狗可以继承动物。
3️⃣ 单继承(Single Inheritance)
定义:一个子类只能有一个直接父类。
特点:
- 结构清晰,类层次呈树状(一根树枝往上追溯只有一条路径)
- 不易产生冲突(不会出现“两个父类有同名方法,子类该听谁的”的问题)
- 代码更易于理解和维护
典型支持语言:Java、C#、Smalltalk
Java 示例(伪代码):
class 动物 { 年龄 吃() { 吃东西 } } class 狗 extends 动物 { // 单继承:狗只有一个父类 看家() { ... } }注意:Java 中一个类只能继承一个父类,但可以通过实现多个接口来弥补多重继承的功能需求。
4️⃣ 多重继承(Multiple Inheritance)
定义:一个子类可以有多个直接父类。
特点:
- 可以组合多个父类的功能,复用性更强
- 但会出现菱形问题(Diamond Problem)——当两个父类有同名方法时,子类不知道该继承谁的
- 类层次结构更复杂,容易出现冲突和混淆
典型支持语言:C++(支持)、Python(支持)
菱形问题示例:
A / \ B C (B和C都重写了A的某方法) \ / D (D同时继承B和C,到底该用B的方法还是C的方法?)C++ 的解决方案:通过虚继承(Virtual Inheritance)来解决菱形问题,但这使得语言更复杂,也更容易出错。
软考高频对比:
| 对比项 | 单继承 | 多重继承 |
|---|---|---|
| 结构复杂度 | 简单清晰 | 复杂,可能出现菱形问题 |
| 功能复用 | 只能从一个父类继承 | 可以从多个父类继承功能 |
| 命名冲突 | 无冲突 | 可能出现同名方法冲突 |
| 典型语言 | Java、C#、Smalltalk | C++、Python |
5️⃣ 继承中的方法覆盖(Override)与super
子类可以重写(覆盖)父类的方法,用自己的实现替换父类的实现。
- 覆盖:子类重新定义父类中已有的方法,方法名、参数列表、返回值类型必须相同
super:在子类中调用父类的方法或构造器(即使用户覆盖了父类方法,仍然可以通过super访问父类版本)
软考常考点:覆盖的方法不能比父类方法拥有更严格的访问权限(如父类是public,子类不能是private)。这是子类可以安全替代父类的保证。
6️⃣ 继承的优缺点(软考常考)
| 优点 | 缺点 |
|---|---|
| 代码复用,减少重复 | 父类改动会影响所有子类(脆弱基类问题) |
| 建立类之间的层次关系,符合现实世界认知 | 过度使用继承会导致类层次过深,难以理解 |
| 支持多态(下一篇细讲) | 继承破坏了封装(子类可以访问父类的protected成员) |
一个设计原则:优先使用组合(Composition),而不是继承(Inheritance)。组合更灵活,不会破坏封装。如果只是为了复用代码而不是表达“is-a”关系,用组合更合适。
7️⃣ 经典例题
例题1:以下关于 Java 语言中继承的描述,正确的是( )。
A. Java 支持多重继承,一个类可以有多个父类
B. Java 不支持继承,所有类都是独立的
C. Java 只支持单继承,但一个类可以实现多个接口
D. Java 中所有类默认继承自 Object 类,因此不支持单继承
解析:Java 是单继承(一个类只能有一个父类),但可以通过实现多个接口来获得多重继承的功能。选C。
例题2:在面向对象系统中,子类可以继承父类的属性和方法。以下关于继承的叙述中,正确的是( )。
A. 继承关系表示“has-a”关系
B. 子类可以继承父类的所有成员,包括私有成员
C. 方法覆盖时,子类方法的访问权限可以比父类更严格
D. 继承体现了“is-a”关系
解析:A错误——继承是“is-a”,组合才是“has-a”;B错误——私有成员不能被继承;C错误——覆盖时不能有更严格的访问权限。D正确。选D。
8️⃣ 记忆口诀
继承就是 IS-A,子类复用父类码。
单继 Java 多继 C++,菱形问题是多继的坑。
多用组合少继承,设计灵活不僵硬。
9️⃣ 小测验(评论区对答案)
以下关于继承的叙述中,错误的是( )。
A. 子类可以继承父类的 public 和 protected 成员
B. 子类可以重写(覆盖)父类的方法
C. 多重继承一定会导致菱形问题
D. 继承关系表示“is-a”关系
🔔本专栏日更,点击头像 → 专栏《软考中级高频考点》订阅,第一时间接收新内容
#软考中级 #软件设计师 #继承 #单继承 #多重继承 #面向对象 #软考备考