Java学习第5章.ppt

上传人:本田雅阁 文档编号:2976861 上传时间:2019-06-16 格式:PPT 页数:92 大小:869.51KB
返回 下载 相关 举报
Java学习第5章.ppt_第1页
第1页 / 共92页
Java学习第5章.ppt_第2页
第2页 / 共92页
Java学习第5章.ppt_第3页
第3页 / 共92页
Java学习第5章.ppt_第4页
第4页 / 共92页
Java学习第5章.ppt_第5页
第5页 / 共92页
点击查看更多>>
资源描述

《Java学习第5章.ppt》由会员分享,可在线阅读,更多相关《Java学习第5章.ppt(92页珍藏版)》请在三一文库上搜索。

1、第5章 接口与多态,Programming in JAVA,2,目录,5.1 接口 5.2 塑型 5.3 多态的概念 5.4 多态的应用 5.5 构造方法与多态 5.6 内部类 5.7 本章小结,3,5.1 接口,接口 与抽象类一样都是定义多个类的共同属性 使抽象的概念更深入了一层,是一个“纯”抽象类,它只提供一种形式,并不提供实现 允许创建者规定方法的基本形式:方法名、参数列表以及返回类型,但不规定方法主体 也可以包含基本数据类型的数据成员,但它们都默认为static和final,4,5.1.1 接口的作用及语法,接口的作用 是面向对象的一个重要机制 实现多继承,同时免除C+中的多继承那样的

2、复杂性 建立类和类之间的“协议” 把类根据其实现的功能来分别代表,而不必顾虑它所在的类继承层次;这样可以最大限度地利用动态绑定,隐藏实现细节 实现不同类之间的常量共享,接口,5,接口允许我们在看起来不相干的对象之间定义共同行为,5.1.1 接口的作用及语法 与抽象类的不同,接口,6,保险公司的例子 具有车辆保险、人员保险、公司保险等多种保险业务,在对外提供服务方面具有相似性,如都需要计算保险费(premium)等,因此可声明一个Insurable 接口 在UML图中,实现接口用带有空三角形的虚线表示,5.1.1 接口的作用及语法 例5_1,接口,7,接口的语法 声明格式为 接口修饰符 inte

3、rface 接口名称 extends 父接口名 /方法的原型声明或静态常量 接口的数据成员一定要赋初值,且此值将不能再更改,允许省略final关键字 接口中的方法必须是“抽象方法”,不能有方法体,允许省略public及abstract关键字,5.1.1 接口的作用及语法,接口,8,例5.1中的Insurable 接口声明如下,可见其中的方法都是抽象方法 public interface Insurable public int getNumber(); public int getCoverageAmount(); public double calculatePremium(); publi

4、c Date getExpiryDate(); ,5.1.1 接口的作用及语法 例5_1保险接口的声明,接口,9,声明一个接口Shape2D,可利用它来实现二维的几何形状类Circle和Rectangle 把计算面积的方法声明在接口里 pi值是常量,把它声明在接口的数据成员里 interface Shape2D /声明Shape2D接口 final double pi=3.14; /数据成员一定要初始化 public abstract double area(); /抽象方法 在接口的声明中,允许省略一些关键字,也可声明如下 interface Shape2D double pi=3.14;

5、double area(); ,5.1.1 接口的作用及语法 例5_2,接口,10,5.1.2 实现接口,接口的实现 接口不能用new运算符直接产生对象,必须利用其特性设计新的类,再用新类来创建对象 利用接口设计类的过程,称为接口的实现,使用implements关键字 语法如下 public class 类名称 implements 接口名称 /* Bodies for the interface methods */ /* Own data and methods. */ 必须实现接口中的所有方法 来自接口的方法必须声明成public,接口,11,实现接口Insurable,声明汽车类实现例

6、5.1中的Insurable接口,实现接口中的所有抽象方法 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

7、code here ,5.1.2 实现接口 例5_3,接口,12,对象可以被转型为其所属类实现的接口类型 getPolicyNumber、calculatePremium是Insurable接口中声明的方法 getMileage是Car类新添加的方法,Insurable接口中没有声明此方法 Car jetta = new Car(); Insurable item = (Insurable)jetta; /对象转型为接口类型 item.getPolicyNumber(); item.calculatePremium(); item.getMileage(); / 接口中没有声明此方法,不可以

8、jetta.getMileage(); / 类中有此方法,可以 (Car)item).getMileage(); / 转型回原类,可调用此方法了,5.1.2 实现接口 对象转型,接口,13,5.1.2 实现接口 例5_4,class Circle implements Shape2D double radius; public Circle(double r) radius=r; public double area() return (pi * radius * radius); ,class Rectangle implements Shape2D int width,height; pu

9、blic Rectangle(int w,int h) width=w; height=h; public double area() return (width * height); ,声明Circle与Rectangle两个类实现Shape2D接口,接口,14,测试类 public class InterfaceTester public static void main(String args) Rectangle rect=new Rectangle(5,6); System.out.println(“Area of rect = “ + rect.area(); Circle cir

10、=new Circle(2.0); System.out.println(“Area of cir = “ + cir.area(); 运行结果 Area of rect = 30.0 Area of cir = 12.56,5.1.2 实现接口 例5_4运行结果,接口,15,声明接口类型的变量,并用它来访问对象 public class VariableTester public static void main(String args) Shape2D var1,var2; var1=new Rectangle(5,6); System.out.println(“Area of var1

11、= “ + var1.area(); var2=new Circle(2.0); System.out.println(“Area of var2 = “ + var2.area(); 输出结果 Area of var1 = 30.0 Area of var2 = 12.56,5.1.2 实现接口 例5_5,接口,16,MovableObject接口定义了所有“可移动对象”能做的事情 public interface MovableObject public boolean start(); public void stop(); public boolean turn(int degrees

12、); public double fuelRemaining(); public void changeSpeed(double kmPerHour); ,5.1.2 实现接口 MovableObject接口,接口,17,Plane、Car、 Train、 Boat 分别实现 MovableObject 接口 public class Plane implements MovableObject public int seatCapacity; public Company owner; public Date lastRepairDate; /实现MovalbelObject接口的所有方法

13、public boolean start() /启动飞机,成功则返回true public void stop() /停止 public boolean turn(int degrees) /转向,成功则返回true public double fuelRemaining() /返回燃料剩余量 public void changeSpeed(double kmPerHour) /改变速度 /plane类自己的方法: public Date getLastRepairDate() /. public double calculateWindResistance() / ,5.1.2 实现接口 M

14、ovableObject接口的实现,接口,18,为 MovableObjects安装遥控器(remote control) public class RemoteControl private MovableObject machine; RemoteControl(MovableObject m) machine = m; /按下“启动”按钮: public void start() boolean okay = machine.start(); if (!okay) display(“No Response on start“); /. remote control 构造方法的形参类型为

15、MovableObject,它可以是Plane, Car, Train, Boat, 等等,5.1.2 实现接口 RemoteControl类,接口,19,5.1.3 多重继承,多重继承 Java的设计以简单实用为导向,不允许一个类有多个父类 但允许一个类可以实现多个接口,通过这种机制可实现多重继承 一个类实现多个接口的语法如下 类修饰符 class 类名称 implements 接口1,接口2, ,接口,20,Car类可以实现接口Insurable,Drivable,Sellable public class Car implements Insurable, Drivable, Sella

16、ble ,5.1.3 多重继承 Car的例子,接口,21,声明Circle类实现接口Shape2D和Color Shape2D具有pi与area()方法,用来计算面积 Color则具有setColor方法,可用来赋值颜色 通过实现这两个接口,Circle类得以同时拥有这两个接口的成员,达到了多重继承的目的 interface Shape2D /声明Shape2D接口 final double pi=3.14; /数据成员一定要初始化 public abstract double area(); /抽象方法 interface Color void setColor(String str); /

17、抽象方法 ,5.1.3 多重继承 例5_6,接口,22,class Circle implements Shape2D,Color / 实现Circle类 double radius; String color; public Circle(double r) /构造方法 radius=r; public double area() /定义area()的处理方式 return (pi*radius*radius); public void setColor(String str) /定义setColor()的处理方式 color=str; System.out.println(“color=“

18、+color); ,接口,5.1.3 多重继承 例5_6,23,测试类 public class MultiInterfaceTester public static void main(String args) Circle cir; cir=new Circle(2.0); cir.setColor(“blue“); System.out.println(“Area = “ + cir.area(); 输出结果 color=blue Area = 12.56,接口,5.1.3 多重继承 例5_6运行结果,24,5.1.4 接口的扩展,接口的扩展 接口可通过扩展的技术派生出新的接口 原来的接

19、口称为基本接口(base interface)或父接口(super interface) 派生出的接口称为派生接口(derived interface)或子接口(sub interface) 派生接口不仅可以保有父接口的成员,同时也可加入新成员以满足实际问题的需要 实现接口的类也必须实现此接口的父接口 接口扩展的语法 interface 子接口的名称 extends 父接口的名称1,父接口的名称2, ,接口,25,Shape是父接口,Shape2D与Shape3D是其子接口。Circle类及Rectangle类实现接口Shape2D,而Box类及Sphere类实现接口Shape3D,5.1.4

20、 接口的扩展 例5_7,接口,26,部分代码如下 / 声明Shape接口 interface Shape double pi=3.14; void setColor(String str); /声明Shape2D接口扩展了Shape接口 interface Shape2D extends Shape double area(); ,5.1.4 接口的扩展 例5_7,接口,27,class Circle implements Shape2D double radius; String color; public Circle(double r) radius=r; public double a

21、rea() 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(2.0); cir.setColor(“blue“); System.out.println(“Area = “ + cir.area(); ,5.1.4 接口的扩

22、展 例5_7,接口,28,运行结果 color=blue Area = 12.56 说明 首先声明了父接口Shape,然后声明其子接口Shape2D 之后声明类Circle实现Shape2D子接口,因而在此类内必须明确定义setColor()与area()方法的处理方式 最后在主类中我们声明了Circle类型的变量cir并创建新的对象,最后通过cir对象调用setColor()与area()方法,5.1.4 接口的扩展 例5_7运行结果,接口,29,FixedInsurable 和DepreciatingInsurable接口 都继承了Insurable接口 实现它们类也必须实现Insurab

23、le接口中的所有方法 public interface DepreciatingInsurable extends Insurable public double computeFairMarketValue(); public interface FixedInsurable extends Insurable public int getEvaluationPeriod(); ,5.1.4 接口的扩展 Insurable接口的例子,接口,30,5.2 塑型,塑型(type-casting) 又称为类型转换 方式 隐式(自动)的类型转换 显式(强制)的类型转换,31,5.2.1 塑型的概念,

24、塑型的对象包括 基本数据类型 将值从一种形式转换成另一种形式 引用变量 将对象暂时当成更一般的对象来对待,并不改变其类型 只能被塑型为 任何一个父类类型 对象所属的类实现的一个接口 被塑型为父类或接口后,再被塑型回其本身所在的类,塑型,32,Manager对象 可以被塑型为Employee、Person、Object或Insurable, 不能被塑型为Customer、Company或Car,5.2.1 塑型的概念 一个例子,塑型,33,基本数据类型 相容类型之间存储容量低的自动向存储容量高的类型转换 引用变量 被塑型成更一般的类 Employee emp; emp = new Manager

25、(); /将Manager类型的对象直接赋给 /Employee类的引用变量,系统会 /自动将Manage对象塑型为Employee类 被塑型为对象所属类实现的接口类型 Car jetta = new Car(); Insurable item = jetta;,5.2.1 塑型的概念 隐式(自动)的类型转换,塑型,34,5.2.1 塑型的概念 显式(强制)的类型转换,基本数据类型 (int)871.34354; / 结果为 871 (char)65; / 结果为A (long)453; / 结果为453L 引用变量:还原为本来的类型 Employee emp; Manager man; em

26、p = new Manager(); man = (Manager)emp; /将emp强制塑型为本来的类型,塑型,35,5.2.2 塑型的应用,塑型应用的场合包括 赋值转换 赋值号右边的表达式类型或对象转换为左边的类型 方法调用转换 实参的类型转换为形参的类型 算数表达式转换 算数混合运算时,不同类型的项转换为相同的类型再进行运算 字符串转换 字符串连接运算时,如果一个操作数为字符串,一个操作数为数值型,则会自动将数值型转换为字符串,塑型,36,当一个类对象被塑型为其父类后,它提供的方法会减少 当Manager对象被塑型为Employee之后,它只能接收getName()及getEmploy

27、eeNumber()方法,不能接收getSalary()方法 将其塑型为本来的类型后,又能接收getSalary()方法了,5.2.2 塑型的应用,塑型,37,5.2.3 方法的查找,如果在塑型前和塑型后的类中都提供了相同的方法,如果将此方法发送给塑型后的对象,那么系统将会调用哪一个类中的方法? 实例方法的查找 类方法的查找,塑型,38,从对象创建时的类开始,沿类层次向上查找,Manager man = new Manager(); Employee emp1 = new Employee(); Employee emp2 = (Employee)man; putePay(); / 调用Emp

28、loyee类中的computePay()方法 putePay(); / 调用Manager类中的computePay()方法 putePay(); / 调用Manager类中的computePay()方法,5.2.3 方法的查找 实例方法的查找,塑型,39,总是在引用变量声明时所属的类中进行查找,Manager man = new Manager(); Employee emp1 = new Employee(); Employee emp2 = (Employee)man; man.expenseAllowance(); /in Manager emp1.expenseAllowance()

29、; /in Employee emp2.expenseAllowance(); /in Employee!,5.2.3 方法的查找 类方法的查找,塑型,40,5.3 多态的概念,多态 是指不同类型的对象可以响应相同的消息 从相同的基类派生出来的多个类型可被当作同一种类型对待,可对这些不同的类型进行同样的处理,由于多态性,这些不同派生类对象响应同一方法时的行为是有所差别的 例如 所有的Object类的对象都响应toString()方法 所有的BankAccount类的对象都响应deposit()方法,41,5.3.1 多态的目的,多态的目的 所有的对象都可被塑型为相同的类型,响应相同的消息 使代

30、码变得简单且容易理解 使程序具有很好的“扩展性”,多态的概念,42,绘图直接的方式 希望能够画出任意子类型对象的形状,可以在Shape 类中声明几个绘图方法,对不同的实际对象,采用不同的画法 if (aShape instanceof Circle) aShape.drawCircle(); if (aShape instanceof Triangle) aShape.drawTriangle(); if (aShape instanceof Rectangle)aShape.drawRectangle();,5.3.1 多态的目的 一个例子,多态的概念,43,绘图更好的方式 在每个子类中都声

31、明同名的draw()方法 以后绘图可如下进行 Shape s = new Circle(); s.draw(); Circle属于Shape的一种,系统会执行自动塑型 当调用方法draw时,实际调用的是Circle.draw() 在程序运行时才进行绑定,接下来介绍绑定的概念,5.3.1 多态的目的 一个例子,多态的概念,44,5.3.2 绑定的概念,绑定 指将一个方法调用同一个方法主体连接到一起 根据绑定时期的不同,可分为 早期绑定 程序运行之前执行绑定 晚期绑定 也叫作“动态绑定”或“运行期绑定 基于对象的类别,在程序运行时执行绑定,多态的概念,45,仍以绘图为例,所有类都放在binding

32、包中 基类Shape建立了一个通用接口 class Shape void draw() void erase() 派生类覆盖了draw方法,为每种特殊的几何形状都提供独一无二的行为 class Circle extends Shape void draw() System.out.println(“Circle.draw()“); void erase() System.out.println(“Circle.erase()“); ,5.3.2 绑定的概念 例5_8,多态的概念,46,class Square extends Shape void draw() System.out.print

33、ln(“Square.draw()“); void erase() 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_8,多态的概念,47,对动态绑定进行测试如下 public class BindingTester public static void main(Strin

34、g args) Shape s = new Shape9; 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 s.length; i+) si.draw(); ,5.3.2 绑定的概念 例5_8,多态的概念,48,运行结果 Square.draw() Triangl

35、e.draw() Circle.draw() Triangle.draw() Triangle.draw() Circle.draw() Square.draw() Circle.draw() Triangle.draw() 说明 编译时无法知道s数组元素的具体类型,运行时才能确定类型,所以是动态绑定 在主方法的循环体中,每次随机生成指向一个Circle、Square或者Triangle的引用,5.3.2 绑定的概念 例5_8运行结果,多态的概念,49,所有类都在music包中 Note类中定义了三个音符 Instrument类中声明并实现了一个play方法 Wind类继承了Instrumen

36、t类,重载了play方法 Music类中包含了main方法 class Note private int value; private Note(int val) value = val; public static final Note MIDDLE_C = new Note(0), C_SHARP = new Note(1), B_FLAT = new Note(2); ,5.3.2 绑定的概念 music的例子,多态的概念,50,class Instrument public void play(Note n) System.out.println(“Instrument.play()“

37、); class Wind extends Instrument public void play(Note n) System.out.println(“Wind.play()“); ,5.3.2 绑定的概念(续) music的例子,多态的概念,51,public class Music public static void tune(Instrument i) i.play(Note.MIDDLE_C); public static void main(String args) Wind flute = new Wind(); tune(flute); 运行结果 Wind.play() 说

38、明 运行中,Wind类的对象实际是Instrument类的,所以调用了Wind类中的play方法,5.3.2 绑定的概念(续) music运行结果,多态的概念,52,5.4 多态的应用,多态的应用 技术基础 向上塑型技术:一个父类的引用变量可以指向不同的子类对象 动态绑定技术:运行时根据父类引用变量所指对象的实际类型执行相应的子类方法,从而实现多态性,多态的概念,53,声明一个抽象类Driver及两个子类FemaleDriver及MaleDriver 在Diver类中声明了抽象方法drives,在两个子类中对这个方法进行了重写 public abstract class Driver publ

39、ic Driver( ) public abstract void drives( ); ,5.4 多态的应用(续) 例5_9,多态的概念,54,public class FemaleDriver extends Driver public FemaleDriver( ) public void drives( ) System.out.println(“A Female driver drives a vehicle.“); public class MaleDriver extends Driver public MaleDriver( ) public void drives( ) Sy

40、stem.out.println(“A male driver drives a vehicle.“); ,5.4 多态的应用(续) 例5_9,多态的概念,55,public class Test1 static public void main(String args) Driver a = new FemaleDriver( ); Driver b = new MaleDriver( ); a.drives( ); b.drives( ); 运行结果 A Female driver drives a vehicle. A male driver drives a vehicle.,5.4

41、多态的应用(续) 例5_9,多态的概念,56,所有类都放在drive包中 试想有不同种类的交通工具(vehicle),如公共汽车(bus)及小汽车(car),由此可以声明一个抽象类Vehicle及两个子类Bus及Car 对前面的drives方法进行改进,使其接收一个Vehicle类的参数,当不同类型的交通工具被传送到此方法时,可以输出具体的交通工具,5.4 多态的应用(续) 例5_9改进,多态的概念,57,测试代码可改写如下: public class DriverTest static public void main(String args) Driver a = new FemaleDr

42、iver( ); Driver b = new MaleDriver( ); Vehicle x = new Car( ); Vehicle y = new Bus( ); a.drives(x); b.drives(y); 并希望输出下面的结果 A female driver drives a Car. A male driver drives a bus.,5.4 多态的应用(续) 例5_9改进,多态的概念,58,Vehicle及其子类声明如下 public abstract class Vehicle private String type; public Vehicle( ) publ

43、ic Vehicle(String s) type = s; public abstract void drivedByFemaleDriver(); public abstract void drivedByMaleDriver(); ,5.4 多态的应用(续) 例5_9改进,多态的概念,59,public class Bus extends Vehicle public Bus( ) public void drivedByFemaleDriver() System.out.println(“A female driver drives a bus.“); public void driv

44、edByMaleDriver() System.out.println(“A male driver drives a bus.“); public class Car extends Vehicle public Car( ) public void drivedByFemaleDriver() System.out.println(“A Female driver drives a car.“); public void drivedByMaleDriver() System.out.println(“A Male driver drives a car.“); ,5.4 多态的应用(续)

45、 例5_9改进,多态的概念,60,对FemaleDriver及MaleDriver类中的drives方法进行改进,在drives方法的定义体中不直接输出结果,而是调用Bus及Car类中的相应方法 public abstract class Driver public Driver() public abstract void drives(Vehicle v ); public class FemaleDriver extends Driver public FemaleDriver( ) public void drives(Vehicle v) v.drivedByFemaleDriver

46、(); public class MaleDriver extends Driver public MaleDriver( ) public void drives(Vehicle v) v.drivedByMaleDriver(); ,5.4 多态的应用(续) 例5_9改进,多态的概念,61,运行结果 A Female driver drives a car. A male driver drives a bus. 说明 这种技术称为二次分发(“double dispatching”),即对输出消息的请求被分发两次 首先根据驾驶员的类型被发送给一个类 之后根据交通工具的类型被发送给另一个类,5.4 多态的应用(续) 例5_9改进运行结果,多态的概念,62,5.5 构造方法与多态,构造方法与多态 构造方法与其他方法是有区别的 构造方法并不具有多态性,但仍然非常有必要理解构造方法如何在复杂的分级结构中随同多态性一同使用的情况,63,构造方法的调用顺序 调用基类的构造方法。这个步骤会不断重复下去,首先得到构建的是分级结构的根部,然后是下一个派生类,等等。直到抵达最深一层的派生类 按声明顺序调用成员初始化模块 调

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1