1.3 程序设计方法
C++语言的两个组成部分是过程性语言部分和“类”部分。过程性语言部分和C语言没有本质差别。“类”部分是C语言中没有的,它是面向对象程序设计的主体。要学好面向对象程序设计,首先必须具有过程性语言的基础。所以学习C++,首先必须学习其过程性语言部分,然后再学习“类”部分。
过程性语言部分采用的是结构化程序设计方法,“类”部分采用的是面向对象程序设计方法,程序设计方法正在从结构化方法向面向对象方法演变。C语言仅支持结构化程序设计,而C++语言既支持结构化程序设计也支持面向对象程序设计。
1.3.1 结构化程序设计方法
结构化程序设计的主要思想是:将任务按功能分解并逐步求精。将复杂的大型任务分解成若干模块,每个模块进一步划分成更小的、功能完整的子模块,继续划分直到得到原子模块,每个原子模块用一个过程或函数完成。一个过程或函数由多条可顺序执行的语句构成。编程者把数据与过程或函数分开存储。编写程序的主要技巧在于追踪函数的调用及返回过程,追踪在这个过程中数据发生了怎样的变化。结构化程序设计方法能够较好地分解并解决一些复杂任务。其主要缺点是,程序依赖于数据结构,当数据结构发生变化时,必须对过程或函数进行修改。另外,当开发一个新任务时,适用于旧任务的程序一般不能重复利用。从编程的角度来说需要重复投入,即重新开发程序。而基于可重用指导思想的面向对象程序设计方法能够较好地解决这一问题。
1.3.2 面向对象程序设计方法
面向对象程序设计(Object Oriented Programming,OOP)方法是近年来十分流行的一种程序设计方法,它试图用客观世界中描述事物的方法来描述一个程序要解决的问题。对象是客观世界中一个实际存在的事物,如一个具体的“人”就是一个对象。将“人”的共同属性抽象出来就可以构成“类”,如“人”类,它具备的静态属性有姓名、年龄、性别、身高和体重等,它同时具备的动态属性有学习、思考、走路、说话和吃饭等,一般将静态属性作为类的数据成员,而将动态属性作为类的执行代码。类是一个抽象的概念,而对象是类的具体实例,如“人”类的一个对象就是指一个具体的人。
面向对象程序设计的3个主要特性如下所示。
1)封装性 封装是实现信息隐蔽的基础。将描述对象的数据(静态属性)及对这些数据进行处理的程序代码(动态属性)有机地组成一个整体,同时对数据及代码的访问权限加以限制,这种特性称为封装。封装可以使对象内部的数据隐藏起来,在类外不能直接访问它们,而只能通过对象的公有执行代码接口来间接访问对象内部的数据。这样既可保护类中的数据成员,也可使编程者只关心该对象可完成的动作,而不必去关心其内部的数据及代码实现细节。
2)继承性 继承是软件重用的基础,它可以提高软件开发效率。通过继承可以在已有类的基础之上扩充并产生一个新类。已有类称为基类或父类,新类称为派生类或子类。派生类除了继承基类的数据及代码之外,可以按需要增加数据和代码。基类的数据和代码在派生类中是可以直接使用的,即基类的代码可以在派生类中重复利用,这就是软件重用,它可以提高代码编写效率。
3)多态性 多态性是提高编程效率及提高编程灵活性的机制。多态分为静态多态和动态多态。
静态多态 静态多态分为函数重载、运算符重载、函数模板和类模板。
函数重载是指同名函数完成不同功能,一般用于完成类似功能,如两个同名函数abs(),分别可以用来求整型量和实型量的绝对值。如果没有函数重载机制,求整型量和实型量的绝对值就必须用两个不同的函数名来实现。函数重载减轻了编程时记忆多个完成类似功能的函数名的负担。
运算符重载是将C++提供的基本运算符应用到新类的机制。例如,加号(+)运算符可以实现C++基本数据类型的整型量、实型量的相加等。对于用户新定义的类如“复数”类,通过运算符重载机制,可以使用加号实现两个复数对象的直接相加。
函数模板是将结构相同而仅仅数据类型不同的多个函数进行数据类型虚拟化得到的函数的抽象描述。类模板是将结构相同而仅仅数据类型不同的多个类进行数据类型虚拟化得到的类的抽象描述。在调用函数模板和使用类模板定义对象时,编译器能够根据实际的数据类型以函数模板和类模板为基础自动生成含有具体类型的函数和类,以提高编程的自动化水平,即提高编程效率。
动态多态 动态多态是指不同的对象在接收到相同的消息后,以不同的行为去应对。所谓消息是指对象接收到的需要执行某个“操作”的命令,操作是函数完成的。动态多态的实现机制是,在基类中定义完成某个操作的虚函数,在不同的派生类中重新定义完成这个“操作”的同名函数,不同派生类中的这些函数完成不同的工作,那么不同派生类对象接收到同样的“消息”时,就可以表现出不同的行为。
例如,基类是一个抽象的“几何图形”,它具有“绘图”行为,但这个行为没有具体含义,因为并不知道具体绘制什么图形。从“几何图形”类派生出“三角形”类、“圆”类或“矩形”类,在派生类中“绘图”功能有具体含义,可重新定义“绘图”功能,实现具体图形的绘制。在基类中的虚拟共同行为“绘图”,在派生类中具有不同的实现行为。不同的派生类对象接收到“绘图”消息时,即产生了不同的行为。
动态多态既提供了“消息”的统一入口,又实现了不同对象对同一消息的不同响应,提高了编程的灵活性。