Click the link below to find out more
我的更多面向对象文章:CLICK HERE
面向对象绪论
图:歼15航母降落
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++
代码如下:
class C1Dobject
{
private:
int x = 0;
public:
int getx() { return x; }
void setx(int xPrime) { x = xPrime; }
};
class C2Dobject: public C1Dobject
{
private:
int y = 0;
public:
int gety() { return y; }
void sety(int yPrime) { y = yPrime; }
};
class C3Dobject: public C2Dobject
{
private:
int z = 0;
public:
int getz() { return z; }
void setz(int zPrime) { z = zPrime; }
};
多态 Polymorphism
使用指向父类的指针或者引用,能够调用子类的对象
结论:
- 当一个类从另一个类继承而来,多态使得子类可以代替父类
- 消息发送方不需要知道消息接收方属于哪一个子类
- 同一类族的接收者可以按自己的方式处理消息
如以下类图例子,定义形状CShape
作为父类,派生出矩形CRectangle
和三角形CTriangle
。现在假设我们知道一个图形shape
,希望获取它的面积,而我们并不需要知道它的具体形状(属于哪一个子类),只需要确保shape
所属的类在CShape
的类组下即可。图形shape
的面积可以通过调用函数area()
实现。
C++
中多态的实现涉及静态多态和动态多态以及虚函数的使用,代码如下:
#include <iostream>
using namespace std;
class CShape
{
protected:
int width, height;
public:
CShape(int a = 0, int b = 0) { width = a, height = b; }
//纯虚函数,具体功能在子类中实现
virtual int area() = 0;
};
class CRectangle: public CShape
{
public:
//显式调用父类的构造函数
CRectangle( int a = 0, int b = 0): CShape(a, b) {};
int area()
{
cout << "CRectangle area calls: ";
return width * height;
}
};
class CTriangle: public CShape
{
public:
//显式调用父类的构造函数
CTriangle( int a = 0, int b = 0): CShape(a, b) {};
int area()
{
cout << "CTriangle area calls: ";
return width * height / 2;
}
};
int main()
{
CShape *ptr;
CRectangle rect(10, 10);
CTriangle tri(10, 10);
//获取矩形的面积
ptr = ▭
cout << ptr->area() << endl;
//获取三角形的面积
ptr = &tri;
cout << ptr->area() << endl;
return 0;
}
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
抽取具体客观事物的共性
抽象是面向对象领域发现类的主要方法
(所谓抽象,玄之又玄,众妙之门)
Click the link below to find out more
更多文章:CLICK HERE