# 面向对象编程概念

> CIE A-Level 计算机科学 · 9618 (2022-2024)
> 来源: https://www.owlsprep.com/zh/study/cie-9618-u11-object-oriented-programming-concepts/

本模块讲解CIE 9618考试中考察的核心面向对象编程（OOP）概念。你将学习类与对象的关系、四大核心OOP原则，以及OOP如何对复杂系统建模。

**先修:** [基础过程式编程概念](https://www.owlsprep.com/zh/study/cie-9618-u10-procedural-programming-concepts/)

## 学习目标

- 区分面向对象编程中类与对象的区别
- 解释四大核心OOP原则：封装、继承、多态、抽象
- 运用OOP概念对简单现实场景建模
- 正确使用OOP术语回答CIE 9618考试题目

## 类与对象

**类** — 可复用的蓝图或模板，定义该类型所有对象将共享的共同属性（数据）和方法（行为）。

*例:* 一个`Car`类定义所有汽车都拥有颜色、型号，并且可以加速。

对象是类的一个实例。每个对象对于类定义的属性拥有自己唯一的值，但和该类的所有其他对象共享相同方法。这允许从单个模板创建多个不同的实体。

**例题:** 使用一个类和两个对象实例对简单银行账户系统建模，列出所需的属性和方法。

1. 首先，将`BankAccount`类定义为蓝图，包含共同属性和方法：
2. 属性：账户持有人姓名、当前余额；方法：存款、取款、查询余额
3. 接下来，从`BankAccount`类创建两个不同的对象实例，各有唯一属性值：
4. 1. `aliceAccount = BankAccount("Alice Smith", 1500)` 2. `bobAccount = BankAccount("Bob Jones", 3250)`
5. 两个对象都使用类中定义的相同`deposit()`和`withdraw()`方法，但各自操作独立的余额值。

## 封装与抽象

**封装** — 将属性和方法捆绑在类中，限制对内部数据的直接访问以防止意外修改的原则。

*例:* 银行账户的余额无法直接修改，只能通过经过验证的存款/取款方法修改。

抽象与封装密切相关：它意味着向用户隐藏不必要的实现细节，仅暴露对象的核心特征。这降低了复杂度，允许用户无需理解内部工作原理即可与对象交互。

> **tip**
>
> 在CIE考试中，你经常需要区分这两个概念：封装是关于数据捆绑和访问限制，抽象是关于隐藏实现复杂度。

**例题:** 解释在存储学生考试成绩的`Student`类中，封装是如何工作的。

1. `Student`类捆绑了`grades`属性（成绩列表）和添加成绩、计算平均成绩的方法。
2. `grades`属性被标记为私有，这意味着无法从类外部直接访问或修改它。
3. 所有对成绩的修改都必须通过`addGrade()`方法，该方法会验证新成绩在0到100之间后才添加，防止无效数据。
4. 用户仅与`addGrade()`和`getAverage()`交互，因此成绩存储的内部实现被抽象隐藏了。

## 继承

**继承** — 新的（子）类从现有（父）类派生属性和方法的机制，支持代码复用和层级分类。

继承允许子类重写继承来的方法以提供特定行为，同时保留父类的所有特性。这支持对相关概念进行层级建模，避免冗余代码。

**例题:** 使用继承为市政停车系统对不同类型的车辆建模。

1. 首先创建父类`Vehicle`，定义所有车辆共享的共同属性和方法：
2. 属性：注册号、制造商、型号；方法：`getRegistrationNumber()`
3. 创建两个子类`Car`和`Motorcycle`，它们继承`Vehicle`的所有成员：
4. `Car`添加`numberOfDoors`属性和`isElectric()`方法；`Motorcycle`添加`engineCapacity`属性和`hasSideCar()`方法
5. 两个子类都自动继承`registrationNumber`属性和`getRegistrationNumber()`方法，因此不需要为每个子类重写这些代码。

## 多态

**多态** — 不同子类的对象能够对同一方法名做出不同类特定行为响应的能力。

OOP中最常见的多态形式是方法重写，即子类对父类已定义的方法提供特定实现。这允许代码与任意父类对象交互，无需知道它具体属于哪个子类。

**例题:** 使用停车场景示例演示多态，所有车辆都需要计算停车费。

1. 在父类`Vehicle`中定义方法`calculateParkingFee(hours)`，默认费率为每小时$2。
2. 在`Car`子类中重写该方法：汽车最低收费为$5，因此方法返回`max(5, 2 * hours)`。
3. 在`Motorcycle`子类中重写该方法：摩托车统一费率为每小时$1.50，因此方法返回`1.5 * hours`。
4. 当遍历`Vehicle`对象列表计算总费用时，无论对象属于哪个子类，都会自动调用正确版本的`calculateParkingFee()`。

> **考试提示:** 考试中被要求解释多态时，一定要包含方法重写的示例才能拿满分。

## 常见错误

- **错误做法:** 混淆类和对象，称类是对象的实例
  - 原因: 关系颠倒了：类是模板，对象是从模板创建的实例
  - 正确做法: 始终说明对象是类的实例，类是对象的模板
- **错误做法:** 混淆封装和抽象，将封装定义为隐藏实现细节
  - 原因: 两个概念的核心侧重点不同，考官会给混淆定义的答案扣分
  - 正确做法: 记住：封装 = 数据捆绑 + 访问限制；抽象 = 隐藏不必要的实现复杂度
- **错误做法:** 认为继承的方向是从子类流向父类
  - 原因: 继承是从现有类创建新类，因此这个说法的方向颠倒了
  - 正确做法: 子类从现有父类继承属性和方法
- **错误做法:** 仅将多态定义为'多种形态'，没有给出实际示例
  - 原因: 考官期望你解释多态在OOP中如何工作，而不只是翻译这个术语
  - 正确做法: 将多态解释为不同子类对象能够对同一方法名做出不同行为响应的能力，通常通过方法重写实现

## 速查表

| OOP概念 | 核心定义 | 主要作用 |
| --- | --- | --- |
| 类 | 对象的蓝图/模板 | 定义共享的属性和方法 |
| 对象 | 类的实例 | 表示单个实体 |
| 封装 | 捆绑数据 + 限制访问 | 防止内部数据被无效修改 |
| 抽象 | 隐藏实现细节 | 降低用户面对的复杂度 |
| 继承 | 子类继承自父类 | 支持代码复用和层级建模 |
| 多态 | 同名方法，不同行为 | 允许多个子类使用通用代码 |

## 下一步

现在你已经理解了OOP的核心概念，可以继续学习如何在代码中实现这些概念，这是CIE 9618试卷1和试卷2都会考察的内容。OOP是大多数现代软件开发的基础，掌握这些核心概念将帮助你高效对复杂问题建模，正确回答理论题，并为你的编程项目编写结构化、可维护的代码。在这里打下坚实基础也能为你未来大学计算机科学的学习做好准备。

- [声明式编程概念](https://www.owlsprep.com/zh/study/cie-9618-u11-declarative-programming-concepts/)
- [软件开发](https://www.owlsprep.com/zh/study/cie-9618-u12-overview/)
- [软件生命周期](https://www.owlsprep.com/zh/study/cie-9618-u12-software-lifecycle/)

---

来自 [OwlsPrep](https://www.owlsprep.com) —— A-Level / IB / AP / IGCSE 免费学习指南，依据官方考纲编写。原页面：https://www.owlsprep.com/zh/study/cie-9618-u11-object-oriented-programming-concepts/
