收藏 分销(赏)

面向对象程序设计.doc

上传人:天**** 文档编号:3901790 上传时间:2024-07-23 格式:DOC 页数:169 大小:235KB
下载 相关 举报
面向对象程序设计.doc_第1页
第1页 / 共169页
面向对象程序设计.doc_第2页
第2页 / 共169页
面向对象程序设计.doc_第3页
第3页 / 共169页
面向对象程序设计.doc_第4页
第4页 / 共169页
面向对象程序设计.doc_第5页
第5页 / 共169页
点击查看更多>>
资源描述

1、第3章 面向对象程序设计3.1 面向对象程序设计思想3.1.1 历史回顾1967年挪威计算中心的Kisten Nygaard和Ole Johan Dahl开发了Simula67语言, 它提供了比子程序更高一级的抽象和封装, 引入了数据抽象和类的概念, 它被认为是第一个面向对象语言。20世纪70年代初, Palo Alto研究中心的Alan Kay所在的研究小组开发出Smalltalk语言, 之后又开发出Smalltalk-80, Smalltalk-80被认为是最纯正的面向对象语言, 它对后来出现的面向对象语言, 如Object-C, C+, Self, Eiffl都产生了深远的影响。随着面向

2、对象语言的出现, 面向对象程序设计也就应运而生且得到迅速发展。之后, 面向对象不断向其它阶段渗透, 1980年Grady Booch提出了面向对象设计的概念, 之后面向对象分析开始。1985年, 第一个商用面向对象数据库问世。1990年以来, 面向对象分析、 测试、 度量和管理等研究都得到长足发展。实际上, ”对象”和”对象的属性”这样的概念能够追溯到20世纪50年代初, 它们首先出现于关于人工智能的早期著作中。可是出现了面向对象语言之后, 面向对象思想才得到了迅速的发展。过去的几十年中, 程序设计语言对抽象机制的支持程度不断提高: 从机器语言到汇编语言, 到高级语言, 直到面向对象语言。汇编

3、语言出现后, 程序员就避免了直接使用0-1, 而是利用符号来表示机器指令, 从而更方便地编写程序; 当程序规模继续增长的时候, 出现了Fortran、 C、 Pascal等高级语言, 这些高级语言使得编写复杂的程序变得容易, 程序员们能够更好地对付日益增加的复杂性。可是, 如果软件系统达到一定规模, 即使应用结构化程序设计方法, 局势仍将变得不可控制。作为一种降低复杂性的工具, 面向对象语言产生了, 面向对象程序设计也随之产生。3.1.2 什么是面向对象程序设计首先我们要了解的是, 什么是面向对象的程序设计方法OOP( Object Oriented Programming) , 它与传统的结

4、构化程序设计方法SP( Structure Programming) 的主要区别是什么。要弄清什么是OOP, 则应了解和回顾一下传统的结构化程序设计方法及其设计思想、 程序结构与特点, 以便比较对照二者之间的差异, 由此领会OOP对SP的继承、 丰富、 发展和突破。1结构化程序设计思想结构化程序设计SP是60年代诞生的, 以针对当时爆发的所谓”软件危机”的挑战, 而在70、 80年代遍及全球成为所有软件开发设计领域、 每个程序员都广为采用的传统的结构化程序设计方法与技术的简称。它的产生和发展形成了现代软件工程学的基础。SP的总的设计思路是两点: 一是自顶向下, 层次化; 二是逐步求精, 精细化

5、。其程序结构是按功能划分基本模块为树型结构, 使模块间的关系尽可能简单、 独立, 并从而单独验证模块的正确性。每一模块均由顺序、 选择和循环三种基本结构组合而成。综言之, 此即所谓”模块化”。因此, SP的程序的基本特点是: a按层次组织模块。( 即战略上划分战役) b每一模块只有一个入口, 一个出口。( 每一战役尽可能简单、 明确) c代码和数据分离实现。( 战术上程序=数据结构+算法) SP实现上述战略战术的具体方法和技术是: 使用局部变量和子程序。SP的优点能够概括为: a子程序对程序其它部分没有或尽可能少的连带作用, 从而为共享代码奠定基础。b由于SP方法的模块化分解与功能抽象, 自顶

6、向下, 分而治之的手段及技术, 从而能有效地将一个复杂的、 中大规模的程序系统的设计任务分成许多易于控制和处理、 可独立编程的子任务、 子程序模块。c对于上述子程序或模块中的每一个都有一个清晰的抽象界面, 它只说明: 对应用程序设计者来说只需了解它做什么( What to do) , 而不必说明: 它如何去做( How to do) 。但从本质上说, 由Pascal和C这样的程序设计推动的传统的SP仍是一种面向数据和过程的设计方法, 它把数据和过程分离为相互独立的实体, 用数据代表问题空间中的客体借以表示实际问题中的信息; 程序代码则体现用于处理加工这些数据的算法。于是, 程序员在编程时必须时

7、刻考虑要处理的数据结构和类型, 对不同的数据格式( 结构和类型) 即使要作同样的处理计算, 或者对于相同的数据格式要作不同的处理都要编写不同的程序, 可见, 使用传统SP方法设计出来的程序或系统, 其可重用的成分很少。另一方面, 当把数据和代码作为不同的分离体时, 总存在着用错误的数据调用正确的程序, 或用正确的数据调用错误的程序的危险。因而, 使数据与程序始终保持相容一致, 已成为程序员的一个沉重的负担。这就是为什么在开发一个大型软件的过程中, 如果用户在工程的中、 后期对数据格式或实现方案提出任何改变请求时, 变化摧毁了前面工作的一切, 前功尽弃。2面向对象程序设计思想为了克服和解决当今许

8、多大型软件项目和系统设计都接近或达到了SP方法所难以控制处理和适应其变化的上述种种矛盾及问题而产生了OOP方法与技术。OOP吸取了SP的一切优点和长处, 同时又正视和顺应现实世界由物质和意识两部分组成的这一普遍原理, 将其映射到对象的解空间就是: 具体事物对象, 抽象概念类; 而一个对象无非就是这样一个实体, 它具有一个名字标识, 并带有自身的状态( 属性) 和自身的功能( 行为或方法) 。世界上的所有事物( 对象) 就是如此奇妙地简单。这正是面向对象方法和技术所追求的目标: 将世界上的问题尽可能简单化。事实上, 用计算机求解的问题都是现实世界中的问题, 它们无非都是由一些相互联系的, 并处于

9、不断运动变化的事物( 即对象) 所组成。每个具体对象都可用两个特征来把握: 描述事物静态数据和可施于这些数据上的有限操作。也就是说, 应当把数据结构和对数据的操作放在地起, 作为一个相互依存不可分离的整体( 即对象类) 来处理( 封装、 信息隐蔽、 数据抽象等) 。而且要考虑不同事物即对象类之间的联系( 消息、 通讯、 协议等) 和事物即对象类的重用性和变化性( 继承、 多态等) , 这才更符合客观世界的原来面目。概言之, OOP与SP不同, 它除了包纳了SP的一切优特点与机制外, 同时又是一个引入若干强有力的、 更能反映事物本质的新概念、 新机制, 从而开创了一个程序新天地的强大新方法。OO

10、P的基本原理是: 用问题领域的模型来模拟现实世界, 从而设计出尽可能直接、 自然地表示问题求解方法的软件, 这样的软件系统由对象组成, 而对象则是完整反映客观世界事物具有不可分割的静态属性( 数据结构) 与动态行为( 方法) 的, 而且它们是既有联系又有变化发展的实体。OOP方法所涉及的新概念, 在理论上最具一般性的对应物及其描述如下等等: a对象对客观世界事物的表示或描述, 世界上任何具体事物均可称为对象。b类是一组对象的抽象定义( 抽象概念、 抽象数据类型) c方法对应于对象的功能。d消息对象之间通讯的途径。e继承对象间具有相同性和差异变化的关系。基于以上概念, 面向对象就成了一个作为现实

11、世界映射的封闭的缩微世界, 一个对象具有自身的属性( 私有数据成员) 和能够为自己或别人工作的功能( 方法、 操作或称成员函数) , 它能经过发送消息与其它对象进行通讯, 协同完成任务。OOP并不是用一两句话就能够精确定义描述清楚的一套方法与技术, 然而在这里, 我们还是非形式化地、 笼统地说明和描述一下OOP的概念: OOP是SP、 信息掩蔽、 知识表示、 并行处理领域等概念的继承和发展。OOP的特点是把系统设计成将所需要求解的问题分解成一些对象及对象间传递消息的符合客观世界规律的自然过程。OOP方法使程序员摆脱具体的数据格式和过程的束缚, 将精力集中到对要处理的对象的设计和研究上, 从而大

12、大减少了软件开发的复杂度。OOP包括了功能抽象的抽象数据、 信息隐蔽即封装等机理, 使对象的内部实现与外界隔离, 从而提供了更理想的模块化机制, 大大减少了程序间的相互干扰和副作用。OOP的抽象数据类型对象类及继承, 则为我们提供了理想的高可重用性的软件成份和机制。另外, 在人工智能领域中, 若用OOP方法表示知识, 则更接近于自然的客观世界的知识表示和认识论, 因而不但能表示描述非常复杂的客观事物和知识, 而且具有模块性强、 结构化程度高, 便于分层实现, 有利于实际开发和维护。因此OOP方法和技术的优特点将非常适合知识处理、 知识库、 专家系统等人工智能领域和数据库、 CAD、 图形处理(

13、 多媒体) 、 系统模拟与构造等大型复杂软件工程化开发。3.1.3 面向对象程序设计语言一个语言要称为面向对象语言必须支持几个主要面向对象的概念。根据支持程度的不同, 一般所说的面向对象语言能够分成两类: 基于对象的语言, 面向对象的语言。基于对象的语言仅支持类和对象, 而面向对象的语言支持的概念包括: 类与对象、 继承、 多态。举例来说, Ada就是一个典型的基于对象的语言, 因为它不支持继承、 多态, 另外其它基于对象的语言还有Alphard、 CLU、 Euclid、 Modula。面向对象的语言中一部分是新创造的语言, 如Smalltalk、 Java, 这些语言本身往往吸取了其它语言

14、的精华, 而又尽量剔除她们的不足, 因此面向对象的特征特别明显, 充满了蓬勃的生机; 另外一些则是对现有的语言进行改造, 增加面向对象的特征演化而来的。如由Pascal发展而来的Object Pascal, 由C发展而来的Objective-C, C+, 由Ada发展而来的Ada 95等, 这些语言保留着对原有语言的兼容, 并不是纯粹的面向对象语言, 但由于其前身往往是有一定影响的语言, 因此这些语言依然宝刀不老, 在程序设计语言中占有十分重要的地位。C+语言及环境中的OOP有五个最基本概念, 这五个基本概念术语是构成整个C+面向对象方法与技术的柱石。它们是: a对象( Object) b消息

15、( Message) c方法( Method) d类( Class) e继承( Inheritence) 下面我们将分别介绍它们的含义、 组成和性质。1对象什么是对象? 对象是私有数据及能够对这些数据施加的操作结合在一起所构成的独立实体。即一个对象基本上包括两个主要部分: 记载对象内部状态的数据和表现对象活动与功能的程序。从传统的SP观点来看, 数据和处理它们的代码是两个不同的独立实体, 它们之间的正确联系、 选择和匹配需要应用系统的设计者时刻考虑。而OOP中, 一个对象则是由私有数据和其上的一组操作代码组成的一个统一体。请看如下示意图: SP观点OOP观点数据代码数据代码对象对象的动作取决于

16、发送给该对象的消息表示式, 消息告诉对象要求完成的功能, 并激活该功能, 这意味着对象具有自动”知道”如何完成相应操作代码的”智能”选择机制, 正是这一机制把SP中应用系统程序员作出的选择操作数据与相应操作函数代码匹配的负担转移给了系统设计者。上述所谓的”智能化”的选择机制并不神秘, 只不过是在对象的操作( 过程或函数) 表中对消息操作名进行按名搜索而已, 对应C+来说, 执行一个消息表示式就是触发选择机制在相应对象的调度表( 内存控制块) 中进行搜索, 找到后便转向对应于该消息的成员函数代码中运行。事实上, 除了上述选择匹配机制是新东西外, 下面这些术语的含义和传统的SP相应名词及说明是相以

17、对应的: 对象内存中的数据块对象标识符指向上述数据的指针向对象发送消息使成员函数作用于数据在OOP中, 数据和代码是紧密结合在一起的计算机中的一内存分块。但局部于该对象中的数据只能够由对象中的代码块( 成员函数) 来访问, 即数据是对象私有的( 受保护的) , 不能被其它对象影响和修改。简单地说, 一个对象从不关心其它对象的内部细节, 而只关心它自己, 对象之间的通讯只是以”做什么”的消息发送为契机, 而且认为接受消息的对象是知道如何去做的。对象能够非常简单, 也能够十分复杂。一般复杂对象由简单的对象层层嵌套组合而成。今后我们将从C+程序实例中看到, 对象形式上只是系统程序员、 应用程序员或用

18、户定义的”类”这种数据结构类型的变量, 当我们定义一个对象, 就已创造出了一种新的抽象数据类型。对象能够说是构成和支撑整个OOP最重要的细胞与基石。除了上述基本组成、 关系和机理特性外, 对象还有以下性质和优点: a模块独立性。逻辑上看, 一个对象是独立存在的模块, 从外部看这模块, 只需了解它具有哪些功能, 至于它如何实现这些功能和使用哪些局部数据来完成它们的细节则”隐蔽”在模块内部。这意味着模块内部状态不受外界干扰改变, 也不会殃及到其它模块。即模块间依赖性极小或几乎没有; 各模块可独立为系统组合选用, 也可被程序员重用, 而不必担心波及或破坏别的模块。b动态连接性。客观世界中各式各样的对

19、象, 并不是孤立存在的, 正是它们之间的相互作用、 联系和连接, 才构成了世间各种不同的系统。同时, 在OOP中, 经过消息( 传送) 激活机制, 把对象之间动态联系连接起来, 便称为对象的动态连接性。c易维护性。由于对象的功能被”隐蔽”和好象被一层封装壳保护在对象内部, 故无论是修改, 还是功能完善以及实现的细节都被囿于该对象内部, 不会播及到外部去, 这增加了对象和整个系统的易维护性。2消息什么是消息? 消息是要求某个对象执行其中某个功能操作的规格说明。通俗地讲, OOP中的术语”消息”只不过是现实世界中的”请求”、 ”命令”等日常生活用语的同义词。一般, OOP的一条消息由选择器( ”消

20、息操作”或”消息名”) 及若干变元( 0个或多个实参) 和接受消息的对象三个部分组成。从程序设计语言的角度出发来说, 除前面曾经提到过的消息具备提供( 激活) 对象的动态选择机制外, 消息表示式从形式上看类似于普通的函数调用。如代码: switch(message) case WM_LBUTTONDOWN;/鼠标左按钮被按下 . break; case WM_LBUTTONUP;/ 鼠标左按钮被放开 . break;一般, 我们把发送消息的对象称为发送者, 接收消息的对象称为接收者。对象间的联系, 只能经过传送消息即执行消息表示式来进行。对象也只有在收到消息时, 才被激活, 补激活的对象的代码

21、将知道如何去进行操作它的私有数据, 以完成所发送的消息要求的功能。消息发送不考虑具体的接收者, 对象能够响应, 也能够不响应。3方法什么是方法? OOP中的术语”方法”对应于对象的能力, 即它是实现对象所具有的功能操作的代码段, 是响应消息的”方法”。C+中, 方法即是类中定义的成员函数, 它只不过是该类对象所能执行的操作的算法实现而已。方法与消息是对应的, 每当对象收到一个消息, 它除了能用”智能化”的选择机制知道和决定应该去做什么( What to do) 外, 还要知道和决定该怎样做( How to do) 。而方法正是与对象相连决定怎么做的的操作执行代码。4类什么是类? 类是对一组对象

22、的抽象归纳概括, 确切地说, 类是对一组具有相同数据成员和相同操作成员的对象的定义和说明。而每个对象都是某个类的一个具体实例。在OOP中, 每个对象由一个类来定义或说明, 类能够看作生产具有相同属性和行为方式对象的模板。类或分类就是所谓”物以类聚, 人以群分”的意思, ”类”就是具有相似性质的事物的同类特征的集中。简言之, 按照对象的相似性, 我们把对象分成一些类和子类, 故相似对象的集合即称为类。对C+程序员而言, 类实际上是一种对象类型。它描述属于该类型的具有相同结构和功能的对象的一般性质。而结构类型则是只有将相关信息( 仅只是不同类型的数据集) 集中在一起的一个C的变量集。从理论上讲,

23、类( class) 是一组同类对象的抽象, 它将该种对象的共同特征, 包括操作特征和存储特征都集中封装起来。由属于此类的对象共享。例如, 讨论食肉动物时, 我们并不只是特指老虎和狮子, 而只是抽象出它们的共同特征: 比如喜欢吃肉。更具体地, 又如: 若为屏幕上的点设计一个类如下: class point x,y; new(); delete(); move(); highlight();则能够说明point类的对象如: point a(100,50),b(30,60);piont中定义的数据是抽象数据类型, 而对象a, b中的数据则是对象对应着内存中的具体数据单元拷贝块, 以其初始化时的具体值

24、和存储于不同单元块而区分不同的对象。5继承什么是继承? 继承是对象类间的一种相关关系, 并具有以下关键内容: a类间的共享的特征( 包括共享程序代码和数据) 。b类间的细微区别或新增部分。c类间的层次结构。继承机制既是一个对象类就获得另一个对象类特征的过程, 也是一个以分层结构组织、 构造和重用类的工具。它是解决客观对象”相似又不同”的方法。具体地讲, 若类B继承了类A, 则属于类B中的对象便具有类A的一切性质和功能。我们称A为基类或父类, 而称B为A的派生类或子类。因此, 要描述或构造一个新类B, 只须去继承一个与之有共同特征的父类A, 然后描述与父类不同的少量特征( 即增加一些新的数据成员

25、或成员函数) 即可。继承机制有以下几个优特点: a能清晰体现相似类间的层次结构关系。b能减少代码和数据的重复冗余度, 增强程序的重用性。c能经过增强一致性来减少模块间的接口和界面, 增强程序的易维护性。d继承是能自动传播代码的有力工具。e继承还是在一些比较一般的类的基础上构造、 建立和扩充新类的最有效的手段。如果没有继承概念的支持, 则OOP中所有的类就象一盘各自为政、 彼此独立的散沙, 每次软件开发都要从”一无所有”开始。C+中, 除了一般OOP方法的树型层次结构的单一继承外, 还支持多重继承。对单一继承, 每个子类只能有一个父类, 而对多重继承, 每个子类则能够有多个父类。3.1.4 面向

26、对象程序设计的优点面向对象出现以前, 结构化程序设计是程序设计的主流, 结构化程序设计又称为面向过程的程序设计。在面向过程程序设计中, 问题被看作一系列需要完成的任务, 函数( 在此泛指例程、 函数、 过程) 用于完成这些任务, 解决问题的焦点集中于函数。其中函数是面向过程的, 即它关注如何根据规定的条件完成指定的任务。在多函数程序中, 许多重要的数据被放置在全局数据区, 这样它们能够被所有的函数访问。每个函数都能够具有它们自己的局部数据。下图显示了一个面向过程程序中函数和数据的关系。代码数据这种结构很容易造成全局数据在无意中被其它函数改动, 因而程序的正确性不易保证。面向对象程序设计的出发点

27、之一就是弥补面向过程程序设计中的一些缺点: 对象是程序的基本元素, 它将数据和操作紧密地连结在一起, 并保护数据不会被外界的函数意外地改变。下图显示了一个面向对象程序中对象与函数和数据的关系。代码数据代码比较面向对象程序设计和面向过程程序设计, 还能够得到面向对象程序设计的其它优点: 数据抽象的概念能够在保持外部接口不变的情况下改变内部实现, 从而减少甚至避免对外界的干扰; 经过继承大幅减少冗余的代码, 并能够方便地扩展现有代码, 提高编码效率, 也减低了出错概率, 降低软件维护的难度; 结合面向对象分析、 面向对象设计, 允许将问题域中的对象直接映射到程序中, 减少软件开发过程中中间环节的转

28、换过程; 经过对对象的辨别、 划分能够将软件系统分割为若干相对为独立的部分, 在一定程度上更便于控制软件复杂度; 以对象为中心的设计能够帮助开发人员从静态( 属性) 和动态( 方法) 两个方面把握问题, 从而更好地实现系统; 经过对象的聚合、 联合能够在保证封装与抽象的原则下实现对象在内在结构以及外在功能上的扩充, 从而实现对象由低到高的升级。 3.1.5 面向对象程序设计主要特征面向对象程序设计主要特征有三个: 继承性、 封装性和多态性。1继承性继承性在上面已作介绍, 不再重复。2封装性OOP中的封装性是一种信息掩蔽技术, 它使系统设计员能够清晰地标明她们所提供的服务界面, 用户和应用程序员

29、则只看得见对象提供的操作功能( 即封装面上的信息) , 看不到其中的数据或操作代码细节。从用户或应用程序员的角度讲, 对象提供了一组服务, 而服务的具体实现( 即对象的内部) 却对用户屏蔽。如下图所示: headinggo:storeon:用户/应用程序员对象标识符MyPencolorpositiondownupcolor=blackposition=10.20heading=180系统程序员move:从用户和系统设计者看封装, 用户只能看见对象提供的服务, 而看不到服务的具体实现, 只有系统设计者才能看见封闭在对象中数据及其过程。对象的这一封装机制的目的在于将对象的设计者和使用者分开, 使用

30、者不必知道对象行为实现的细节, 只须用设计者提供的消息命令对象去做就行了。总之, 我们能够这样来定义封装: a一个清楚的边界。对象的所有私有数据、 内部程序即方法( 成员函数) 细节被囿定在这个边界内。b一个接口。这个接口描述了对象之间的相互作用, 请求和响应, 它就是消息。c对象内部实现代码受到封装壳的保护, 其它对象不能直接修改本对象拥有的( 私有的) 数据和代码, 只有经过本对象类的内部代码( 成员函数) 来修改。这就是OOP中对象的封装性。3多态性OOP支持多态性, 它指的是相同的函数调用, 被不同的对象接收时, 可导致不同的行为。利用多态性, 我们能够把函数的不同的实现细节留给接受函

31、数调用的对象, 而程序中则用同一函数名进行一般形式的调用。例如, 消息函数调用Print( ) 被发送到一图形对象时和将其发送到一正文对象时的结果肯定不一样。例如, 有三个函数: abs() 返回整数绝对值labs() 返回long的绝对值fabs() 返回double的绝对值尽管这三个函数执行几乎相同的操作, 在SP中, 须用三个不同的函数说明及调来表示和使用它们, 即大同小异的函数也必须有不同的函数名。于是, 虽然仅只是一个求绝对值的运算行为, 程序员必须至少记住三件事( 三个函数) 。在C+中, 则改变了这一传统做法, 能够用一个名字来表示和访问这三个函数而不会出现混乱。即如下: #in

32、cludeint abs(int i) return i 0 ? -i: i;double abs(double d) return d 0 ? -d: d;long abs(long l) return l 0 ? -l: l;main() coutabs(-10)”n”; coutabs(-11.0)”n”; coutabs(-9L)”n”;它们是不同的函数, 却使用同一名字abs, 当程序中调用abs时, OOP编译器会根据自变量类型自动录找正确的那个函数进行运算, 这就将要记住的三件事减少为只须记住一件事了, 从应用的角度来看, 就好象一个函数支持三种不同的运算( 功能) 一样, 这就

33、是函数的多态性。除以上三大特性之外, 面向对象程序设计还具有动态连接、 消息驱动等特点。所谓连接, 是把例程地址送给例程调用者的过程。在运行前的编译时便以目标代码的形式与系统完成连接称为静态连接, 而在运行时进行上述连接的则称为动态连接。传统的C仅支持静态连接, 而面向对象的程序设计语言在其实现中使用了动态编译技术, 因而允许以目标代码的形式在运行过程中才与系统进行连接。这使得系统的灵活性和方便性大大增强。OOP中的消息驱动机制不同于SP中的子程序调用, 这是因为, 子程序调用者与被调用者有控制与被控制的关系, 且凡调用必须有返回。而消息驱动则是当一个对象想激活另一个对象的某个功能时, 它把请

34、求以消息的形式传送给接受者就算了事, 至于接受对象如何行动, 如何处理该消息, 完全是接受者自行决定的私事, 其行为既不受发送者的控制, 也不一定有求必应和必有返回。下图给出一个处理键盘输入的消息驱动过程: Windows应用程序Z系统队列用户按Z键ZWinMain函数消息循环应用程序队列ZZWindows从应用程序的消息循环中接收消息, 并处理应用程序窗口的消息窗口函数ZZ作为窗口函数TextOut要求的结果, Windows对应用程序窗口输出”Z”应用程序窗口ZZ注意, 上述过程中, 每个应用程序将有被创立的一个对应的应用程序队列。3.1.7 面向对象设计方法的特点和面临的问题面向对象设计

35、方法以对象为基础, 利用特定的软件工具直接完成从对象客体的描述到软件结构之间的转换。这是面向对象设计方法最主要的特点和成就。面向对象设计方法的应用解决了传统结构化开发方法中客观世界描述工具与软件结构的不一致性问题, 缩短了开发周期, 解决了从分析和设计到软件模块结构之间多次转换映射的繁杂过程, 是一种很有发展前途的系统开发方法。可是同原型方法一样, 面向对象设计方法需要一定的软件基础支持才能够应用, 另外在大型的MIS开发中如果不经自顶向下的整体划分, 而是一开始就自底向上的采用面向对象设计方法开发系统, 同样也会造成系统结构不合理、 各部分关系失调等问题。因此面向对象设计方法和结构化方法当前

36、仍是两种在系统开发领域相互依存的、 不可替代的方法。3.2 类和对象3.2.1 类和对象概述1类和对象的声明在C程序设计中我们学习过结构体, 它的掌握非常重要, 重要在哪里呢? 重要在结构体和类有相同的特性, 但又有很大的区别, 类是构成面向对象编程的基础, 但它是和结构体有着极其密切的关系。我们在C语言中创立一个结构体我们使用如下方法: struct test private: int number; public: float socre;类的创立方式和结构体几乎一样, 看如下的代码: class test private: int number; public: float socre;

37、 public: int rp() return number; void setnum(int a) number=a; ;可是大家注意到没有, 标准C中是不允许在结构体中声明函数的, 但C+中的类能够, 这一点就和C有了本质的区别, 很好的体现了C+面向对象的特点! 过去的C语言是一种非面向对象的语言, 它的特性是: 程序=算法+数据结构。但C+的特性是: 对象=算法+数据结构; 程序=对象+对象+对象+对象+.。因此根据这一特性, 我们在定义一个自己定义的结构体变量的时候。这个变量就应该是叫做对象或者叫实例。例如: test a;那么a就是test结构的一个对象(实例), test结构体

38、内的成员能够叫做是分量, 例如:a.socre=10.1f;那么number就是test结构的对象a的分量(或者叫数据成员,或者叫属性)score;在C语言中结构体中的各成员她们的默认存储控制是public 而 c+中类的默认存储控制是private, 因此在类中的成员如果需要外部掉用一定要加上关键字public声明成公有类型, 这一特性同样使用于类中的成员函数, 函数的操作方式和普通函数差别并不大。例如上面的例子中的rp()成员函数, 我们如果有如下定义: test a;调用rp()就应该写成: a.rp();成员函数的调用和普通成员变量的调用方式一致都采用.的操作符。下面给出一个完整的例子

39、: #includeclass testprivate:/私有成员类外不能够直接访问 int number; public:/共有成员类外能够直接访问 float socre; public: int rp() return number; void setnum(int a) number=a; ;void main() test a; /a.number=10;/错误的,私有成员不能外部访问 a.socre=99.9f; couta.socreendl;/公有成员能够外部访问 a.setnum(100);/经过公有成员函数setnum()对私有成员number进行赋值操作 couta.rp

40、();/间接返回私有成员number的值 cin.get();运行结果: 99.91002在类体外定义成员函数 内联函数和外联函数。类的成员函数能够分为内联函数和外联函数。内联函数是指那些定义在类体内的成员函数, 即该函数的函数体放在类体内。而说明在类体内, 定义在类体外的成员函数叫外联函数。外联函数的函数体定义在类的实现部分。内联函数在调用时不是象一般函数那样要转去执行被调用函数的函数体, 执行完成后再转回调用函数中。而是在调用函数处用内联函数体的代码来替换, 这样将会节省调用开销, 提高运行速度。内联函数与前面讲过的带参数的宏定义比较, 它们的代码效率是一样的, 可是内联函数要优于宏定义,

41、 因为内联函数遵循函数的类型和作用域规则, 它与一般函数更相近, 在一些编译器中, 一旦关上内联扩展, 将与一般函数一样进行调用, 调试比较方便。在类体外定义的外联函数能够用一种形式转变成内联函数, 即在函数头加上关键字inline就能够了。 重载性。两个以上的函数, 取同一个名字, 只要使用不同类型的参数或参数个数不同, 编译器便知道在什么情况下, 调用哪个函数。这就叫做函数重载。成员函数能够进行重载。构造函数能够重载, 而析构函数不能重载。一般的成员函数都能够重载。上面介绍了在类内部定义成员函数(方法)的方法, 下面我们要介绍一下域区分符(:)的作用。即在类外部定义成员函数。下面我们来看一

42、个例子, 利用这个例子中我们要说明几个重要问题: #includeint pp=0;class testprivate:int number;public:float socre;int pp;public:void rp();void test:rp()/在外部利用域区分符定义test类的成员函数:pp=11;/变量名前加域区分符给全局变量pp赋值pp=100;/设置结构体变量void main()test a;test b;a.rp();coutppendl;couta.pppp=100;因此你把上面的成员函数写成如下形势也是正确的: void test:rp():pp=11;this-pp=100;/this指针就是指向a对象的指针类的成员函数和普通函数一样是能够进行重载操作的, 关于重载函数, 我们将在后面讨论, 这里只给出一个例子看看: #includeclass testprivate:int number;public:float socre;int pp;public:void rp(int);void rp(float);void test:rp(int a)/在外部利用域区分符定义test类的成员函数cout调用成员函数!

展开阅读全文
部分上传会员的收益排行 01、路***(¥15400+),02、曲****(¥15300+),
03、wei****016(¥13200+),04、大***流(¥12600+),
05、Fis****915(¥4200+),06、h****i(¥4100+),
07、Q**(¥3400+),08、自******点(¥2400+),
09、h*****x(¥1400+),10、c****e(¥1100+),
11、be*****ha(¥800+),12、13********8(¥800+)。
相似文档                                   自信AI助手自信AI助手
百度文库年卡

猜你喜欢                                   自信AI导航自信AI导航
搜索标签

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2024 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服