面向对象程序设计-第二章a.ppt
1,第二章 面象对象的程序设计 主讲:徐宏喆,2,第二章 面象对象的程序设计主讲:徐宏喆,3,面向对象程序设计在程序设计模式中是一个新的概念,对于不同的人可能意味着不同的内容。因此在我们继续下面的内容之前,我们定义一下面向对象程序设计::1,see,4,2.1引言,面向对象程序设计方法(OOP)的主要出发点是弥补面向过程程序设计方法中的一些缺点。OOP把数据看作程序开发中的基本元素,并且不允许它们在系统中自由流动。它将数据和操作这些数据的函数紧密的连结在一起,并保护数据不会被外界的函数意外的改变。OOP允许我们将问题分解为一系列“实体”这些“实体”被称为对象(object),然后围绕这些实体建立数据和函数。,5,面向对象的程序设计,“面向对象”作为一个术语,在不同的人群中有着不同的解释。因此,了解一些在面向对象程序设计中广泛应用的概念是必须的。本节我们讨论以下这些内容:1、对象(Object)2、类(Class)3、数据抽象(Data abstraction)4、继承(Inheritance)5、数据封装(Data encapsulation)6、多态性(Polymorphism)7、消息传递(Message passing),6,2.2对象和类,对象和类的概念对象是现实世界中一个实体,类是对多个实体进行综合抽象的结果,7,类,事实上,对象就是类类型(class type)的变量。一旦定义了一个类,我们就可以创建这个类的多个对象,每个对象与一组数据相关,而这组数据的类型在类中定义。因此,一个类就是具有相同类型的对象的抽象。例如,芒果、苹果和桔子都是fruit类的对象。类是用户定义的数据类型,但在一个程序设计语言中,它和内建的数据类型行为相同。比如创建一个类对象的语法和创建一个整数对象的语法一模一样。如果fruit被定义为一个类,那么语句fruit mango;就创建了一个fruit类的对象mango。,8,定义支持继承性和多态的抽象数据类型(ADT)使用一个自定义类型和基本类型没有本质区别,看到的只是类型名和一组操作的声明(包括操作名,参数,操作含义,操作使用规则),类(Class),9,访问控制(封装性)面向对象语言中提供了外界对类的访问控制机制访问控制的程度不同也称为“能见度”不同,类(Class),10,对象,在一个面向对象的系统中,对象是运行期的基本实体。它也可以用来表示一个人或者说一个银行帐户,一张数据表格,或者其它什么需要被程序处理的东西。它也可以用来表示用户定义的数据,例如一个向量,时间或者列表。在面向对象程序设计中,问题的分析一般以对象及对象间的自然联系为依据。如前所述,对象在内存中占有一定空间,并且具有一个与之关联的地址,就像Pascal中的record和C中的结构一样。,11,对象,当一个程序运行时,对象之间通过互发消息来相互作用。例如,程序中包含一个“customer”对象和一个“account”对象,而customer对象可能会向account对象发送一个消息,查询其银行帐目。每个对象都包含数据以及操作这些数据的代码。即使不了解彼此的数据和代码的细节,对象之间依然可以相互作用,所要了解的只是对象能够接受的消息的类型,以及对象返回的响应的类型,虽然不同的人会以不同的方法实现它们。,12,定义对象是某个特定类的实例。用同一个类产生的对象具有相同的数据结构,操作集合和能见度,不同的标识,相同或不同的初始状态,拥有和保持不同的运行状态。对象之间通过消息传递进行交互。对象与一般数据类型的实例之间的区别:对象是主动的数据,对象之间通过消息传递进行通信,而一般数据只能被动的由过程来处理。,对象,13,对象,属性,服务,对象标识,14,对象特性主动数据消息传递状态保持,对象,15,对象的特征,对象的名字:用不同的对象名字来将它们加以区分对象的属性:属性是对实体某一方面的描述对象的操作:对象的操作指的是对象能够进行的行为,16,例子,下面是一个对象的例子:对象名称:小明 对象属性:学历:大学 年龄:21 专业:历史系 对象操作:上课 吃饭,17,消息传递,对象的交互,现实中的对象不是孤立的,他们之间存在着各种练习,对象之间的相互交互是通过消息传递来进行的。,18,消息传递,一个面向对象的程序由许多对象组成,这些对象之间需要相互沟通。因此,在面向对象程序设计语言中,程序设计的主要步骤如:2对象之间通过收发信息相互沟通,这一点类似于人与人之间的信息传递。信息传递的概念使得真实世界的直接模拟更易于和建立系统交流。对于某个特定对象来说,消息就是请求执行某个过程,因此,消息的接收对象会调用一个函数(过程),以产生预期的结果。传递的消息的内容包括接收消息的对象的名字,需要调用的函数的名字,以及必要的信息。对象就有一个生命周期。它们可以被创建和销毁。只要对象正处于其生存期,就可以与其进行通讯。,see,19,消息传递,对象之间的消息,消息的性质:同一对象可以接受不同形式的多个消息,作出不同的响应相同的消息可以传给不同的对象,所作出的响应可以是不 同的消息之间的发送可以不考虑具体的接受者,对象可以响应 消息,也可以不响应,消息的分类:公有消息:由其他对象向自己直接发送的消息私有消息:由对象自己向自己发送的消息,20,消息传递机制与函数调用机制的区别一,在消息传递机制中,每一个消息被发送给指定的接收者(对象)。在命令式编程范型中,函数调用机制没有指定的接收者。这一区别支持封装。二,消息的解释(用来完成服务请求的方法或操作/代码集)依赖接收者,并且因接收者的不同而异。这一区别对于支持信息隐藏和多态(重载)是必要的。三,在面向对象的范型中,通常在运行时才能知道给定消息的特定的接收者。这样,在消息(服务请求/函数调用)和用来完成对行为的请求的方法(代码片段)之间存在后期连接。命令式编程范型中的函数调用与代码片段之间存在的是早期连接(编译或连接时)。,消息传递与方法,21,2.3数据的抽象和封装,数据的抽象,抽象是通过特定的实例和例子抽取共同性以后形成概念的过程,它是面向对象程序设计的一种基本思想。,抽象是对象系统的简化描述和规范说明,它强调了系统中的一部分细节和特性,例如做什么;而忽略其他部分,例如如何做。,比如:我们对录音机进行抽象录音机的属性:长、宽、高、生产厂家等录音机的行为:放音、录音、停止、倒带、快进等我们并不关心录音机的放音是怎么实现的,这些是在类的实现中要考虑的。,22,数据的抽象,抽象指仅表现核心的特性而不描述背景细节的行为。类使用了抽象的概念,并且被定义为一系列抽象的属性如尺寸、重量和价格,以及操作这些属性的函数。类封装了将要被创建的对象的所有核心属性。因为类使用了数据抽象的概念,所以它们被称为抽象数据类型(ADT)。,23,抽 象,从事物中舍弃个别的非本质的特征,而抽取共同的、本质特征的做法叫抽象;一个现实事物,可能担任很多角色,只有与问题域有关的角色,才予以考虑。,24,数据的封装,封装就是将数据和对数据的操作组成一个实体,数据的表示方式和对数据的操作细节被隐藏起来,用户通过操作接口对数据进行操作.,BalanceOwnerMakeDeposit()WithDraw()Transfer(),MakeDeposit()WithDraw()Transfer(),接口,用户,实现细节(对用户不可见),25,封 装,26,数据的封装,把数据和函数包装在一个单独的单元(称为类)的行为称为封装。数据封装是类的最典型特点。数据不能被外界访问,只能被封装在同一个类中的函数访问。这些函数提供了对象数据和程序之间的接口。避免数据被程序直接访问的概念被称为“数据隐藏”。,27,数据的封装,封装机制将数据和代码捆绑到一起,避免了外界的干扰和不确定性。它同样允许创建对象。简单的说,一个对象就是一个封装了数据和操作这些数据的代码的逻辑实体。在一个对象内部,某些代码和(或)某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。,28,封 装,封装常常被简单的描述为“数据隐藏”。一般情况下,对象不会把它们的内部数据暴露给外部世界(即内部数据的可见性是protected 或private)但封装的含义不仅仅是数据隐藏。一般来说,封装意味着任何形式的隐藏。,29,2.4继承性,继承性的概念,继承性是面向对象的基本特征,从面向对象程序设计的观点来看,继承表达的是对象类之间相关的关系。,30,31,32,继承性,继承带来好处,继承机制为程序员提供了一种组织,构造和重用类的基本手段,继承可以使基类的数据和操作可以被另一个内(派生类)重用,在派生类只需要描述基类中没有的数据和操作。,继承的分类,单继承每个派生类只直接继承了一个基类的特征。,多继承多个基类派生出一个派生类。,33,继承性,例如,哺乳动物和猫是两个对象,它们都有恒温,胎生等特性,但猫除了这些特性之外还具有其他特性,如食肉。从面向对象的角度来看,猫这个对象继承了哺乳动物这个对象的所有属性,同时猫还具有其他特有的属性,如下图:,34,继承性,箭头由猫指向哺乳动物表示猫继承了哺乳动物所有的属性,这个关系不能颠倒过来。这里所说的继承是面向对象程序设计中的一个概念,和现实生活中继承的概念有一定的区别,面向对象中的继承要求具有继承关系的两个类具有以下两个特征:继承类(如上例中的猫)必须包括被继承类(如上例中的哺乳动物)的所有属性继承类要有自己独有的属性,35,继承性,继承是可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。例如,知更鸟属于飞鸟类,也属于鸟类。在OOP中,继承的概念很好的支持了代码的重用性(reusability),也就是说,我们可以向一个已经存在的类中添加新的特性,而不必改变这个类。这可以通过从这个已存在的类派生一个新类来实现。这个新的类将具有原来那个类的特性,以及新的特性。而继承机制的魅力和强大就在于它允许程序员利用已经存在的类(接近需要,而不是完全符合需要的类),并且可以以某种方式修改这个类,而不会影响其它的东西。,36,继承性:能在类之间体现其共性和差别,并能将这样的关系进行传递的机制继承性是面向对象技术实现向前兼容的递增开发的主要机制继承的传递性将增加类之间的耦合度,应该防止滥用继承。重视多重继承带来的问题,使用多重继承不可能代替对象的组装设计,继承性与类层次结构,37,类之间的继承关系是传递的一个类的所有直接和间接父类(子类)统称为这个类的父类(子类)单重继承 只允许一个类有最多一个直接父类多重继承允许一个类有超过一个直接父类,继承性与类层次结构,38,在一个面向对象系统中,子类和父类的继承关系构成了系统的类层次结构,可以用树来描述。,继承性与类层次结构,39,继承与封装的关系,继承是一种在两个类之间共享代码的机制,这种共享并不会破坏对象的封装性。封装性要求外部看不到对象内部的属性和操作,代码的共享似乎会暴露对象内部的代码。代码共享只是为了减少程序员编写代码的操作,在系统内部,具有继承关系的两个类被当作两个独立封装好的类来处理。继承和封装并不矛盾,在减少编程代码量这一点上是一致的。,40,多态性,多态是OOP的另一个重要概念。多态的意思是事物具有不同形式的能力。举个例子,对于不同的实例,某个操作可能会有不同的行为。这个行为依赖于所要操作数据的类型。比如说加法操作,如果操作的数据是数,它对两个数求和。如果操作的数据是字符串,则它将连接两个字符串。,41,多态,“多态(polymorphism)”这个词来源于“poly”(意思是“许多”)和“morph”(意思是“形态”)。多态是指同一个命名可具有不同的语义OO方法中,常指在一般类中定义的属性或服务被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为,42,多态性的概念,多态性就是特定功能有多种实现方法。,对于下面的一段绘图功能代码例子:不使用多态性:void Shape:DrawMe()siwtch(Shape.Type)/判别图形的类型,调用各自对象的DrawMe方法 case“Circle”shape.DrawCircle();/如果是圆形,调用圆的方法case“Rectangle”shape.DrawRectangle();/如果是矩形case“Line”shape.DrawLine();/如果是直线,43,多态性的好处,多态性使得软件易于维护。,使用多用多态性void Shape:DrawMe()shape.DrawMe();/使用多态性,自动调用相应对象的DrawMe()方法,对于上面的代码,如果应用程序要画一个新的图形,在非多态的情况下需要给Shape对象增加一个DrawNewshape()的方法,Shape对象的DrawMe方法也要做相应的修改。使用多态性,只需要创建新的三角形对象,实现一个DrawMe()函数进行绘图,不需要改变Shape对象中的代码。,44,多态性的分类,编译多态性 编译时多态是通过重载来实现的。编译处理程序在编译的时侯根据函数的参数来确定不同的同名函数。,运行多态性 运行时多态性是通过虚函数来实现的,程序运行时使用程序的那个函数版本,在运行的时侯通过对象发送的消息来确定。,45,重载,重载的概念 在编程的过程中经常遇到这样的事情,如一个打印函数,它有一个参数,但这个参数可以是int 型的,也可以是char型的,但一个函数参数只能有1个类型。所以我们不得不用两个不同名称的函数来完成打印工作,在遇到不同的参数的时候我们要为不同类型的参数指定匹配的打印函数才能正常工作。更麻烦的是每次调用打印的时候我们都得针对不同的参数选择不同的打印函数,而不是简单给出打印指令就可以的。,46,面向对象程序设计的一些显著的特性包括:,3,see,47,2.6本章小结,本章介绍了面向对象的几个基本概念 面向对象最基础的概念就是对象。对象是对客观世界中实体的认识,对象之间也是有联系的,具有相同类型属性和操作的对象可以被抽象为类,类是对象的模板。面向对象的主要特性:封装性:对象中的属性和操作都被隐藏起来,只把接口暴露给外界。继承性:对象间的一种层次关系,某个对象继承了另一个对象就具有了那个对象所有的属性和方法。多态性:同一个操作作用在不同对象的时候表现出的不同行为。,48,2.7思考与练习题,什么是程序设计,什么是编程语言,二者是什么关系?结构化程序设计的思路是什么?什么是面向对象程序设计?为什么说C+是一种混合型编程语言?请简述类与对象的概念。类和对象之间的关系是什么?面向对象中,对象的交互机制是什么?面向对象的三大特性是什么?请举例说明什么是对象中数据的抽象和封装。请举例说明现实生活中继承的概念。什么是多继承,举例说明。继承会破坏数据的封装性吗?什么是多态?多态有几种实现方法,分别是什么?,