OOP 和 POP

OOP 全称 Object Oriented Programming,即面向对象编程;POP 全程 Procedure Oriented Programming,即面向过程编程 or 过程性编程。

面向对象编程是一种特殊的设计程序的概念性方法,它是一种编程思想,并不是 C++ 特有的。实际上,使用 C 语言依旧可以采取面向对象编程,只是 C++ 通过一些特性改进了 C 语言,使得 C++ 应用面向对象编程更容易。

面向对象编程的重要特性有:抽象、封装、继承、多态、代码的可重用性。
为了实现面向对象编程的特性,C++ 做的最重要的改进就是提供了(class)。之后会介绍类的概念,并解释抽象和封装,并演示类是如何实现这些特性的。

面向对象编程和面向过程编程的思路是不同的。采用面向过程编程方法时,首先考虑要遵循的步骤,然后考虑如何表示这些数据;而面向对象编程时,首先考虑的是数据,然后是如何使用数据。
总之,OOP 是从用户角度考虑对象 —— 描述对象所需的数据以及描述用户与数据交互所需的操作。完成对接口的描述后,需要确定如何实现接口和数据存储。最后,使用新的设计方案创建出程序。

抽象和类

面向对象编程的第一步是描述数据,这个数据并不是 C++ 的基本数据类型,因为基本数据类型太简单了,单靠基本数据类型是无法描述一些复杂的数据,因此需要用户自定义数据类型。说到自定义类型,可能会想到前面学习的结构体,没错,类和结构体很相似,而且 C++ 对结构体进行了一些拓展,但类更适应于面向对象编程。因此,在实际的编程中类比结构体常用的多。

生活中充满了复杂性,处理复杂性的方法之一就是简化和抽象。抽象:将问题的本质特征抽象出来,并根据特征来描述解决方案。抽象是通往用户定义类型的捷径,在 C++ 中,用户定义类型指的是实现抽象接口的类设计。

例如,现在需要编写一个学生档案管理系统,那么学生就是我们需要描述的数据。但是描述一个学生是复杂的,因为他会具有很多特征,如性别、高矮、胖瘦等等,但是这些特征并不全是学生档案管理系统需要的,因此我们需要从学生的特征中抽象出档案管理系统需要的本质特征即可。比如,这里我们可以将学生的性别、出生年月、教育经历作为描述的数据,其他的胖瘦等特征则不进行描述。

为什么要在自定义类型之前进行抽象?因为世间的事物都是多面的,每一个事物都具有很多特征,是无限的,而计算机描述事物要求有限性,因此必须从中抽象出有限个特征进行描述。另外,即使事物的特征是有限的,但是在解决指定问题时,并不是所有特征都是需要的,如果全都描述出来也是浪费资源,因此需要抽象出有用的特征进行描述。总之,抽象是为了从事物中提取有限个有用的特征来描述数据的。

封装特性

封装:隐藏对象的属性和实现细节,仅对外公开接口来对象进行交互,将数据和操作数据的方法进行有机结合。封装是面向对象的三大特性之一。
数据隐藏(将数据放到类的私有部分中)是一种封装,将实现的细节隐藏在私有部分中(私有成员函数),也是一种封装。封装的另一个例子是将类函数定义和类声明分别放在不同的文件中。

C 语言虽然也可以采取面向对象编程,但是 C 语言没有访问控制,因此直接访问结构成员并没有违反 C 语言规则,却会违反面向对象的精神。而 C++ 程序中试图直接访问私有成员就会违反 C++ 规则,被编译器捕获。

数据隐藏不仅可以防止直接访问数据,保证数据安全性还让开发者 (使用类的开发人员) 无需了解该类中数据是如何表示的。从使用类的角度看,需要知道的只是各种 public 成员函数的功能;也就是说,需要知道成员函数接受什么样的参数、返回什么类型的值。

原则上,是将成员函数的实现细节从接口设计中分离出来。如果以后找到更好的实现函数细节的方法可以对这些细节进行修改,而无需修改程序接口,这使得程序维护起来更容易。

所谓接口设计简单来说就是固定好成员函数的参数列表和返回值类型。