1、JAVA语言程序设计1第5章 接口与多态v5.1 接口接口v5.2 塑型塑型v5.3 多态的概念多态的概念v5.4 多态的应用多态的应用v5.5 构造方法与多态构造方法与多态v5.6 内部类内部类v5.7 本章小结本章小结JAVA语言程序设计25.1 接口v接口接口n与抽象类一样都是定义多个类的共同属性与抽象类一样都是定义多个类的共同属性n使抽象的概念更深入了一层,是一个使抽象的概念更深入了一层,是一个“纯纯”抽象类,抽象类,它只提供一种形式,并不提供实现它只提供一种形式,并不提供实现n允许创建者规定允许创建者规定方法方法的基本形式:的基本形式:方法名方法名、参数列参数列表表以及以及返回类型返
2、回类型,但不规定方法主体,但不规定方法主体n也可以包含基本数据类型的也可以包含基本数据类型的数据成员数据成员,但它们都默,但它们都默认为认为static和和finalJAVA语言程序设计35.1.1 接口的作用及语法v接口的作用接口的作用n是面向对象的一个重要机制是面向对象的一个重要机制n实现多继承,同时免除实现多继承,同时免除C+中的多继承那样的复中的多继承那样的复杂性杂性n建立类和类之间的建立类和类之间的“协议协议”把类根据其实现的功能来分别代表,而不必顾虑它所把类根据其实现的功能来分别代表,而不必顾虑它所在的类继承层次;这样可以最大限度地利用动态绑定,在的类继承层次;这样可以最大限度地利
3、用动态绑定,隐藏实现细节隐藏实现细节实现不同类之间的常量共享实现不同类之间的常量共享JAVA语言程序设计4v接口允许我们在看起来不相干的对象之间接口允许我们在看起来不相干的对象之间定义共同行为定义共同行为5.1.1 接口的作用及语法与抽象类的不同JAVA语言程序设计5v保险公司的例子保险公司的例子n具有车辆保险、人员保险、公司保险等多种保险业务,具有车辆保险、人员保险、公司保险等多种保险业务,在对外提供服务方面具有相似性,如都需要计算保险费在对外提供服务方面具有相似性,如都需要计算保险费(premium)等,因此可声明一个等,因此可声明一个Insurable 接口接口n在在UML图中,实现接口
4、用带有空三角形的虚线表示图中,实现接口用带有空三角形的虚线表示5.1.1 接口的作用及语法例5_1InsurableCompanyPersonCarJAVA语言程序设计6v接口的语法接口的语法n声明格式为声明格式为接口修饰符接口修饰符 interface 接口名称接口名称 extends 父接口父接口名名/方法的原型声明或静态常量方法的原型声明或静态常量n接口的数据成员一定要赋初值,且此值将不接口的数据成员一定要赋初值,且此值将不能再更改,允许省略能再更改,允许省略final关键字关键字n接口中的方法必须是接口中的方法必须是“抽象方法抽象方法”,不能有,不能有方法体,允许省略方法体,允许省略p
5、ublic及及abstract关键字关键字5.1.1 接口的作用及语法JAVA语言程序设计7v例例5.1中的中的Insurable 接口声明如下,可见其接口声明如下,可见其中的方法都是抽象方法中的方法都是抽象方法 public interface Insurable public int getNumber(); public int getCoverageAmount(); public double calculatePremium(); public Date getExpiryDate(); 5.1.1 接口的作用及语法例5_1保险接口的声明JAVA语言程序设计8v声明一个接口声明一个
6、接口Shape2D,可利用它来实现二维的几可利用它来实现二维的几何形状类何形状类Circle和和Rectanglen把计算面积的方法声明在接口里把计算面积的方法声明在接口里npi值是常量,把它声明在接口的数据成员里值是常量,把它声明在接口的数据成员里interface Shape2D /声明声明Shape2D接口接口 final double pi=3.14; /数据成员一定要初始化数据成员一定要初始化 public abstract double area();/抽象方法抽象方法n在接口的声明中,允许省略一些关键字,也可声明如下在接口的声明中,允许省略一些关键字,也可声明如下interfac
7、e Shape2D double pi=3.14; double area(); 5.1.1 接口的作用及语法例5_2JAVA语言程序设计95.1.2 实现接口v接口的实现接口的实现n接口不能用接口不能用newnew运算符直接产生对象,必须利用其运算符直接产生对象,必须利用其特性设计新的类,再用新类来创建对象特性设计新的类,再用新类来创建对象n利用接口设计类的过程,称为接口的实现,使用利用接口设计类的过程,称为接口的实现,使用implementsimplements关键字关键字n语法如下语法如下public class public class 类名称类名称 implements implem
8、ents 接口名称接口名称 / /* * Bodies for the interface methods Bodies for the interface methods * */ / / /* * Own data and methods. Own data and methods. * */ / 必须实现接口中的所有方法必须实现接口中的所有方法来自接口的方法必须声明成来自接口的方法必须声明成publicpublicJAVA语言程序设计10v实现接口实现接口Insurable,声明汽车类实现例声明汽车类实现例5.1中的中的Insurable接口,实现接口中的所有抽象方法接口,实现接口中的所
9、有抽象方法public class Car implements Insurable public int getPolicyNumber() / write code here public double calculatePremium() / write code here public Date getExpiryDate() / write code here public int getCoverageAmount() / write code here public int getMileage() /新添加的方法新添加的方法 /write code here 5.1.2 实现接
10、口 例5_3JAVA语言程序设计11v对象可以被转型为其所属类实现的接口类型对象可以被转型为其所属类实现的接口类型ngetPolicyNumber、calculatePremium是是Insurable接口中声接口中声明的方法明的方法ngetMileage是是Car类新添加的方法,类新添加的方法,Insurable接口中没有声明接口中没有声明此方法此方法Car jetta = new Car(); Insurable item = (Insurable)jetta; /对象转型为接口类型对象转型为接口类型 item.getPolicyNumber();item.calculatePremium
11、(); item.getMileage(); / 接口中没有声明此方法,不可以接口中没有声明此方法,不可以jetta.getMileage(); / 类中有此方法,可以类中有此方法,可以(Car)item).getMileage(); / 转型回原类,可调用此方法了转型回原类,可调用此方法了5.1.2 实现接口实现接口对象转型对象转型JAVA语言程序设计125.1.2 实现接口 例5_4class Circle implements Shape2D double radius; public Circle(double r) radius=r; public double area() ret
12、urn (pi * radius * radius); class Rectangle implements Shape2D int width,height; public Rectangle(int w,int h) width=w; height=h; public double area() return (width * height); l声明声明Circle与与Rectangle两个类实现两个类实现Shape2D接口接口JAVA语言程序设计13v测试类测试类public class InterfaceTester public static void main(String ar
13、gs) Rectangle rect=new Rectangle(5,6); System.out.println(Area of rect = + rect.area(); Circle cir=new Circle(2.0); System.out.println(Area of cir = + cir.area(); v运行结果运行结果Area of rect = 30.0Area of cir = 12.565.1.2 实现接口例5_4运行结果JAVA语言程序设计14v声明接口类型的变量,并用它来访问对象声明接口类型的变量,并用它来访问对象public class VariableTe
14、ster public static void main(String args) Shape2D var1,var2;var1=new Rectangle(5,6);System.out.println(Area of var1 = + var1.area();var2=new Circle(2.0);System.out.println(Area of var2 = + var2.area();v输出结果输出结果Area of var1 = 30.0Area of var2 = 12.565.1.2 实现接口例5_5JAVA语言程序设计15vMovableObject接口定义了所有接口定义
15、了所有“可移动对象可移动对象”能做的事情能做的事情public interface MovableObject public boolean start(); public void stop(); public boolean turn(int degrees); public double fuelRemaining(); public void changeSpeed(double kmPerHour);5.1.2 实现接口MovableObject接口JAVA语言程序设计16vPlane、Car、 Train、 Boat 分别实现分别实现 MovableObject 接口接口publi
16、c class Plane implements MovableObject public int seatCapacity; public Company owner; public Date lastRepairDate; /实现实现MovalbelObjectMovalbelObject接口的所有方法接口的所有方法 public boolean start() /启动飞机,成功则返回启动飞机,成功则返回true public void stop() /停止停止 public boolean turn(int degrees) /转向,成功则返回转向,成功则返回true public do
17、uble fuelRemaining() /返回燃料剩余量返回燃料剩余量 public void changeSpeed(double kmPerHour) /改变速度改变速度 /plane/plane类自己的方法:类自己的方法: public Date getLastRepairDate() /. public double calculateWindResistance() /. 5.1.2 实现接口MovableObject接口的实现JAVA语言程序设计17v为为 MovableObjects安装遥控器安装遥控器(remote control)public class RemoteCon
18、trol private MovableObject machine; RemoteControl(MovableObject m) machine = m; /按下按下“启动启动”按钮:按钮: public void start() boolean okay = machine.start(); if (!okay) display(No Response on start); /. nremote control 构造方法的形参类型为构造方法的形参类型为 MovableObject,它可以是它可以是Plane, Car, Train, Boat, 等等等等5.1.2 实现接口RemoteC
19、ontrol类JAVA语言程序设计185.1.3 多重继承v多重继承多重继承nJava的设计以简单实用为导向,不允许一个类有的设计以简单实用为导向,不允许一个类有多个父类多个父类n但允许一个类可以实现多个接口,通过这种机制但允许一个类可以实现多个接口,通过这种机制可实现多重继承可实现多重继承n一个类实现多个接口的语法如下一个类实现多个接口的语法如下类修饰符类修饰符 class 类名称类名称 implements 接口接口1,接口接口2, JAVA语言程序设计19vCar类可以实现接口类可以实现接口Insurable,Drivable,Sellablepublic class Car imple
20、ments Insurable, Drivable, Sellable . 5.1.3 多重继承Car的例子JAVA语言程序设计20v声明声明Circle类实现接口类实现接口Shape2D和和ColornShape2D具有具有pi与与area()方法,用来计算面积方法,用来计算面积nColor则具有则具有setColor方法,可用来赋值颜色方法,可用来赋值颜色n通过实现这两个接口,通过实现这两个接口,Circle类得以同时拥有这两个类得以同时拥有这两个接口的成员,达到了多重继承的目的接口的成员,达到了多重继承的目的interface Shape2D /声明声明Shape2D接口接口 final
21、 double pi=3.14; /数据成员一定要初始化数据成员一定要初始化 public abstract double area(); /抽象方法抽象方法interface Color void setColor(String str); /抽象方法抽象方法5.1.3 多重继承 例5_6JAVA语言程序设计21class Circle implements Shape2D,Color / 实现Circle类 double radius; String color; public Circle(double r) /构造方法 radius=r; public double area() /定
22、义area()的处理方式 return (pi*radius*radius); public void setColor(String str) /定义setColor()的处理方式 color=str; System.out.println(color=+color); 5.1.3 多重继承例5_6JAVA语言程序设计22v测试类测试类public class MultiInterfaceTester public static void main(String args) Circle cir; cir=new Circle(2.0); cir.setColor(blue); System
23、.out.println(Area = + cir.area(); v输出结果输出结果color=blueArea = 12.565.1.3 多重继承 例5_6运行结果JAVA语言程序设计235.1.4 接口的扩展v接口的扩展接口的扩展n接口可通过扩展的技术派生出新的接口接口可通过扩展的技术派生出新的接口原来的接口称为基本接口原来的接口称为基本接口(base interface)或父接口或父接口(super interface)派生出的接口称为派生接口派生出的接口称为派生接口(derived interface)或子接口或子接口(sub interface)n派生接口不仅可以保有父接口的成员,
24、同时也可加入新成员以满足派生接口不仅可以保有父接口的成员,同时也可加入新成员以满足实际问题的需要实际问题的需要n实现接口的类也必须实现此接口的父接口实现接口的类也必须实现此接口的父接口n接口扩展的语法接口扩展的语法interface 子接口的名称子接口的名称 extends 父接口的名称父接口的名称1,父接口的名称,父接口的名称2, JAVA语言程序设计24vShape是父接口,是父接口,Shape2D与与Shape3D是其子接是其子接口。口。Circle类及类及Rectangle类实现接口类实现接口Shape2D,而而Box类及类及Sphere类实现接口类实现接口Shape3D5.1.4 接
25、口的扩展例5_7Shape接口接口Shape2D接口接口Shape3D接口接口Sphere类类Box类类Rectangle类类Circle类类JAVA语言程序设计25v部分代码如下部分代码如下/ 声明声明Shape接口接口interface Shape double pi=3.14; void setColor(String str); /声明声明Shape2D接口扩展了接口扩展了Shape接口接口interface Shape2D extends Shape double area();5.1.4 接口的扩展例5_7JAVA语言程序设计26class Circle implements Sh
26、ape2D double radius; String color; public Circle(double r) radius=r; public double area() return (pi*radius*radius); public void setColor(String str) color=str; System.out.println(color=+color); public class ExtendsInterfaceTester /测试类 public static void main(String args) Circle cir; cir=new Circle(
27、2.0); cir.setColor(blue); System.out.println(Area = + cir.area(); 5.1.4 接口的扩展例5_7JAVA语言程序设计27v运行结果运行结果color=blueArea = 12.56v说明说明n首先声明了父接口首先声明了父接口Shape,然后声明其子接口然后声明其子接口Shape2Dn之后声明类之后声明类Circle实现实现Shape2D子接口,因而在此类内子接口,因而在此类内必须明确定义必须明确定义setColor()与与area()方法的处理方式方法的处理方式n最后在主类中我们声明了最后在主类中我们声明了Circle类型的变
28、量类型的变量cir并创建新并创建新的对象,最后通过的对象,最后通过cir对象调用对象调用setColor()与与area()方法方法5.1.4 接口的扩展例5_7运行结果JAVA语言程序设计28vFixedInsurable 和和DepreciatingInsurable接口接口n都继承了都继承了Insurable接口接口n实现它们类也必须实现实现它们类也必须实现Insurable接口中的所有方法接口中的所有方法public interface DepreciatingInsurable extends Insurable public double computeFairMarketValu
29、e(); public interface FixedInsurable extends Insurable public int getEvaluationPeriod();5.1.4 接口的扩展 Insurable接口的例子JAVA语言程序设计295.2 塑型v塑型塑型( (type-casting)type-casting)n又称为类型转换又称为类型转换n方式方式隐式隐式( (自动自动) )的类型转换的类型转换显式显式( (强制强制) )的类型转换的类型转换JAVA语言程序设计305.2.1 塑型的概念v塑型的对象包括塑型的对象包括n基本数据类型基本数据类型将值从一种形式转换成另一种形式
30、将值从一种形式转换成另一种形式n引用变量引用变量将对象暂时当成更一般的对象来对待,并不改变其将对象暂时当成更一般的对象来对待,并不改变其类型类型只能被塑型为只能被塑型为p任何一个父类类型任何一个父类类型p对象所属的类实现的一个接口对象所属的类实现的一个接口p被塑型为父类或接口后,再被塑型回其本身所在的类被塑型为父类或接口后,再被塑型回其本身所在的类JAVA语言程序设计31vManager对象对象n可以被塑型为可以被塑型为Employee、Person、Object或或Insurable,n不能被塑型为不能被塑型为Customer、Company或或Car ObjectPersonEmploye
31、eCustomerManagerCompanyCarInsurable5.2.1 塑型的概念一个例子JAVA语言程序设计32v基本数据类型基本数据类型n相容类型之间存储容量低的自动向存储容量高的类型转相容类型之间存储容量低的自动向存储容量高的类型转换换v引用变量引用变量n被塑型成更一般的类被塑型成更一般的类Employee emp; emp = new Manager(); /将将Manager类型的对象直接赋给类型的对象直接赋给 /Employee类的引用变量,系统会类的引用变量,系统会 /自动自动将将Manage对象对象塑型为塑型为Employee类类n被塑型为对象所属类实现的接口类型被塑
32、型为对象所属类实现的接口类型Car jetta = new Car(); Insurable item = jetta; 5.2.1 塑型的概念 隐式(自动)的类型转换JAVA语言程序设计335.2.1 塑型的概念 显式(强制)的类型转换v基本数据类型基本数据类型(int)871.34354; / 结果为结果为 871 (char)65; / 结果为结果为A (long)453; / 结果为结果为453Lv引用变量:还原为本来的类型引用变量:还原为本来的类型Employee emp; Manager man;emp = new Manager();man = (Manager)emp; /将将
33、emp强制塑型为本来的类型强制塑型为本来的类型JAVA语言程序设计345.2.2 塑型的应用v塑型应用的场合包括塑型应用的场合包括n赋值转换赋值转换赋值号右边的表达式类型或对象转换为左边的类型赋值号右边的表达式类型或对象转换为左边的类型n方法调用转换方法调用转换实参的类型转换为形参的类型实参的类型转换为形参的类型n算数表达式转换算数表达式转换算数混合运算时,不同类型的项转换为相同的类型再进行运算算数混合运算时,不同类型的项转换为相同的类型再进行运算n字符串转换字符串转换字符串连接运算时,如果一个操作数为字符串,一个操作数为字符串连接运算时,如果一个操作数为字符串,一个操作数为数值型,则会自动将
34、数值型转换为字符串数值型,则会自动将数值型转换为字符串 JAVA语言程序设计35v当一个类对象被塑型为其父类后,它提供的方法会减少当一个类对象被塑型为其父类后,它提供的方法会减少n当当Manager对象被塑型为对象被塑型为Employee之后,它只能接收之后,它只能接收getName()及及getEmployeeNumber()方法,不能接收方法,不能接收getSalary()方法方法n将其塑型为本来的类型后,又能接收将其塑型为本来的类型后,又能接收getSalary()方法了方法了5.2.2 塑型的应用JAVA语言程序设计365.2.3 方法的查找v如果在塑型前和塑型后的类中都提供了相如果在
35、塑型前和塑型后的类中都提供了相同的方法,如果将此方法发送给塑型后的同的方法,如果将此方法发送给塑型后的对象,那么系统将会调用哪一个类中的方对象,那么系统将会调用哪一个类中的方法法?n实例方法的查找实例方法的查找n类方法的查找类方法的查找JAVA语言程序设计37v从对象创建时的类开始,沿类层次向上查找从对象创建时的类开始,沿类层次向上查找 Manager man = new Manager(); Manager man = new Manager(); Employee emp1 = new Employee(); Employee emp1 = new Employee(); Employee
36、 emp2 = (Employee)man; Employee emp2 = (Employee)man; putePay(); / putePay(); / 调用调用EmployeeEmployee类中的类中的computePay()computePay()方法方法 putePay(); / putePay(); / 调用调用ManagerManager类中的类中的computePay()computePay()方法方法 putePay(); / putePay(); / 调用调用ManagerManager类中的类中的computePay()computePay()方法方法 5.2.3 方
37、法的查找 实例方法的查找JAVA语言程序设计38v总是在引用变量声明时所属的类中进行查找总是在引用变量声明时所属的类中进行查找 Manager man = new Manager(); Manager man = new Manager(); Employee emp1 = new Employee(); Employee emp1 = new Employee(); Employee emp2 = (Employee)man; Employee emp2 = (Employee)man; man.expenseAllowance(); /in Manager man.expenseAllow
38、ance(); /in Manager emp1.expenseAllowance(); /in Employee emp1.expenseAllowance(); /in Employee emp2.expenseAllowance(); /in Employee! emp2.expenseAllowance(); /in Employee! 5.2.3 方法的查找类方法的查找JAVA语言程序设计395.3 多态的概念v多态多态n是指不同类型的对象可以响应相同的消息是指不同类型的对象可以响应相同的消息n从相同的基类派生出来的多个类型可被当作同一种类从相同的基类派生出来的多个类型可被当作同一种
39、类型对待,可对这些不同的类型进行同样的处理,由于型对待,可对这些不同的类型进行同样的处理,由于多态性,这些多态性,这些不同派生类对象不同派生类对象响应同一方法时的行为响应同一方法时的行为是有所差别的是有所差别的 n例如例如所有的所有的Object类的对象都响应类的对象都响应toString()方法方法所有的所有的BankAccount类的对象都响应类的对象都响应deposit()方法方法JAVA语言程序设计405.3.1 多态的目的v多态的目的多态的目的n所有的对象都可被塑型为相同的类型,响应相同所有的对象都可被塑型为相同的类型,响应相同的消息的消息n使代码变得简单且容易理解使代码变得简单且容
40、易理解n使程序具有很好的使程序具有很好的“扩展性扩展性”JAVA语言程序设计41v绘图绘图直接的方式直接的方式n希望能够画出任意子类型对象的形状,可以在希望能够画出任意子类型对象的形状,可以在Shape 类中声明几个绘图方法,类中声明几个绘图方法,对不同的实际对象,采用不同对不同的实际对象,采用不同的画法的画法if (aShape instanceof Circle) aShape.drawCircle(); if (aShape instanceof Triangle) aShape.drawTriangle(); if (aShape instanceof Rectangle)aShape
41、.drawRectangle();5.3.1 多态的目的一个例子JAVA语言程序设计42v绘图绘图更好的方式更好的方式n在每个子类中都声明同名的在每个子类中都声明同名的draw()方法方法n以后绘图可如下进行以后绘图可如下进行Shape s = new Circle(); s.draw(); Circle属于属于Shape的一种,系统会执行自动塑型的一种,系统会执行自动塑型当调用方法当调用方法draw时,实际调用的是时,实际调用的是Circle.draw()在程序运行时才进行绑定,接下来介绍绑定的概念在程序运行时才进行绑定,接下来介绍绑定的概念5.3.1 多态的目的一个例子JAVA语言程序设计
42、435.3.2 绑定的概念v绑定绑定n指将一个方法调用同一个方法主体连接指将一个方法调用同一个方法主体连接到一起到一起n根据绑定时期的不同,可分为根据绑定时期的不同,可分为早期绑定早期绑定p程序运行之前执行绑定程序运行之前执行绑定晚期绑定晚期绑定p也叫作也叫作“动态绑定动态绑定”或或“运行期绑定运行期绑定p基于对象的类别,在程序运行时执行绑定基于对象的类别,在程序运行时执行绑定JAVA语言程序设计44v仍以绘图为例,所有类都放在仍以绘图为例,所有类都放在binding包中包中n基类基类Shape建立了一个通用接口建立了一个通用接口class Shape void draw() void era
43、se() n派生类覆盖了派生类覆盖了draw方法,为每种特殊的几何形状都方法,为每种特殊的几何形状都提供独一无二的行为提供独一无二的行为class Circle extends Shape void draw() System.out.println(Circle.draw(); void erase() System.out.println(Circle.erase(); 5.3.2 绑定的概念例5_8JAVA语言程序设计45class Square extends Shape void draw() System.out.println(Square.draw(); void erase(
44、) System.out.println(Square.erase(); class Triangle extends Shape void draw() System.out.println(Triangle.draw(); void erase() System.out.println(Triangle.erase(); 5.3.2 绑定的概念例5_8JAVA语言程序设计46v对动态绑定进行测试如下对动态绑定进行测试如下public class BindingTester public static void main(String args) Shape s = new Shape9;
45、int n; for(int i = 0; i s.length; i+) n = (int)(Math.random() * 3); switch(n) case 0: si = new Circle(); break; case 1: si = new Square(); break; case 2: si = new Triangle(); for(int i = 0; i 100) System.out.println(Over budget!); /不能重载不能重载 private String label = dest; public String readLabel() return label; ; public static void main(String args) Parcel9 p = new Parcel9(); Destination d = p.dest(Tanzania, 101.395F);