第5章java接口与多态课件

PPT
  • 阅读 67 次
  • 下载 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和finalJAVA语言程序设计35.1.1接口的作用及语法❖接口的作用◼是面向对象的一个重要机制◼实现多继承,同

时免除C++中的多继承那样的复杂性◼建立类和类之间的“协议”➢把类根据其实现的功能来分别代表,而不必顾虑它所在的类继承层次;这样可以最大限度地利用动态绑定,隐藏实现细节➢实现不同类之间的常量共享JAVA语言程序设计4❖接口允许我

们在看起来不相干的对象之间定义共同行为5.1.1接口的作用及语法——与抽象类的不同JAVA语言程序设计5❖保险公司的例子◼具有车辆保险、人员保险、公司保险等多种保险业务,在对外提供服务方面具有相似性,如都需要计算保险费(premium)等,因此可声明一个Insurable接

口◼在UML图中,实现接口用带有空三角形的虚线表示5.1.1接口的作用及语法——例5_1<<Interface>>InsurableCompanyPersonCarJAVA语言程序设计6❖接口的语法◼声明格式为[接口修饰符]inte

rface接口名称[extends父接口名]{…//方法的原型声明或静态常量}◼接口的数据成员一定要赋初值,且此值将不能再更改,允许省略final关键字◼接口中的方法必须是“抽象方法”,不能有方法体,允许省略p

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

{publicintgetNumber();publicintgetCoverageAmount();publicdoublecalculatePremium();publicDategetExpiryDate();}5.1.1接口的作用及语法——

例5_1保险接口的声明JAVA语言程序设计8❖声明一个接口Shape2D,可利用它来实现二维的几何形状类Circle和Rectangle◼把计算面积的方法声明在接口里◼pi值是常量,把它声明在接口的数据成员里interfaceShape2D{//声明Shape2D接口finaldoubl

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

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

icclass类名称implements接口名称{/*Bodiesfortheinterfacemethods*//*Owndataandmethods.*/}➢必须实现接口中的所有方法➢来自接口的方法必须声明成publicJAVA语言

程序设计10❖实现接口Insurable,声明汽车类实现例5.1中的Insurable接口,实现接口中的所有抽象方法publicclassCarimplementsInsurable{publicintgetPolicyNumber(){//w

ritecodehere}publicdoublecalculatePremium(){//writecodehere}publicDategetExpiryDate(){//writecodehere}publicintg

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

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

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

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

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

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

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

t.println("Areaofcir="+cir.area());}}❖运行结果Areaofrect=30.0Areaofcir=12.565.1.2实现接口——例5_4运行结果JAVA语言程序设计14❖声明接口类型的变量,并用它来访问对象publicclassVariableTeste

r{publicstaticvoidmain(String[]args){Shape2Dvar1,var2;var1=newRectangle(5,6);System.out.println("Areaofvar1="+va

r1.area());var2=newCircle(2.0);System.out.println("Areaofvar2="+var2.area());}}❖输出结果Areaofvar1=30.0Areaofvar2=12.565.1.2实现接口——例5_5JAVA语言程序设

计15❖MovableObject接口定义了所有“可移动对象”能做的事情publicinterfaceMovableObject{publicbooleanstart();publicvoidstop();publicbooleanturn(intdegrees);publicdou

blefuelRemaining();publicvoidchangeSpeed(doublekmPerHour);}5.1.2实现接口—MovableObject接口JAVA语言程序设计16❖Plane、Ca

r、Train、Boat分别实现MovableObject接口publicclassPlaneimplementsMovableObject{publicintseatCapacity;publicCompanyowner;publicDatelastRepairDate;

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

tdegrees){//转向,成功则返回true}publicdoublefuelRemaining(){//返回燃料剩余量}publicvoidchangeSpeed(doublekmPerHour){//改变速度}//plane类自己的方

法:publicDategetLastRepairDate(){//...}publicdoublecalculateWindResistance(){//....}}5.1.2实现接口——MovableObject接口的实现JAVA语言程序设计17❖为MovableObjec

ts安装遥控器(remotecontrol)publicclassRemoteControl{privateMovableObjectmachine;RemoteControl(MovableObjectm){machine=m;}//按下“启动”按钮:publicvoidstart(){bool

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

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

]class类名称implements接口1,接口2,…{……}JAVA语言程序设计19❖Car类可以实现接口Insurable,Drivable,SellablepublicclassCarimplementsIn

surable,Drivable,Sellable{....}5.1.3多重继承——Car的例子JAVA语言程序设计20❖声明Circle类实现接口Shape2D和Color◼Shape2D具有pi与area()方法,用

来计算面积◼Color则具有setColor方法,可用来赋值颜色◼通过实现这两个接口,Circle类得以同时拥有这两个接口的成员,达到了多重继承的目的interfaceShape2D{//声明Shape2D接口finaldoublepi=3.14;//数据成员一定要初始化publicabstra

ctdoublearea();//抽象方法}interfaceColor{voidsetColor(Stringstr);//抽象方法}5.1.3多重继承——例5_6JAVA语言程序设计21classCircleimplement

sShape2D,Color//实现Circle类{doubleradius;Stringcolor;publicCircle(doubler)//构造方法{radius=r;}publicdoublearea()//定义a

rea()的处理方式{return(pi*radius*radius);}publicvoidsetColor(Stringstr)//定义setColor()的处理方式{color=str;System.out.println("col

or="+color);}}5.1.3多重继承——例5_6JAVA语言程序设计22❖测试类publicclassMultiInterfaceTester{publicstaticvoidmain(Stringargs[]){Circlecir;cir=newCircle(2.0);ci

r.setColor("blue");System.out.println("Area="+cir.area());}}❖输出结果color=blueArea=12.565.1.3多重继承——例5_6运行结果JAVA语言程序设计2

35.1.4接口的扩展❖接口的扩展◼接口可通过扩展的技术派生出新的接口➢原来的接口称为基本接口(baseinterface)或父接口(superinterface)➢派生出的接口称为派生接口(derivedinterface)或子接口(subinterface)

◼派生接口不仅可以保有父接口的成员,同时也可加入新成员以满足实际问题的需要◼实现接口的类也必须实现此接口的父接口◼接口扩展的语法interface子接口的名称extends父接口的名称1,父接口的名称2,…{……}JAVA语言程序设计24❖Sha

pe是父接口,Shape2D与Shape3D是其子接口。Circle类及Rectangle类实现接口Shape2D,而Box类及Sphere类实现接口Shape3D5.1.4接口的扩展——例5_7Shape接口Shape2

D接口Shape3D接口Sphere类Box类Rectangle类Circle类JAVA语言程序设计25❖部分代码如下//声明Shape接口interfaceShape{doublepi=3.14;voidsetCo

lor(Stringstr);}//声明Shape2D接口扩展了Shape接口interfaceShape2DextendsShape{doublearea();}5.1.4接口的扩展——例5_7JAVA语言程序设计26classCi

rcleimplementsShape2D{doubleradius;Stringcolor;publicCircle(doubler){radius=r;}publicdoublearea(){return(pi*radius*radius);}publicv

oidsetColor(Stringstr){color=str;System.out.println("color="+color);}}publicclassExtendsInterfaceTester{//测试类publicstaticvoidmain(Stri

ng[]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和Depreciatin

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

mputeFairMarketValue();}publicinterfaceFixedInsurableextendsInsurable{publicintgetEvaluationPeriod();}5.1.4接口的扩展——Insur

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

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

为Customer、Company或CarObjectPersonEmployeeCustomerManagerCompanyCar<<Interface>>Insurable5.2.1塑型的概念——一

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

yee类的引用变量,系统会//自动将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=newManag

er();man=(Manager)emp;//将emp强制塑型为本来的类型JAVA语言程序设计345.2.2塑型的应用❖塑型应用的场合包括◼赋值转换➢赋值号右边的表达式类型或对象转换为左边的类型◼方法调用转换➢实参的类型转换为形参的类型

◼算数表达式转换➢算数混合运算时,不同类型的项转换为相同的类型再进行运算◼字符串转换➢字符串连接运算时,如果一个操作数为字符串,一个操作数为数值型,则会自动将数值型转换为字符串JAVA语言程序设计35❖当一个类对象被塑型为其父类后,它提供的方法会减少◼当Manager对象被塑型为Empl

oyee之后,它只能接收getName()及getEmployeeNumber()方法,不能接收getSalary()方法◼将其塑型为本来的类型后,又能接收getSalary()方法了5.2.2塑型的应用JAVA语言程序设计365.2.3方法的查找❖如果在塑型前和塑型后的类中都提供了相同的方

法,如果将此方法发送给塑型后的对象,那么系统将会调用哪一个类中的方法?◼实例方法的查找◼类方法的查找JAVA语言程序设计37❖从对象创建时的类开始,沿类层次向上查找Managerman=newManager();Employeeemp1=newEmployee();Employeeemp2=(E

mployee)man;emp1.computePay();//调用Employee类中的computePay()方法man.computePay();//调用Manager类中的computePay()方法emp2.computePay();//调用Manager类中的comput

ePay()方法5.2.3方法的查找——实例方法的查找JAVA语言程序设计38❖总是在引用变量声明时所属的类中进行查找Managerman=newManager();Employeeemp1=newEmployee();Employeee

mp2=(Employee)man;man.expenseAllowance();//inManageremp1.expenseAllowance();//inEmployeeemp2.expenseAllowance();//inEmployee!!!5.2.3方法的查找——类方法的查找J

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

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

为每种特殊的几何形状都提供独一无二的行为classCircleextendsShape{voiddraw(){System.out.println("Circle.draw()");}voiderase(){System.

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

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

ngle.draw()");}voiderase(){System.out.println("Triangle.erase()");}}5.3.2绑定的概念——例5_8JAVA语言程序设计46❖对动态绑定进行

测试如下publicclassBindingTester{publicstaticvoidmain(String[]args){Shape[]s=newShape[9];intn;for(inti=0;i<s.length;i++){n=(

int)(Math.random()*3);switch(n){case0:s[i]=newCircle();break;case1:s[i]=newSquare();break;case2:s[i]=newTriangle();}}for(inti=0;i<s.len

gth;i++)s[i].draw();}}5.3.2绑定的概念——例5_8JAVA语言程序设计47❖运行结果Square.draw()Triangle.draw()Circle.draw()Triangle.draw()Triangle.d

raw()Circle.draw()Square.draw()Circle.draw()Triangle.draw()❖说明◼编译时无法知道s数组元素的具体类型,运行时才能确定类型,所以是动态绑定◼在主方法的循环体中,每次随机生成指向一个Circle、Square或者Tria

ngle的引用5.3.2绑定的概念—例5_8运行结果JAVA语言程序设计48❖所有类都在music包中◼Note类中定义了三个音符◼Instrument类中声明并实现了一个play方法◼Wind类继承了Ins

trument类,重载了play方法◼Music类中包含了main方法classNote{privateintvalue;privateNote(intval){value=val;}publicstati

cfinalNoteMIDDLE_C=newNote(0),C_SHARP=newNote(1),B_FLAT=newNote(2);}5.3.2绑定的概念——music的例子JAVA语言程序设计49classInstrument{publicvoidplay(Noten){Syste

m.out.println("Instrument.play()");}}classWindextendsInstrument{publicvoidplay(Noten){System.out.println("W

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

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

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

术:运行时根据父类引用变量所指对象的实际类型执行相应的子类方法,从而实现多态性JAVA语言程序设计52❖声明一个抽象类Driver及两个子类FemaleDriver及MaleDriver❖在Diver类中声明了抽象方法dri

ves,在两个子类中对这个方法进行了重写publicabstractclassDriver{publicDriver(){}publicabstractvoiddrives();}5.4多态的应用(续)——例5_9JAVA语言程序设计53pub

licclassFemaleDriverextendsDriver{publicFemaleDriver(){}publicvoiddrives(){System.out.println("AFemaledriverdrivesavehicle.");}}publi

cclassMaleDriverextendsDriver{publicMaleDriver(){}publicvoiddrives(){System.out.println("Amaledriverdrivesavehicle.");}

}5.4多态的应用(续)——例5_9JAVA语言程序设计54publicclassTest1{staticpublicvoidmain(String[]args){Drivera=newFemaleDrive

r();Driverb=newMaleDriver();a.drives();b.drives();}}❖运行结果AFemaledriverdrivesavehicle.Amaledriverdrivesavehicle.5.4多态的应用(续)——例5_9J

AVA语言程序设计55❖所有类都放在drive包中◼试想有不同种类的交通工具(vehicle),如公共汽车(bus)及小汽车(car),由此可以声明一个抽象类Vehicle及两个子类Bus及Car◼对前面的drives

方法进行改进,使其接收一个Vehicle类的参数,当不同类型的交通工具被传送到此方法时,可以输出具体的交通工具5.4多态的应用(续)——例5_9改进JAVA语言程序设计56❖测试代码可改写如下:publicclassDr

iverTest{staticpublicvoidmain(String[]args){Drivera=newFemaleDriver();Driverb=newMaleDriver();Vehiclex=newCar();V

ehicley=newBus();a.drives(x);b.drives(y);}}❖并希望输出下面的结果AfemaledriverdrivesaCar.Amaledriverdrivesabus.5.4多态的应用(续)——

例5_9改进JAVA语言程序设计57❖Vehicle及其子类声明如下publicabstractclassVehicle{privateStringtype;publicVehicle(){}publicVehicle(Strings){type=s;}publicabstract

voiddrivedByFemaleDriver();publicabstractvoiddrivedByMaleDriver();}5.4多态的应用(续)——例5_9改进JAVA语言程序设计58publ

icclassBusextendsVehicle{publicBus(){}publicvoiddrivedByFemaleDriver(){System.out.println("Afemaledriverdrivesabus.");}publi

cvoiddrivedByMaleDriver(){System.out.println("Amaledriverdrivesabus.");}}publicclassCarextendsVehicle{publicCar(){}publicvoiddrivedByFemaleDriver(){S

ystem.out.println("AFemaledriverdrivesacar.");}publicvoiddrivedByMaleDriver(){System.out.println("AMaledriver

drivesacar.");}}5.4多态的应用(续)——例5_9改进JAVA语言程序设计59❖对FemaleDriver及MaleDriver类中的drives方法进行改进,在drives方法的定义体中不直接输出结果,而是调

用Bus及Car类中的相应方法publicabstractclassDriver{publicDriver(){}publicabstractvoiddrives(Vehiclev);}publicclassFemaleDriverextendsDriver{public

FemaleDriver(){}publicvoiddrives(Vehiclev){v.drivedByFemaleDriver();}}publicclassMaleDriverextendsDriver{publicMaleDriver(){}publicvoid

drives(Vehiclev){v.drivedByMaleDriver();}}5.4多态的应用(续)——例5_9改进JAVA语言程序设计60❖运行结果AFemaledriverdrivesacar.Amaledriverdrivesabus.❖说明◼这种技术称为二次分

发(“doubledispatching”),即对输出消息的请求被分发两次➢首先根据驾驶员的类型被发送给一个类➢之后根据交通工具的类型被发送给另一个类5.4多态的应用(续)——例5_9改进运行结果JAVA语言程序设计615.5构造方法与多态❖构造方法与多态◼构造方法与其他方法是

有区别的◼构造方法并不具有多态性,但仍然非常有必要理解构造方法如何在复杂的分级结构中随同多态性一同使用的情况JAVA语言程序设计62❖构造方法的调用顺序◼调用基类的构造方法。这个步骤会不断重复下去,首先得到构建的

是分级结构的根部,然后是下一个派生类,等等。直到抵达最深一层的派生类◼按声明顺序调用成员初始化模块◼调用派生构造方法5.5.1构造方法的调用顺序JAVA语言程序设计63❖构建一个点类Point,一个球类Ball,一

个运动的球类MovingBall继承自BallpublicclassPoint{privatedoublexCoordinate;privatedoubleyCoordinate;publicPoint(){}publicPoint(dou

blex,doubley){xCoordinate=x;yCoordinate=y;}publicStringtoString(){return"("+Double.toString(xCoordinate)+","+Double.toString(yCoo

rdinate)+")";}}5.5.1构造方法的调用顺序(续)——例5_10JAVA语言程序设计64publicclassBall{privatePointcenter;//中心点privatedoubleradius;//半径privateStringcolour;//颜色publicBal

l(){}publicBall(doublexValue,doubleyValue,doubler){center=newPoint(xValue,yValue);//调用Point中的构造方法radius=r;}publicBall(doublexValue,doubleyValue,dou

bler,Stringc){this(xValue,yValue,r);//调用三个参数的构造方法colour=c;}publicStringtoString(){return"Aballwithcenter"+center.toString()+",radius"+Doubl

e.toString(radius)+",colour"+colour;}}5.5.1构造方法的调用顺序(续)——例5_10JAVA语言程序设计65publicclassMovingBallextend

sBall{privatedoublespeed;publicMovingBall(){}publicMovingBall(doublexValue,doubleyValue,doubler,Stringc

,doubles){super(xValue,yValue,r,c);speed=s;}publicStringtoString(){returnsuper.toString()+",speed"+Double.toString(spe

ed);}}❖子类不能直接存取父类中声明的私有数据成员,super.toString调用父类Ball的toString方法输出类Ball中声明的属性值5.5.1构造方法的调用顺序(续)——例5_10JAVA语言程序设计66publicclassTeste

r{publicstaticvoidmain(Stringargs[]){MovingBallmb=newMovingBall(10,20,40,"green",25);System.out.println(mb);}}❖运行结果

Aballwithcenter(10.0,20.0),radius40.0,colourgreen,speed25.05.5.1构造方法的调用顺序(续)——例5_10运行结果JAVA语言程序设计67❖上面的代码中,构造方法调用的顺序为MovingBall(doublexVal

ue,doubleyValue,doubler,Stringc,doubles)Ball(doublexValue,doubleyValue,doubler,Stringc)Ball(doublexValue,doubleyValue,d

oubler)Point(doublex,doubley)5.5.1构造方法的调用顺序(续)——例5_10说明JAVA语言程序设计68❖构造方法的调用顺序举例2classMeal{//饭类Meal(){System.out.println("Meal()");}}cl

assBread{//面包类Bread(){System.out.println("Bread()");}}classCheese{//奶酪类Cheese(){System.out.println("Cheese()");}}classLettuce{//莴苣

类Lettuce(){System.out.println("Lettuce()");}}5.5.1构造方法的调用顺序(续)——例5_11JAVA语言程序设计69classLunchextendsMeal{//午餐类继承自饭类Lunch(){System.out.println("Lunch()

");}}classPortableLunchextendsLunch{PortableLunch(){System.out.println("PortableLunch()");}}publicclassSandwichextendsPor

tableLunch{Breadb=newBread();Cheesec=newCheese();Lettucel=newLettuce();Sandwich(){System.out.println("Sandwich()");}pu

blicstaticvoidmain(String[]args){newSandwich();}}5.5.1构造方法的调用顺序(续)——例5_11JAVA语言程序设计70❖输出结果Meal()Lunch()PortableLunch()Bread()Cheese()Lettuce()Sand

wich()❖说明◼当我们在构造派生类的时候,必须能假定基类的所有成员都是有效的。在构造方法内部,必须保证使用的所有成员都已初始化。因此唯一的办法就是首先调用基类构造方法,然后在进入派生类构造方法之前,初始化所有能够访问的成员5.5.1构造方法的调用顺序(续)——例5_1

1运行结果JAVA语言程序设计71❖构造方法中的多态方法◼在构造方法内调用准备构造的那个对象的动态绑定方法➢会调用位于派生类里的一个方法➢被调用方法要操纵的成员可能尚未得到正确的初始化➢可能造成一些难于发现的程序错误5.5.2构造方法中的多态方法JAVA语言程序设计72❖在Glyp

h中声明一个抽象方法,并在构造方法内部调用之abstractclassGlyph{abstractvoiddraw();Glyph(){System.out.println("Glyph()beforedraw()");draw();Syst

em.out.println("Glyph()afterdraw()");}}5.5.2构造方法中的多态方法(续)——例5_12JAVA语言程序设计73classRoundGlyphextendsGlyph{intradiu

s=1;RoundGlyph(intr){radius=r;System.out.println("RoundGlyph.RoundGlyph(),radius="+radius);}voiddraw(){System.out.println("RoundGlyph.draw(),radius

="+radius);}}publicclassPolyConstructors{publicstaticvoidmain(String[]args){newRoundGlyph(5);}}5.5.2构造方法中的多态方法(续)——例5_12JAVA语言程序设计74❖运行结果Glyp

h()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(表示类中声明的第一个匿名内部类)JAVA语言程序设计77publicclassParcel1{classContents{//内部类privateinti=11;

publicintvalue(){returni;}}classDestination{//内部类privateStringlabel;Destination(StringwhereTo){label=whereTo;}Stringread

Label(){returnlabel;}}publicvoidship(Stringdest){Contentsc=newContents();Destinationd=newDestination(

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

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

5.6内部类——Parcel1.javaJAVA语言程序设计79❖外部类的方法可以返回内部类的引用变量publicclassParcel2{classContents{privateinti=11;publicintvalue(){returni;}}classDe

stination{privateStringlabel;Destination(StringwhereTo){label=whereTo;}StringreadLabel(){returnlabel;}}pub

licDestinationto(Strings){returnnewDestination(s);}publicContentscont(){returnnewContents();}5.6内部类——Parcel2.javaJAVA语言程序设计80publicv

oidship(Stringdest){Contentsc=cont();Destinationd=to(dest);System.out.println(d.readLabel());}publicstaticvoidm

ain(String[]args){Parcel2p=newParcel2();p.ship("Tanzania");Parcel2q=newParcel2();Parcel2.Contentsc=q.cont();Parcel2.Destina

tiond=q.to("Borneo");}}❖说明◼to()方法返回内部类Destination的引用◼cont()方法返回内部类Contents的引用5.6内部类——Parcel2.javaJAVA语言程序设计81❖内部类实现接口◼可以完全不被

看到,而且不能被调用◼可以方便实现“隐藏实现细则”。你所能得到的仅仅是指向基类(baseclass)或者接口的一个引用❖例子abstractclassContents{abstractpublicintvalue();}interfac

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

ivateinti=11;publicintvalue(){returni;}}protectedclassPDestinationimplementsDestination{privateStringlabel

;privatePDestination(StringwhereTo){label=whereTo;}publicStringreadLabel(){returnlabel;}}publicDestinationdest(Strings){ret

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

ain(String[]args){Parcel3p=newParcel3();Contentsc=p.cont();Destinationd=p.dest("Tanzania");}}❖说明◼内部类PContents实现了抽象了Contents◼内部类PDe

nstination实现了接口Destination◼外部类Test中不能声明对private的内部类的引用5.6内部类——Parcel3测试JAVA语言程序设计84❖在方法内定义一个内部类◼为实现某个接口,产生并返回一个引用◼为解决一个复杂问题,需要建立一个类,而又不想它为外界所用5

.6内部类——方法中的内部类JAVA语言程序设计85publicclassParcel4{publicDestinationdest(Strings){classPDestinationimplementsDestination{privateStringlabel;pr

ivatePDestination(StringwhereTo){label=whereTo;}publicStringreadLabel(){returnlabel;}returnnewPDestinat

ion(s);}publicstaticvoidmain(String[]args){Parcel4p=newParcel4();Destinationd=p.dest("Tanzania");}}5.6内部类——Parcel4.javaJAVA语言程序设

计86publicclassParcel5{privatevoidinternalTracking(booleanb){if(b){classTrackingSlip{privateStringid;TrackingSlip(Strings){id=s;}S

tringgetSlip(){returnid;}}TrackingSlipts=newTrackingSlip("slip");Strings=ts.getSlip();}}publicvoidtrack(){internalTracking(true)

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

rnnewContents(){privateinti=11;publicintvalue(){returni;}};}publicstaticvoidmain(String[]args){Parcel6p=newParce

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

){returnnewWrapping(x){publicintvalue(){returnsuper.value()*47;}};}publicstaticvoidmain(String[]args){Parcel7p=newParcel7();Wrappingw=p.wra

p(10);}}5.6内部类——匿名的内部类5.6内部类——匿名的内部类匿名内部类对象的初始化publicclassParcel8{publicDestinationdest(finalStringdest){returnnewDestinati

on(){privateStringlabel=dest;publicStringreadLabel(){returnlabel;}};}publicstaticvoidmain(String[]args){Parcel8p=newParcel8();Destinationd=p.des

t("Tanzania");}}内部类

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