第5章java接口与多态课件

PPT
  • 阅读 76 次
  • 下载 0 次
  • 页数 89 页
  • 大小 513.500 KB
  • 2022-11-12 上传
  • 收藏
  • 违规举报
  • © 版权认领
下载文档30.00 元 加入VIP免费下载
此文档由【小橙橙】提供上传,收益归文档提供者,本网站只提供存储服务。若此文档侵犯了您的版权,欢迎进行违规举报版权认领
第5章java接口与多态课件
可在后台配置第一页与第二页中间广告代码
第5章java接口与多态课件
可在后台配置第二页与第三页中间广告代码
第5章java接口与多态课件
可在后台配置第三页与第四页中间广告代码
第5章java接口与多态课件
第5章java接口与多态课件
还剩10页未读,继续阅读
【这是免费文档,您可以免费阅读】
/ 89
  • 收藏
  • 违规举报
  • © 版权认领
下载文档30.00 元 加入VIP免费下载
文本内容

【文档说明】第5章java接口与多态课件.ppt,共(89)页,513.500 KB,由小橙橙上传

转载请保留链接:https://www.ichengzhen.cn/view-3319.html

以下为本文档部分文字说明:

JAVA语言程序设计1第5章接口与多态❖5.1接口❖5.2塑型❖5.3多态的概念❖5.4多态的应用❖5.5构造方法与多态❖5.6内部类❖5.7本章小结JAVA语言程序设计25.1接口❖接口◼与抽象类一样都是定义多个类的共同属性◼使抽象的概念更深

入了一层,是一个“纯”抽象类,它只提供一种形式,并不提供实现◼允许创建者规定方法的基本形式:方法名、参数列表以及返回类型,但不规定方法主体◼也可以包含基本数据类型的数据成员,但它们都默认为static和f

inalJAVA语言程序设计35.1.1接口的作用及语法❖接口的作用◼是面向对象的一个重要机制◼实现多继承,同时免除C++中的多继承那样的复杂性◼建立类和类之间的“协议”➢把类根据其实现的功能来分别代表,而不必顾虑它所在的类继承层

次;这样可以最大限度地利用动态绑定,隐藏实现细节➢实现不同类之间的常量共享JAVA语言程序设计4❖接口允许我们在看起来不相干的对象之间定义共同行为5.1.1接口的作用及语法——与抽象类的不同JAVA语言程序设计5❖保险公司的例子◼具有车辆保险、人员保险、公司保险等多种保险业务,在对外提供

服务方面具有相似性,如都需要计算保险费(premium)等,因此可声明一个Insurable接口◼在UML图中,实现接口用带有空三角形的虚线表示5.1.1接口的作用及语法——例5_1<<Interface>>InsurableCompanyPersonCar

JAVA语言程序设计6❖接口的语法◼声明格式为[接口修饰符]interface接口名称[extends父接口名]{…//方法的原型声明或静态常量}◼接口的数据成员一定要赋初值,且此值将不能再更改,允许省略final关键字◼接口中的方法必须是“抽象方法”,不能有方法体,允许省略public及abst

ract关键字5.1.1接口的作用及语法JAVA语言程序设计7❖例5.1中的Insurable接口声明如下,可见其中的方法都是抽象方法publicinterfaceInsurable{publicintgetNumber();publicintgetCove

rageAmount();publicdoublecalculatePremium();publicDategetExpiryDate();}5.1.1接口的作用及语法——例5_1保险接口的声明JAVA语言程序设

计8❖声明一个接口Shape2D,可利用它来实现二维的几何形状类Circle和Rectangle◼把计算面积的方法声明在接口里◼pi值是常量,把它声明在接口的数据成员里interfaceShape2D{//声明Shape2D接口fina

ldoublepi=3.14;//数据成员一定要初始化publicabstractdoublearea();//抽象方法}◼在接口的声明中,允许省略一些关键字,也可声明如下interfaceShape2D{doublepi=3.14;doublearea();}5.1.1接口的作

用及语法——例5_2JAVA语言程序设计95.1.2实现接口❖接口的实现◼接口不能用new运算符直接产生对象,必须利用其特性设计新的类,再用新类来创建对象◼利用接口设计类的过程,称为接口的实现,使用implements关键字◼语法如下publicclass类名称

implements接口名称{/*Bodiesfortheinterfacemethods*//*Owndataandmethods.*/}➢必须实现接口中的所有方法➢来自接口的方法必须声明成publicJAVA语言程序设计10❖实现接口Insur

able,声明汽车类实现例5.1中的Insurable接口,实现接口中的所有抽象方法publicclassCarimplementsInsurable{publicintgetPolicyNumber(){//writecodehere}publicdoublecalculate

Premium(){//writecodehere}publicDategetExpiryDate(){//writecodehere}publicintgetCoverageAmount(){//writecodehere}publici

ntgetMileage(){//新添加的方法//writecodehere}}5.1.2实现接口——例5_3JAVA语言程序设计11❖对象可以被转型为其所属类实现的接口类型◼getPolicyNumb

er、calculatePremium是Insurable接口中声明的方法◼getMileage是Car类新添加的方法,Insurable接口中没有声明此方法Carjetta=newCar();Insurableitem=(Insurabl

e)jetta;//对象转型为接口类型item.getPolicyNumber();item.calculatePremium();item.getMileage();//接口中没有声明此方法,不可以jetta.getMileage();//类中有此方法,可以((Car)item).ge

tMileage();//转型回原类,可调用此方法了5.1.2实现接口——对象转型JAVA语言程序设计125.1.2实现接口——例5_4classCircleimplementsShape2D{doubleradius;publicCircle(

doubler){radius=r;}publicdoublearea(){return(pi*radius*radius);}}classRectangleimplementsShape2D{intwidth,height;publicRectangle(i

ntw,inth){width=w;height=h;}publicdoublearea(){return(width*height);}}⚫声明Circle与Rectangle两个类实现Shape2D接口JAVA语言程序设计13❖测试类publicclassInterfaceTester{p

ublicstaticvoidmain(Stringargs[]){Rectanglerect=newRectangle(5,6);System.out.println("Areaofrect="+rect.area());Circlecir=newCircle(2.0);S

ystem.out.println("Areaofcir="+cir.area());}}❖运行结果Areaofrect=30.0Areaofcir=12.565.1.2实现接口——例5_4运行结果JAVA语言程序设计14❖声明

接口类型的变量,并用它来访问对象publicclassVariableTester{publicstaticvoidmain(String[]args){Shape2Dvar1,var2;var1=newRectangle(5,6);System.out.pr

intln("Areaofvar1="+var1.area());var2=newCircle(2.0);System.out.println("Areaofvar2="+var2.area());}}❖输出结果Areaofvar1=30.0Areaofvar2=12.56

5.1.2实现接口——例5_5JAVA语言程序设计15❖MovableObject接口定义了所有“可移动对象”能做的事情publicinterfaceMovableObject{publicbooleanstart();publicvoidstop();publicboolea

nturn(intdegrees);publicdoublefuelRemaining();publicvoidchangeSpeed(doublekmPerHour);}5.1.2实现接口—MovableObject接口JAVA语言程序设计16❖Plane、Car、Tr

ain、Boat分别实现MovableObject接口publicclassPlaneimplementsMovableObject{publicintseatCapacity;publicCompanyowner;publicDatelastRep

airDate;//实现MovalbelObject接口的所有方法publicbooleanstart(){//启动飞机,成功则返回true}publicvoidstop(){//停止}publicbooleanturn(intdegrees){//转向,成功则返回true}p

ublicdoublefuelRemaining(){//返回燃料剩余量}publicvoidchangeSpeed(doublekmPerHour){//改变速度}//plane类自己的方法:publicDategetLastRepairDate(){//...}public

doublecalculateWindResistance(){//....}}5.1.2实现接口——MovableObject接口的实现JAVA语言程序设计17❖为MovableObjects安装遥控器(remotecontrol)publicclassRemoteContr

ol{privateMovableObjectmachine;RemoteControl(MovableObjectm){machine=m;}//按下“启动”按钮:publicvoidstart(){

booleanokay=machine.start();if(!okay)display("NoResponseonstart");//...}}◼remotecontrol构造方法的形参类型为MovableObject,它可以是Plane,Car,Train,Boat,

等等5.1.2实现接口——RemoteControl类JAVA语言程序设计185.1.3多重继承❖多重继承◼Java的设计以简单实用为导向,不允许一个类有多个父类◼但允许一个类可以实现多个接口,通过这种机制可实现多重继承◼一个类实现多个接口的语法如下[类修饰符]class类名称implem

ents接口1,接口2,…{……}JAVA语言程序设计19❖Car类可以实现接口Insurable,Drivable,SellablepublicclassCarimplementsInsurable,Drivable,Sel

lable{....}5.1.3多重继承——Car的例子JAVA语言程序设计20❖声明Circle类实现接口Shape2D和Color◼Shape2D具有pi与area()方法,用来计算面积◼Color则具有setColor方法,可用来赋值颜色◼通过实现这两个接口,Circl

e类得以同时拥有这两个接口的成员,达到了多重继承的目的interfaceShape2D{//声明Shape2D接口finaldoublepi=3.14;//数据成员一定要初始化publicabstractdoublearea();//

抽象方法}interfaceColor{voidsetColor(Stringstr);//抽象方法}5.1.3多重继承——例5_6JAVA语言程序设计21classCircleimplementsShape2D,Color//实现Circle类{doubleradius;Strin

gcolor;publicCircle(doubler)//构造方法{radius=r;}publicdoublearea()//定义area()的处理方式{return(pi*radius*radius);}publicvoidsetColor(Stringstr)//定义

setColor()的处理方式{color=str;System.out.println("color="+color);}}5.1.3多重继承——例5_6JAVA语言程序设计22❖测试类publicclassMultiInterfaceTester{publi

cstaticvoidmain(Stringargs[]){Circlecir;cir=newCircle(2.0);cir.setColor("blue");System.out.println("A

rea="+cir.area());}}❖输出结果color=blueArea=12.565.1.3多重继承——例5_6运行结果JAVA语言程序设计235.1.4接口的扩展❖接口的扩展◼接口可通过扩展

的技术派生出新的接口➢原来的接口称为基本接口(baseinterface)或父接口(superinterface)➢派生出的接口称为派生接口(derivedinterface)或子接口(subinterface)◼派生接口不仅可以保有父接口的成员,同时也可加入新成员以满足

实际问题的需要◼实现接口的类也必须实现此接口的父接口◼接口扩展的语法interface子接口的名称extends父接口的名称1,父接口的名称2,…{……}JAVA语言程序设计24❖Shape是父接口,Shape2D与Shape3D是其子接口。Circle类及Rectangle类实现接口

Shape2D,而Box类及Sphere类实现接口Shape3D5.1.4接口的扩展——例5_7Shape接口Shape2D接口Shape3D接口Sphere类Box类Rectangle类Circle类JAVA语言程序设计25❖部分代码如下//声明Shape接口interfaceShape{do

ublepi=3.14;voidsetColor(Stringstr);}//声明Shape2D接口扩展了Shape接口interfaceShape2DextendsShape{doublearea();}5.1.4接口的扩展——例5

_7JAVA语言程序设计26classCircleimplementsShape2D{doubleradius;Stringcolor;publicCircle(doubler){radius=r;}publicdoublearea(){return(pi*radius*r

adius);}publicvoidsetColor(Stringstr){color=str;System.out.println("color="+color);}}publicclassExtendsInterfaceTester{//

测试类publicstaticvoidmain(String[]args){Circlecir;cir=newCircle(2.0);cir.setColor("blue");System.out.println("Area="+cir.area());}}5.

1.4接口的扩展——例5_7JAVA语言程序设计27❖运行结果color=blueArea=12.56❖说明◼首先声明了父接口Shape,然后声明其子接口Shape2D◼之后声明类Circle实现Shape2D子接口,因而在此类内必

须明确定义setColor()与area()方法的处理方式◼最后在主类中我们声明了Circle类型的变量cir并创建新的对象,最后通过cir对象调用setColor()与area()方法5.1.4接口的扩展——例5_7运行结果JAVA语言程序设计28❖FixedInsurable和D

epreciatingInsurable接口◼都继承了Insurable接口◼实现它们类也必须实现Insurable接口中的所有方法publicinterfaceDepreciatingInsurableextendsInsurable{publicdoublecomputeFairMar

ketValue();}publicinterfaceFixedInsurableextendsInsurable{publicintgetEvaluationPeriod();}5.1.4接口的扩展——Insurable接口的例子JAV

A语言程序设计295.2塑型❖塑型(type-casting)◼又称为类型转换◼方式➢隐式(自动)的类型转换➢显式(强制)的类型转换JAVA语言程序设计305.2.1塑型的概念❖塑型的对象包括◼基本数据类型➢将值从一种形式转换成另一种形式◼引用变量➢将对象暂时当成更一般的对

象来对待,并不改变其类型➢只能被塑型为任何一个父类类型对象所属的类实现的一个接口被塑型为父类或接口后,再被塑型回其本身所在的类JAVA语言程序设计31❖Manager对象◼可以被塑型为Employee、Person、Object或I

nsurable,◼不能被塑型为Customer、Company或CarObjectPersonEmployeeCustomerManagerCompanyCar<<Interface>>Insurable5.2.1塑型

的概念——一个例子JAVA语言程序设计32❖基本数据类型◼相容类型之间存储容量低的自动向存储容量高的类型转换❖引用变量◼被塑型成更一般的类Employeeemp;emp=newManager();//将Manager类型的对象直接赋

给//Employee类的引用变量,系统会//自动将Manage对象塑型为Employee类◼被塑型为对象所属类实现的接口类型Carjetta=newCar();Insurableitem=jetta;5.2.1塑型的概念——隐

式(自动)的类型转换JAVA语言程序设计335.2.1塑型的概念——显式(强制)的类型转换❖基本数据类型(int)871.34354;//结果为871(char)65;//结果为‘A’(long)453;//结果为453L❖引用变

量:还原为本来的类型Employeeemp;Managerman;emp=newManager();man=(Manager)emp;//将emp强制塑型为本来的类型JAVA语言程序设计345.2.2塑型的应用❖塑型应用

的场合包括◼赋值转换➢赋值号右边的表达式类型或对象转换为左边的类型◼方法调用转换➢实参的类型转换为形参的类型◼算数表达式转换➢算数混合运算时,不同类型的项转换为相同的类型再进行运算◼字符串转换➢字符串连接运算时,如

果一个操作数为字符串,一个操作数为数值型,则会自动将数值型转换为字符串JAVA语言程序设计35❖当一个类对象被塑型为其父类后,它提供的方法会减少◼当Manager对象被塑型为Employee之后,它只能接收getName()

及getEmployeeNumber()方法,不能接收getSalary()方法◼将其塑型为本来的类型后,又能接收getSalary()方法了5.2.2塑型的应用JAVA语言程序设计365.2.3方法的查找❖如

果在塑型前和塑型后的类中都提供了相同的方法,如果将此方法发送给塑型后的对象,那么系统将会调用哪一个类中的方法?◼实例方法的查找◼类方法的查找JAVA语言程序设计37❖从对象创建时的类开始,沿类层次向上查找Managerman=newMan

ager();Employeeemp1=newEmployee();Employeeemp2=(Employee)man;emp1.computePay();//调用Employee类中的computePay()方法man.computePay();/

/调用Manager类中的computePay()方法emp2.computePay();//调用Manager类中的computePay()方法5.2.3方法的查找——实例方法的查找JAVA语言程序设计38

❖总是在引用变量声明时所属的类中进行查找Managerman=newManager();Employeeemp1=newEmployee();Employeeemp2=(Employee)man;man.expenseAllowance(

);//inManageremp1.expenseAllowance();//inEmployeeemp2.expenseAllowance();//inEmployee!!!5.2.3方法的查找——类方法的查找JAVA语

言程序设计395.3多态的概念❖多态◼是指不同类型的对象可以响应相同的消息◼从相同的基类派生出来的多个类型可被当作同一种类型对待,可对这些不同的类型进行同样的处理,由于多态性,这些不同派生类对象响应同一方法时的行为是有所差别的

◼例如➢所有的Object类的对象都响应toString()方法➢所有的BankAccount类的对象都响应deposit()方法JAVA语言程序设计405.3.1多态的目的❖多态的目的◼所有的对象都可被塑型为相同的类型,响应相同的消息◼使代码变得简单且容易理解◼使程序具有很好的“扩展性”JA

VA语言程序设计41❖绘图——直接的方式◼希望能够画出任意子类型对象的形状,可以在Shape类中声明几个绘图方法,对不同的实际对象,采用不同的画法if(aShapeinstanceofCircle)aShape

.drawCircle();if(aShapeinstanceofTriangle)aShape.drawTriangle();if(aShapeinstanceofRectangle)aShape.drawRectangle();5.3.1多态的目的——一个例子JAVA语言程序设计42❖

绘图——更好的方式◼在每个子类中都声明同名的draw()方法◼以后绘图可如下进行Shapes=newCircle();s.draw();➢Circle属于Shape的一种,系统会执行自动塑型➢当调用方法draw时,实际调用的是Circle.draw()➢在程序运行时才进行绑定

,接下来介绍绑定的概念5.3.1多态的目的——一个例子JAVA语言程序设计435.3.2绑定的概念❖绑定◼指将一个方法调用同一个方法主体连接到一起◼根据绑定时期的不同,可分为➢早期绑定程序运行之前执行绑定➢晚期绑定也叫作“动态绑定”或“运行期绑定基于对

象的类别,在程序运行时执行绑定JAVA语言程序设计44❖仍以绘图为例,所有类都放在binding包中◼基类Shape建立了一个通用接口classShape{voiddraw(){}voiderase(){}}◼派生类覆盖了draw方法,为每种特殊的几何形状都提供独一无二的行为classCi

rcleextendsShape{voiddraw(){System.out.println("Circle.draw()");}voiderase(){System.out.println("Circle.eras

e()");}}5.3.2绑定的概念——例5_8JAVA语言程序设计45classSquareextendsShape{voiddraw(){System.out.println("Square.draw()");}voiderase(){System.out.pr

intln("Square.erase()");}}classTriangleextendsShape{voiddraw(){System.out.println("Triangle.draw()");}voiderase(){System.out.println("Triangl

e.erase()");}}5.3.2绑定的概念——例5_8JAVA语言程序设计46❖对动态绑定进行测试如下publicclassBindingTester{publicstaticvoidmain(String[]a

rgs){Shape[]s=newShape[9];intn;for(inti=0;i<s.length;i++){n=(int)(Math.random()*3);switch(n){case0:s[i]=newCircle();b

reak;case1:s[i]=newSquare();break;case2:s[i]=newTriangle();}}for(inti=0;i<s.length;i++)s[i].draw();}}5.3.2绑定的概念——例5_8JAVA语言程序设计47❖运行结果Square.draw()T

riangle.draw()Circle.draw()Triangle.draw()Triangle.draw()Circle.draw()Square.draw()Circle.draw()Triangle.draw()❖说明◼编译时无法知道s数组元素的具体类型,运行时才

能确定类型,所以是动态绑定◼在主方法的循环体中,每次随机生成指向一个Circle、Square或者Triangle的引用5.3.2绑定的概念—例5_8运行结果JAVA语言程序设计48❖所有类都在music包中

◼Note类中定义了三个音符◼Instrument类中声明并实现了一个play方法◼Wind类继承了Instrument类,重载了play方法◼Music类中包含了main方法classNote{privatein

tvalue;privateNote(intval){value=val;}publicstaticfinalNoteMIDDLE_C=newNote(0),C_SHARP=newNote(1),B_FLAT=newNote(2);}5.3.2绑定的概念——musi

c的例子JAVA语言程序设计49classInstrument{publicvoidplay(Noten){System.out.println("Instrument.play()");}}classWindextendsInstrument{publicvoidplay(Noten

){System.out.println("Wind.play()");}}5.3.2绑定的概念(续)——music的例子JAVA语言程序设计50publicclassMusic{publicstaticvoidtune(Instrumenti){i.play(Note.MIDDLE_C)

;}publicstaticvoidmain(String[]args){Windflute=newWind();tune(flute);}}❖运行结果Wind.play()❖说明◼运行中,Instrument类的对

象实际是Wind类的,所以调用了Wind类中的play方法5.3.2绑定的概念(续)——music运行结果JAVA语言程序设计515.4多态的应用❖多态的应用◼技术基础➢向上塑型技术:一个父类的引用变量可以指向不同的子类对象➢动态绑定技术:运行时根据父类引用变量所指对象的实际类型执行相应的子

类方法,从而实现多态性JAVA语言程序设计52❖声明一个抽象类Driver及两个子类FemaleDriver及MaleDriver❖在Diver类中声明了抽象方法drives,在两个子类中对这个方法进行了重写

publicabstractclassDriver{publicDriver(){}publicabstractvoiddrives();}5.4多态的应用(续)——例5_9JAVA语言程序设计53publicclassFemaleDriverextendsD

river{publicFemaleDriver(){}publicvoiddrives(){System.out.println("AFemaledriverdrivesavehicle.");}}publicclassMaleDriverextendsDriv

er{publicMaleDriver(){}publicvoiddrives(){System.out.println("Amaledriverdrivesavehicle.");}}5.4多态的应用(续)——例5_9JAVA语言程序设计

54publicclassTest1{staticpublicvoidmain(String[]args){Drivera=newFemaleDriver();Driverb=newMaleDriver();a.dri

ves();b.drives();}}❖运行结果AFemaledriverdrivesavehicle.Amaledriverdrivesavehicle.5.4多态的应用(续)——例5_9JAVA语言程序设计55❖所有类

都放在drive包中◼试想有不同种类的交通工具(vehicle),如公共汽车(bus)及小汽车(car),由此可以声明一个抽象类Vehicle及两个子类Bus及Car◼对前面的drives方法进行改进,使其接收一个Vehicle类的参数,当不同类型的交通工具被传送到此方法时,可以输出具

体的交通工具5.4多态的应用(续)——例5_9改进JAVA语言程序设计56❖测试代码可改写如下:publicclassDriverTest{staticpublicvoidmain(String[]args){Drivera=new

FemaleDriver();Driverb=newMaleDriver();Vehiclex=newCar();Vehicley=newBus();a.drives(x);b.drives(y);}}❖并希望输出下面的

结果AfemaledriverdrivesaCar.Amaledriverdrivesabus.5.4多态的应用(续)——例5_9改进JAVA语言程序设计57❖Vehicle及其子类声明如下publicabstractclassVehicle{privat

eStringtype;publicVehicle(){}publicVehicle(Strings){type=s;}publicabstractvoiddrivedByFemaleDriver();publicabstractvoidd

rivedByMaleDriver();}5.4多态的应用(续)——例5_9改进JAVA语言程序设计58publicclassBusextendsVehicle{publicBus(){}publicvoiddrivedByFemaleDriver(){System.out.pri

ntln("Afemaledriverdrivesabus.");}publicvoiddrivedByMaleDriver(){System.out.println("Amaledriverdrivesabus.");}}publiccla

ssCarextendsVehicle{publicCar(){}publicvoiddrivedByFemaleDriver(){System.out.println("AFemaledriverdrivesa

car.");}publicvoiddrivedByMaleDriver(){System.out.println("AMaledriverdrivesacar.");}}5.4多态的应用(续)——例5_9改进

JAVA语言程序设计59❖对FemaleDriver及MaleDriver类中的drives方法进行改进,在drives方法的定义体中不直接输出结果,而是调用Bus及Car类中的相应方法publicabstractclassDriver{publicDriver(){}publicabstract

voiddrives(Vehiclev);}publicclassFemaleDriverextendsDriver{publicFemaleDriver(){}publicvoiddrives(Vehiclev){v.drivedByFemaleDriver();}}pub

licclassMaleDriverextendsDriver{publicMaleDriver(){}publicvoiddrives(Vehiclev){v.drivedByMaleDriver();}}5.4多态的应用(续)——例5_9改进JAVA语言程序设计6

0❖运行结果AFemaledriverdrivesacar.Amaledriverdrivesabus.❖说明◼这种技术称为二次分发(“doubledispatching”),即对输出消息的请求被分发两次➢首先根据驾驶员的

类型被发送给一个类➢之后根据交通工具的类型被发送给另一个类5.4多态的应用(续)——例5_9改进运行结果JAVA语言程序设计615.5构造方法与多态❖构造方法与多态◼构造方法与其他方法是有区别的◼构造方法并不具有多态性,但仍然非常有必要理解构造方法如何在复杂的分级结构中随同多态性一同使

用的情况JAVA语言程序设计62❖构造方法的调用顺序◼调用基类的构造方法。这个步骤会不断重复下去,首先得到构建的是分级结构的根部,然后是下一个派生类,等等。直到抵达最深一层的派生类◼按声明顺序调用成员初始化模块

◼调用派生构造方法5.5.1构造方法的调用顺序JAVA语言程序设计63❖构建一个点类Point,一个球类Ball,一个运动的球类MovingBall继承自BallpublicclassPoint{privatedoublexCoordi

nate;privatedoubleyCoordinate;publicPoint(){}publicPoint(doublex,doubley){xCoordinate=x;yCoordinate=y;}publicStringtoString(){

return"("+Double.toString(xCoordinate)+","+Double.toString(yCoordinate)+")";}}5.5.1构造方法的调用顺序(续)——例5_10JAVA语言程序设计64publicclassBall{private

Pointcenter;//中心点privatedoubleradius;//半径privateStringcolour;//颜色publicBall(){}publicBall(doublexValue,doubleyValue,double

r){center=newPoint(xValue,yValue);//调用Point中的构造方法radius=r;}publicBall(doublexValue,doubleyValue,doubler,Stringc){this(xValue,yValue,r);//调用三个参数的

构造方法colour=c;}publicStringtoString(){return"Aballwithcenter"+center.toString()+",radius"+Double.toString(ra

dius)+",colour"+colour;}}5.5.1构造方法的调用顺序(续)——例5_10JAVA语言程序设计65publicclassMovingBallextendsBall{privatedoublespeed;publicMovingBall(){}publi

cMovingBall(doublexValue,doubleyValue,doubler,Stringc,doubles){super(xValue,yValue,r,c);speed=s;}publicStringtoString(){returnsuper.toSt

ring()+",speed"+Double.toString(speed);}}❖子类不能直接存取父类中声明的私有数据成员,super.toString调用父类Ball的toString方法输出类Ball中声明的属性值5.5.1构造方法的调用顺序(续)——例5_10

JAVA语言程序设计66publicclassTester{publicstaticvoidmain(Stringargs[]){MovingBallmb=newMovingBall(10,20,40,"green",25);System.ou

t.println(mb);}}❖运行结果Aballwithcenter(10.0,20.0),radius40.0,colourgreen,speed25.05.5.1构造方法的调用顺序(续)——例5_10运行结果JAVA语言程

序设计67❖上面的代码中,构造方法调用的顺序为MovingBall(doublexValue,doubleyValue,doubler,Stringc,doubles)Ball(doublexValue,doubleyValu

e,doubler,Stringc)Ball(doublexValue,doubleyValue,doubler)Point(doublex,doubley)5.5.1构造方法的调用顺序(续)——例5_10说明JAVA语言程序设计68❖构造方法的调用顺序举例2classMea

l{//饭类Meal(){System.out.println("Meal()");}}classBread{//面包类Bread(){System.out.println("Bread()");}}classCheese{//奶酪类Cheese(){System.o

ut.println("Cheese()");}}classLettuce{//莴苣类Lettuce(){System.out.println("Lettuce()");}}5.5.1构造方法的调用顺序(续)——例5_11JAVA语言程序设计69cla

ssLunchextendsMeal{//午餐类继承自饭类Lunch(){System.out.println("Lunch()");}}classPortableLunchextendsLunch{Portab

leLunch(){System.out.println("PortableLunch()");}}publicclassSandwichextendsPortableLunch{Breadb=newBread();Cheesec=newCheese();Lettucel=newLettuce(

);Sandwich(){System.out.println("Sandwich()");}publicstaticvoidmain(String[]args){newSandwich();}}5.5.1构造方法的调用顺序(续)——例5_11JAVA语言程序设计70❖输出结果Meal(

)Lunch()PortableLunch()Bread()Cheese()Lettuce()Sandwich()❖说明◼当我们在构造派生类的时候,必须能假定基类的所有成员都是有效的。在构造方法内部,必

须保证使用的所有成员都已初始化。因此唯一的办法就是首先调用基类构造方法,然后在进入派生类构造方法之前,初始化所有能够访问的成员5.5.1构造方法的调用顺序(续)——例5_11运行结果JAVA语言程序设计71❖构造方法中的多态方法◼在构造方法内调用准备构造的那个对象的动态绑定方

法➢会调用位于派生类里的一个方法➢被调用方法要操纵的成员可能尚未得到正确的初始化➢可能造成一些难于发现的程序错误5.5.2构造方法中的多态方法JAVA语言程序设计72❖在Glyph中声明一个抽象方法,并在构造方法内部调

用之abstractclassGlyph{abstractvoiddraw();Glyph(){System.out.println("Glyph()beforedraw()");draw();System.out.println("Glyph()aft

erdraw()");}}5.5.2构造方法中的多态方法(续)——例5_12JAVA语言程序设计73classRoundGlyphextendsGlyph{intradius=1;RoundGlyph(intr){radius=r;System.out.pri

ntln("RoundGlyph.RoundGlyph(),radius="+radius);}voiddraw(){System.out.println("RoundGlyph.draw(),radius="+radius);}}publicclassPol

yConstructors{publicstaticvoidmain(String[]args){newRoundGlyph(5);}}5.5.2构造方法中的多态方法(续)——例5_12JAVA语言程序设计74❖运行结果Glyph()beforedraw()RoundGlyph.draw

(),radius=0Glyph()afterdraw()RoundGlyph.RoundGlyph(),radius=5❖说明◼在Glyph中,draw()方法是抽象方法,在子类RoundGlyph中对此方法进行了覆

盖。Glyph的构造方法调用了这个方法◼从运行的结果可以看到:当Glyph的构造方法调用draw()时,radius的值甚至不是默认的初始值1,而是05.5.2构造方法中的多态方法(续)——例5_12运行结果JAVA语言程序设计75❖定义构造方法的注意事

项◼用尽可能少的动作把对象的状态设置好◼如果可以避免,不要调用任何方法◼在构造方法内唯一能够安全调用的是在基类中具有final属性的那些方法(也适用于private方法,它们自动具有final属性)。这些方法不能被覆盖,所以不会出现上述潜在

的问题5.5.2构造方法中的多态方法JAVA语言程序设计765.6内部类❖内部类◼在另一个类或方法的定义中定义的类◼可访问其外部类中的所有数据成员和方法成员◼可对逻辑上相互联系的类进行分组◼对于同一个包中的其他类来说,能够隐藏◼可非常方便地编写事件驱动程序◼声明方式➢命名的内部类:可在类的

内部多次使用➢匿名内部类:可在new关键字后声明内部类,并立即创建一个对象◼假设外层类名为Myclass,则该类的内部类名为➢Myclass$c1.class(c1为命名的内部类名)➢Myclass$1.class(表示类中声明的第一个匿名内部类)J

AVA语言程序设计77publicclassParcel1{classContents{//内部类privateinti=11;publicintvalue(){returni;}}classDestination{//内部类privateS

tringlabel;Destination(StringwhereTo){label=whereTo;}StringreadLabel(){returnlabel;}}publicvoidship(Stringdest){Contentsc=newCont

ents();Destinationd=newDestination(dest);System.out.println(d.readLabel());}5.6内部类——Parcel1.javaJAVA语言程序设计78publicstaticvoidmain(String[]args){Parce

l1p=newParcel1();p.ship("Tanzania");}}❖说明◼在Parcel1类中声明了两个内部类Contents、Destination◼在ship方法中生成两个内部类对象,并调用了内部类中声明的一个方法5.6内部类——Parcel1.j

avaJAVA语言程序设计79❖外部类的方法可以返回内部类的引用变量publicclassParcel2{classContents{privateinti=11;publicintvalue(){returni;}}classDestination{privateStr

inglabel;Destination(StringwhereTo){label=whereTo;}StringreadLabel(){returnlabel;}}publicDestinationto(Strings){returnnewDestination(s);}pu

blicContentscont(){returnnewContents();}5.6内部类——Parcel2.javaJAVA语言程序设计80publicvoidship(Stringdest){Contentsc=cont();Destinationd

=to(dest);System.out.println(d.readLabel());}publicstaticvoidmain(String[]args){Parcel2p=newParcel2();p.ship("Tanzania");Parcel2q=newParcel2

();Parcel2.Contentsc=q.cont();Parcel2.Destinationd=q.to("Borneo");}}❖说明◼to()方法返回内部类Destination的引用◼cont()方法返回内部类Contents的引用5.6内部类——Parcel2.javaJAVA语

言程序设计81❖内部类实现接口◼可以完全不被看到,而且不能被调用◼可以方便实现“隐藏实现细则”。你所能得到的仅仅是指向基类(baseclass)或者接口的一个引用❖例子abstractclassContents{abstr

actpublicintvalue();}interfaceDestination{StringreadLabel();}5.6内部类——内部类实现接口JAVA语言程序设计82publicclassParcel3{privateclassPContentsextendsContent

s{privateinti=11;publicintvalue(){returni;}}protectedclassPDestinationimplementsDestination{privateStringlabel;pri

vatePDestination(StringwhereTo){label=whereTo;}publicStringreadLabel(){returnlabel;}}publicDestinationdest(Strings){returnne

wPDestination(s);}publicContentscont(){returnnewPContents();}}5.6内部类——Parcel3.javaJAVA语言程序设计83classTest{publicst

aticvoidmain(String[]args){Parcel3p=newParcel3();Contentsc=p.cont();Destinationd=p.dest("Tanzania");}}❖说明◼内部类P

Contents实现了抽象了Contents◼内部类PDenstination实现了接口Destination◼外部类Test中不能声明对private的内部类的引用5.6内部类——Parcel3测试JAVA语言程序设计84❖在方法内定义一个内部类◼为实现某个接口,产生并返回一个引

用◼为解决一个复杂问题,需要建立一个类,而又不想它为外界所用5.6内部类——方法中的内部类JAVA语言程序设计85publicclassParcel4{publicDestinationdest(Strings){classPDestinatio

nimplementsDestination{privateStringlabel;privatePDestination(StringwhereTo){label=whereTo;}publicStringreadLabel(){returnlab

el;}returnnewPDestination(s);}publicstaticvoidmain(String[]args){Parcel4p=newParcel4();Destinationd=p.dest("Tanzania");}}5.6内部

类——Parcel4.javaJAVA语言程序设计86publicclassParcel5{privatevoidinternalTracking(booleanb){if(b){classTrackingSlip{privateStringid;TrackingSlip(Stri

ngs){id=s;}StringgetSlip(){returnid;}}TrackingSlipts=newTrackingSlip("slip");Strings=ts.getSlip();}}publicvoidtrack(){internalTracking(tr

ue);}publicstaticvoidmain(String[]args){Parcel5p=newParcel5();p.track();}}5.6内部类——作用域中的内部类JAVA语言程序设计87publicclassParcel6{p

ublicContentscont(){returnnewContents(){privateinti=11;publicintvalue(){returni;}};}publicstaticvoidmain(String[]args){

Parcel6p=newParcel6();Contentsc=p.cont();}}5.6内部类——匿名的内部类JAVA语言程序设计88❖基类需要一个含参数的构造方法publicclassParcel7{pub

licWrappingwrap(intx){returnnewWrapping(x){publicintvalue(){returnsuper.value()*47;}};}publicstaticvoidmain(String[]args){Parcel

7p=newParcel7();Wrappingw=p.wrap(10);}}5.6内部类——匿名的内部类5.6内部类——匿名的内部类匿名内部类对象的初始化publicclassParcel8{publicDestinationdest(finalStringdest){returnnew

Destination(){privateStringlabel=dest;publicStringreadLabel(){returnlabel;}};}publicstaticvoidmain(String[]args){Parcel8

p=newParcel8();Destinationd=p.dest("Tanzania");}}内部类

小橙橙
小橙橙
文档分享,欢迎浏览!
  • 文档 25747
  • 被下载 7
  • 被收藏 0
相关资源
广告代码123
若发现您的权益受到侵害,请立即联系客服,我们会尽快为您处理。侵权客服QQ:395972555 (支持时间:9:00-21:00) 公众号
Powered by 太赞文库
×
确认删除?