Java语言程序设计第05章.ppt_第1页
Java语言程序设计第05章.ppt_第2页
Java语言程序设计第05章.ppt_第3页
Java语言程序设计第05章.ppt_第4页
Java语言程序设计第05章.ppt_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第5章 继承与多态,面向对象程序设计的三大原则是封装性、继承性、多态性。对于封装性,我们实际上已通过上一章的叙述作了说明。在本章里,将主要介绍Java语言在继承和多态(重点是重载)方面的特性。,5.1 继承机制 5.2 创建多级层次类 5.3 多态与重载 5.4 方法的动态调度 5.5 使用抽象类,Return,5.1 继承机制,继承是面向对象编程技术的一块基石,因为它允许创建分等级层次的类。运用继承能够创建一个通用类,该类还可以被更具体的类继承,每个具体的类都增加一些自己特有的性质。,5.1.1 关于继承 5.1.2 使用super关键字 5.1.3 使用final关键字,Return,5.1.1 关于继承,在Java术语中,被继承的类叫超类(superclass),继承超类的类叫子类(subclass)。因此子类是超类的一个专门用途的版本,它继承了超类定义的所有实例变量和方法,并且为它自己增添了独特的元素。 继承一个类,只需要用extends关键字把一个类的定义合并到另一个中就可以了。在Java中,只能给所创建的每个子类定义一个超类。Java语言不支持多超类的继承。你可按照规定创建一个继承的层次。该层次中,一个子类成为另一个子类的超类。然而,没有类可以成为它自己的超类。关于“继承”的详细情况见教材P128132页。,Return,5.1.2 使用super关键字,任何时候一个子类需要引用它直接的超类,可以用关键字super来实现。super有两种通用形式。 第一种调用超类的构造函数; 第二种用来访问被子类的成员隐藏的超类成员。 下面分别介绍每一种用法。,1使用super调用超类构造函数,子类可以调用超类中定义的构造函数方法,用super的下面形式:super(parameter-list); 这里,parameter-list定义了超类中构造函数所用到的所有参数。super( )必须是在子类构造函数中的第一个执行语句。考察并分析教材P134135页的示例。,Super的第二种形式,除了总是引用它所在子类的超类,它的行为有点像this。这种用法有下面的通用形式: super.member 这里,member既可以是一个方法也可以是一个实例变量。 Super的第二种形式多数是用于超类成员名被子类中同样的成员名隐藏的情况。考察并分析教材P136137页的示例。,2Super关键字的另外一种用法,3关于Object类,这里大致介绍一下Object类。在Java中,定义有一种特殊的类Object,其他所有的类都是Object的子类。也就是说,Object是所有其他类的超类。这意味着一个Object类型的引用变量可以引用其他任何一个类的对象。同样,因为数组像类一样执行,Object类型变量可以引用任何数组。 Object定义了下面的方法,意味着它们可以被任何对象调用,如教材P137页表5-1所示。 其中,getClass()、notify()、notifyAll()和wait()方法被定义成final。你可以重载除这些方法以外的其他方法。注意这两个方法:equals()和toString()。equals()方法比较两个对象的内容。如果对象是相等的,它返回true,否则返回false。toString()方法返回一个包含调用它的对象描述的字符串。而且,该方法在对象使用println()输出时自动调用。很多类都重载该方法,这样做使它们生成它们创建对象类型的一个特殊描述。,Return,5.1.3 使用final关键字,Final关键字有三个用途:首先,它可以用来创建一个已命名的常量,这个用法在前一章中已介绍过。Final的其他两个用法是用于继承中,下面分别予以介绍。,1使用final阻止继承,有时候,你可能希望防止一个类被继承。做到这点只需在类声明前加final。声明一个final类含蓄的宣告了它的所有方法也都是final。你可能会想到,声明一个既是abstract又是final的类是不合法的,因为抽象类本身是不完整的,它依靠它的子类提供完整的实现。下面是一个final类的例子: final class A / . class B extends A / ERROR! Cant subclass A / . 正如注释所说明的,B继承A是不合法的,因为A声明成final。,2使用final阻止重载,Return,尽管方法重载(本章后面将会介绍)是Java的一个最强大的特性,有些时候也可能希望防止它的发生。不接受方法被重载,在方法前定义final修饰符。声明成final的方法不能被重载。下面的程序段阐述了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 创建多级层次类,到目前为止,我们已经用到了只含有一个超类和一个子类的简单类层次结构。同时,我们也可以如自己所愿建立包含任意多层继承的类层次结构。,5.2.1 多级层次的类 5.2.2 何时调用构造函数,Return,5.2.1 多级层次的类,前面提到过,用一个子类作为另一个类的超类是完全可行的。例如,给定三个类A、B和C。C是B的一个子类,而B又是A的一个子类。当这种类似的情形发生时,每个子类继承它的所有超类的属性。在此情况下,C继承B和A的所有方面。为理解多级层次的用途,考察教材P139141页的示例程序。在该程序中,子类BoxWeight用作超类来创建一名为Shipment的子类。Shipment继承了BoxWeight和Box的所有特征,并且增加了一个名为cost的成员,该成员记录了运送这样一个小包的费用。 由该示例可知,Shipment可以利用原先定义好的Box 和BoxWeight类,仅为自己增加特殊用途的其他信息。这体现了继承的部分价值:它允许代码重用。同时该例子还说明了另外一点:super()总是引用子类最接近的超类的构造函数。Shipment中super( )调用了BoxWeight的构造函数。BoxWeight中的super()调用了Box中的构造函数。在类层次结构中,如果超类构造函数需要参数,那么不论子类自己需不需要参数,都必须向上传递这些参数。,Return,5.2.2 何时调用构造函数,类层次结构创建以后,组成层次结构的类的构造函数以怎样的顺序被调用?举个例子来说,给定一个名为B的子类和超类A,是A的构造函数在B的构造函数之前调用,还是情况相反?回答是在类层次结构中,构造函数以派生的次序调用,从超类到子类。而且,尽管super()必须是子类构造函数的第一个执行语句,无论你用到了super()没有,这个次序不变。如果super()没有被用到,每个超类的默认的或无参数的构造函数将执行。教材P142页的例子阐述了何时执行构造函数。 从该例子可以看出,构造函数以派生的顺序被调用。构造函数以派生的顺序执行是很有意义的。因为超类不知道任何子类的信息,任何它需要完成的初始化是与子类的初始化分离的,而且它可能是完成子类初始化的先决条件。因此,它必须最先执行。,Return,5.3 多态与重载,多态是面向对象程序设计的基本特性之一,而重载则是多态的一种体现形式。本节将对这方面的内容进行介绍。,5.3.1 关于多态 5.3.2 方法的重载 5.3.3 构造函数重载,Return,5.3.1 关于多态,多态即程序中同名的不同方法共存的情况,常见的两种多态方式为: 子类对父类方法的覆盖; 利用重载在同一个类中定义多个同名的不同方法。 重载是类对自身已有的同名方法的重新定义,常见的如构造函数的重载。构造函数可以从超类那里继承,也可以互相重载。类的若干个构造函数可以相互调用,一个构造函数调用另一构造函数时,可以使用关键字this。同时,这个调用语句应该是整个构造函数的第一个可执行语句。,Return,5.3.2 方法的重载,在Java中,同一个类中的两个或两个以上的方法可以有同一个名字,只要它们的参数声明不同即可。在这种情况下,该方法就被称为重载(overloaded),这个过程称为方法重载。方法重载是Java实现多态性的一种方式。如果读者以前从来没有使用过一种允许方法重载的语言,这个概念最初可能有点奇怪。但后面将看到,方法重载是Java最激动人心和最有用的特性之一。 当一个重载方法被调用时,Java用参数的类型和(或)数量来表明实际调用的重载方法的版本。因此,每个重载方法的参数的类型和(或)数量必须是不同的。虽然每个重载方法可以有不同的返回类型,但返回类型并不足以区分所使用的是哪个方法。当Java调用一个重载方法时,参数与调用参数匹配的方法被执行。分析教材P143144页的例子。,Return,5.3.3 构造函数重载,除了重载正常的方法外,构造函数也能够重载。实际上,对于大多数创建的类,重载构造函数是很常见的,并不是什么例外。为了加深理解,让我们回顾一下上一章中举过的Box类例子。教材P146页给出了最新版本的Box类的例子。 在这个例子中,Box()构造函数需要三个自变量,这意味着定义的所有Box对象必须给Box()构造函数传递三个参数。例如,下面的语句在当前情况下是无效的。 Box ob = new Box(); 由于Box( )要求有三个参数,因此如果不带参数地调用它则是一个错误。这会引起一些重要的问题。如果你只想要一个盒子而不在乎(或知道)它的原始的尺寸该怎么办?或者,如果想用仅仅一个值来初始化一个立方体,而该值可以被用作它的所有的三个尺寸又该怎么办?如果Box类是像现在这样写的,与此类似的其他问题都没有办法解决,因为你只能带三个参数而没有别的选择权。要解决这些问题,实际上是相当容易的:重载Box构造函数,使它能处理刚才描述的情况。分析教材P146147页Box的一个改进版本程序,它就是运用对Box构造函数的重载来解决这些问题的。,Return,5.4 方法的动态调度,前面说明了方法重载机制,但并没有显示它们的作用。实际上,如果方法重载只是一个名字空间的约定,那就没有实用价值,但实际情况并非如此。,5.4.1 关于多态方法调用 5.4.2 为什么要重载方法 5.4.3 运用方法重载,Return,5.4.1 关于多态方法调用,方法重载构成Java的一个最强大概念的基础:动态方法调度(dynamic method dispatch)。动态方法调度是一种在运行时而不是编译时调用重载方法的机制。动态方法调度对Java来说是很重要的,因为这是Java实现运行时多态性的基础。 下面从一个重要的原则开始谈起:超类的引用变量可以引用子类对象。Java用这一事实来解决在运行期间对重载方法的调用。过程如下:当一个重载方法通过超类引用被调用,Java根据当前被引用对象的类型来决定执行哪个版本的方法。如果引用的对象类型不同,就会调用一个重载方法的不同版本。换句话说,是被引用对象的类型(而不是引用变量的类型)决定执行哪个版本的重载方法。因此,如果超类包含一个被子类重载的方法,那么当通过超类引用变量引用不同对象类型时,就会执行该方法的不同版本。分析教材P148页的例子。,Return,5.4.2 为什么要重载方法,前面提到过,重载方法允许Java支持运行时多态性。多态性是面向对象编程的本质,原因如下:它允许通用类指定方法,这些方法对该类的所有派生类都是公用的。同时该方法允许子类定义这些方法中的某些或全部的特殊实现。重载方法是Java实现它的多态性“一个接口,多个方法”的另一种方式。 成功应用多态的关键部分是理解超类和子类形成了一个从简单到复杂的类层次。正确应用多态,超类提供子类可以直接运用的所有元素。多态也定义了这些派生类必须自己实现的方法。这允许子类在加强一致接口的同时,灵活地定义它们自己的方法。这样,通过继承和重载方法的联合,超类可以定义供它的所有子类使用的方法的通用形式。 动态的运行时多态是面向对象设计代码重用的一个最强大的机制。现有代码库在维持抽象接口同时不重新编译的情况下调用新类实例的能力是一个极其强大的工具。,Return,5.4.3 运用方法重载,教材P149150页的例子就是一个运用方法重载的实际的例子。在该程序中,创建了一个名为Figure的超类,存储不同二维对象的大小。还定义了一个方法area( ),该方法计算对象的面积。程序从Figure派生了两个子类。第一个是Rectangle,第二个是Triangle。每个子类重载area( )方法,它们分别返回一个矩形和一个三角形的面积。 通过继承和运行时多态的双重机制,可以定义一个被很多不同却有关的对象类型运用的一致的接口。这种情况下,如果一个对象是从Figure派生,那么它的面积可以由调用area()来获得。无论用到哪种图形的类型,该操作的

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论