任务九子承父业(继承和多态的使用).ppt

上传人:sh****n 文档编号:12763929 上传时间:2020-05-23 格式:PPT 页数:36 大小:978.50KB
返回 下载 相关 举报
任务九子承父业(继承和多态的使用).ppt_第1页
第1页 / 共36页
任务九子承父业(继承和多态的使用).ppt_第2页
第2页 / 共36页
任务九子承父业(继承和多态的使用).ppt_第3页
第3页 / 共36页
点击查看更多>>
资源描述
阜阳师范学院计算机与信息学院,Java程序设计,主讲教师:曹红兵,236,目录,任务一搭建环境(构建Java集成开发环境),任务二Java欢迎你(开发简单Java应用程序,任务三小试牛刀(学习Java语言基础),任务四挑战选择(使用分支控制流程),任务五游戏人生(使用循环控制流程),任务六回归自然(创建、使用类和对象),任务七3G时代的消息传递(定义和使用类方法),任务八保护你的隐私(封装的使用),任务九子承父业(继承和多态的使用),任务十上帝万能之手(接口的使用),336,任务十一用数组存储信息(使用数组),任务十二使用字符串进行交流(使用字符串),任务十三防患于未然(捕获并处理异常),任务十四主动出击(抛出异常),任务十五认识JavaApplet(Applet入门),任务十六丰富多彩的Applet(在Applet中播放声音和显示图像),任务十七进入Windows世界(设计图形用户界面),任务十八布局规划(使用布局管理器),任务十九事件委托处理(如何处理事件),任务二十选择之道(使用选择控件和选择事件),目录,436,任务二十一简明清晰的菜单(使用菜单和其他常用事件),任务二十二访问数据(使用JDBC连接数据库),任务二十三访问数据升级(数据库编程),任务二十四文件管理(目录与文件管理),任务二十五顺序进出之道(文件的顺序访问),任务二十六随机进出之道(文件的随机访问),任务二十七JAVA的分身术(创建和启动线程),任务二十八线程的生命周期与优先级(线程的状态与调度),任务二十九基于连接的通信(Java中的套接字Socket),任务三十基于无连接的通信(Java中的数据报编程),目录,536,任务九子承父业(继承和多态的使用),2,1,知识目标,能力目标,继承的概念;继承关键字;父类与子类之间的关系,super关键字。多态的概念;静态多态,动态多态;多态的实现。最终类和抽象类。,掌握继承的实现;掌握super关键字;掌握多态的实现。,636,内容提要,4,跟我做:汽车的分类关系,1,2,3,5,实现方案,代码分析,必备知识,动手做一做,736,9.1跟我做:汽车的分类关系,任务情景汽车是一般的交通工具,具有车类型、品牌、引擎数量、外观颜色等属性,能够发动、加速、刹车、停车等功能。汽车又可分为公共汽车、出租车、卡车等。公共汽车具有自己的第几路编号、最大载客数量属性,能够报站。出租车具有所属公司、最大载客数量属性,能够给乘客打发票。卡车具有最大载重量属性,能够卸货。请编写Vehicle汽车类、Bus公共汽车类。Taxi类和Truck类待学完本任务后自行完成。运行结果,第1章目录,836,问题分析回忆任务六中定义类的三个步骤,先定义类名,再编写类的属性,最后编写类的方法。本任务采用这三个步骤,编写好代码后,我们很快就会发现,Vehicle汽车类和Bus公共汽车类出现了许多相同的语句代码。在属性方面,都包含了车类型、品牌、引擎数量、外观颜色重复的信息定义,在功能上都有发动、加速、刹车、停车等重复的行为定义。汽车、公共汽车的成员变量和成员方法对照请见图9-2。现在,我们换个思路考虑。汽车是一般性的概念,它包含的成员变量和成员方法,在公共汽车、出租车、卡车中也具有,因为公共汽车是一种汽车,出租车、卡车也是一种汽车,只不过公共汽车、出租车、卡车是一种更具体的汽车,除了汽车的公共特性外,还有自己的特有性质。经过分析,采取如下措施,在定义类时,将公共汽车类、出租车类、卡车类中相同的属性和方法抽象出来,集中放在汽车类中,形成一种共享的机制,公共汽车类、出租车类、卡车类中只放自己特有的成员变量和成员方法,减少重复代码。这样的汽车类称为父类,公共汽车类、出租车类、卡车类称为子类。子类继承父类的非私有成员变量和成员方法。,第1章目录,9.2实现方案,936,解决步骤1.打开Eclipse,在study项目中创建包com.task09,再确定类名Vehicle,得到类的框架。packagecom.task09;publicclassVehicle2.然后,进行类的属性描述,只输入抽象出来的共有的成员变量Stringtype;Stringbrand;intengineNum;Stringcolor;3.接着,定义类的构造方法:publicVehicle()publicVehicle(Stringtype,Stringbrand,intengineNum,Stringcolor)4.再定义抽象出来的共有的方法:/发动、加速、刹车、停车publicvoidstart()publicvoidaccelerate()publicvoidbrake()publicvoidstop(),9.2实现方案,1036,5.定义Bus类。Bus类作为更具体的子类,只定义自己特有的性质。父类Vehicle类已有的成员变量和成员方法不再定义。publicclassBusextendsVehicle/加上extends关键字和父类名Vehicle/公共汽车具有自己的最大载客数量、第几路编号属性intmaxLoad;/特有的成员变量StringbusNo;/*构造方法*/publicBus()publicBus(intmaxLoad,StringbusNo)/报站publicvoidannounceBusStop()/特有的成员方法6.定义VehicleTest测试类,运行程序。对Vehicle类、Bus类的继承关系进行测试,Bus类能否访问父类的成员变量,能否调用父类的成员方法。Busbus=newBus(子类公共汽车,女神,2,白色,50,9路);bus.start();/调用父类的成员方法bus.announceBusStop();/公共汽车报站,9.2实现方案,1136,程序代码,第1章目录,9.3代码分析,1236,9.3代码分析,应用扩展Bus类继承了Vehicle类后,在发动、加速、刹车、停车功能上加上自己的特性,就要重写这四个方法。重写形成了多态。Bus类升级新增方法如下:/发动、加速、刹车、停车publicvoidstart()System.out.println(type+busNo+brand+engineNum+引擎+color+汽车发动);publicvoidaccelerate()System.out.println(type+busNo+brand+engineNum+引擎+color+汽车加速);publicvoidbrake()System.out.println(type+busNo+brand+engineNum+引擎+color+汽车刹车);publicvoidstop()System.out.println(type+busNo+brand+engineNum+引擎+color+汽车停车);,第1章目录,1336,9.4必备知识,9.4.1类的继承1.继承的概念由一个已有类定义一个新类,称为新类继承了已有类。已有类称为父类,新类称为子类。例如,汽车类是父类,公共汽车类、出租车类、卡车类是子类。通过子类继承父类,子类具有父类的一般特性,包括非私有的属性和行为。子类还可以增加自身特性,定义新的属性和行为,甚至可以重新定义父类中的属性和方法,扩展类的功能。例如,汽车类具有车类型、品牌、引擎数量、外观颜色,能够发动、加速、刹车、停车等一般特性。作为子类的公共汽车类、出租车类、卡车类继承了父类的这些特性,另外,新增了自己的特性,公共汽车具有自己的第几路编号、最大载客数量属性,能够报站。出租车具有所属公司、最大载客数量属性,能够给乘客打发票。卡车具有最大载重量属性,能够卸货。公共汽车类还重新定义了父类的发动、汽车公共汽车出租车卡车加速、刹车、停车功能。,第1章目录,图9-2汽车又可分为公共汽车、出租车、卡车,1436,怎样判断类与类之间具有继承关系呢?汽车具有一般特性,公共汽车、出租车、卡车是一种汽车,具有更具体的特性,符合is-a关系。根据这种原则,确定汽车是父类,公共汽车、出租车、卡车是子类。父类更通用、子类更具体。再看一看人、消费者和经销商关系。人具有姓名、年龄属性,能够说话。消费者、经销商是一种人,具有姓名、年龄属性,能够说话。消费者还能够购物、付费,经销商能够进货、收费,具有更具体的特性。符合is-a关系。所以,人是父类,消费者和经销商是子类。,第1章目录,9.4必备知识,1536,2.继承的意义在定义汽车类、公共汽车类、出租车类、卡车类时,通过分析了解到,汽车类和其他车类之间的重复代码太多,具有许多相同的成员变量和成员方法,既增加了程序员的工作量,降低编程效率,也违背了Java语言的“writeonce,onlyonce”的原则。如果把所有子类中相同的代码都抽取到父类中,建立继承关系,让子类自动继承父类的属性和方法,那么子类中就省去重复代码。例如,在汽车类、公共汽车类、出租车类、卡车类建立了继承关系后,公共汽车类、出租车类、卡车类中相同的代码,包括成员变量定义和方法的定义,抽取到汽车类中,子类中不再进行重复定义,程序的有效实现代码得到复用。因此,使用继承提高代码的复用性。,9.4必备知识,1636,3.继承的实现继承的实现分两个步骤:定义父类父类可以是系统类,也可以是自定义类。如果是系统类,该步骤可以省略。在父类中只定义一些通用的属性与方法,例如:Vehicle汽车类只定义了车类型、品牌、引擎数量、外观颜色属性,以及发动、加速、刹车、停车行为。Stringtype;/车类型、品牌、引擎数量、外观颜色属性Stringbrand;intengineNum;Stringcolor;publicvoidstart()/发动、加速、刹车、停车行为publicvoidaccelerate()publicvoidbrake()publicvoidstop(),9.4必备知识,1736,定义子类子类定义格式:类修饰符class子类名extends父类名extends关键字表示一个类继承了另一个类。例如,Bus公共汽车类继承Vehicle汽车类。publicclassBusextendsVehicle/父类名只能有一个然后,定义子类特有的成员变量和成员方法。例如,Bus公共汽车类作为子类,新增了自己的特性。intmaxLoad;/子类特有的属性StringbusNo;publicvoidannounceBusStop()/报站,子类特有的方法System.out.println(busNo+公共汽车报站);注意:一个子类只能继承一个父类,即单继承。但一个父类可以有多个子类。,9.4必备知识,1836,改错:下面继承定义有哪些错误?/*人(Person)具有姓名(name)、年龄属性(age),能够说话(talk)。*消费者(Customer)具有姓名(name)、年龄属性(age),能够说话(talk),还能够购物(shop)。*/publicclassPersonStringname;intage;publicvoidtalk()System.out.println(name+说话);publicclasspersonextendsCustomer,ShopStringname;publicvoidtalk()System.out.println(name+说话);privatevoidshop()System.out.println(name+购物);提示:有5个错误。,9.4必备知识,1936,4.子类与父类的关系定义子类之后,父类与子类之间就产生了一些特殊的关系,在代码编写上会受到影响,程序员必须清楚。子类自动继承父类的属性和方法,但不能继承访问权限为private的成员变量和成员方法。例如:父类Vehicle中有一私有成员变量和一私有成员方法:privateStringcolor;/父类中私有成员变量privatevoidstart()/父类中私有成员方法子类Bus中,按如下方式对父类成员变量和成员方法进行访问,将会出错。color=银灰色;/子类中访问父类中私有成员变量,出错start();/子类中调用父类中私有成员方法,出错当我们将父类Vehicle中private改为缺省时,子类Bus中访问顺利完成。Stringcolor;/父类中private改为缺省voidstart()/父类中private改为缺省子类中可以定义特定的属性和方法。例如,在子类Bus中,增加售票员(conductor)属性,和开门open()方法:Stringconductor;voidopen(),9.4必备知识,2036,子类中方法重写。所谓方法重写就是子类定义的方法和父类的方法具有相同的名称、参数列表、返回类型和访问修饰符。例如,父类Vehicle中有如下方法:publicvoidaccelerate()System.out.println(type+brand+engineNum+引擎+color+汽车加速);在子类Bus中,新增自己的加速accelerate()方法,这就是方法重写。publicvoidaccelerate()/方法重写super.accelerate();System.out.println(这是子类Bus中的重写方法);方法重写会隐藏父类的同名方法。也就是说,在子类Bus中,如果调用accelerate()方法,将不再是调用父类的accelerate()方法,而是子类Bus中的方法。子类的属性与父类的属性相同时,也会出现隐藏的现象。,9.4必备知识,2136,super关键字与this关键字出现隐藏现象后,如果需要使用父类的成员属性和成员方法,可以通过使用super关键字。例如,在子类Bus中,调用父类的accelerate()方法:super.accelerate();/super指当前对象的父对象如果用this关键字,则表示调用当前对象的accelerate()方法:this.accelerate();/this指当前对象通过使用super关键字与this关键字,可以很显式地区分开调用的是当前对象的成员,还是父对象的成员。另外,当方法体中定义的变量,或方法的形式参数与对象的成员变量名相同,也必须用this关键字指明当前对象的成员变量。,9.4必备知识,2236,子类的构造方法子类不能继承父类的构造方法,因为父类的构造方法用来创建父类对象,子类需定义自己的构造方法,创建子类对象。子类的构造方法中,通过super关键字调用父类的构造方法。例如,在子类Bus的构造方法中,用如下语句实现了对父类构造方法的调用:super();/调用父类的无参构造方法super(type,brand,engineNum,color);/调用父类的带参构造方法注意:super(参数);必须是子类构造方法的第一条语句。如果该语句省略,则会自动调用父类无参构造方法。因为子类创建对象时,先创建父类对象,再创建子类对象。如果需要调用当前类中的构造方法,用this关键字。例如,在子类Bus的构造方法中,用如下语句实现了对当前类中的构造方法的调用:this(40,“8路”);/调用当前类中的带参构造方法,9.4必备知识,2336,5.根类Object在Java中,所有的类都是通过直接或间接地继承java.lang.Object类得到的,Object类是一切类的祖先,称为根类。当定义类,而没有使用extends关键字时,表示所定义类的父类为Object类,这是Java中的一种特别约定。根类Object类的方法如clone()、equals(obj)、finalize()、getClass()、hashCode()、notify()、notifyAll()、toString()、wait()等,子类都可以通过继承,进行调用。关于toString()方法,在任务六的类的定义中,通过重写,已经多次使用了该方法。,9.4必备知识,2436,9.4.2类的多态1.多态的概念多态是指一个方法声明的多种实现状态,即在程序中同名的不同方法共存,调用者只需要使用同一个方法名,系统会根据不同情况,调用相应的方法,从而实现不同的功能。简而言之,多态性即“一个名字,多个方法”。例如,父类Vehicle中有如下方法:publicvoidaccelerate()在子类Bus中,也有accelerate()方法:publicvoidaccelerate()/方法重写在程序中同名的不同方法共存,形成了多态。2.多态的意义在面向对象程序设计中,多态是具有表现多种形态的能力的特征,有时需要利用方法的重名,提高程序的抽象度和简洁性,以及程序的可扩展性及可维护性。例如使用多态之后,当需要增加新的子类PoliceCar警车类时,无需更改父类Vehicle,代码得到了扩展,维护起来也方便。,9.4必备知识,2536,3.多态的分类多态分为静态多态和动态多态。静态多态指通过同一个类中的方法重载实现的多态,动态多态指通过类与类之间的方法重写实现的多态。方法重载参见8.4.4。方法重写参见本任务9.4.1类的继承4.子类与父类的关系子类中方法重写部分。静态多态是编译时多态,指程序会根据参数的不同来调用相应的方法,具体调用哪个被重载的方法,由编译器在编译阶段静态决定。动态多态是运行时多态,指在运行时根据调用该方法的实例的类型来决定调用哪个重写方法。静态多态对程序运行更有效率,动态多态更具有灵活性。4.多态的实现多态通过给同一个方法定义几个版本来实现的。例如,现有三个类,Grandfather类是Father类的父类,Father类是Child类的父类。三个类的代码如下:,9.4必备知识,2636,packagecom.task09;/*Grandfather.java*多态,本类作为Father的父类*/publicclassGrandfatherinti;intj;/*parami*paramj*/publicGrandfather(inti,intj)this.i=i;this.j=j;intsmoke()System.out.println(Grandfather的方法smoke():);returni+j;,9.4必备知识,2736,packagecom.task09;/*Father.java*多态,本类作为Grandfather的子类,本类作为Child的父类*/publicclassFatherextendsGrandfather/*parami*paramj*/publicFather(inti,intj)super(i,j);intdrink()System.out.println(Father的方法drink():);return0;,9.4必备知识,2836,packagecom.task09;/*Child.java*多态,本类作为Father的子类*/publicclassChildextendsFather/*parami*paramj*/publicChild(inti,intj)/子类的构造方法super(i,j);/调用父类的构造方法intdrink()/重写了父类的方法System.out.println(Child重写的方法drink():);returni*j;packagecom.task09;publicclassGrandfatherTest/*paramargs*/publicstaticvoidmain(Stringargs)/创建子类的对象,赋给父类对象变量fatherFatherfather=newChild(3,4);/调用子类Child重写的drink()方法System.out.println(father.getClass()+喝水杯数+father.drink();/调用父类Grandfather的smoke()方法(子类未重写)System.out.println(father.getClass()+抽烟支数+father.smoke();,9.4必备知识,2936,多态程序运行结果见图9-3。在GrandfatherTest测试类中,首先声明Father类型的变量father,然后建立Father类的子类Child类的一个实例,并把引用存储到father中。Java运行时,系统分析该引用是Child类型的一个实例,因此调用子类Child重写的drink()方法。因为方法smoke()未被子类Child重写,所以运行时系统调用继承的父类Father的父类Grandfather的smoke()方法。注意:因为子类通过继承具备了父类的所有属性(私有属性除外),所以,凡是要求使用父类对象的地方,都可以用子类对象来代替。对子类的一个实例,运行时系统到底调用哪一个方法呢?如果子类重写了父类的方法,则调用子类的方法;如果子类未重写父类的方法,则调用父类的方法。因此,父类对象可以通过引用子类的实例调用子类的方法。,9.4必备知识,3036,改错:下面关于多态定义有哪些错误?父类Grandfather中有如下方法:intsmoke()System.out.println(Grandfather的方法smoke():);returni+j;子类Father中定义了方法:intsmoke(inti)System.out.println(Father的方法smoke():);returni+j;提示:有1个错误。,9.4必备知识,3136,9.4.3最终类和抽象类1.最终类当一个类的定义使用了final关键字时,该类称为最终类。最终类不能有子类,也就是不能被继承。一般,用来完成某种标准功能的类,例如,系统类String、Byte和Double,或定义已经很完美,不需要生成子类的类,通常定义为最终类。最终类的声明格式:finalclass类名2.抽象类当一个类的定义使用了abstract关键字时,该类称为抽象类。抽象类是供子类继承却不能创建实例的类。抽象类中可以声明只有方法头没有方法体的抽象方法,方法体由子类实现。抽象类提供了方法声明与方法实现分离的机制,使各子类表现出共同的行为模式。抽象方法在不同的子类中表现出多态性。抽象类的声明格式:publicabstractclass类名,9.4必备知识,3236,在面向对象程序设计时,抽象类一般用于现实世界抽象的概念,例如,食物,水果、交通工具等,我们看不到他们的实例,只能看到他们子类,例如米饭、苹果、飞机等子类的实例。Java中的java.lang.Number类是抽象类,没有实例,它是integer和float具体数字类型的抽象父类。例如,有计算机类Computer和笔记本电脑类Notebook两个类。Computer为抽象类,Notebook为其实现子类。代码如下:,9.4必备知识,3336,packagecom.task09;/*Computer.java*抽象类,本类作为Notebook的父类*/publicabstractclassComputer/抽象类的定义要有abstract关键字Stringbrand;/成员变量abstractvoidshowBrand();/抽象方法,没有方法体packagecom.task09;/*Notebook.java*实现类,本类作为Computer的实现子类*/publicclassNotebookextendsComputerOverridevoidshowBrand()/实现抽象方法brand=Dell;System.out.println(品牌:+brand);,9.4必备知识,3436,/*paramargs*/publicstaticvoidmain(Stringargs)Computercomputer=newNotebook();/子类的对象赋给抽象类的变量computer.showBrand();,9.4必备知识,3536,改错:下面关于抽象类有哪些错误?publicabstractclassFoodprivateintstatus=0;intgetStatus()returnstatus;classEggextendsFoodpublicclassFoodTest()publicstaticvoidmain(Stringargs)Foodfood=newFood();food.getStatus();提示:有1个错误。牢记抽象类、抽象方法的定义和使用要求。,9.4必备知识,3636,9.5动手做一做,一、实训目的掌握继承的概念和实现;掌握多态的概念和实现。二、实训内容编写动物世界的继承关系代码。动物(Animal)包括山羊(Goat)和狼(Wolf),他们吃(eat)的行为不同,山羊吃草,狼吃肉,但走路(walk)的行为是一致的。通过继承实现以上需求,并编写AnimalTest测试类进行测试。三、简要提示山羊类和狼类具有共同的吃、走路行为,应该抽象出来,放在动物类中。但山羊吃草,狼吃肉,具体吃的行为各不相同,所以,在山羊类和狼类中要重写吃行为。四、程序代码参见本教材教学资源。五、实训思考1.继承如何实现?2.方法重写如何实现?3.理解测试类中的调用方法过程。,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!