1.3 程序设计方法
面向过程的程序设计和面向对象的程序设计是在软件开发过程中两种不同的程序设计方法,面向过程的程序设计是按照事物正常的发展顺序进行开发的,如:先输入一个数据,然后对数据进行处理,最后获得结果,程序运行时是一步步进行的。面向对象的程序设计方法是人类20世纪80年代提出的一种概念,主张把系统分为几个相互独立而又联系的对象集合,它可以直接描述对象之间的相互关系。下面将详细介绍这两种不同的程序设计方法。
1.3.1 面向过程的程序设计
程序是由计算机语言组成的一组操作序列,在针对同一个问题或功能设计程序时,如果设计的程序有不同的操作序列,那么这就体现了设计程序方法的不同。
运用面向过程的程序设计方法解决问题时主要是按照事情的发展步骤进行的,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用,就像一连串的事件按照一定顺序发生,前面的事件是后面事件的前提,后面发生的事件是前面发生的事件的基础。例如下面以一个人早上起来需要做的事情为例:
(1)起床
(2)穿衣
(3)洗脸刷牙
(4)吃早餐
(5)去学校
这5个步骤就是按照事情的发展顺序一步步完成的,在编写程序的时候只要把它们对应的功能编写成各自的函数,然后执行程序的时候按照顺序进行调用就可以了。
面向过程其实是最为实际的一种思考方式,就算是面向对象的方法也是含有面向过程的思想。可以说面向过程是一种基础的方法,它考虑的是实际的实现。一般的面向过程是从上往下步步求精,所以面向过程的方法是基于结构化的,当一个程序的规模不是很大时,面向过程的程序设计方法会很好地体现出它的优势,下面来看一个具体的例子。
【实例1-2】面向过程思想。
有一个存放日期型数据的文件data.txt,文件中保存的日期型文件的值凑起来如果是闰年就保存起来,并按照从大到小进行排序。
总体来说解决这个问题可以分为三个部分:
(1)将程序从文件中读取出的数据存放到该类型数据的数组中;
(2)判断这些数据哪些是闰年,并对数据进行处理;
(3)将处理完成后的数据按照题目要求进行输出。
在实际进行编写程序时通常将数据处理的部分分成两个阶段:第一个阶段是判断从输入数组中读取到的数据是否是闰年然后保存到一个数组中;第二个阶段是对闰年的年月日进行排序,使保存的数据按照从大到小的顺序进行排列。
针对这个问题编写成的算法如下所示:
(1)输入(从文本文件中读取数据放入数组一中);
(2)处理数据(将数组一中的数据进行处理然后放到数组二中);
(3)输出数据(将数组二中的数据输出到显示器或文件上)。其中,处理数据的部分又可以分为两个阶段:
❑ 过滤数据,判断日期文件中的数据是否是闰年。
❑ 对过滤的数据进行排序,按照题目要求从大到小进行排列。
可以将上面的算法画成流程图,如图1.1所示。
图1.1 程序结构逻辑图
在实际编写算法的过程中,算法描述一般是从抽象到具体的,这样会使算法的描述更加清晰、更加详细。
将一些复杂的过程按照功能进行划分,变成几个简单的功能从而达到解决问题的目的,这种思想就是面向过程型的思想,过程化的程序设计是以一系列过程的划分和组织来观察、思考、分析和解决问题的。面向过程的方法进行设计程序时应注意设计出的函数要保证每个模块都具有良好的独立性,即要设计出内聚性强、外联性少的程序。
❑ 内聚性:即要使每个模块的功能设计单一,这也符合模块化程序设计的思想,模块化功能越单一,代码就越容易维护。
❑ 外联性:外联性是指程序块之间的联系复杂度,联系的越少越好,这样每个程序块的功能受到的影响越小,模块的独立性就越强。而且修改模块时,对其他模块的影响也就越小,有利于代码的维护和修改。
1.3.2 面向对象的程序设计
面向对象的程序设计思想是当前软件开发的主流程序设计思想,从它兴起一直到今天占据着越来越重要的位置。面向对象的概念和应用已超越了程序设计和软件开发,扩展到了其他的领域,如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。
所谓面向对象的程序设计,就是把面向对象的思想应用到软件工程中,并指导开发维护软件。
面向对象思想设计程序从本质上来说也是基于面向过程的思想的,只是把程序中的某些数据关系给提取了出来,然后组织成为一个类,在以后的使用中便可以进行重复使用了。C++语言中的类机制可以使程序开发人员更好地工作。
从计算机编程的模型上来说对程序访问的权限进行了严格的限制。这种模型是围绕着程序中的数据和程序中定义的与对象有关的接口来进行组织的。相对于面向过程的程序设计思想来说,面向对象的程序设计有其自己的特点。
1.抽象
面向对象最基本的思想就是抽象,通过对一类相同事物的抽象来表示事物的复杂特性。程序开发人员可以运用抽象的思想管理复杂的程序。
面向对象分析中的抽象主要分为两类:一类是数据抽象,将一类问题的实体对象抽象成由数据项和函数构成的类,数据项标识对象的属性,函数用于定义对象的行为,这个整体将作为问题空间真实对象的抽象模型;另一类是过程抽象,将复杂对象所提供的某项功能抽象为各组成对象之间的相互作用,以消息传递及对象的消息处理方式加以描述。具体化是与抽象化相对的概念,通过抽象化,抓住问题的主要方面加以描述,在大框架已经明了的前提下逐步对描述加以精化,添加一系列细节使模型逐步丰富,最终达到精确描述问题空间对象属性和行为的目的。
2.封装
封装是运用面向对象思想分析问题空间对象和软件系统模块的重要手段,通过封装方法将对象的属性和方法紧密地结合在一起。封装可以被理解成一种用于保护作用的保护袋,用来防止代码和数据被保护袋外部所定义的其他代码随意访问,并对保护袋内部代码和数据的访问通过一个定义的接口来控制。封装代码的好处是实现了代码的隐蔽性,任何人通过程序提供的接口都可以调用代码而且不需要考虑方法实现细节,同时不用担心处理该方法调用产生的异常。
在定义一个类时,需要定义构成该类的代码与数据。类所定义的对象叫类的实例。操作数据的代码叫做成员方法,在成员方法中使用类里面的成员变量。类的成员变量可以定义为私有类型、保护类型和公有类型的。每种类型定义的变量在调用时访问的权限是有差别的,这样很好地保护了类里面的成员变量,防止被外部方法随意调用、更改。
3.继承
继承是指一个对象从另一个对象中获得属性的过程。它支持按层次分类的概念。例如,东北虎是老虎的一种,老虎又是哺乳动物的一种,哺乳动物又是动物的一种。如果不使用继承,就需要对每个对象明确地定义各自的全部特征。通过运用继承的概念,只需要为该对象定义一个属于其自身的特性,然后从父类中继承它的通用属性即可。因此,可以把一个对象理解成一类拥有相同特征的事物的一个实例。一个子类将继承它在类层次中的每个祖先的所有属性。
继承与封装可以互相作用。如果一个给定的类封装了某些属性,它的所有的子类将会得到相同的父类的特征,新的子类继承其所有祖先的所有属性,子类和系统中的其他代码不会产生无法预料的交互作用。
4.多态
多态是指一个方法只能有一个名称,但可以有许多形态,也就是程序中可以定义多个同名的方法,用“一个接口,多个方法”来描述,可以通过方法的参数和类型引用。多态性使得能够利用同一类(基类)的指针来引用不同类的对象,以及根据所引用对象的不同,以不同的方式执行相同的操作。
在利用面向对象的思想进行编程时,各个对象之间的关系是相互独立的,是一种和谐的共存关系,而不是你命令我、我强迫你的关系。程序中需要使用什么样的功能就调用什么样的接口。程序的运行是对象通过调用抽象数据类型来表达和实现的,抽象数据类型是通过对象来实现实例化的。
一些对象可能早就在系统中建立了,它们是独立运行的。程序运行时,解决问题的实体是对象,运行时是对象的世界,因此我们可以将程序理解为:
程序=对象+对象+…+对象
总之,现实世界是由许多对象组成的,我们要运用面向对象的方法和思维分析、设计、编程,这也是运用面向对象的方法进行编程的重点。