当c++爱上对象
当c++爱上对象
“自顶向下,逐步求精”的面向过程程序设计
旧的面向过程思想在解决问题时总是按照这样的流程:先提出问题;然后分析问题的处理流程;接着根据流程需要把一个大问题划分为几个小问题;如果细分后的小问题仍然比较复杂,则进一步细分,直到小问题可以简单解决为止;实现每个子模块,解决每个小问题;最后通过主函数按照业务流程次序调用这些子模块,最终解决整个大问题。

面向过程的程序设计有三个优势:
1. 程序仅由三种基本结构组成
面向过程程序设计思想限定程序只有顺序、选择和循环这三种基本控制结构。任何程序逻辑,无论是简单的还是复杂的,都可以用这三种基本的控制结构经过不同的组合或嵌套来实现。这就使得程序的结构相对比较简单,易于实现和维护。
2. 分而治之,各个击破
面向过程程序设计思想采取“分而治之”的策略,把较大的程序按照业务逻辑划分为多个子模块,然后分工逐个完成这些子模块,最后再按照业务流程把它们组织起来,最终使得整个问题得到解决。
按照一定的原则,把大问题细分为小问题“各个击破”,符合人们思考问题的一般规律,其设计结果更易于理解,同时这种方法也更易于人们掌握。
通过分解问题,降低了问题的复杂度,使得程序易于实现和维护。
另外,部分分解后的小问题(子模块)可以重复使用,从而避免了重复开发。而多个子模块也可由多人分工协作完成,提高了开发效率。
3. 自顶向下,逐步求精
面向过程程序设计思想倡导的方法是“自顶向下,逐步求精”。所谓“自顶向下,逐步求精”,就是先从宏观角度考虑,按照功能或者业务逻辑划分程序的子模块,定义程序的整体结构,然后再对各个子模块逐步细化,最终分解到程序语句为止。这种方法使得程序员能够全面考虑问题,使程序的逻辑关系清晰明了。它让整个开发过程从原来的考虑“怎么做”变成考虑“先做什么,再做什么”,流程也更加清晰。
面向过程出现的问题:
在面向过程程序设计中,数据和操作是相互分离的,这就导致如果数据的结构发生变化,相应的操作函数就不得不重新改写;如果遇到需求变化或者新的需求,还可能涉及模块的重新划分,这就要修改大量原先写好的功能模块。面向过程程序设计中数据和操作相互分离的特点,使得一些模块跟具体的应用环境结合紧密,旧有的程序模块很难在新的程序中得到复用。
万般皆对象:面向对象程序设计
面向对象程序设计(Object Oriented Programming, OOP)是对面向过程程序设计的继承和发展,它不仅汲取了后者的精华,而且以一种更接近人类思维的方式来分析和解决问题:程序是对现实世界的抽象和描述,现实世界的基本单元是物体,与之对应的,程序中的基本单元就是对象。
面向对象思想认为:现实世界是由很多彼此相关并互通信息的实体——对象组成的。大到一个星球、一个国家,小到一个人、一个分子,无论是有生命的,还是没有生命的,都可以看成是一个对象。通过分析这些对象,发现每个对象都由两部分组成:描述对象状态或属性的数据(变量)和描述对象行为或功能的方法(函数)。与面向过程将数据和对数据进行操作的函数相分开不同的是,面向对象将数据和操作数据的函数紧密结合,共同构成对象来更加准确地描述现实世界。这可以说是面向过程与面向对象两者最本质的区别。
跟现实世界相对应的,在面向对象中,我们用某个对象来代表现实世界中的某个实体,每个对象都有自己的属性和行为,而整个程序则由一系列相互作用的对象构成,对象之间通过互相操作来完成复杂的业务逻辑。
比如在一个班中,有一位陈老师和50名学生,那么我们就可以用一个老师对象和50个学生对象来抽象和描述这一个班级。对这51个对象而言,有些属性是它们所共有的,比如姓名、年龄等,每个对象都有;而有部分属性则是某类对象特有的,比如老师对象有职务这个属性,而学生对象则没有。另外,老师和学生这两种对象还有各自不同的行为;比如老师对象有备课、上课、批改作业的行为;而学生对象则有听课、完成作业等行为。老师对象和学生对象各自负责自己的行为和职责,同时又相互发生联系,比如老师上课的动作需要以学生作为动作对象。通过对象之间的相互作用,整个班级就可以正常运作。整个面向对象分析设计的结果,跟我们的现实世界非常接近,自然也就更容易理解和实现了。

面向对象的重要性:
这一点,也许可以从面向对象的诞生说起。
在面向对象出生之前,有一个叫做面向过程的人,它将整个待解决的问题,抽象为描述事物的数据以及描述对数据进行处理的函数,或者说数据处理过程。当问题规模比较小,需求变化不大的时候,面向过程工作得很好。
可是(任何事物都怕“可是”二字),当问题的规模越来越大越来越复杂,需求变化越来越快的时候,面向过程就显得力不从心了。想象一下,当我们根据需求变化修改了某个结构体,就不得不修改与之相关的所有过程函数,而一个过程函数的修改,往往又会涉及到其他数据结构,在系统规模较小的时候,这还比较容易解决,可是当系统规模越来越大,特别是涉及到多人协作开发的时候,这简直就是一场噩梦。这就是那场著名的软件危机。
为了解决这场软件危机,面向对象应运而生了(有问题的出现,必然就有解决问题的方法的出现,英雄人物大都是这样诞生的)。
我们知道,面向对象的三板斧分别是封装、继承和多态:它用封装将问题中的数据和对数据进行处理的函数结合在了一起,形成了一个整体的类的概念,这样更加符合人的思维习惯,更利于理解,自然在理解和抽象一些复杂系统的时候也更加容易;它用继承来应对系统的扩展,在原有系统的基础上,只要简单继承,就可以完成系统的扩展,而无需重起炉灶;它用多态来应对需求的变化,统一的借口,却可以有不同的实现。
可以说,面向对象思想用它的三板斧,在一定程度上解决了软件危机,这就是它重要性的根本体现
面向对象的三座基石:封装、继承与多态
封装、继承与多态是面向对象思想的三座基石,正是它们的共同作用,才使得“软件危机”得到了一定程度的解决。

1.封装
程序是用来抽象和描述现实世界的。那么先来看看在现实世界中我们又是如何描述周围的事物的。我们总是从数据和操作两个方面来描述某个事物:这个事物是什么和这个事物能做什么。比如我们要描述一位老师,我们会说:他身高178厘米,体重72公斤,年龄32岁,同时他能给学生上课,能批改作业。这样,一个活生生的老师形象就会在我们头脑中建立起来。
在传统的面向过程思想中,程序中的数据和操作是相互分离的。也就是说,在描述一个事物的时候,事物是什么(数据)和事物能做什么(操作)是相互分离的。但在面向对象思想中,我们通过封装机制将数据和相应的操作捆绑到了一起,以形成一个完整的、具有属性(数据)和行为(操作)的数据类型。在C++中,我们把这种数据类型称为类(class),而用这种数据类型所定义的变量,就被称为对象(object)。这样就使得程序中的数据和对这些数据的操作结合在了一起,更加符合人们描述某个事物的思维习惯,因此也更加容易理解和实现。简单来说,对象就是封装了数据和操作这些数据的动作的逻辑实体,也是现实世界中事物在程序中的反映,如图6-4所示。

封装机制还带来了另外一个好处,那就是对数据的保护。在面向过程思想中,因为数据和操作是相互分离的,某些操作有可能错误地修改了不属于它的数据,从而造成程序错误。而在面向对象思想中,数据和操作被捆绑在一起成了对象,而数据可以是某个对象所私有的,只能由与它捆绑在一起的操作访问,这样就避免了数据被其他操作意外地访问。这就如同钱包里的钱是我们的私有财产,只有我们自己可以访问,别人是不可以访问的。
2.继承
在创造某个新事物的时候,我们总是希望可以在某个旧事物的基础之上开始,毫无疑问这样会提高效率。可是对于面向过程的C语言而言,这一点却很难做到。在C语言中,如果已经写好了一个“上课”的函数,而要想再写一个“上数学课”的函数,很多时候我们都不得不另起炉灶全部重新开始。如果我们每次都另起炉灶,那样开发效率就太低了。显然,这无法满足大型的复杂系统的开发需要。
正是为了解决这个问题,面向对象思想提出了继承的机制。继承是可以让某个类型获得另一个类型的属性(成员变量)和行为(成员函数)的简单方法。继承就如同现实世界中的进化一样,继承得到的子类型,既可以拥有父类型的属性和行为,又可以新增加子类型所特有的属性和行为。比如我们已经用封装机制将姓名属性和说话行为封装成了“人”这个类,再此基础之上,我们可以很容易地通过继承“人”这个类,同时添加职务属性和上课行为而得到一个新的“老师”类。而这个新的“老师”类,不仅拥有它的父类“人”的姓名属性和说话行为,同时还拥有它自己的职务属性和上课行为。如果需要,我们还可以在“老师”类的基础之上继承得到“数学老师”、“语文老师”类等等。在这个过程中,我们直接复用了父类已有的属性和行为,这就避免了面向过程的另起炉灶重新开始,很大程度地提高了开发效率。

3. 多态
“见领导阿谀奉承,见下属飞扬跋扈”,是说一个人两面三刀,不是什么好人。可在C++世界中,这种在不同情况下做不同事情的现象,却被冠以一个冠冕堂皇的名字——多态,成为面向对象思想的一个重要特性。
多态是继承的直接结果。由于继承,在同一个继承体系中的多个类型的对象往往拥有相同的行为能干同样的事情,但是因为类型的不同,这些行为往往又需要有不同的实现方式。比如,“大学老师”和“小学老师”都是从“老师”这个父类继承而来的,它们两者都同样从“老师”父类中继承得到了“上课”这个行为,然而两者“上课”的具体方式又是不同的:“小学老师”是拿着课本上课,而“大学老师”是拿着鼠标上课。多态就是让一个对象在做某件事(调用某个接口函数)时,该对象能够搞清楚到底怎么完成(采用何种实现)这件事。还是上面的例子,有了多态机制,同样是对“上课”函数的调用,如果这个对象是“小学老师”类型的,就使用“小学老师”类的实现,而如果这个对象是“大学老师”类型的,就使用“大学老师”类的实现。这就是C++世界中的“见领导阿谀奉承,见下属飞扬跋扈”。

总结
面向对象关注的是当前问题下涉及到了哪些”东西“,并且研究这些:东西”之间的关系是怎样的。
面向过程关注的是解决当前问题的时间顺序。

浙公网安备 33010602011771号