java程序设计第5章

上传人:zhan****gclb 文档编号:231399712 上传时间:2023-09-03 格式:PPT 页数:92 大小:1.15MB
返回 下载 相关 举报
java程序设计第5章_第1页
第1页 / 共92页
java程序设计第5章_第2页
第2页 / 共92页
java程序设计第5章_第3页
第3页 / 共92页
亲,该文档总共92页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第第5章章 接口与多态接口与多态Programming in JAVAJAVA语言程序设计目录目录l5.1 接口接口l5.2 塑型塑型l5.3 多态的概念多态的概念l5.4 多态的应用多态的应用l5.5 构造方法与多态构造方法与多态l5.6 内部类内部类l5.7 本章小结本章小结2JAVA语言程序设计5.1 接口接口l接口接口与抽象类一样都是定义多个类的共同属性使抽象的概念更深入了一层,是一个“纯”抽象类,它只提供一种形式,并不提供实现允许创建者规定方法的基本形式:方法名、参数列表以及返回类型,但不规定方法主体也可以包含基本数据类型的数据成员,但它们都默认为static和final3JAVA语言程序设计5.1.1 接口的作用及语法接口的作用及语法l接口的作用接口的作用是面向对象的一个重要机制实现多继承,同时免除C+中的多继承那样的复杂性建立类和类之间的“协议”l把类根据其实现的功能来分别代表,而不必顾虑它所在的类继承层次;这样可以最大限度地利用动态绑定,隐藏实现细节l实现不同类之间的常量共享接口4JAVA语言程序设计l接口允许我们在看起来不相干的对象接口允许我们在看起来不相干的对象之间定义共同行为之间定义共同行为5.1.1 接口的作用及语法接口的作用及语法与抽象类的不同与抽象类的不同接口5JAVA语言程序设计l保险公司的例子保险公司的例子具有车辆保险、人员保险、公司保险等多种保险业务,在对外提供服务方面具有相似性,如都需要计算保险费(premium)等,因此可声明一个Insurable接口在UML图中,实现接口用带有空三角形的虚线表示5.1.1 接口的作用及语法接口的作用及语法例例5_1InsurableCompanyPersonCar接口6JAVA语言程序设计l接口的语法接口的语法声明格式为接口修饰符interface接口名称extends父接口名/方法的原型声明或静态常量接口的数据成员一定要赋初值,且此值将不能再更改,允许省略final关键字接口中的方法必须是“抽象方法”,不能有方法体,允许省略public及abstract关键字5.1.1 接口的作用及语法接口的作用及语法接口7JAVA语言程序设计l例例5.1中的中的Insurable 接口声明如下,接口声明如下,可见其中的方法都是抽象方法可见其中的方法都是抽象方法publicinterfaceInsurablepublicintgetNumber();publicintgetCoverageAmount();publicdoublecalculatePremium();publicDategetExpiryDate();5.1.1 接口的作用及语法接口的作用及语法 例例5_1保险接口的声明保险接口的声明接口8JAVA语言程序设计l声明一个接口声明一个接口Shape2D,可利用它来实现可利用它来实现二维的几何形状类二维的几何形状类Circle和和Rectangle把计算面积的方法声明在接口里pi值是常量,把它声明在接口的数据成员里interfaceShape2D/声明Shape2D接口finaldoublepi=3.14;/数据成员一定要初始化publicabstractdoublearea();/抽象方法在接口的声明中,允许省略一些关键字,也可声明如下interfaceShape2Ddoublepi=3.14;doublearea();5.1.1 接口的作用及语法接口的作用及语法例例5_2接口9JAVA语言程序设计5.1.2 实现接口实现接口l接口的实现接口的实现接口不能用new运算符直接产生对象,必须利用其特性设计新的类,再用新类来创建对象利用接口设计类的过程,称为接口的实现,使用implements关键字语法如下public class 类名称 implements 接口名称 /*Bodies for the interface methods*/*Own data and methods.*/l必须实现接口中的所有方法l来自接口的方法必须声明成public接口10JAVA语言程序设计l实现接口实现接口Insurable,声明汽车类实现例声明汽车类实现例5.1中的中的Insurable接口,实现接口中的所有抽象方法接口,实现接口中的所有抽象方法publicclassCarimplementsInsurablepublicintgetPolicyNumber()/writecodeherepublicdoublecalculatePremium()/writecodeherepublicDategetExpiryDate()/writecodeherepublicintgetCoverageAmount()/writecodeherepublicintgetMileage()/新添加的方法/writecodehere5.1.2 实现接口实现接口 例例5_3接口11JAVA语言程序设计l对象可以被转型为其所属类实现的接口类型对象可以被转型为其所属类实现的接口类型getPolicyNumber、calculatePremium是Insurable接口中声明的方法getMileage是Car类新添加的方法,Insurable接口中没有声明此方法Carjetta=newCar();Insurableitem=(Insurable)jetta;/对象转型为接口类型item.getPolicyNumber();item.calculatePremium();item.getMileage();/接口中没有声明此方法,不可以jetta.getMileage();/类中有此方法,可以(Car)item).getMileage();/转型回原类,可调用此方法了5.1.2 实现接口实现接口 对象转型对象转型接口12JAVA语言程序设计5.1.2 实现接口实现接口 例例5_4classCircleimplementsShape2Ddoubleradius;publicCircle(doubler)radius=r;publicdoublearea()return(pi*radius*radius);classRectangleimplementsShape2Dintwidth,height;publicRectangle(intw,inth)width=w;height=h;publicdoublearea()return(width*height);l声明声明Circle与与Rectangle两个类实现两个类实现Shape2D接口接口接口13JAVA语言程序设计l测试类测试类publicclassInterfaceTesterpublicstaticvoidmain(Stringargs)Rectanglerect=newRectangle(5,6);System.out.println(Areaofrect=+rect.area();Circlecir=newCircle(2.0);System.out.println(Areaofcir=+cir.area();l运行结果运行结果Areaofrect=30.0Areaofcir=12.565.1.2 实现接口实现接口 例例5_4运行结果运行结果接口14JAVA语言程序设计l声明接口类型的变量,并用它来访问对象声明接口类型的变量,并用它来访问对象publicclassVariableTesterpublicstaticvoidmain(Stringargs)Shape2Dvar1,var2;var1=newRectangle(5,6);System.out.println(Areaofvar1=+var1.area();var2=newCircle(2.0);System.out.println(Areaofvar2=+var2.area();l输出结果输出结果Areaofvar1=30.0Areaofvar2=12.565.1.2 实现接口实现接口 例例5_5接口15JAVA语言程序设计lMovableObject接口定义了所有接口定义了所有“可移动可移动对象对象”能做的事情能做的事情publicinterfaceMovableObjectpublicbooleanstart();publicvoidstop();publicbooleanturn(intdegrees);publicdoublefuelRemaining();publicvoidchangeSpeed(doublekmPerHour);5.1.2 实现接口实现接口 MovableObject接口接口接口16JAVA语言程序设计lPlane、Car、Train、Boat 分别实现分别实现 MovableObject 接口接口publicclassPlaneimplementsMovableObjectpublicintseatCapacity;publicCompanyowner;publicDatelastRepairDate;/实现MovalbelObject接口的所有方法publicbooleanstart()/启动飞机,成功则返回truepublicvoidstop()/停止publicbooleanturn(intdegrees)/转向,成功则返回truepublicdoublefuelRemaining()/返回燃料剩余量publicvoidchangeSpeed(doublekmPerHour)/改变速度/plane类自己的方法:publicDategetLastRepairDate()/.publicdoublecalculateWindResistance()/.5.1.2 实现接口实现接口 MovableObject接口的实现接口的实现接口17JAVA语言程序设计l为为 MovableObjects安装遥控器安装遥控器(remote control)publicclassRemoteControlprivateMovableObjectmachine;RemoteControl(MovableObjectm)machine=m;/按下“启动”按钮:publicvoidstart()booleanokay=machine.start();if(!okay)display(NoResponseonstart);/.remotecontrol构造方法的形参类型为MovableObject,它可以是Plane,Car,Train,Boat,等等5.1.2 实现接口实现接口 RemoteControl类类接口18JAVA语言程序设计5.1.3 多重继承多重继承l多重继承多重继承Java的设计以简单实用为导向,不允许一个类有多个父类但允许一个类可以实现多个接口,通过这种机制可实现多重继承一个类实现多个接口的语法如下类修饰符class类名称implements接口1,接口2,接口19JAVA语言程序设计lCar类可以实现接口类可以实现接口Insurable,Drivable,SellablepublicclassCarimplementsInsurable,Drivable,Sellable.5.1.3 多重继承多重继承 Car的例子的例子接口20JAVA语言程序设计l声明声明Circle类实现接口类实现接口Shape2D和和ColorShape2D具有pi与area()方法,用来计算面积Color则具有setColor方法,可用来赋值颜色通过实现这两个接口,Circle类得以同时拥有这两个接口的成员,达到了多重继承的目的interfaceShape2D/声明Shape2D接口finaldoublepi=3.14;/数据成员一定要初始化publicabstractdoublearea();/抽象方法interfaceColorvoidsetColor(Stringstr);/抽象方法5.1.3 多重继承多重继承 例例5_6接口21JAVA语言程序设计classCircleimplementsShape2D,Color/实现Circle类doubleradius;Stringcolor;publicCircle(doubler)/构造方法radius=r;publicdoublearea()/定义area()的处理方式return(pi*radius*radius);publicvoidsetColor(Stringstr)/定义setColor()的处理方式color=str;System.out.println(color=+color);接口5.1.3 多重继承多重继承 例例5_622JAVA语言程序设计l测试类测试类publicclassMultiInterfaceTesterpublicstaticvoidmain(Stringargs)Circlecir;cir=newCircle(2.0);cir.setColor(blue);System.out.println(Area=+cir.area();l输出结果输出结果color=blueArea=12.56接口5.1.3 多重继承多重继承 例例5_6运行结果运行结果23JAVA语言程序设计5.1.4 接口的扩展接口的扩展l接口的扩展接口的扩展接口可通过扩展的技术派生出新的接口l原来的接口称为基本接口(baseinterface)或父接口(superinterface)l派生出的接口称为派生接口(derivedinterface)或子接口(subinterface)派生接口不仅可以保有父接口的成员,同时也可加入新成员以满足实际问题的需要实现接口的类也必须实现此接口的父接口接口扩展的语法interface子接口的名称extends父接口的名称1,父接口的名称2,接口24JAVA语言程序设计lShape是父接口,是父接口,Shape2D与与Shape3D是其子接是其子接口。口。Circle类及类及Rectangle类实现接口类实现接口Shape2D,而而Box类及类及Sphere类实现接口类实现接口Shape3D 5.1.4 接口的扩展接口的扩展 例例5_7Shape接口接口Shape2D接口接口Shape3D接口接口Sphere类类Box类类Rectangle类类Circle类类接口25JAVA语言程序设计l部分代码如下部分代码如下/声明Shape接口interfaceShapedoublepi=3.14;voidsetColor(Stringstr);/声明Shape2D接口扩展了Shape接口interfaceShape2DextendsShapedoublearea();5.1.4 接口的扩展接口的扩展 例例5_7接口26JAVA语言程序设计classCircleimplementsShape2Ddoubleradius;Stringcolor;publicCircle(doubler)radius=r;publicdoublearea()return(pi*radius*radius);publicvoidsetColor(Stringstr)color=str;System.out.println(color=+color);publicclassExtendsInterfaceTester/测试类publicstaticvoidmain(Stringargs)Circlecir;cir=newCircle(2.0);cir.setColor(blue);System.out.println(Area=+cir.area();5.1.4 接口的扩展接口的扩展 例例5_7接口27JAVA语言程序设计l运行结果运行结果color=blueArea=12.56l说明说明首先声明了父接口Shape,然后声明其子接口Shape2D之后声明类Circle实现Shape2D子接口,因而在此类内必须明确定义setColor()与area()方法的处理方式最后在主类中我们声明了Circle类型的变量cir并创建新的对象,最后通过cir对象调用setColor()与area()方法5.1.4 接口的扩展接口的扩展 例例5_7运行结果运行结果接口28JAVA语言程序设计lFixedInsurable 和和DepreciatingInsurable接口接口都继承了Insurable接口实现它们类也必须实现Insurable接口中的所有方法publicinterfaceDepreciatingInsurableextendsInsurablepublicdoublecomputeFairMarketValue();publicinterfaceFixedInsurableextendsInsurablepublicintgetEvaluationPeriod();5.1.4 接口的扩展接口的扩展 Insurable接口的例子接口的例子接口29JAVA语言程序设计5.2 塑型塑型l塑型塑型(type-casting)type-casting)又称为类型转换方式l隐式(自动)的类型转换l显式(强制)的类型转换30JAVA语言程序设计5.2.1 塑型的概念塑型的概念l塑型的对象包括塑型的对象包括基本数据类型l将值从一种形式转换成另一种形式引用变量l将对象暂时当成更一般的对象来对待,并不改变其类型l只能被塑型为任何一个父类类型对象所属的类实现的一个接口被塑型为父类或接口后,再被塑型回其本身所在的类塑型31JAVA语言程序设计lManager对象对象可以被塑型为Employee、Person、Object或Insurable,不能被塑型为Customer、Company或CarObjectPersonEmployeeCustomerManagerCompanyCarInsurable5.2.1 塑型的概念塑型的概念 一个例子一个例子塑型32JAVA语言程序设计l基本数据类型基本数据类型相容类型之间存储容量低的自动向存储容量高的类型转换l引用变量引用变量被塑型成更一般的类Employeeemp;emp=newManager();/将Manager类型的对象直接赋给/Employee类的引用变量,系统会/自动将Manage对象塑型为Employee类被塑型为对象所属类实现的接口类型Carjetta=newCar();Insurableitem=jetta;5.2.1 塑型的概念塑型的概念 隐式隐式(自动自动)的类型转换的类型转换塑型33JAVA语言程序设计5.2.1 塑型的概念塑型的概念 显式显式(强制强制)的类型转换的类型转换l基本数据类型基本数据类型(int)871.34354;/结果为871(char)65;/结果为A(long)453;/结果为453Ll引用变量:还原为本来的类型引用变量:还原为本来的类型Employeeemp;Managerman;emp=newManager();man=(Manager)emp;/将emp强制塑型为本来的类型塑型34JAVA语言程序设计5.2.2 塑型的应用塑型的应用l塑型应用的场合包括塑型应用的场合包括赋值转换l赋值号右边的表达式类型或对象转换为左边的类型方法调用转换l实参的类型转换为形参的类型算数表达式转换l算数混合运算时,不同类型的项转换为相同的类型再进行运算字符串转换l字符串连接运算时,如果一个操作数为字符串,一个操作数为数值型,则会自动将数值型转换为字符串塑型35JAVA语言程序设计l当一个类对象被塑型为其父类后,它提供的方法会当一个类对象被塑型为其父类后,它提供的方法会减少减少当Manager对象被塑型为Employee之后,它只能接收getName()及getEmployeeNumber()方法,不能接收getSalary()方法将其塑型为本来的类型后,又能接收getSalary()方法了5.2.2 塑型的应用塑型的应用塑型36JAVA语言程序设计5.2.3 方法的查找方法的查找l如果在塑型前和塑型后的类中都提供如果在塑型前和塑型后的类中都提供了相同的方法,如果将此方法发送给了相同的方法,如果将此方法发送给塑型后的对象,那么系统将会调用哪塑型后的对象,那么系统将会调用哪一个类中的方法一个类中的方法?实例方法的查找类方法的查找塑型37JAVA语言程序设计l从对象创建时的类开始,沿类层次向上查从对象创建时的类开始,沿类层次向上查找找 ManagerManager man man=new Manager();=new Manager();EmployeeEmployee emp1 emp1=new Employee();=new Employee();EmployeeEmployee emp2 emp2=(Employee)man;=(Employee)man;putePaycomputePay();();/调用调用EmployeeEmployee类中的类中的computePaycomputePay()()方法方法 putePaycomputePay();();/调用调用ManagerManager类中的类中的computePaycomputePay()()方法方法 putePaycomputePay();();/调用调用ManagerManager类中的类中的computePaycomputePay()()方法方法 5.2.3 方法的查找方法的查找 实例方法的查找实例方法的查找塑型38JAVA语言程序设计l总是在引用变量声明时所属的类中进行查总是在引用变量声明时所属的类中进行查找找 Manager manManager man=new Manager();=new Manager();Employee emp1Employee emp1=new Employee();=new Employee();Employee emp2Employee emp2=(Employee)man;=(Employee)man;manman.expenseAllowanceexpenseAllowance();/in Manager();/in Manager emp1emp1.expenseAllowanceexpenseAllowance();/in Employee();/in Employee emp2emp2.expenseAllowanceexpenseAllowance();/in Employee!();/in Employee!5.2.3 方法的查找方法的查找 类方法的查找类方法的查找塑型39JAVA语言程序设计5.3 多态的概念多态的概念l多态多态是指不同类型的对象可以响应相同的消息从相同的基类派生出来的多个类型可被当作同一种类型对待,可对这些不同的类型进行同样的处理,由于多态性,这些不同派生类对象响应同一方法时的行为是有所差别的例如l所有的Object类的对象都响应toString()方法l所有的BankAccount类的对象都响应deposit()方法40JAVA语言程序设计5.3.1 多态的目的多态的目的l多态的目的多态的目的所有的对象都可被塑型为相同的类型,响应相同的消息使代码变得简单且容易理解使程序具有很好的“扩展性”多态的概念41JAVA语言程序设计l绘图绘图直接的方式直接的方式希望能够画出任意子类型对象的形状,可以在Shape类中声明几个绘图方法,对不同的实际对象,采用不同的画法if(aShapeinstanceofCircle)aShape.drawCircle();if(aShapeinstanceofTriangle)aShape.drawTriangle();if(aShapeinstanceofRectangle)aShape.drawRectangle();5.3.1 多态的目的多态的目的 一个例子一个例子多态的概念42JAVA语言程序设计l绘图绘图更好的方式更好的方式在每个子类中都声明同名的draw()方法以后绘图可如下进行Shapes=newCircle();s.draw();lCircle属于Shape的一种,系统会执行自动塑型l当调用方法draw时,实际调用的是Circle.draw()l在程序运行时才进行绑定,接下来介绍绑定的概念5.3.1 多态的目的多态的目的 一个例子一个例子多态的概念43JAVA语言程序设计5.3.2 绑定的概念绑定的概念l绑定绑定指将一个方法调用同一个方法主体连接到一起根据绑定时期的不同,可分为l早期绑定程序运行之前执行绑定l晚期绑定也叫作“动态绑定”或“运行期绑定基于对象的类别,在程序运行时执行绑定多态的概念44JAVA语言程序设计l仍以绘图为例,所有类都放在仍以绘图为例,所有类都放在binding包中包中基类Shape建立了一个通用接口classShapevoiddraw()voiderase()派生类覆盖了draw方法,为每种特殊的几何形状都提供独一无二的行为classCircleextendsShapevoiddraw()System.out.println(Circle.draw();voiderase()System.out.println(Circle.erase();5.3.2 绑定的概念绑定的概念 例例5_8多态的概念45JAVA语言程序设计classSquareextendsShapevoiddraw()System.out.println(Square.draw();voiderase()System.out.println(Square.erase();classTriangleextendsShapevoiddraw()System.out.println(Triangle.draw();voiderase()System.out.println(Triangle.erase();5.3.2 绑定的概念绑定的概念 例例5_8多态的概念46JAVA语言程序设计l对动态绑定进行测试如下对动态绑定进行测试如下publicclassBindingTesterpublicstaticvoidmain(Stringargs)Shapes=newShape9;intn;for(inti=0;is.length;i+)n=(int)(Math.random()*3);switch(n)case0:si=newCircle();break;case1:si=newSquare();break;case2:si=newTriangle();for(inti=0;is.length;i+)si.draw();5.3.2 绑定的概念绑定的概念 例例5_8多态的概念47JAVA语言程序设计l运行结果运行结果Square.draw()Triangle.draw()Circle.draw()Triangle.draw()Triangle.draw()Circle.draw()Square.draw()Circle.draw()Triangle.draw()l说明说明编译时无法知道s数组元素的具体类型,运行时才能确定类型,所以是动态绑定在主方法的循环体中,每次随机生成指向一个Circle、Square或者Triangle的引用5.3.2 绑定的概念绑定的概念 例例5_8运行结果运行结果多态的概念48JAVA语言程序设计l所有类都在所有类都在music包中包中Note类中定义了三个音符Instrument类中声明并实现了一个play方法Wind类继承了Instrument类,重载了play方法Music类中包含了main方法classNoteprivateintvalue;privateNote(intval)value=val;publicstaticfinalNoteMIDDLE_C=newNote(0),C_SHARP=newNote(1),B_FLAT=newNote(2);5.3.2 绑定的概念绑定的概念 music的例子的例子多态的概念49JAVA语言程序设计classInstrumentpublicvoidplay(Noten)System.out.println(Instrument.play();classWindextendsInstrumentpublicvoidplay(Noten)System.out.println(Wind.play();5.3.2 绑定的概念绑定的概念(续续)music的例子的例子多态的概念50JAVA语言程序设计publicclassMusicpublicstaticvoidtune(Instrumenti)i.play(Note.MIDDLE_C);publicstaticvoidmain(Stringargs)Windflute=newWind();tune(flute);l运行结果运行结果Wind.play()l说明说明运行中,Instrument类的对象实际是Wind类的,所以调用了Wind类中的play方法5.3.2 绑定的概念绑定的概念(续续)music运行结果运行结果多态的概念51JAVA语言程序设计5.4 多态的应用多态的应用 l多态的应用多态的应用技术基础l向上塑型技术:一个父类的引用变量可以指向不同的子类对象l动态绑定技术:运行时根据父类引用变量所指对象的实际类型执行相应的子类方法,从而实现多态性多态的概念52JAVA语言程序设计l声明一个抽象类声明一个抽象类Driver及两个子类及两个子类FemaleDriver及及MaleDriverl在在Diver类中声明了抽象方法类中声明了抽象方法drives,在两在两个子类中对这个方法进行了重写个子类中对这个方法进行了重写publicabstractclassDriverpublicDriver()publicabstractvoiddrives();5.4 多态的应用多态的应用(续续)例例5_9多态的概念53JAVA语言程序设计publicclassFemaleDriverextendsDriverpublicFemaleDriver()publicvoiddrives()System.out.println(AFemaledriverdrivesavehicle.);publicclassMaleDriverextendsDriverpublicMaleDriver()publicvoiddrives()System.out.println(Amaledriverdrivesavehicle.);5.4 多态的应用多态的应用(续续)例例5_9多态的概念54JAVA语言程序设计publicclassTest1staticpublicvoidmain(Stringargs)Drivera=newFemaleDriver();Driverb=newMaleDriver();a.drives();b.drives();l运行结果运行结果AFemaledriverdrivesavehicle.Amaledriverdrivesavehicle.5.4 多态的应用多态的应用(续续)例例5_9多态的概念55JAVA语言程序设计l所有类都放在所有类都放在drive包中包中试想有不同种类的交通工具(vehicle),如公共汽车(bus)及小汽车(car),由此可以声明一个抽象类Vehicle及两个子类Bus及Car对前面的drives方法进行改进,使其接收一个Vehicle类的参数,当不同类型的交通工具被传送到此方法时,可以输出具体的交通工具5.4 多态的应用多态的应用(续续)例例5_9改进改进多态的概念56JAVA语言程序设计l测试代码可改写如下:测试代码可改写如下:publicclassDriverTeststaticpublicvoidmain(Stringargs)Drivera=newFemaleDriver();Driverb=newMaleDriver();Vehiclex=newCar();Vehicley=newBus();a.drives(x);b.drives(y);l并希望输出下面的结果并希望输出下面的结果AfemaledriverdrivesaCar.Amaledriverdrivesabus.5.4 多态的应用多态的应用(续续)例例5_9改进改进多态的概念57JAVA语言程序设计lVehicle及其子类声明如下及其子类声明如下publicabstractclassVehicleprivateStringtype;publicVehicle()publicVehicle(Strings)type=s;publicabstractvoiddrivedByFemaleDriver();publicabstractvoiddrivedByMaleDriver();5.4 多态的应用多态的应用(续续)例例5_9改进改进多态的概念58JAVA语言程序设计publicclassBusextendsVehiclepublicBus()publicvoiddrivedByFemaleDriver()System.out.println(Afemaledriverdrivesabus.);publicvoiddrivedByMaleDriver()System.out.println(Amaledriverdrivesabus.);publicclassCarextendsVehiclepublicCar()publicvoiddrivedByFemaleDriver()System.out.println(AFemaledriverdrivesacar.);publicvoiddrivedByMaleDriver()System.out.println(AMaledriverdrivesacar.);5.4 多态的应用多态的应用(续续)例例5_9改进改进多态的概念59JAVA语言程序设计l对对FemaleDriver及及MaleDriver类中的类中的drives方法进方法进行改进,在行改进,在drives方法的定义体中不直接输出结果,方法的定义体中不直接输出结果,而是调用而是调用Bus及及Car类中的相应方法类中的相应方法publicabstractclassDriverpublicDriver()publicabstractvoiddrives(Vehiclev);publicclassFemaleDriverextendsDriverpublicFemaleDriver()publicvoiddrives(Vehiclev)v.drivedByFemaleDriver();publicclassMaleDriverextendsDriverpublicMaleDriver()publicvoiddrives(Vehiclev)v.drivedByMaleDriver();5.4 多态的应用多态的应用(续续)例例5_9改进改进多态的概念60JAVA语言程序设计l运行结果运行结果AFemaledriverdrivesacar.Amaledriverdrivesabus.l说明说明这种技术称为二次分发(“doubledispatching”),即对输出消息的请求被分发两次l首先根据驾驶员的类型被发送给一个类l之后根据交通工具的类型被发送给另一个类5.4 多态的应用多态的应用(续续)例例5_9改进运行结果改进运行结果多态的概念61JAVA语言程序设计5.5 构造方法与多态构造方法与多态l构造方法与多态构造方法与多态构造方法与其他方法是有区别的构造方法并不具有多态性,但仍然非常有必要理解构造方法如何在复杂的分级结构中随同多态性一同使用的情况62JAVA语言程序设计l构造方法的调用顺序构造方法的调用顺序调用基类的构造方法。这个步骤会不断重复下去,首先得到构建的是分级结构的根部,然后是下一个派生类,等等。直到抵达最深一层的派生类按声明顺序调用成员初始化模块调用派生构造方法5.5.1 构造方法的调用顺序构造方法的调用顺序构造方法与多态63JAVA语言程序设计l构建一个点类构建一个点类Point,一个球类一个球类Ball,一个运动的一个运动的球类球类MovingBall继承自继承自BallpublicclassPointprivatedoublexCoordinate;privatedoubleyCoordinate;publicPoint()publicPoint(doublex,doubley)xCoordinate=x;yCoordinate=y;publicStringtoString()return(+Double.toString(xCoordinate)+,+Double.toString(yCoordinate)+);5.5.1 构造方法的调用顺序构造方法的调用顺序(续续)例例5_10构造方法与多态64JAVA语言程序设计publicclassBallprivatePointcenter;/中心点privatedoubleradius;/半径privateStringcolour;/颜色publicBall()publicBall(doublexValue,doubleyValue,doubler)center=newPoint(xValue,yValue);/调用Point中的构造方法radius=r;publicBall(doublexValue,doubleyValue,doubler,Stringc)this(xValue,yValue,r);/调用三个参数的构造方法colour=c;publicStringtoString()returnAballwithcenter+center.toString()+,radius+Double.toString(radius)+,colour+colour;5.5.1 构造方法的调用顺序构造方法的调用顺序(续续)例例5_10构造方法与多态65JAVA语言程序设计publicclassMovingBallextendsBallprivatedoublespeed;publicMovingBall()publicMovingBall(doublexValue,doubleyValue,doubler,Stringc,doubles)super(xValue,yValue,r,c);speed=s;publicStringtoString()returnsuper.toString()+,speed+Double.toString(speed);l子类不能直接存取父类中声明的私有数据成员,子类不能直接存取父类中声明的私有数据成员,super.toString调用父类调用父类Ball的的toString方法输出类方法输出类Ball中声明的属性值中声明的属性值5.5.1 构造方法的调用顺序构造方法的调用顺序(续续)例例5_10构造方法与多态66JAVA语言程序设计publicclassTesterpublicstaticvoidmain(Stringargs)MovingBallmb=newMovingBall(10,20,40,green,25);System.out.println(mb);l运行结果运行结果Aballwithcenter(10.0,20.0),radius40.0,colourgreen,speed25.05.5.1 构造方法的调用顺序构造方法的调用顺序(续续)例例5_10运行结果运行结果构造方法与多态67JAVA语言程序设计l上面的代码中,构造方法调用的顺序为上面的代码中,构造方法调用的顺序为MovingBall(doublexValue,doubleyValue,doubler,Stringc,doubles)Ball(doublexValue,doubleyValue,doubler,Stringc)Ball(doublexValue,doubleyValue,doubler)Point(doublex,doubley)5.5.1 构造方法的调用顺序构造方法的调用顺序(续续)例例5_10说明说明构造方法与多态68JAVA语言程序设计l构造方法的调用顺序举例构造方法的调用顺序举例2classMeal/饭类Meal()System.out.println(Meal();classBread/面包类Bread()System.out.println(Bread();classCheese/奶酪类Cheese()System.out.println(Cheese();classLettuce/莴苣类Lettuce()System.out.println(Lettuce();5.5.1 构造方法的调用顺序构造方法的调用顺序(续续)例例5_11构造方法与多态69JAVA语言程序设计classLunchextendsMeal/午餐类继承自饭类 Lunch()System.out.println(Lunch();classPortableLunchextendsLunchPortableLunch()System.out.println(PortableLunch();publicclassSandwichextendsPortableLunchBreadb=newBread();Cheesec=newCheese();Lettucel=newLettuce();Sandwich()System.out.println(Sandwich();publicstaticvoidmain(Stringargs)newSandwich();5.5.1 构造方法的调用顺序构造方法的调用顺序(续续)例例5_11构造方法与多态70JAVA语言程序设计l输出结果输出结果Meal()Lunch()PortableLunch()Bread()Cheese()Lettuce()Sandwich()l说明说明当我们在构造派生类的时候,必须能假定基类的所有成员都是有效的。在构造方法内部,必须保证使用的所有成员都已初始化。因此唯一的办法就是首先调用基类构造方法,然后在进入派生类构造方法之前,初始化所有能够访问的成员5.5.1 构造方法的调用顺序构造方法的调用顺序(续续)例例5_11运行结果运行结果构造方法与多态71JAVA语言程序设计l构造方法中的多态方法构造方法中的多态方法在构造方法内调用准备构造的那个对象的动态绑定方法l会调用位于派生类里的一个方法l被调用方法要操纵的成员可能尚未得到正确的初始化l可能造成一些难于发现的程序错误构造方法与多态5.5.2 构造方法中的多态方法构造方法中的多态方法72JAVA语言程序设计构造方法与多态l在在Glyph中声明一个抽象方法,并在构造方中声明一个抽象方法,并在构造方法内部调用之法内部调用之abstractclassGlyphabstractvoiddraw();Glyph()System.out.println(Glyph()beforedraw();draw();System.out.println(Glyph()afterdraw();5.5.2 构造方法中的多态方法构造方法中的多态方法(续续)例例5_1273JAVA语言程序设计class RoundGlyph extends Glyph int radius=1;RoundGlyph(int r)radius=r;System.out.println(RoundGlyph.RoundGlyph(),radius=+radius);void draw()System.out.println(RoundGlyph.draw(),radius=+radius);public class PolyConstructors public static void main(String args)new RoundGlyph(5);5.5.2 构造方法中的多态方法构造方法中的多态方法(续续)例例5_12构造方法与多态74JAVA语言程序设计l运行结果运行结果Glyph()beforedraw()RoundGlyph.draw(),radius=0Glyph()afterdraw()RoundGlyph.RoundGlyph(),radius=5l说明说明在Glyph中,draw()方法是抽象方法,在子类RoundGlyph中对此方法进行了覆盖。Glyph的构造方法调用了这个方法从运行的结果可以看到:当Glyph的构造方法调用draw()时,radius的值甚至不是默认的初始值1,而是0构造方法与多态5.5.2 构造方法中的多态方法构造方法中的多态方法(续续)例例5_12运行运行结果结果75JAVA语言程序设计l定义构造方法的注意事项定义构造方法的注意事项用尽可能少的动作把对象的状态设置好如果可以避免,不要调用任何方法在构造方法内唯一能够安全调用的是在基类中具有final属性的那些方法(也适用于private方法,它们自动具有final属性)。这些方法不能被覆盖,所以不会出现上述潜在的问题5.5.2 构造方法中的多态方法构造方法中的多态方法构造方法与多态76JAVA语言程序设计5.6 内部类内部类l内部类内部类在另一个类或方法的定义中定义的类可访问其外部类中的所有数据成员和方法成员可对逻辑上相互联系的类进行分组对于同一个包中的其他类来说,能够隐藏可非常方便地编写事件驱动程序声明方式l命名的内部类:可在类的内部多次使用l匿名内部类:可在new关键字后声明内部类,并立即创建一个对象假设外层类名为Myclass,则该类的内部类名为lMyclass$c1.class(c1为命名的内部类名)lMyclass$1.class(表示类中声明的第一个匿名内部类)77JAVA语言程序设计publicclassParcel1classContents/内部类privateinti=11;publicintvalue()returni;classDestination/内部类privateStringlabel;Destination(StringwhereTo)label=whereTo;StringreadLabel()returnlabel;publicvoidship(Stringdest)Contentsc=newContents();Destinationd=newDestination(dest);System.out.println(d.readLabel();5.6 内部类内部类 Parcel1.java内部类78JAVA语言程序设计 publicstaticvoidmain(Stringargs)Parcel1p=newParcel1();p.ship(Tanzania);l说明说明在Parcel1类中声明了两个内部类Contents、Destination在ship方法中生成两个内部类对象,并调用了内部类中声明的一个方法 5.6 内部类内部类 Parcel1.java内部类79JAVA语言程序设计l 外部类的方法可以返回内部类的引用变量外部类的方法可以返回内部类的引用变量publicclassParcel2classContentsprivateinti=11;publicintvalue()returni;classDestinationprivateStringlabel;Destination(StringwhereTo)label=whereTo;StringreadLabel()returnlabel;publicDestinationto(Strings)returnnewDestination(s);publicContentscont()returnnewContents();5.6 内部类内部类 Parcel2.java内部类80JAVA语言程序设计 publicvoidship(Stringdest)Contentsc=cont();Destinationd=to(dest);Sys
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 大学资料


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

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


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