本篇,来介绍面向对象的基本概念。
1 面向过程与面向对象
面向过程与面向对象,是两种不同的编程思想。
1.1 面向过程
面向过程的思路,是按照问题的解决步骤,将程序分解为一个个具体的函数或过程,然后依次调用这些函数来实现程序的功能。
面向对象的程序设计,程序的执行流程比较直观,按照步骤一次执行,适合处理简单的,单线程的任务。
1.2 面向对象
面向对象的思路,是将事物抽象成对象,每个对象有自己的属性(变量)和方法(函数)。对象是程序的基本单元,通过对象之间的交互、消息传递等来实现程序的功能。
2 对象的概念
2.1 对象数据
保存在对象中的数据,描述了该对象的状态。在面向对象中,数据被称为属性。
例如,一个员工的属性,可以包含员工号、生日、性别、电话号码等。
2.2 对象行为
对象的行为,表示这个对象可以做什么。在面向对象中,数据被称为方法。
例如,员工对象的方法,可以有setGender()和getGender()来设置和获取性别。
3 类的概念
3.1 类与对象
类可以理解为对象的蓝图。在实例化一个对象时,是基于这个类来构建对象。
类也可以理解为是对象的模板或模具,用来创建对象。
例如,创建一个整数或浮点数:
int x;
float y;
也可以使用自定义的类来创建对象
myClass myObject;
3.2 类的属性、方法和消息
以一个Person类为例来介绍:
class Person{
// 属性
private:
std::string name;
std::string address;
// 方法
public:
std::string getName(){
return name;
}
std::string setName(std::string n){
name = n;
}
std::string getAddress(){
return address;
}
std::string setAddress(std::string adr){
address = adr;
}
}
3.2.1 属性
类的数据通过属性来表示,用来存放该类实例化的每个对象的状态
属性可以有3种类型:
public: 其它对象可以访问private: 只有自身对象可以访问protected: 只允许相关对象访问
3.2.2 方法
方法实现了一个类需要的行为。
在Person类中,方法有getName()、getName()、getAddress()、setAddress()。
通过方法来检查或修改对象的属性,是面向对象中常用的技术。
3.2.3 消息
消息是对象之间的通信机制。
当对象A调用了对象B的一个方法,则表示对象A正在向对象B发送一个消息,对象B的响应即为其返回值。
class Payroll{
std::string name;
Person p = new Person();
p.setName("Joe");
//...
name = p.getName();
}
3.3 类的可视化描述——UML与类图
统一建模语言UML(Unified Modeling Language)是一种可视化建模工具,其中的UML类图,可以用来描述类的特征。
每个类图由三部分组成:类名、属性(数据)和方法(行为)。
类图中:
- 加号(+)表示公有访问减号(-)表示私有访问井号(#)表示保护访问
4 面向对象的特性
经典的面向对象,拥有三大特性:封装(encapsulation)、继承(inheritance)和多态(polymorphism)。除此之外,面向对象还会加入“组合”的特性。
4.1 封装
封装是指把对象的属性和方法进行封装,对外隐藏其内部的实现细节。
使用对象的好处之一,是无须对外暴露其所有的属性和方法。
一个好的设计,是仅暴露出必要的接口来与其它对象进行交互。
4.1.1 接口与实现
接口定义了对象之间的通信方式。实现是具体功能的实现过程。
用户通过类的接口与对象交互时,只需要关注接口的形式,无需关注(也不应该看到)对象的内部实现。
4.1.2 举例
一个计算整数的平方的例子:
class IntSquare{
// 私有属性
private:
int squareValue;
// 公共接口
public:
int getSquare (int value){
squareValue = calculateSquare(value);
return squareValue;
}
// 私有实现
private:
int calculateSquare(int value){
return value*value;
}
}
该类中,外部对象唯一能访问的,就是公共接口getSquare(),其余的私有属性squareValue以及私有方法calculateSquare,外部对象无需知道这些私有属性和方法的存在。
4.2 继承
继承是指一个类可以继承另一个类的属性和方法。
可以通过提取公共属性和方法来创建新类。
例如:有一个猫类(Cat)和一个狗类(Dog),这两个类都有一个属性可以表示眼睛的颜色。在面向对象中,可以将颜色属性上移到名为哺乳动物的类中(Mammal)。
4.2.1 超类和子类
- 超类:也称父类、基类。它包含了所有子类的公共属性和行为。使用基类的好处在于,通过继承基类,减少了大量重复的工作。子类:即超类的衍生类,是超类的扩展
4.2.2 抽象
在实现了哺乳动物类和猫、狗类后,还可以添加其它哺乳动物(老虎、狮子),也可以将猫类作为父类,继续扩展出不同品种的猫(波斯猫、加菲猫)
4.2.3 is-a关系
继承的关系,也称作is-a关系,例如,猫is a哺乳动物,狗is a哺乳动物。
多重继承:
多数编程语言中(Java、.Net、Swift),一个类只有一个父类,一个父类可以有多个子类但在C++中,一个类可以有多个父类,即允许继承多个父类的功能。
4.3 多态
多态与继承是紧耦合的关系。
当向一个对象发送消息时,该对象必须定义其实现来响应消息。
在继承的关系中,子类从父类中继续接口,但每个子列又是各有特点的,因此每个子类各自实现对应的接口功能,实现独特的应答。
4.4 组合
组合,字母理解,多个对象,组合为一个新的对象,例如,车架、车轮、发动机等对象组成了汽车对象。
4.4.1 抽象
类比继承方式,通过组合的方式,也是构建对象的一种机制。实际上,构建 新类方式,就是继承和组合这两种方式。
使用继承,是把属性和方法提取到通用的类中。
使用组合,是把类嵌入到其它类中的来构造新的类。
4.4.2 has-a关系
组合的关系,也称作has-a关系,例如,汽车has a发动机。
5 总结
本篇介绍了面向对象的一些基本概念,是面向对象编程的基础。