面向对象的比喻实在太多了。不知哪个比喻更能让你明白呢? 理解面向对象编程(Object Oriented Programming 简称OOP)所谓"面向对象编程",其实指的是一种编程思想模式。与之对应的是"面向过程编程"。 两者有什么区别?我们先展开一下想象,话说你想请洪七公吃叫化鸡。按照现代的做法,是将一只鸡杀死拔毛之后清洗干净鸡腔内脏,并在里面填充上适当的调味料,接着用锡纸包起这个鸡并在外面涂上泥巴,最后丢进炭火里煨熟, 估算时间差不多后,将鸡取出来拍开泥土,剥开锡纸再送到七公手上...这种做法就是面向过程模式。 但你是一个头脑很发达的人,你制造出一台新型的全自动化“烤叫化鸡”机器,只要在这机器指定的入口扔一个鸡进去,这台机器运作后就会在另一个出口输送出一个香喷喷的叫化鸡。 这种做法就是面向对象模式。很明显,面向过程的制作叫化鸡方法,采用的是按顺序按步骤得到叫化鸡。我们将这些步骤抽取出关键词对应编程的术语,每个关键词代表一个功能函数: 杀鸡-拔毛-清洗-填料-包锡纸-涂泥巴-煨熟-取出-拍泥土怎么样,一目了然易于理解是吧。 再来看面向对象方式的制作叫化鸡: 制造一台全自动化机器--往入口扔一只鸡--往出口取一只鸡。就这么简单。 你不必理会机器内部怎么杀怎么清洗...怎么运作的。 只要知道这台机器的用途是制作叫化鸡,操作方法是往入口丢一只鸡进去,再从出口拿这只鸡出来就行。 通过这个比喻,我们来进一步来了解面向对象的特点:1只做一只叫化鸡时面向过程比较方便和易于理解。但要量产时无疑是选择面向对象。2面向对象要构思机器的制造方法,在机器内部来设定上面所述的那些功能函数。而外部只能操作入口放只鸡进去和在出口取 只鸡出来,如果有控制键,还可以只操作其中部分功能,比如仅仅是杀鸡并拔毛(这就是构建类函数并封装,封装后那些功能函数只能调用。)3通过使用这台机器会制造出一个个的叫化鸡。(类的实例化结果就是对象)4如果用这机器制造10只叫化鸡,每个生产出来的叫化鸡咸淡味感都是一样的。(类的对象有相同的属性)5把这10只鸡其中一只撒上辣椒或撕下一条鸡腿,其余九只不会因此而有辣味或缺条腿。(增加或减少对象属性的任何操作都不影响到同类的对象属性)6如果将机器的调料设定改变,生产出来(实例化)的鸡口味也会改变(这就是类和对象的关系)7生产出来的叫化鸡七公嫌太熟且味道淡了些,只要将机器内部的烤温降低并增加盐的份量就行了。(面向对象易于维护和改进)8七公吃了一个觉得不够还想吃,甚至要发放到丐帮人均一只叫化鸡,这问题第1点的量产提到啦(所以面向对象模式更适合项目规模大的需要)9每个丐帮人员口味需求不一样,一个叫化鸡而已,居然有的要甜有的要酸,不过难不倒这机器,另外加料就行,除了口味不一样其它的还是一样。不用重新设计一台机器(用继承来重用代码)10有个叫鲁有脚的长老竟然异想天开想吃叫化鸭。没问题啊,叫化鸡叫化鸭叫化鹅都行的。抓只鸭子丢进机器就可以。(这就是对象的多态性,参数由鸡改成鸭)从现实世界中客观存在的事物(即对象)出发来构造软件系统,并在系统构造中尽可能运用人类的自然思维方式,强调直接以问题域(现实世界)中的事物为中心来思考问题,认识问题,并根据这些事物的本质特点,把它们抽象地表示为系统中的对象,作为系统的基本构成单位(而不是用一些与现实世界中的事物相关比较远,并且没有对应关系的其它概念来构造系统)。这可以使系统直接地映射问题域,保持问题域中事物及其相互关系的本来面貌。
它可以有不同层次的理解:
从世界观的角度可以认为:面向对象的基本哲学是认为世界是由各种各样具有自己的运动规律和内部状态的对象所组成的;不同对象之间的相互作用和通讯构成了完整的现实世界。因此,人们应当按照现实世界这个本来面貌来理解世界,直接通过对象及其相互关系来反映世界。这样建立起来的系统才能符合现实世界的本来面目。
从方法学的角度可以认为:面向对象的方法是面向对象的世界观在开发方法中的直接运用。它强调系统的结构应该直接与现实世界的结构相对应,应该围绕现实世界中的对象来构造系统,而不是围绕功能来构造系统。
从程序设计的角度来看,面向对象的程序设计语言必须有描述对象及其相互之间关系的语言成分。这些程序设计语言可以归纳为以下几类:系统中一切皆为对象;对象是属性及其操作的封装体;对象可按其性质划分为类,对象成为类的实例;实例关系和继承关系是对象之间的静态关系;消息传递是对象之间动态联系的唯一形式,也是计算的唯一形式;方法是消息的序列。
面向对象
面向对象(Object Oriented,OO)是当前计算机界关心的重点,它是90年代软件开发方法的主流。面向对象的概念和应用已超越了程序设计和软件开发,扩展到很宽的范围。如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。
谈到面向对象,这方面的文章非常多。但是,明确地给出对象的定义或说明对象的定义的非常少——至少我现在还没有发现。其初,“面向对象”是专指在程序设计中采用封装、继承、抽象等设计方法。可是,这个定义显然不能再适合现在情况。面向对象的思想已经涉及到软件开发的各个方面。如,面向对象的分析(OOA,ObjectOriented Analysis),面向对象的设计(OOD,Object OrientedDesign)、以及我们经常说的面向对象的编程实现(OOP,Object OrientedProgramming)。许多有关面向对象的文章都只是讲述在面向对象的开发中所需要注意的问题或所采用的比较好的设计方法。看这些文章只有真正懂得什么是对象,什么是面向对象,才能最大程度地对自己有所裨益。这一点,恐怕对初学者甚至是从事相关工作多年的人员也会对它们的概念模糊不清。
面向对象是当前计算机界关心的重点,它是90年代软件开发方法的主流。面向对象的概念和应用已超越了程序设计和软件开发,扩展到很宽的范围。如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。
它强调对象的“抽象”、“封装”、“继承”、“多态”。一、oop的基本思想
OOP的许多原始思想都来之于Simula语言,并在Smalltalk语言的完善和标准化过程中得到更多的扩展和对以前的思想的重新注解。可以说OO思想和OOPL几乎是同步发展相互促进的。与函数式程序设计(functional-programming)和逻辑式程序设计(logic-programming)所代表的接近于机器的实际计算模型所不同的是,OOP几乎没有引入精确的数学描叙,而是倾向于建立一个对象模型,它能够近似的反映应用领域内的实体之间的关系,其本质是更接近于一种人类认知事物所采用的哲学观的计算模型。由此,导致了一个自然的话题,那就是OOP到底是什么?[D&T 1988][B.S 1991] .。在OOP中,对象作为计算主体,拥有自己的名称,状态以及接受外界消息的接口。在对象模型中,产生新对象,旧对象销毁,发送消息,响应消息就构成OOP计算模型的根本。 对象的产生有两种基本方式。一种是以原型(prototype)对象为基础产生新的对象。一种是以类(class)为基础产生新对象。原型的概念已经在认知心理学中被用来解释概念学习的递增特性,原型模型本身就是企图通过提供一个有代表性的对象为基础来产生各种新的对象,并由此继续产生更符合实际应用的对象。而原型-委托也是OOP中的对象抽象,代码共享机制中的一种。一个类提供了一个或者多个对象的通用性描叙。从形式化的观点看,类与类型有关,因此一个类相当于是从该类中产生的实例的集合。而这样的观点也会带来一些矛盾,比较典型的就是在继承体系下,子集(子类)对象和父集(父类)对象之间的行为相融性可能很难达到,这也就是OOP中常被引用的---子类型(subtype)不等于子类(subclass) [Budd 2002]。而在一种所有皆对象的世界观背景下,在类模型基础上还诞生出了一种拥有元类(metaclass)的新对象模型。即类本身也是一种其他类的对象。以上三种根本不同的观点各自定义了三种基于类(class-based),基于原型(prototype-based)和基于元类(metaclass-based)的对象模型。而这三种对象模型也就导致了许多不同的程序设计语言(如果我们暂时把静态与动态的差别放在一边)。是的,我们经常接触的C++,Java都是使用基于类的对象模型,但除此之外还有很多我们所没有接触的OOPL采用了完全不一样的对象模型,他们是在用另外一种观点诠释OOP的内涵。 什么是oop的基本思想呢?把组件的实现和接口分开,并且让组件具有多态性。不过,两者还是有根本的不同。oop强调在程序构造中语言要素的语法。你必须得继承,使用类,使用对象,对象传递消息。gp不关心你继承或是不继承,它的开端是分析产品的分类,有些什么种类,他们的行为如何。就是说,两件东西相等意味着什么?怎样正确地定义相等操作?不单单是相等操作那么简单,你往深处分析就会发现“相等”这个一般观念意味着两个对象部分,或者至少基本部分是相等的,据此我们就可以有一个通用的相等操作。再说对象的种类。假设存在一个顺序序列和一组对于顺序序列的操作。那么这些操作的语义是什么?从复杂度权衡的角度看,我们应该向用户提供什么样的顺序序列?该种序列上存在那些操作?那种排序是我们需要的?只有对这些组件的概念型分类搞清楚了,我们才能提到实现的问题:使用模板、继承还是宏?使用什么语言和技术?gp的基本观点是把抽象的软件组件和它们的行为用标准的分类学分类,出发点就是要建造真实的、高效的和不取决于语言的算法和数据结构。当然最终的载体还是语言,没有语言没法编程。stl 使用c++,你也可以用ada来实现,用其他的语言来实现也行,结果会有所不同,但基本的东西是一样的。到处都要用到二分查找和排序,而这就是人们正在做的。对于容器的语义,不同的语言会带来轻微的不同。但是基本的区别很清楚是gp所依存的语义,以及语义分解。例如,我们决定需要一个组件swap,然后指出这个组件在不同的语言中如果工作。显然重点是语义以及语义分类。而oop所强调的(我认为是过分强调的)是清楚的定义类之间的层次关系。oop告诉了你如何建立层次关系,却没有告诉你这些关系的实质。 (这段不太好理解,有一些术语可能要过一段时间才会有合适的中文翻译——译者) 面向对象的编程方法OOP是九十年代才流行的一种软件编程方法。它强调对象的“抽象”、“封装”、“继承”、“多态”。我们讲程序设计是由“数据结构”+“算法”组成的。从宏观的角度讲,OOP下的对象是以编程为中心的,是面向程序的对象。我们今天要讲的OOD是面向信息的对象,是以用户信息为中心的。