面向对象绪论
Guderian出品
面向对象的基本概念
- 类 Class
- 对象 Object
浅显理解:类是抽象的对象,对象是具体的类
概念之间的互用
- 属性 Attribute == 数据 Data == 状态 State == 信息 Information
- 操作 Operation == 方法 Method == 行为 Behavior == 职责 Responsibility
- 对象 Object == 实例 Instance
面向对象的核心特征
- 封装 Encapsulation
- 继承 Inheritance
- 多态 Polymorphism
封装、继承和多态被称为所谓的“面向对象三大特征”
- 聚合/组合 Aggregation / Composition
- 接口/实现 Interface / Implementation
- 抽象 Abstraction
封装 Encapsulation
是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
- 封装什么?
- 内部的、不想让其他人随意了解的信息
- 类的属性 Attribute
- 类的方法 Method
- 为什么要封装?
- 保护隐私
- 保护数据安全
- 隔离复杂度
- 面向对象的封装有四种方式
- Public
- Private
- Protected
- Package
继承 Inheritance
一个类从其他类获得它的状态和行为,同时还可以加上自己额外的状态和行为
父类中的属性和方法,在子类中可以重复使用,子类就不需要再定义了,这样即可实现代码的可重用性。如以下类图例子,定义类C1Dobject
一维物体,它有一个属性x
对应x轴上的一个坐标,两个方法getx()
和setx(int)
分别表示x坐标的获取和设置。如果我们需要定义二维物体,就没有必要把x坐标重复定义。我们在类C1Dobject
的基础上派生出子类C2Dobject
,只需再定义属性y
和方法gety()
及sety(int)
就可以完整地抽象出一个二维物体;类似地,如果我们需要定义三维物体,没有必要把x坐标、y坐标重复定义,只需再类C2Dobject
的基础上派生出子类C3Dobject
,再定义属性z
和方法getz()
及setz(int)
即可。显而易见,继承提高了代码的可重用性,减少了创建类的工作量。
以上类图对应的C++
代码如下:
1 | class C1Dobject |
多态 Polymorphism
使用指向父类的指针或者引用,能够调用子类的对象
结论:
- 当一个类从另一个类继承而来,多态使得子类可以代替父类
- 消息发送方不需要知道消息接收方属于哪一个子类
- 同一类族的接收者可以按自己的方式处理消息
如以下类图例子,定义形状CShape
作为父类,派生出矩形CRectangle
和三角形CTriangle
。现在假设我们知道一个图形shape
,希望获取它的面积,而我们并不需要知道它的具体形状(属于哪一个子类),只需要确保shape
所属的类在CShape
的类组下即可。图形shape
的面积可以通过调用函数area()
实现。
C++
中多态的实现涉及静态多态和动态多态以及虚函数的使用,代码如下:
1 |
|
C++
中构成多态需要满足两个条件:
聚合/组合 Aggregation / Composition
聚合 Aggregation
A has B,B是A的一部分,但A不控制B的生命周期
如:学校由学生组成,那么学校与学生是聚合关系
UML
图中聚合关系的符号如下图
组合 Composition
A has B,B是A的一部分,且A控制B的生命周期
如:树由树叶组成,那么树与树叶是组合关系
UML
图中聚合关系的符号如下图
接口/实现 Interface / Implementation
接口 Interface
描述一个类的用户如何与这个类交互
实现 Implementation
完成接口所定义的功能,如类、构建等完成的任务
如电视机、插座、发电厂的关系如何呢?
- 电视机是用户 client
- 插座是接口 Interface
- 发电厂是实现 Implementation
抽象 Abstraction
抽取具体客观事物的共性
抽象是面向对象领域发现类的主要方法
(所谓抽象,玄之又玄,众妙之门)
1. 重写:函数重写必须函数名一致、参数一致、返回值一致 ↩
2. 虚函数:在类的成员函数前加virtual
关键字 ↩