




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第10章继承和多态本章中将通过设计一组汽车类作为学习的出发点,为了给这组汽车类增加新的功能,我们会通过分析一步步引出继承和多态,并在此过程中学习相关的语法和知识点。设计这组汽车类的分析过程其实就是利用面向对象的语法和思想,一步步分析和解决问题的过程。我们本章的重点应该放在理解继承和多态的作用,理解面向对蟮乃枷搿10.1继承——我们的最优解决方案本节中我们将通过汽车的例子来引出继承的概念。然后我们将讲述继承的语法,然后将例子改造成使用继承的模式。通过这个例子我们将看到继承给程序带来哪些直观的好处。好,现在让我们开始本节的内容。10.1.1饭前水果:实例变量的访问控制符其实实例变量的访问控制符和方法的访问控制符是一个概念。如果使用public修饰一个实例变量,那么当创建一个此类的对象后,对象的这个属性将可以在任意代码中使用。使用访问控制符修饰变量的语法如下。访问控制符+变量类型+变量名访问控制符也可以用来修饰实例变量,以控制实例变量的可访问范围。局部变量不能使用访问控制符修饰。10.1.2一切还是从汽车开始假设我们现在需要为一个大的程序设计用来表示系统中汽车的类。汽车包含名字,速度,颜色三个属性。汽车应该有加速和减速两个方法。好,这很容易,跟我们在第7章中学习的类蛮相似的。10.1.3一类车,一个类现在我们决定把代码从新编写,保持让一个类只代表某一类汽车。我们需要三个类来分别表示汽车,公共汽车和跑车。10.1.4分开也有麻烦……系统总是在一次次的升级中完善的,这次系统需要给所有的车增加最高速度的限制(默认为90),然后在加速的方法中保证速度不会超出这个限制。要想完成这个功能,我们需要给每一个类都增加一个新的属性,然后修改每一个类的speedUp方法。首先,代码多了肯定更容易出错。每个类中都有大量相同的代码。为了让这些代码相同,每次都要对这些代码做出相同的修改,这个过程难免出错。而且出错后不容易排除错误——我们要一个类一个类的检查才知道具体是那个类中的代码除了错。其次,代码不够简洁。其实从常识出发,这些相同的代码应该只出现一次,这样就不用每次系统升级时都把所有的类中的代码都修改一遍了。10.1.5使用继承——问题迎刃而解子类继承了父类的属性和方法(包括类属性和类方法)。了解子类(ChildClass)和父类(ParentClass)的概念。学会Java中继承的语法:子类类名+extends+父类类名。开始注意理解继承的含义。10.1.6使用Bus类本小节中,我们来些个小程序使用一下Bus类和SportsCar类。例程中我们将使用子类和子类继承自父类中的方法与属性。当我们使用一个引用来访问方法和属性的时候,无论这个方法或者属性是其父类的还是它自己的,其语法形式是没有不同的。使用父类中的属性和方法并没有语法上的差异。10.1.7Java中的单继承子类和父类是发生继承关系的类的一种相对称呼。Java中的继承关系是单继承。也就是说一个子类只能继承自一个类。也就是说extends关键字后面只可以跟一个类的名字。多数情况下,我们没有必要去特意强调这种多代继承,祖先类和直接父类这两个名字其实很少使用。我们可以将CarBase类和Bus类都称作是ElectronicBus类的父类。这其实只是一个称呼而已。关键的一点是我们要记住:Java中的继承是单继承。Java中的继承可以有无限延续下去Java中的继承是单继承。10.1.8Java中的类图类与类之间的继承关系由连接方块之间的箭头表示:箭头指向的部分是父类,箭头的尾巴连接的方块是子类。我们的图中,连接CarBase和SportsCar的线中有箭头的一端指向了CarBase类;没有箭头的一端连着SportsCar类。这就说明CarBase是SportsCar的父类。10.1.9万类之祖——Object类Object类的特殊性是:Java中所有的类,除了Object类之外,都肯定直接或者间接的继承自Object类。本章之前我们没有接触过继承,更没有接触过extends关键字,为什么这些类也继承自Object类呢?这是因为Java编译器在编译类的源代码时,一旦发现除了Object类之外的类没有父类,则会默认的让类继承自Object类。Java中所有的类,除了Object类之外,都是直接或者间接继承自Object类的。Object类中没有属性,有几个重要的方法。10.2子类对象?父类对象?上一节中,我们主要在类的层面上理解了继承——子类继承了父类的属性和方法。但是从对象层面上,除了可以使用子类的引用无差别的调用子类自己的属性和方法或者继承自父类的属性和方法之外,继承还给对象带来的一些精妙的功能。子类的对象和父类的对象并不是独立的。本节中我们来理解继承在对象层面上带来的惊喜。10.2.1父随子行实际上,“Java在创建一个子类的对象的同时,也创建了其父类的一个对象”。没错,这句话是事实。为什么子类中会包含父类的属性呢?我们可以这么理解——子类对象在创建的同时会创建一个其父类的对象,而这个对象是隐含(或者说是内嵌)在子类中的。当我们通过子类的引用使用其父类的属性的时候,其实可以理解为是访问这个内嵌的父类对象的属性。创建一个类的对象的过程:首先创建这个类的父类的对象,然后创建这个类的对象。这是一个循环递归的过程,仔细揣摩ElectronicBus类的对象的流程。10.2.2当构造方法遇到继承我们需要了解Java中的另一个关键字——super。super关键字可以用来在子类构造方法中使用,用来指定调用父类中的某个构造方法。其语法如下。super(参数值列表)这里的参数值列表必须与父类中的某个构造方法匹配。看上去和使用this关键字调用同一个类中的不同构造方法的语法是相同的。通过super关键字调用父类的构造方法,只能够在子类的构造方法中使用。即不能够在其它方法中使用super关键字调用父类的构造方法。必须在子类的构造方法中的第一行使用此语法。语法中的参数值列表需要和父类中某个构造方法的形式参数匹配,否则Java编译器会给出语法错误。10.2.3记得给类一个无参数的构造方法我们通过例程来说明super关键字的使用。正是由于编译器会在子类中没有显示的调用父类中的某个构造方法时,帮我们调用父类的无参数构造方法。所以为了避免错误,最好我们在类中有写一个无参数的构造方法。为了避免错误,记得保留一个无参数的构造方法。10.2.4调用父类中的构造方法现在CarBase类有了两个构造方法,分别有参数和没参数。我们通过给其子类Bus类和SportsCar类增加构造方法,来看看如何使用super关键字在子类中指定调用父类的构造方法。子类构造方法的第一行总会是父类构造方法:或者是编程中使用super来指定,如果不指定,Java编译器则会默认帮我们指定父类无参数的构造方法。这也从另一个侧面解释了对象创建的过程以及构造方法的调用流程。因为子类构造方法的第一行总会是去调用其父类的某个构造方法,所以父类的构造方法中的代码总会是先于子类执行。熟练使用super关键字调用父类方法。10.2.5对象也会“变脸”总结一下改变对象引用类型的Java语法规则:一个子类的引用可以用来给父类引用赋值,无需进行强制类型转换。也就是说父类的引用可以无条件的指向子类的对象。为了简单的记住这条规则,我们只需记住“Object类的引用可以指向Java中所有对象”。引用类型决定了可以调用对象的哪些方法,访问对象的哪些属性。我们使用CarBase类的引用指向了SportsCar类的对象,则通过这个引用只能够调用Carbase类中有的属性和方法,而不能访问SportsCar类中的属性和方法。如果我们确定某个父类的引用指向的是子类的对象,我们可以通过强制类型转换来将父类的引用转换为子类的引用,并使用转换后的值给子类的引用赋值。10.2.6遵守语法,正确“变脸”类的继承关系都是我们设计好的,只要我们能够保证是使用子类的引用给父类赋值,就没有问题。当然,如果我们没有遵守这个规则,Java编译器会给出编译错误,我们看下面的例程。packagecom.javaeasy.learnextends;publicclassErrorAssignment{publicstaticvoidmain(String[]args){Busbus=newBus();SportsCarsportsCar=bus; //错误}}对象引用的强制类型转换的正确性需要程序员来保证。Java不允许将一个引用随便转换成别的类的引用。10.3覆盖——与继承如影随形上面一节中我们已经掌握了继承的基本用法。因为继承,一个类的对象不再只有一面,我们可以通过使用不同类型的引用来让对象“伪装”成不同的类型。从上一节中的内容看,使用继承的基本功能其实很简单。但是对象的“变脸”并仅仅是我们上一节中学到的那些内容。继承给程序带来了另一个功能——覆盖(Override)。覆盖可以帮助我们解决更多的问题,提供更多的“最优解决方案”。它和继承一起,组成了“面向对象编程”的重要武器。本节中我们将学习关于覆盖的内容。10.3.1当方法不再通用经过了上次的大变动,我们将继承引入了汽车类中,问题似乎被完美的解决了。这时候,系统又需要做出升级,要给跑车类增加一个功能:对于跑车的加速方法,可以设定在加速的时候就使用指定数量的氮气,以缩短加速所需时间。如何解决这个问题呢?1分析可能的解决方案2问题变得更突出了10.3.2覆盖——让众口不再难调本小节中我们将首先使用“覆盖”来实现上一小节中的(3)号解决方案。然后学习“覆盖(Override)”的概念。在这里,覆盖其实并没有牵扯到我们没有学过的语法知识。我们只需要“在SportsCar类中把新的speedUp方法写出来”就可以了。为了在一个新的包中创建本节中的代码,我们首先创建一个叫做“com.javaeasy.override”的包。然后在包中创建一个和之前的CarBase类代码相同的类(当然Package语句是不同的)。覆盖的意思就是子类的方法“遮盖”住了父类的方法。当子类的方法覆盖了父类的方法后,父类的方法将被屏蔽。覆盖的含义是:特殊情况,特殊处理。10.3.3覆盖——到底调用了哪个方法?必须找到符合方法签名的方法,这个和方法名、方法形参和方法实参之间的类型匹配等都有关系,这个详细的过程我们在学习方法的时候已经讲述过,这里不再赘述。Java平台会首先根据在对象的实际所属的类中寻找符合方法签名的方法,如果找不到,则去它的父类中寻找符合方法签名的方法,如果再找不到,则去它父类的父类中寻找符合方法签名的方法,一直到找到为止。找到后,就执行找到的方法。10.3.4覆盖的语法不简单对于覆盖,有下面的几点语法规则要注意。首先,子类必须把这个方法从父类中继承过来。子类中的一个方法的签名与继承自父类中的某个方法的签名相同时,则Java语法要求:子类中的这个方法的访问控制符赋予方法的访问权限必须与父类中那个方法的访问权限相同或者更宽松。子类中的一个方法的签名与继承自父类中的某个方法的签名相同时,则Java语法要求:子类中方法的返回值类型必须能够赋值给父类方法的返回值类型。在父类中,使用public修饰符修饰可能被子类覆盖的方法。在子类中,使用与父类完全相同的方法签名、访问控制符和返回值类型。10.3.5更复杂的使用覆盖的情况现在,从代码到语法,我们已经充分理解了(3)号解决方案。紧接着,系统又需要升级了:系统要求所有的汽车类都要增加一个同步汽车速度的方法,方法的的逻辑是:如果汽车比另一辆汽车速度快,则调用汽车的减速方法,让汽车与另一辆汽车速度相同;如果汽车比另一辆汽车速度慢,则调用汽车的加速方法,让汽车与另一辆汽车速度相同。1覆盖引出的疑问2理解覆盖——它并非如此简单重载的方法必须在运行的时候才能知道具体会执行哪个类的哪个方法10.3.6覆盖——不得不打开的潘多拉魔盒根据我们上一节中学习的知识可以看到,覆盖给类带来了很大的灵活性。但是这种灵活性有时候也会造成问题。1覆盖可能带来的错误2程序执行的过程当子类的方法覆盖父类的方法时,在完成子类特殊的功能之外,我们还应该保证子类中的方法完成了父类中方法应该完成的功能。10.3.7使用super调用父类中的方法和属性本章的内容让我们学习的并不轻松。在本节的最后,我们来学习一个相对轻松点的语法——如何使用super关键字调用父类中的方法。在前面我们学习了如何使用super关键字在子类的构造方法中调用父类的构造方法。其实我们还可以使用super关键字在子类中调用父类的方法和属性。我们学习过使用this关键字调用本类中的方法和属性,只要将this换成super,就是调用父类中的方法和属性了,这个语法格式如下。super+.+父类中的方法或属性使用super关键字操作父类的属性和方法10.4多态(Polymorphism)以及其它什么是多态呢?Java中的“多态”来自于英语单词“Polymorphism”。这个单词原本的意思是“多形性,同质异像”。但从字面上理解不是很容易。其实我们在不知不觉中已经学习了多态的内容了。本节中我们将正式引入多态的概念,并学习使用多态。同时,本节中还会讲解重载给程序带来的多态性。10.4.1多态——运行方知结果多态的本质是:同一个东西在不同的环境下有不同表现。我们前面一节中学习的覆盖其实就是多态的一种形式,它让程序只有程序在执行的时候才能够断定调用哪个方法。多态还有一种形式,就是重载,当我们通过不同的实参调用方法名相同的函数时,执行的方法会有不同。理解多态的本质。10.4.2重载也不简单我们来温习一下重载的定义:当同一个类中的出现方法名相同而方法签名不同的多个方法时,这个方法就称作重载的方法。如果一个重载的方法的形式参数有继承关系,那么具体会调用哪个方法是与形参的内容有关的。当继承被引入到重载的参数中时,决定函数重载的哪个方法被调用的是实参。这里的实参指的是引用的类型,而不是引用指向对象的类型。10.4.3使用多态构建车队现在,系统又要升级了,需要我们提供一个车队类。车队类中包含一个领队车和一组随从车,车队类中应该让所有的随从车与领队车保持相同的速度。车队的构造方法不允许为空,它需要一个领队车和随从车队(数组表示)的引用。根据本节中的例子理解继承和多态。10.5在多态的环境中拨开迷雾先我们学习了继承和多态。对待纷杂的面向对象的世界,有些不知所措了:我们不知道一个引用到底指向那个类的对象。而多态和继承的特性决定了程序的执行流程需要在执行的时候才能够确定下来。本节中我们将学习如何在多态的环境中拨开这重重迷雾。10.5.1神秘的Class类Java中有一个非常神秘的类——java.lang.Class。Class类的功能十分强大,它包含的一个类所有的信息:类名、属性、方法和父类等等。Class类的另一点特殊之处就是我们无法通过常见的new关键字来创建出Class类的一个对象。不过实际上我们也无需这么做,Java平台已经为每一个类都创建了一个Class类的对象。如何得到这个Class类的对象呢?Object类中提供了
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年上半年宁波前湾控股集团人员招聘24人易考易错模拟试题(共500题)试卷后附参考答案
- 2025上海兽鸟智能科技有限公司招聘2人笔试参考题库附带答案详解
- 2024陕西延长石油物流集团有限公司社会招聘笔试参考题库附带答案详解
- 2024贵州毕节市农投菌业科技有限责任公司面向社会招聘笔试笔试参考题库附带答案详解
- 2024年高温合金粉末项目项目投资申请报告代可行性研究报告
- 2024年实木类家具项目资金申请报告代可行性研究报告
- 名师讲坛2025版高考数学二轮复习专题一三角函数和平面向量微切口8极化恒等式练习无答案
- 2025年半杯文胸项目可行性研究报告
- 2025年钟表与计时仪器项目发展计划
- 加盟京东商城合同范本
- GB/T 6822-2024船体防污防锈漆体系
- 高三地理一轮复习+课件+第三部分+4.4国际合作
- 10.1溶液的酸碱性教学设计-2024-2025学年九年级化学人教版下册
- 消防安全隐患台账表
- 2024解析:第九章液体压强-讲核心(原卷版)
- 2024解析:第二十章电与磁-基础练(解析版)
- 《个体防护装备安全管理规范AQ 6111-2023》知识培训
- 重症患者的康复治疗
- 低空经济产业示范区建设实施路径
- 常见隔离手术
- 第47届世界技能大赛江苏省选拔赛网络安全项目技术工作文件
评论
0/150
提交评论