《《Java语言程序设计实验指导》电子教案第05章.ppt》由会员分享,可在线阅读,更多相关《《Java语言程序设计实验指导》电子教案第05章.ppt(19页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第5章章 继承与多态继承与多态面向对象程序设计的三大原则是封装性、继承面向对象程序设计的三大原则是封装性、继承性、多态性。对于封装性,我们实际上已通过上一性、多态性。对于封装性,我们实际上已通过上一章的叙述作了说明。在本章里,将主要介绍章的叙述作了说明。在本章里,将主要介绍JavaJava语语言在继承和多态(重点是重载)方面的特性。言在继承和多态(重点是重载)方面的特性。5.1 继承机制继承机制5.2 创建多级层次类创建多级层次类5.3 多态与重载多态与重载5.4 方法的动态调度方法的动态调度5.5 使用抽象类使用抽象类Return5.1 继承机制继承机制继承是面向对象编程技术的一块基石,因
2、为继承是面向对象编程技术的一块基石,因为它允许创建分等级层次的类。运用继承能够创建它允许创建分等级层次的类。运用继承能够创建一个通用类,该类还可以被更具体的类继承,每一个通用类,该类还可以被更具体的类继承,每个具体的类都增加一些自己特有的性质。个具体的类都增加一些自己特有的性质。5.1.1 关于继承关于继承5.1.2 使用使用super关键字关键字5.1.3 使用使用final关键字关键字Return5.1.1 关于继承关于继承 在在JavaJava术术语语中中,被被继继承承的的类类叫叫超超类类(superclasssuperclass),继继承承超超类类的的类类叫叫子子类类(subclass
3、subclass)。因因此此子子类类是是超超类类的的一一个个专专门门用用途途的的版版本本,它它继继承承了了超超类类定定义义的的所所有有实实例例变变量量和方法,并且为它自己增添了独特的元素。和方法,并且为它自己增添了独特的元素。继承一个类,只需要用继承一个类,只需要用extendsextends关键字把一个类的定关键字把一个类的定义合并到另一个中就可以了。在义合并到另一个中就可以了。在JavaJava中,只能给所创建的中,只能给所创建的每个子类定义一个超类。每个子类定义一个超类。JavaJava语言不支持多超类的继承。语言不支持多超类的继承。你可按照规定创建一个继承的层次。该层次中,一个子你可按
4、照规定创建一个继承的层次。该层次中,一个子类成为另一个子类的超类。然而,没有类可以成为它自类成为另一个子类的超类。然而,没有类可以成为它自己的超类。关于己的超类。关于“继承继承”的详细情况见教材的详细情况见教材P128132P128132页。页。Return5.1.2 使用使用super关键字关键字 任任何何时时候候一一个个子子类类需需要要引引用用它它直直接接的的超超类类,可可以以用用关关键键字字supersuper来实现。来实现。supersuper有两种通用形式。有两种通用形式。第一种调用超类的构造函数;第一种调用超类的构造函数;第二种用来访问被子类的成员隐藏的超类成员。第二种用来访问被子
5、类的成员隐藏的超类成员。下面分别介绍每一种用法。下面分别介绍每一种用法。1 1使用使用supersuper调用超类构造函数调用超类构造函数子类可以调用超类中定义的构造函数方法,用super的下面形式:super(parameter-list);这里,parameter-list定义了超类中构造函数所用到的所有参数。super()必须是在子类构造函数中的第一个执行语句。考察并分析教材P134135页的示例。Super的第二种形式,除了总是引用它所在子类的超类,它的行为有点像this。这种用法有下面的通用形式:super.member这里,member既可以是一个方法也可以是一个实例变量。Supe
6、r的第二种形式多数是用于超类成员名被子类中同样的成员名隐藏的情况。考察并分析教材P136137页的示例。2Super关键字的另外一种用法关键字的另外一种用法 3关于关于Object类类 这这里里大大致致介介绍绍一一下下ObjectObject类类。在在JavaJava中中,定定义义有有一一种种特特殊殊的的类类ObjectObject,其其他他所所有有的的类类都都是是ObjectObject的的子子类类。也也就就是是说说,ObjectObject是是所所有有其其他他类类的的超超类类。这这意意味味着着一一个个ObjectObject类类型型的的引引用用变变量量可可以以引引用用其其他他任任何何一一个
7、个类类的的对对象象。同同样样,因因为为数数组组像像类类一样执行,一样执行,ObjectObject类型变量可以引用任何数组。类型变量可以引用任何数组。ObjectObject定定义义了了下下面面的的方方法法,意意味味着着它它们们可可以以被被任任何何对对象象调调用,如教材用,如教材P137P137页表页表5-15-1所示。所示。其其中中,getClass()getClass()、notify()notify()、notifyAll()notifyAll()和和wait()wait()方方法法被被定定义义成成finalfinal。你你可可以以重重载载除除这这些些方方法法以以外外的的其其他他方方法法
8、。注注意意这这两两个个方方法法:equals()equals()和和toString()toString()。equals()equals()方方法法比比较较两两个个对对象象的的内内容容。如如果果对对象象是是相相等等的的,它它返返回回truetrue,否否则则返返回回falsefalse。toString()toString()方方法法返返回回一一个个包包含含调调用用它它的的对对象象描描述述的的字字符符串串。而而且且,该该方方法法在在对对象象使使用用println()println()输输出出时时自自动动调调用用。很很多多类类都都重重载载该该方方法法,这样做使它们生成它们创建对象类型的一个特殊
9、描述。这样做使它们生成它们创建对象类型的一个特殊描述。Return5.1.3 使用使用final关键字关键字FinalFinal关键字有三个用途:首先,它可以用来创建一个已命名的常关键字有三个用途:首先,它可以用来创建一个已命名的常量,这个用法在前一章中已介绍过。量,这个用法在前一章中已介绍过。FinalFinal的其他两个用法是用于继承的其他两个用法是用于继承中,下面分别予以介绍。中,下面分别予以介绍。1 1使用使用finalfinal阻止继承阻止继承有时候,你可能希望防止一个类被继承。做到这点只需在类声明前加final。声明一个final类含蓄的宣告了它的所有方法也都是final。你可能会
10、想到,声明一个既是abstract又是final的类是不合法的,因为抽象类本身是不完整的,它依靠它的子类提供完整的实现。下面是一个final类的例子:final class A /.class B extends A /ERROR!Cant subclass A /.正如注释所说明的,B继承A是不合法的,因为A声明成final。2 2 2 2使用使用使用使用finalfinalfinalfinal阻止重载阻止重载阻止重载阻止重载Return尽管方法重载(本章后面将会介绍)是Java的一个最强大的特性,有些时候也可能希望防止它的发生。不接受方法被重载,在方法前定义final修饰符。声明成fina
11、l的方法不能被重载。下面的程序段阐述了final的用法。class A final void meth()System.out.println(This is a final method.);class B extends A void meth()/ERROR!Cant override.System.out.println(Illegal!);其中,由于meth()被声明成final,它不能被B重载,如果你试图这样做,将会生成一个编译时错误。5.2 创建多级层次类创建多级层次类到目前为止,我们已经用到了只含有一个超到目前为止,我们已经用到了只含有一个超类和一个子类的简单类层次结构。同时,
12、我们也类和一个子类的简单类层次结构。同时,我们也可以如自己所愿建立包含任意多层继承的类层次可以如自己所愿建立包含任意多层继承的类层次结构。结构。5.2.1 多级层次的类多级层次的类5.2.2 何时调用构造函数何时调用构造函数Return5.2.1 5.2.1 多级层次的类多级层次的类多级层次的类多级层次的类前面提到过,用一个子类作为另一个类的超类是完全可行的。例前面提到过,用一个子类作为另一个类的超类是完全可行的。例如,给定三个类如,给定三个类A A、B B和和C C。C C是是B B的一个子类,而的一个子类,而B B又是又是A A的一个子类。的一个子类。当这种类似的情形发生时,每个子类继承它
13、的所有超类的属性。在此当这种类似的情形发生时,每个子类继承它的所有超类的属性。在此情况下,情况下,C C继承继承B B和和A A的所有方面。为理解多级层次的用途,考察教材的所有方面。为理解多级层次的用途,考察教材P139141P139141页的示例程序。在该程序中,子类页的示例程序。在该程序中,子类BoxWeightBoxWeight用作超类来创用作超类来创建一名为建一名为ShipmentShipment的子类。的子类。ShipmentShipment继承了继承了BoxWeightBoxWeight和和BoxBox的所有特的所有特征,并且增加了一个名为征,并且增加了一个名为costcost的成
14、员,该成员记录了运送这样一个小的成员,该成员记录了运送这样一个小包的费用。包的费用。由由该该示示例例可可知知,ShipmentShipment可可以以利利用用原原先先定定义义好好的的BoxBox和和BoxWeightBoxWeight类类,仅仅为为自自己己增增加加特特殊殊用用途途的的其其他他信信息息。这这体体现现了了继继承承的的部部分分价价值值:它它允允许许代代码码重重用用。同同时时该该例例子子还还说说明明了了另另外外一一点点:super()super()总总是是引引用用子子类类最最接接近近的的超超类类的的构构造造函函数数。ShipmentShipment中中super()super()调调用
15、用了了BoxWeightBoxWeight的的构构造造函函数数。BoxWeightBoxWeight中中的的super()super()调调用用了了BoxBox中中的的构构造造函函数数。在在类类层层次次结结构构中中,如如果果超超类类构构造造函函数数需需要要参参数数,那那么么不不论论子子类类自自己己需需不不需需要要参参数数,都都必必须向上传递这些参数。须向上传递这些参数。Return5.2.2 5.2.2 何时调用构造函数何时调用构造函数何时调用构造函数何时调用构造函数类层次结构创建以后,组成层次结构的类的构造函数以怎样的顺类层次结构创建以后,组成层次结构的类的构造函数以怎样的顺序被调用?举个例
16、子来说,给定一个名为序被调用?举个例子来说,给定一个名为B B的子类和超类的子类和超类A A,是,是A A的构造的构造函数在函数在B B的构造函数之前调用,还是情况相反?回答是在类层次结构中,的构造函数之前调用,还是情况相反?回答是在类层次结构中,构造函数以派生的次序调用,从超类到子类。而且,尽管构造函数以派生的次序调用,从超类到子类。而且,尽管super()super()必须必须是子类构造函数的第一个执行语句,无论你用到了是子类构造函数的第一个执行语句,无论你用到了super()super()没有,这个没有,这个次序不变。如果次序不变。如果super()super()没有被用到,每个超类的默
17、认的或无参数的构没有被用到,每个超类的默认的或无参数的构造函数将执行。教材造函数将执行。教材P142P142页的例子阐述了何时执行构造函数。页的例子阐述了何时执行构造函数。从从该该例例子子可可以以看看出出,构构造造函函数数以以派派生生的的顺顺序序被被调调用用。构构造造函函数数以以派派生生的的顺顺序序执执行行是是很很有有意意义义的的。因因为为超超类类不不知知道道任任何何子子类类的的信信息息,任任何何它它需需要要完完成成的的初初始始化化是是与与子子类类的的初初始始化化分分离离的的,而而且且它它可可能能是是完完成成子子类初始化的先决条件。因此,它必须最先执行。类初始化的先决条件。因此,它必须最先执行
18、。Return5.3 多态与重载多态与重载多态是面向对象程序设计的基本特性之一,多态是面向对象程序设计的基本特性之一,而重载则是多态的一种体现形式。本节将对这方而重载则是多态的一种体现形式。本节将对这方面的内容进行介绍。面的内容进行介绍。5.3.1 关于多态关于多态5.3.2 方法的重载方法的重载5.3.3 构造函数重载构造函数重载Return5.3.1 5.3.1 关于多态关于多态关于多态关于多态 多多态态即即程程序序中中同同名名的的不不同同方方法法共共存存的的情情况况,常常见见的的两两种种多多态态方方式式为为:子子类类对对父父类类方方法法的的覆覆盖盖;利利用用重重载载在在同同一一个个类类中
19、定义多个同名的不同方法。中定义多个同名的不同方法。重载是类对自身已有的同名方法的重新定义,常见的如构重载是类对自身已有的同名方法的重新定义,常见的如构造函数的重载。构造函数可以从超类那里继承,也可以互相重造函数的重载。构造函数可以从超类那里继承,也可以互相重载。类的若干个构造函数可以相互调用,一个构造函数调用另载。类的若干个构造函数可以相互调用,一个构造函数调用另一构造函数时,可以使用关键字一构造函数时,可以使用关键字thisthis。同时,这个调用语句应。同时,这个调用语句应该是整个构造函数的第一个可执行语句。该是整个构造函数的第一个可执行语句。Return5.3.2 5.3.2 方法的重载
20、方法的重载方法的重载方法的重载 在在JavaJava中中,同同一一个个类类中中的的两两个个或或两两个个以以上上的的方方法法可可以以有有同同一一个个名名字字,只只要要它它们们的的参参数数声声明明不不同同即即可可。在在这这种种情情况况下下,该该方方法法就就被被称称为为重重载载(overloadedoverloaded),这这个个过过程程称称为为方方法法重重载载。方方法法重重载载是是JavaJava实实现现多多态态性性的的一一种种方方式式。如如果果读读者者以以前前从从来来没没有有使使用用过过一一种种允允许许方方法法重重载载的的语语言言,这这个个概概念念最最初初可可能能有有点点奇奇怪怪。但但后后面面将
21、将看看到到,方方法法重重载载是是JavaJava最最激激动动人人心心和和最最有有用用的的特特性性之之一。一。当当一一个个重重载载方方法法被被调调用用时时,JavaJava用用参参数数的的类类型型和和(或或)数数量量来来表表明明实实际际调调用用的的重重载载方方法法的的版版本本。因因此此,每每个个重重载载方方法法的的参参数数的的类类型型和和(或或)数数量量必必须须是是不不同同的的。虽虽然然每每个个重重载载方方法法可可以以有有不不同同的的返返回回类类型型,但但返返回回类类型型并并不不足足以以区区分分所所使使用用的的是是哪哪个个方方法法。当当JavaJava调调用用一一个个重重载载方方法法时时,参参数
22、数与与调调用用参参数数匹匹配配的的方方法被执行。法被执行。分析教材分析教材P143P143 144144页的例子。页的例子。Return5.3.3 5.3.3 构造函数重载构造函数重载构造函数重载构造函数重载 除除了了重重载载正正常常的的方方法法外外,构构造造函函数数也也能能够够重重载载。实实际际上上,对对于于大大多多数数创创建建的的类类,重重载载构构造造函函数数是是很很常常见见的的,并并不不是是什什么么例例外外。为为了了加加深深理理解解,让让我我们们回回顾顾一下上一章中举过的一下上一章中举过的BoxBox类例子。教材类例子。教材P146P146页给出了最新版本的页给出了最新版本的BoxBox
23、类的例子。类的例子。在在这这个个例例子子中中,Box()Box()构构造造函函数数需需要要三三个个自自变变量量,这这意意味味着着定定义义的的所所有有BoxBox对对象象必必须须给给Box()Box()构构造造函函数数传传递递三三个个参参数数。例例如如,下下面面的的语语句句在在当当前前情情况况下下是是无无效的。效的。Box ob=new Box();Box ob=new Box();由由于于Box(Box()要要求求有有三三个个参参数数,因因此此如如果果不不带带参参数数地地调调用用它它则则是是一一个个错错误误。这这会会引引起起一一些些重重要要的的问问题题。如如果果你你只只想想要要一一个个盒盒子子
24、而而不不在在乎乎(或或知知道道)它它的的原原始始的的尺尺寸寸该该怎怎么么办办?或或者者,如如果果想想用用仅仅仅仅一一个个值值来来初初始始化化一一个个立立方方体体,而而该该值值可可以以被被用用作作它它的的所所有有的的三三个个尺尺寸寸又又该该怎怎么么办办?如如果果BoxBox类类是是像像现现在在这这样样写写的的,与与此此类类似似的的其其他他问问题题都都没没有有办办法法解解决决,因因为为你你只只能能带带三三个个参参数数而而没没有有别别的的选选择择权权。要要解解决决这这些些问问题题,实实际际上上是是相相当当容容易易的的:重重载载BoxBox构构造造函函数数,使使它它能能处处理理刚刚才才描描述述的的情情
25、况况。分分析析教教材材P146147P146147页页BoxBox的的一一个个改改进进版版本本程程序序,它它就就是是运运用用对对BoxBox构造函数的重载来解决这些问题的。构造函数的重载来解决这些问题的。Return5.4 方法的动态调度方法的动态调度前面说明了方法重载机制,但并没有显示它前面说明了方法重载机制,但并没有显示它们的作用。实际上,如果方法重载只是一个名字们的作用。实际上,如果方法重载只是一个名字空间的约定,那就没有实用价值,但实际情况并空间的约定,那就没有实用价值,但实际情况并非如此。非如此。5.4.1 关于多态方法调用关于多态方法调用5.4.2 为什么要重载方法为什么要重载方法
26、5.4.3 运用方法重载运用方法重载Return5.4.1 关于多态方法调用关于多态方法调用方法重载构成方法重载构成JavaJava的一个最强大概念的基础:动态方法调度(的一个最强大概念的基础:动态方法调度(dynamic dynamic method dispatchmethod dispatch)。动态方法调度是一种在运行时而不是编译时调用重载)。动态方法调度是一种在运行时而不是编译时调用重载方法的机制。动态方法调度对方法的机制。动态方法调度对JavaJava来说是很重要的,因为这是来说是很重要的,因为这是JavaJava实现运行实现运行时多态性的基础。时多态性的基础。下面从一个重要的原则
27、开始谈起:超类的引用变量可以引用子类对象。下面从一个重要的原则开始谈起:超类的引用变量可以引用子类对象。JavaJava用这一事实来解决在运行期间对重载方法的调用。过程如下:当一个重用这一事实来解决在运行期间对重载方法的调用。过程如下:当一个重载方法通过超类引用被调用,载方法通过超类引用被调用,JavaJava根据当前被引用对象的类型来决定执行哪根据当前被引用对象的类型来决定执行哪个版本的方法。如果引用的对象类型不同,就会调用一个重载方法的不同版个版本的方法。如果引用的对象类型不同,就会调用一个重载方法的不同版本。换句话说,是被引用对象的类型(而不是引用变量的类型)决定执行哪本。换句话说,是被
28、引用对象的类型(而不是引用变量的类型)决定执行哪个版本的重载方法。因此,如果超类包含一个被子类重载的方法,那么当通个版本的重载方法。因此,如果超类包含一个被子类重载的方法,那么当通过超类引用变量引用不同对象类型时,就会执行该方法的不同版本。分析教过超类引用变量引用不同对象类型时,就会执行该方法的不同版本。分析教材材P148P148页的例子。页的例子。Return5.4.2 为什么要重载方法为什么要重载方法 前前面面提提到到过过,重重载载方方法法允允许许JavaJava支支持持运运行行时时多多态态性性。多多态态性性是是面面向向对对象象编编程程的的本本质质,原原因因如如下下:它它允允许许通通用用类
29、类指指定定方方法法,这这些些方方法法对对该该类类的的所所有有派派生生类类都都是是公公用用的的。同同时时该该方方法法允允许许子子类类定定义义这这些些方方法法中中的的某某些些或或全全部部的的特特殊殊实实现现。重重载载方方法法是是JavaJava实实现现它它的的多多态态性性“一一个个接接口,多个方法口,多个方法”的另一种方式。的另一种方式。成成功功应应用用多多态态的的关关键键部部分分是是理理解解超超类类和和子子类类形形成成了了一一个个从从简简单单到到复复杂杂的的类类层层次次。正正确确应应用用多多态态,超超类类提提供供子子类类可可以以直直接接运运用用的的所所有有元元素素。多多态态也也定定义义了了这这些
30、些派派生生类类必必须须自自己己实实现现的的方方法法。这这允允许许子子类类在在加加强强一一致致接接口口的的同同时时,灵灵活活地地定定义义它它们们自自己己的的方方法法。这这样样,通通过过继继承承和和重重载载方法的联合,超类可以定义供它的所有子类使用的方法的通用形式。方法的联合,超类可以定义供它的所有子类使用的方法的通用形式。动态的运行时多态是面向对象设计代码重用的一个最强大的机制。动态的运行时多态是面向对象设计代码重用的一个最强大的机制。现有代码库在维持抽象接口同时不重新编译的情况下调用新类实例的现有代码库在维持抽象接口同时不重新编译的情况下调用新类实例的能力是一个极其强大的工具。能力是一个极其强
31、大的工具。Return5.4.3 运用方法重载运用方法重载教材教材P149150P149150页的例子就是一个运用方法重载的实际的例子。页的例子就是一个运用方法重载的实际的例子。在该程序中,创建了一个名为在该程序中,创建了一个名为FigureFigure的超类,存储不同二维对象的超类,存储不同二维对象的大小。还定义了一个方法的大小。还定义了一个方法area()area(),该方法计算对象的面积。,该方法计算对象的面积。程序从程序从FigureFigure派生了两个子类。第一个是派生了两个子类。第一个是RectangleRectangle,第二个是,第二个是TriangleTriangle。每个
32、子类重载。每个子类重载area()area()方法,它们分别返回一个矩形方法,它们分别返回一个矩形和一个三角形的面积。和一个三角形的面积。通过继承和运行时多态的双重机制,可以定义一个被很多不通过继承和运行时多态的双重机制,可以定义一个被很多不同却有关的对象类型运用的一致的接口。这种情况下,如果一个同却有关的对象类型运用的一致的接口。这种情况下,如果一个对象是从对象是从FigureFigure派生,那么它的面积可以由调用派生,那么它的面积可以由调用area()area()来获得。无来获得。无论用到哪种图形的类型,该操作的接口是相同的。论用到哪种图形的类型,该操作的接口是相同的。Return5.5
33、 使用抽象类使用抽象类要声明一个抽象方法,其通用形式如下要声明一个抽象方法,其通用形式如下 abstract type name(parameter-list);abstract type name(parameter-list);任任何何含含有有一一个个或或多多个个抽抽象象方方法法的的类类都都必必须须声声明明成成抽抽象象类类。声声明明一一个个抽抽象象类类,只只需需在在类类声声明明开开始始时时在在关关键键字字classclass前前使使用用关关键键字字abstractabstract。抽抽象象类类没没有有对对象象。也也就就是是说说,一一个个抽抽象象类类不不能能通通过过newnew操操作作符符直直接接实实例例化化。这这样样的的对对象象是是无无用用的的,因因为为抽抽象象类类是是不不完完全全定定义义的的。而而且且,你你不不能能定定义义抽抽象象构构造造函函数数或或抽抽象象静静态态方方法法。所所有有抽抽象象类类的的子子类类都都必必须须执执行行超超类类中中的的所所有有抽抽象象方方法法或或者者是是它它自自己己也也声声明明成成abstractabstract。分分析析教材教材P151P151页的示例。页的示例。Return