1 / 7
文档名称:

面向对象技术论文.pdf

格式:pdf   大小:859KB   页数:7页
下载后只包含 1 个 PDF 格式的文档,没有任何的图纸或源代码,查看文件列表

如果您已付费下载过本站文档,您可以点这里二次下载

分享

预览

面向对象技术论文.pdf

上传人:青山代下 2024/5/21 文件大小:859 KB

下载得到文件列表

面向对象技术论文.pdf

相关文档

文档介绍

文档介绍:该【面向对象技术论文 】是由【青山代下】上传分享,文档一共【7】页,该文档可以免费在线阅读,需要了解更多关于【面向对象技术论文 】的内容,可以使用淘豆网的站内搜索功能,选择自己适合的文档,以下文字是截取该文章内的部分文字,如需要获得完整电子版,请下载此文档到您的设备,方便您编辑和打印。:..面向对象技术论文摘要:面向对象程序设计以及数据抽象在现代程序设计思想中占有很重要的地位,在这篇论文中,我将从程序设计语言的发展和程序设计思想的演化之间的关系,来理解和思考面向对象程序设计技术,并逐步讨论如下。关键字:关键字:面向对象过程化程序设计程序设计技术计算机程序设计的本质就是把现实生活中我们遇到的问题,通过抽象然后利用计算机语言转化到机器能够理解的层次,并最终利用机器来寻求问题的解。在此过程中,涉及到两方面问题:一,如何把我们所面对的问题抽象化?使问题能够很好的被抽象语言描叙。二,如何把已经抽象解决了的问题映射到机器能够理解的语言里面去。从第一方面体现了程序设计思想而第二方面则体现了程序设计语言,有此可见,两者是有密切关系的,其中的连接点就是抽象机制。1,程序设计语言的概论程序设计语言的发展是一个不断演化的过程,其根本的推动力就是抽象机制更高的要求,以及对程序设计思想的更好的支持。具体的说,就是把机器能够理解的语言提升到也能够很好的模仿人类思考问题的形式。程序设计语言的演化从最开始的机器语言到汇编语言到各种结构化高级语言,最后到支持面向对象技术的面向对象语言,反映的就是一条抽象机制不断提高的演化道路,机器语言和汇编语言几乎没有抽象,对于机器而言是最合适的描叙,它可以操作到机器里面的位单位,并且任何操作都是针对机器的,这就要求人们在使用机器或者汇编语言编写程序时,必须按照机器的方式去思考问题,因为没有抽象机制,所以程序员很容易陷入复杂的事务之中。C,PASCAL,FORTRAN,随等结构化高级语言的诞生,使程序员可以离开机器层次,在更抽象的层次上表达意图。由此诞生的三种重要控制结构,以及一些基本数据类型都能够很好的开始让程序员以接近问题本质的方式去思考和描叙问题。随着程序规模的不段断扩大,在60年代末期出现了软件危机,在当时的程序设计范型中都无法克服错误随着代码的扩大而级数般的扩大,以至到了无法控制的地步,这个时候就出现了一种新的思考程序设计方式和程序设计范型-----面向对象程序设计,由此也诞生了一批支持此技术的程序设计语言,比如C++,Java,这些语言都以新的观点去看待问题,即问题就是由各种不同属性的对象以及对象之间的消息传递构成。面向对象语言由此必须支持新的程序设计技术,例如:数据隐藏,数据抽象,用户定义类型,继承,多态等等。,过程式的程序设计是一种自上而下的设计方法,设计者用一个main函数概括出整个应用程序需要做的事,而main函数由对一系列子函数的调用组成。对于main中的每一个子函数,都又可以再被精炼成更小的函数。重复这个过程,就可以完成一个过程式的设计。其特征是以函数为中心,用函数来作为划分程序的基本单位,数据在过程式设计中往往处于从属的位置。过程式设计的优点是易于理解和把握,这种逐步细化问题的设计方法和大多数人的思维方式比较接近。然而,过程式设计对于比较复杂的问题,或是在开发中需求变化比较多的时候,往往显得力不从心。这是因为过程式的设计是自上而下的,这要求设计者在一开始就要对需要解决的问题有一定的了解。在问题比较复杂的时候,要:..做到这一点会比较困难,而当开发中需求变化的时候,以前对问题的理解也许会变得不再适用。事实上,开发一个系统的过程往往也是一个对系统不断了解和学****的过程,而过程式的设计方法忽略了这一点。在过程式设计的语言中,一般都既有定义数据的元素,如C语言中的结构,也有定义操作的元素,C语言中的函数。如这样做的结果是数据和操作被分离开,轻易导致对一种数据的操作分布在整个程序的各个角落,而一个操作也可能会用到很多种数据,在这种情况下,对数据和操作的任何一部分进行修改都会变得很困难。在过程式设计中,main()函数处于一个非常重要的地位。设计者正是在main()函数中,对整个系统进行一个概括的描述,再以此为起点,逐步细化出整个应用程序。然而,这样做的一个后果,是轻易将一些较外延和易变化的逻辑(比如用户交互)同程序的核心逻辑混淆在一起。假设我们编写一个图形界面的计算器程序和一个命令行界面的计算器程序,可以想象这两个版本的main()函数会有很大的差异,由此衍生出来的程序很有可能也会迥然不同,而这两个版本的程序本应该有很大部分可以共用才对。,就已经在宏观上明确了各个模块应具有什么功能,应放在体系结构的哪个位置。我们****惯地从功能上划分模块,保持“功能独立”是模块化设计的基本原则。因为,“功能独立”的模块可以降低开发、测试、维护等阶段的代价。但是“功能独立”并不意味着模块之间保持绝对的孤立。一个系统要完成某项任务,需要各个模块相互配合才能实现,此时模块之间就要进行信息交流。比如手和脚是两个“功能独立”的模块。没有脚时,手照样能干活。没有手时,脚仍可以走路。但如果希望跑得快,那么迈左脚时一定要伸右臂甩左臂,迈右脚时则要伸左臂甩右臂。在设计一个模块时不仅要考虑“这个模块就该提供什么样的功能”,还要考虑“这个模块应该怎样与其它模块交流信息”。模块设计优劣的三个特征因素:“信息隐藏”、“内聚与耦合”和“封闭——开放性”。,老师叹气道:“要是坐在后排聊天的同学能象中间打牌的同学那么安静,就不会影响到前排睡觉的同学。”这个故事告诉我们,如果不想让坏事传播开来,就应该把坏事隐藏起来,“家丑不可外扬”就是这个道理。为了尽量避免某个模块的行为去干扰同一系统中的其它模块,在设计模块时就要注意信息隐藏。应该让模块仅仅公开必须要让外界知道的内容,而隐藏其它一切内容。模块的信息隐藏可以通过接口设计来实现。一个模块仅提供有限个接口(Interface),执行模块的功能或与模块交流信息必须且只须通过调用公有接口来实现。如果模块是一个C++对象,那么该模块的公有接口就对应于对象的公有函数。对象,对象的接口。对象可以有多个接口,而每个接口实质上是一些函数的集合。(Cohesion)是一个模块内部各成分之间相关联程度的度量。耦合(Coupling)是模块之间依赖程度的度量。内聚和耦合是密切相关的,与其它模块存在强耦合的模块通常意味着弱内聚,而强内聚的模块通常意味着与其它模:..块之间存在弱耦合。模块设计追求强内聚,弱耦合。一、内聚强度内聚按强度从低到高有以下几种类型:(1)偶然内聚。如果一个模块的各成分之间毫无关系,则称为偶然内聚。(2)逻辑内聚。几个逻辑上相关的功能被放在同一模块中,则称为逻辑内聚。如一个模块读取各种不同类型外设的输入。尽管逻辑内聚比偶然内聚合理一些,但逻辑内聚的模块各成分在功能上并无关系,即使局部功能的修改有时也会影响全局,因此这类模块的修改也比较困难。(3)时间内聚。如果一个模块完成的功能必须在同一时间内执行(如系统初始化),但这些功能只是因为时间因素关联在一起,则称为时间内聚。(4)过程内聚。如果一个模块内部的处理成分是相关的,而且这些处理必须以特定的次序执行,则称为过程内聚。(5)通信内聚。如果一个模块的所有成分都操作同一数据集或生成同一数据集,则称为通信内聚。(6)顺序内聚。如果一个模块的各个成分和同一个功能密切相关,而且一个成分的输出作为另一个成分的输入,则称为顺序内聚。(7)功能内聚。模块的所有成分对于完成单一的功能都是必须的,则称为功能内聚。二、耦合强度耦合的强度依赖于以下几个因素:(1)一个模块对另一个模块的调用;(2)一个模块向另一个模块传递的数据量;(3)一个模块施加到另一个模块的控制的多少;(4)模块之间接口的复杂程度。耦合按从强到弱的顺序可分为以下几种类型:(1)内容耦合。当一个模块直接修改或操作另一个模块的数据,或者直接转入另一个模块时,就发生了内容耦合。此时,被修改的模块完全依赖于修改它的模块。(2)公共耦合。两个以上的模块共同引用一个全局数据项就称为公共耦合。(3)控制耦合。一个模块在界面上传递一个信号(如开关值、标志量等)控制另一个模块,接收信号的模块的动作根据信号值进行调整,称为控制耦合。(4)标记耦合。模块间通过参数传递复杂的内部数据结构,称为标记耦合。此数据结构的变化将使相关的模块发生变化。(5)数据耦合。模块间通过参数传递基本类型的数据,称为数据耦合。(6)非直接耦合。模块间没有信息传递时,属于非直接耦合。如果模块间必须存在耦合,就尽量使用数据耦合,少用控制耦合,限制公共耦合的范围,坚决避免使用内容耦合。——开放性如果一个模块可以作为一个独立体被其它程序引用,则称模块具有封闭性。如果一个模块可以被扩充,则称模块具有开放性。从字面上看,让模块具有“封闭——开放性”是矛盾的,但这种特征在软件开发过程中是客观存在的。当着手一个新问题时,我们很难一次性解决问题。应该先纵观问题的一些重要方面,同时作好以后补充的准备。因此让模块存在“开放性”并不是坏事情。“封闭性”也是需要的,因为我们不能等到完全掌握解决问题的信息后再把程序做成别人能用的模块。模块的“封闭——开放性”实际上对应于软件质量因素中的可复用性和可扩充性。采用面向过程的方法进行程序设计,很难开发出既具有封闭性又具有开放性的模块。采用面向对象设计方法可以较好地解决这个问题。设计程序的着重点已经从有关过程的设计转移到了对数据的组织,这种转移也反映了程序规模增大的情况。相关的过程与他们所操作的数据组织在一起,通称为一个模块,:..程序设计范型变成:确定需要哪些模块;将程序分为一些模块,使数据隐藏于模块之中。在这样的设计范型中,最重要的概念就是数据隐藏原理。,这种类型的行为方式与内部类型几乎完全一样,这样的类型常常被称为抽象数据类型,其程序设计范型是:确定需要哪些类型;为每个类型提供完整的一组操作。支持这种范型的典型设计语言就是ADA。,加入继承和多态这两个组重要的概念就演变出了现在最流行的程序设计方法---面向对象程序设计,其范型是:确定需要哪些类;为每个类提供完整的一组操作;利用继承去明确地表示共性。支持此范型的典型语言就是EIFFEL,JAVA,C++等。、机制是对象,对象可以被定义由属性(数据)和操作这些数据的方法(代码)组成的软件单元。数据不能被对象的使用者直接访问,只允许通过由对象提供的方法或者代码访问数据(也就是说,函数调用它的方法)。封装对象既包含数据又包含操作或者改变该数据的方法(代码)对象的服。务定义了其他的对虾感怎样获得对其方法的访问。每一个对象都将愿意提供给所有对象的公共服务公开化。它也提供仅局限与特定对象的其他的服务(保护和私有的)。我提供服务的思想定义了面向对象范型的第二个原则---信息隐藏。信息隐藏包含属性(数据)的对象定义什么服务(函数)可被其他对象访问,实际上,其他对象无法访问或者感知数据(属性)及其这样提供服务(方法、代码)。对象通过使用消息机制发送遵守服务的原型的消息,能够使用另外一个对象的公共服务。消息机制就构成了面向对象范型的第三个原则--消息传递。消息传递对象只能借助消息传递机制才能同其他对象通信,每个消息必须发送个指定的接受者,并且消息的解释以来于接受者。在面向对象的范型中,通常在运行时才知道给定消息的特定接受者。这样,在消息和用来完成对行为的轻骑的方法之间存在后期连接。命令式程序范型中的函数调用与代码片段存在的是早期连接。对后期连接的支持定义了面向对象范型的第四个原则---后期连接。后期连接它能够在运行时对一个消息决定要执行的特定接受者及其相应的方法。我们不仅将对象组织为类别,而且也将类别整理为从一般到特殊的层次结构。这将我们引入面向对象的第四个原则---泛化。无多态的泛化可以用层次性继承结构来组织类。在该机构中,子类将从位于数结构高层的父类中继承属性,关系和方法,抽象的父类是指仅用来产生子类的超类。这样抽象类就没有直接实例。有多态的泛化可以使用层次继承结构组织类,子类可以继承位于树型结构:..的高层的父类的树型,关系和方法。然而,子类可以产生它自己的方法来代替其他任何超类的方法。面向对象的三个基本特征是:封装、继承、多态。封装封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。继承面向对象编程(OOP)语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”。被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。在某些OOP语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。继承概念的实现方式有三类:实现继承、接口继承和可视继承。实现继承是指使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力;可视继承是指子窗体(类)使用基窗体(类)的外观和实现代码的能力。在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,Employee是一个人,Manager也是一个人,因此这两个类都可以继承Person类。但是Leg类却不能继承Person类,因为腿并不是一个人。抽象类仅定义将由子类创建的一般属性和方法,创建抽象类时,请使用关键字Interface而不是Class。面向对象开发范式大致为:划分对象→抽象类→将类组织成为层次化结构(继承和合成)→用类与实例进行设计和实现几个阶段。多态多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。实现多态,有二种方式,覆盖,重载。覆盖,是指子类重新定义父类的虚函数的做法。重载,是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。其实,重载的概念并不属于“面向对象编程”,重载的实现是:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数(至少对于编译器来说是这样的)。如,有两个同名函数:functionfunc(p:integer):integer;和functionfunc(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的:int_func、str_func。对于这两个函数的调用,在编译器间就已经确定了,是静态的(记住:是静态)。也就是说,它们的地:..址在编译期就绑定了(早绑定),因此,重载和多态无关!真正和多态相关的是“覆盖”。当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态(记住:是动态!)的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。因此,这样的函数地址是在运行期绑定的(晚邦定)。结论就是:重载只是一种语言特性,与多态无关,与面向对象也无关!引用一句BruceEckel的话:“不要犯傻,如果它不是晚邦定,它就不是多态。”那么,多态的作用是什么呢?我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。4,数组的演化数组是相同类型元素的集合,我将通过数组在C/C++语言上形式的演化来具体说明面向对象程序设计的优点和面向对象程序设计的技术上所支持的概念。//声明一个整型数组intfun[];虽然C++对数组类型提供了内置支持,但是这种支持仅限于“用来读写单个元素”的机制。C++不支持数组的抽象,也不支持对整个数组的操作。例如:我们无法把一个数组复制到另外一个数组,对两个数组进行比较,或者想知道数组的大小。Intarray0[10],array1[10];//错误:不能直接把一个数组复制到另外一个数组array0=array1;intfun[];如果我们希望把一个数组复制到另外一个,则必须自己写程序:for(intindex=0;index<10;++index)array0[index]=array1[index];然而数组没有自我意识,它不知道自己的长度,这样的程序设计反映了数据与对其进行操作的算法的分离,任何函数都可以访问一个数组,数组对于函数来说是不受保护的,而这正是过程话程序设计的特征。++的类机制来设计一个数组抽象1,数组类的实现中有内置的自我意识,首先它知道自己的大小。2,数组类支持数组之间的复制,比较等操作。3,可以查询数组里面的最大植和最小值,以及需要的数值。4,可以排序。classarray{public:Booloperator==(constarray&)const;Booloperator!=(constarray&)const;array&operator=(constarray&);intsize();:..voidsort();intmin();intmax();intfind(intvalue);private://……}关键字private和public控制地类成员的访问,一般来说公有成员提供该类的接口—即实现这个类的行为的操作的集合。私有成员提供私有实现代码—即存储信息的数据。这种类的公共借口与私有代码的分离称为信息隐藏。这样我们就可以对数组进行整体操作,实现了数据和算法的捆绑。,而不具有普遍性,也就是说有的用户也许根本不需要排序这样的功能,但是我们却为其加入了,我们如何才能支持各种用户对于我们的数组类的要求呢?面向对象程序设计方法为我们提供了这样的一种能力,即继承机制和多态机制。我们可以把普遍和共同的属性通过基类来实现,而各种特殊的要求,我们通过继承和多态来表达需要的更多于基类的行为。,我们可以清楚的看到面向对象程序设计的核心思想是:抽象数据类型,继承和多态。我们也可以清晰的感受到面向对象程序设计对于过程式程序设计的好处和优点。参考文献:参考文献:《C++程序设计语言》机械出版社Stroustrup著《C++PRIMER中文版》中国电力出版社Lippman著《object-OrientedSoftwareConstructure》***《面向对象程序设计教程》电子工业出版社冷英男,李文超著《面向对象程序设计:C++语言描述》***出版社(美)RichardJohnsonbaugh,MartinKalin著蔡宇辉译