#P2118. 面向对象编程
面向对象编程
1. 面向对象编程的概念
面向对象是一种将面向对象的思想应用于软件开发过程并指导开发活动的系统方法。
这是一种基于“对象”概念的方法论。对象是由数据和允许的操作组成的包,它与目标实体有直接的对应关系。
对象类定义了一组具有类似属性的对象。类的继承是共享具有层次关系的类的属性和操作的一种方式。面向对象是基于对象的概念,以对象为中心,以类和继承为构建机制,认识、理解和描绘客观世界,设计和构建相应的软件系统。
上面的话都很抽象,我们用一些实际例子来帮助我们理解。
例子 1 :水果、蔬菜
苹果、雪梨、香蕉、榴莲.....这些都是水果。水果会有一些属性,例如 名字,重量、价格、皮的颜色、肉的颜色、味道(酸不酸、甜不甜之类),还可以有产地属性(热带水果,亚热带水果、温带水果....)
所以,我们就可以定义水果的 类
class fruit{
public:
string name; //水果的名字
int weight; //重量
int price; // 单价
int color; //颜色,假设我们用不同的数字来表达不同的颜色
string zone; // 产地
}
大家有没有觉得上面的这个写法很熟悉?是不是和结构体很相似?对的,类 就是从 结构体 演变过来了。C 语言已经支持 结构体,到了 C++ 开始支持 类,后者比前者增加了一些新的功能。而且,在 C++ 里你定义结构体,实际上也是类(也就是说,C++ 内部已经用 类 来看待和处理你定义的结构体了,即便你以为你定义的是结构体,但是实际上你定义出来的就是类)。
上面的水果类里面有一个新的关键字: public ,意思是下面的这些成员变量是公开的,在类的外部可以访问到这些成员变量。默认情况下,类的成员是 private 的,意思是不能被外部访问,但是可以被类的成员函数访问。而 结构体 的成员默认是 public 的(为了和 C 语言的习惯保持一致)。
如果单单看上面这段代码,你会觉得既然这个东西就是跟结构体很像,干嘛还要学类呢?下面,我们做一些非常简单的扩展,满足大家的欲望,先让大家看一些不一样的东西。
试想一下,我们还定义另外一个类别,是食物。水果和食物是什么关系?我们想到,所有的水果都是食物,但是有一些食物不是水果。也就是是说,水果是食物的一个类别。这时候,我们可以考虑另外定义一个食物的类,把水果的那些属性都包含进去(那就是重写一遍了),也可以基于水果的类别来拓展。
class food: public fruit // 这个地方表示继承的 fruit 类
{
public:
bool shengchi; // 这是在水果类的基础上新增的属性,假设 shengchi 表示这个肉能否生吃
}
那么,食物类就继承了水果类的的所有额户型,水果类有的属性(name/weight/price/color/zone) 都会在食物类出现,而且还可以扩展出新的属性。这个行为,就叫 对象的继承。
面向对称编程会有好些内容是以对象为中心,继承、多态、重载。以后,这些内容会逐步向大家介绍。这些功能,在大型软件项目中非常有用。我们想象一下,电视机公司开发一个软件,是运行在电视机的硬件上的,是整个电视机运作软件。然后,这个软件分成了几个大部分,一个部分是和屏幕发光元件打交道的,把图像的信号传给发光元件;一个模块是负责接受遥控器的按键的,并且按照上下文关系,把按键信息转换成一些内部命令,同一个按键,在不同的上下文关系中可能都有不一样的含义,例如在选频道的时候按“确定”表示你选择了一个频道,如果你是在做色彩控制的时候选择了“确定”,又是表示更改了电视机的某个参数;然后还有一个模块是负责运行一个小游戏的(比方一个 俄罗斯方块 游戏)......
然后,有好几个研发部门,各自负责一个模块。这时候如果我们把这些模块都定义成一个类,类下面有成员变量,有函数,然后把一些外部接口公开给兄弟部门(其余的细节都可以隐藏),兄弟部门只管用你这个部门写出来的类,只关心公开的那一丢丢东西,那你说这个软件的开发项目是不是可以做到井井有条?
然后,你们公司要开发一台新的电视机,在这个新型号里,会有一些新的功能要求,这时候,大家定好接口,你开发你的,我开发我的,相互之间基本不影响。这个功能效率就很高了。
2. 我们所熟悉的 string 类
过去,我们编程的时候其实也有用到类,例如 string 就是一个类。string 和 int , long long, char 是不一样的。int 、 long long 、 char 是 C++ 的基本数据类型。也就是说,你什么头文件都不引入,就可以用到 int 和 long long 、char 。但是,你如果要用 string,你就要 #inclue <string.h>
,这个 string.h 就是一个头文件,简单来说,就是有一些人写了一个 string 类出来,你可以直接用人家写好的这些东西。
string a; // 这里,是声明一个 string 实例。实例是类的具体表现,例如 水果 是一个类,香蕉是水果的一个具体例子,所以叫实例
string b = string("abcdefg12345"); // 每一个类都会有自己的构造函数,构造函数和类名相同,所以 string("abcdefg12345") 就是调用构造函数,基础 "abcdefg12345" 来构造出一个 string 实例。
string c = b.substr(3); // substr 是 string 类的一个方法,用这个方法可以截取出一个子串,当只有 1 个参数是,表示从这个参数对应的位置开始一直截取到最后,返回截取出来的字符串,所以,相当于 c 被赋值为 "defg12345"
string d = b.substr(3,5); // substr 是 string 类的重载方法,也就是说可以有多种输出参数情况,不同的参数情况对应不同的含义,如果有 2 个参数,则表示从第一个参数的位置开始,截取第二个参数那么长的子串,所以,相当于 d 被赋值为 "defg1"
cout<< b.find("123"); // find 也是 string 的成员函数,它查找一个目标字符串或者字符,返回第一个找到的位置
上面的这些例子可以简单演示 string 类的一些用法。我们其实不怎么关心 find 、substr、replace 、erase 这些成员函数的实现细节,我们只需要知道怎么使用就可以了。这就体现了类的优点,我们在享受这些好处。