收藏 分享(赏)

工学Java语言程序设计第三版清华第5章PPT课件.ppt

上传人:微传9988 文档编号:2337743 上传时间:2018-09-11 格式:PPT 页数:121 大小:651KB
下载 相关 举报
工学Java语言程序设计第三版清华第5章PPT课件.ppt_第1页
第1页 / 共121页
工学Java语言程序设计第三版清华第5章PPT课件.ppt_第2页
第2页 / 共121页
工学Java语言程序设计第三版清华第5章PPT课件.ppt_第3页
第3页 / 共121页
工学Java语言程序设计第三版清华第5章PPT课件.ppt_第4页
第4页 / 共121页
工学Java语言程序设计第三版清华第5章PPT课件.ppt_第5页
第5页 / 共121页
点击查看更多>>
资源描述

1、第5章 接口与多态,Java 2 实用教程-4.13,Programming in JAVA,2,目录,5.1 接口 5.2 塑型 5.3 多态的概念 5.4 多态的应用 5.5 构造方法与多态 5.6 内部类 5.7 本章小结,3,5.1 接口,Java不支持多继承性,即一个类只能有一个父类,Java程序中类的层次结构为树状结构 单继承使Java程序简单,易于管理 如果有不相干的类之间有共同的属性和功能,能否处理?如何处理?,4,各种图形都需要实现绘图方法,可在它们的抽象父类中声明一个draw抽象方法 abstract class GraphicObject int x, y;void mo

2、veTo(int newX, int newY) . . . abstract void draw(); ,比较抽象类,抽象类,5,然后在每一个子类中重写draw方法,例如: class Circle extends GraphicObject void draw() . . . class Rectangle extends GraphicObject void draw() . . . ,抽象类,6,abstract Charge() abstract ContruoTemperature(),一个抽象类的子类如果不是抽象类,则它必须为父类 中的所有抽象方法书写方法体,即重写父类中的所有

3、抽象方法,7,接口允许我们在看起来不相干的对象之间定义共同行为,5.1.1 接口的作用及语法 与抽象类的不同,接口,interface Tempreture,8,什么是接口 在实际中,不相关的类有时会有相同的属性和功能,可将这些属性和功能组织成相对独立的集合,凡是需要这种特定功能的类,均可以实现这个集合,该集合被称为接口。利用接口Java可以实现类似多继承的网状结构 可将接口想象为一个“纯”抽象类。它允许创建者规定一个类的基本形式:方法名、参数列,但不规定方法主体 也可以包含基本数据类型的数据成员,但它们都默认为static和final,一定要赋予初值;方法默认为public abstract

4、,9,5.1.1 接口的作用及语法,接口的作用 是面向对象的一个重要机制 实现多继承,同时免除C+中的多继承那样的复杂性 用来定制一个规范, 建立类和类之间的“协议” 把类根据其实现的功能来分别代表,而不必顾虑它所在的类继承层次;这样可以最大限度地利用动态绑定,隐藏实现细节 实现不同类之间的常量共享 一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能),接口,10,public interface 收费 public void 收取费用(); ,public interface 调节温度 public void controlT

5、emperature(); ,public class 公共汽车 implements 收费 public void 收取费用() System.out.println(“公共汽车:一元/张,不计算公里数“); ,public class 出租车 implements 收费, 调节温度 public void 收取费用() System.out.println(“出租车:1.60元/公里,起价3公里“);public void controlTemperature() System.out.println(“安装了Hair空调“);,返回,11,保险公司的例子 具有车辆保险、人员保险、公司保险

6、等多种保险业务,在对外提供服务方面具有相似性,如都需要计算保险费(premium)等,因此可声明一个Insurable 接口 在UML图中,实现接口用带有空三角形的虚线表示,5.1.1 接口的作用及语法 例5_1,接口,12,接口的语法 声明格式为 接口修饰符 interface 接口名称 extends 父接口名 /方法的原型声明或静态常量 接口的数据成员一定要赋初值,且此值将不能再更改,允许省略final关键字 接口中的方法必须是“抽象方法”,不能有方法体,允许省略public及abstract关键字,5.1.1 接口的作用及语法,接口,13,声明一个接口Shape2D,可利用它来实现二维

7、的几何形状类Circle和Rectangle 把计算面积的方法声明在接口里 pi值是常量,把它声明在接口的数据成员里 interface Shape2D /声明Shape2D接口final double pi=3.14; /数据成员一定要初始化public abstract double area(); /抽象方法 在接口的声明中,由于只有常量的定义和public的abstract方法定义,允许省略一些关键字,也可声明如下 interface Shape2D double pi=3.14; double area(); ,5.1.1 接口的作用及语法 例5_2,接口,14,例5.1中的Insu

8、rable 接口声明如下,可见其中的方法都是抽象方法public interface Insurable public int getNumber(); public int getCoverageAmount(); public double calculatePremium(); public Date getExpiryDate(); ,5.1.1 接口的作用及语法 例5_1保险接口的声明,接口,15,5.1.2 实现接口,接口的实现 接口不能用new运算符直接产生对象,必须利用其特性设计新的类,再用新类来创建对象 利用接口设计类的过程,称为接口的实现,使用implements关键字 语

9、法如下 public class 类名称 implements 接口名称 /* Bodies for the interface methods */ /* Own data and methods. */ 必须实现接口中的所有方法 来自接口的方法必须声明成public,接口,16,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 Recta

10、ngle implements Shape2D int width,height;public Rectangle(int w,int h) width=w;height=h;public double area()return (width * height);,声明Circle与Rectangle两个类实现Shape2D接口,接口,interface Shape2D final double pi=3.14; public abstract double area(); ,17,测试类 public class InterfaceTester public static void main

11、(String args)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(); 运行结果 Area of rect = 30.0 Area of cir = 12.56,5.1.2 实现接口 例5_4运行结果,接口,18,5.1.2 实现接口(补充),1、类在实现接口方法时,一定要使用public进行修饰; 2、类实现的接口方法

12、以及接口中的常量可以被类的对象调用,而且常量可以用类名或接口名直接调用(为什么?)例子:Example4_25.java3、如果一个类使用了某个接口,那么这个类必须实现该接口的所有方法,即为这些方法提供方法体。如果没有实现所有的方法,则该类必须是abstract类。 例子:见后,19,interface Computable int MAX=100;int f(int x);void speak(String s); ,abstract class comp1 implements Computable int number;public int f(int x) int sum=0;for(

13、int i=1;i=x;i+) sum=sum+i;return sum; ,20,4、接口声明时,如果关键字interface前有public,则为public接口,public接口可以被任意一个类使用。如果一个接口没有public,则为友好接口,则只能被同一包中的类使用。,21,理解接口(总结),class comp1 int number;public int f(int x) int sum=0;for(int i=1;i=x;i+) sum=sum+i;return sum; ,class comp2 int number;public int f(int x) return 44+

14、x; ,如果去掉Example4_25中的接口和Computable.MAX, 观察其结果:,22,public class Example4_25 public static void main(String args) China zhang; comp1 zhang;comp2 wang;zhang=new comp1(); wang=new comp2(); zhang.number=991998; wang.number=941548;System.out.println(“number:“+zhang.number+“求和“+zhang.f(100);System.out.prin

15、tln(“number:“+wang.number+“求和“+wang.f(100); ,返回,输出结果: Number:991998求和5050 Number:941548求和144,23,问题:上例中不使用接口程序一样运行。那么为什么要使用接口? 子类必须实现父类所有的抽象方法,即使有的方法在子类并不需要;,机动车,轿车,拖拉机,摩托车,收取费用() 调解温度(),24,接口的思想在于它可以增加很多类都需要实现的功能,使用相同的接口类不一定有继承关系; 如果采用继承父类的方法,那么当父类是abstract类时,子类需要实现父类所有的abstract方法,这有些对子类是没有必要的; 例子:w

16、orkspace/interface/Example4_26.javaEclipse中的interface创建,25,public interface 收费 public void 收取费用(); ,public interface 调节温度 public void controlTemperature(); ,public class 公共汽车 implements 收费 public void 收取费用() System.out.println(“公共汽车:一元/张,不计算公里数“); ,public class 出租车 implements 收费, 调节温度 public void 收取

17、费用() System.out.println(“出租车:1.60元/公里,起价3公里“);public void controlTemperature() System.out.println(“安装了Hair空调“);,26,public class Example4_26 public static void main(String args) / TODO Auto-generated method stub 公共汽车 七路=new 公共汽车();出租车 天宇=new 出租车();电影院 红星=new 电影院();七路.收取费用();天宇.收取费用();红星.收取费用();天宇.con

18、trolTemperature();红星.controlTemperature(); ,public class 电影院 implements 收费, 调节温度 public void 收取费用() System.out.println(“电影院:门票,十元/张“);public void controlTemperature() System.out.println(“安装了中央空调“); ,27,5.1.3 多重继承,多重继承 Java的设计以简单实用为导向,不允许一个类有多个父类 但允许一个类可以实现多个接口,通过这种机制可实现多重继承 一个类实现多个接口的语法如下 类修饰符 class

19、 类名称 implements 接口1,接口2, ,接口,28,Car类可以实现接口Insurable,Drivable,Sellable public class Car implements Insurable, Drivable, Sellable ,5.1.3 多重继承 Car的例子,接口,29,声明Circle类实现接口Shape2D和Color Shape2D具有pi与area()方法,用来计算面积 Color则具有setColor方法,可用来赋值颜色 通过实现这两个接口,Circle类得以同时拥有这两个接口的成员,达到了多重继承的目的 interface Shape2D /声明S

20、hape2D接口final double pi=3.14; /数据成员一定要初始化public abstract double area(); /抽象方法 interface Colorvoid setColor(String str); /抽象方法 ,5.1.3 多重继承 例5_6,接口,30,class Circle implements Shape2D,Color / 实现Circle类 double radius;String color;public Circle(double r) /构造方法radius=r;public double area() /定义area()的处理方式r

21、eturn (pi*radius*radius);public void setColor(String str) /定义setColor()的处理方式color=str;System.out.println(“color=“+color); ,接口,5.1.3 多重继承 例5_6,31,测试类 public class MultiInterfaceTesterpublic static void main(String args) Circle cir;cir=new Circle(2.0);cir.setColor(“blue“);System.out.println(“Area = “

22、+ cir.area(); 输出结果 color=blue Area = 12.56,接口,5.1.3 多重继承 例5_6运行结果,32,5.1.4 接口的扩展,接口的扩展 接口可通过扩展的技术派生出新的接口 原来的接口称为基本接口(base interface)或父接口(super interface) 派生出的接口称为派生接口(derived interface)或子接口(sub interface) 派生接口不仅可以保有父接口的成员,同时也可加入新成员以满足实际问题的需要 实现接口的类也必须实现此接口的父接口 接口扩展的语法 interface 子接口的名称 extends 父接口的名称

23、1,父接口的名称2, ,接口,33,Shape是父接口,Shape2D与Shape3D是其子接口。Circle类及Rectangle类实现接口Shape2D,而Box类及Sphere类实现接口Shape3D,5.1.4 接口的扩展 例5_7,接口,34,部分代码如下 / 声明Shape接口 interface Shape double pi=3.14; void setColor(String str); /声明Shape2D接口扩展了Shape接口 interface Shape2D extends Shape double area(); ,5.1.4 接口的扩展 例5_7,接口,35,c

24、lass Circle implements Shape2D 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

25、 cir;cir=new Circle(2.0);cir.setColor(“blue“);System.out.println(“Area = “ + cir.area(); ,5.1.4 接口的扩展 例5_7,接口,36,运行结果 color=blue Area = 12.56 说明 首先声明了父接口Shape,然后声明其子接口Shape2D 之后声明类Circle实现Shape2D子接口,因而在此类内必须明确定义setColor()与area()方法的处理方式 最后在主类中我们声明了Circle类型的变量cir并创建新的对象,最后通过cir对象调用setColor()与area()方法,

26、5.1.4 接口的扩展 例5_7运行结果,接口,37,FixedInsurable 和DepreciatingInsurable接口 都继承了Insurable接口 实现它们类也必须实现Insurable接口中的所有方法 public interface DepreciatingInsurable extends Insurable public double computeFairMarketValue(); public interface FixedInsurable extends Insurable public int getEvaluationPeriod(); ,5.1.4 接

27、口的扩展 Insurable接口的例子,接口,38,接口回调(补充),接口回调是指:把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中。那么该接口变量就可以调用被类实现的接口中的方法。 为什么要有接口回调? 由于不能直接由接口来创建对象,而必须由实现接口的类创建对象。可以通过声明接口类型的变量,并由该变量来访问对象-对象的变量和方法。,39,interface ShowMessage void 显示商标(String s); class TV implements ShowMessage public void 显示商标(String s) System.out.println(s)

28、; Class PC implements ShowMessage public void 显示商标(String s);,public class Example4_27 public static void main(String args) ShowMessage sm; sm=new TV(); /接口变量sm存放对象引用 sm.显示商标(“长城牌电视机“); sm=new PC(); sm.显示商标(“联想奔月5008PC机“); ,40,public class VariableTester public static void main(String args)Shape2D v

29、ar1,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(); 输出结果 Area of var1 = 30.0 Area of var2 = 12.56,例5_5,接口,41,接口做参数,一个方法的参数是接口类型,可以将任何实现该接口的类的实例的引用传递给该接口参数,接口参数就可以回调类实现的接口方法。 例子:Example4_29.java

30、,42,接口回调和对象塑型 比较Example4_22.java 和Example4_28.java,43,5.2 塑型,塑型(type-casting) 又称为类型转换 方式 隐式(自动)的类型转换 (低到高) 显式(强制)的类型转换(特殊到一般),44,5.2.1 塑型的概念,塑型的对象包括 基本数据类型 将值从一种形式转换成另一种形式 显示(低高)、隐式(高低)-强制转换 特别:字符串与基本数据类型的转换 引用变量 将对象暂时当成更一般的对象来对待,并不改变其类型 只能被塑型为 任何一个父类类型 对象所属的类实现的一个接口 被塑型为父类或接口后,再被塑型回其本身所在的类,塑型,45,假设

31、B类是A类的子类或间接子类,当用子类B创建一个对象,并把这个对象的引用放到A类的对象中时:A a;B b=new B();a=b; 称A类对象 a是子类对象b的上转型对象。 B对象此时被暂时当成A的对象,失去原子类对象的一些属性和功能。例 Employee emp; emp = new Manager(); /将Manager类型的对象直接赋给/Employee类的引用变量,系统会 /自动将Manage对象塑型为Employee类,46,Manager对象 可以被塑型为Employee、Person、Object或Insurable, 不能被塑型为Customer、Company或Car,5.

32、2.1 塑型的概念 一个例子,塑型,47,5.2.1 塑型的概念 塑型的方式,隐式(自动)的类型转换 基本数据类型,相容类型之间存储容量低的自动向存储容量高的类型转换; 引用变量,当一个类需要被塑型为更一般的类(父类、接口)时,系统自动转型。 Employee emp; emp = new Manager(); Car jetta = new Car(); Insurable item= jetta; 显式(强制)的类型转换 当隐式转换不可能时,进行强制转换,48,5.2.2 塑型的应用,塑型应用的场合包括 赋值转换 赋值号右边的表达式类型或对象转换为左边的类型 方法调用转换 实参的类型转换为

33、形参的类型(如:回调) 算数表达式转换 算数混合运算时,不同类型的项转换为相同的类型再进行运算 字符串转换 字符串连接运算时,如果一个操作数为字符串,一个操作数为数值型,则会自动将数值型转换为字符串,塑型,49,当一个类对象被塑型为其父类后,它提供的方法会减少 当Manager对象被塑型为Employee之后,它只能接收getName()及getEmployeeNumber()方法,不能接收getSalary()方法 将其塑型为本来的类型后,又能接收getSalary()方法了,5.2.2 塑型的应用,塑型,50,5.2.3 方法的查找,如果在塑型前和塑型后的类中都提供了相同的方法,如果将此方

34、法发送给塑型后的对象,那么系统将会调用哪一个类中的方法? 实例方法的查找 类方法的查找,塑型,51,对于实例方法从对象创建时的原始类开始,沿类层次向上查找,Manager man = new Manager(); Employee emp1 = new Employee(); Employee emp2 = (Employee)man; / emp2=new Manger(); putePay(); / 调用Employee类中的computePay()方法 putePay(); / 调用Manager类中的computePay()方法 putePay(); / 调用Manager类中的com

35、putePay()方法,5.2.3 方法的查找 实例方法的查找,塑型,52,对于类方法,总是在引用变量声明时所属的类中进行查找,Manager man = new Manager(); Employee emp1 = new Employee(); Employee emp2 = (Employee)man; man.expenseAllowance(); /in Manager emp1.expenseAllowance(); /in Employee emp2.expenseAllowance(); /in Employee!,5.2.3 方法的查找 类方法的查找,塑型,53,class

36、Teacher protected String name;public String Teaching (String className)return “正在教小学“+className;public int Year (int y)return y; ,class Professor extends Teacherpublic String Teaching (String className) return “正在教大学“+className;,54,public class Demopublic static void main(String args)Professor p=new

37、 Professor();Teacher t=(Teacher)p; /t成为p的上转对象System.out.println (p.Teaching(“语文“); /继承父类方法System.out.println (t.Teaching(“数学”); /调用Professor中的方法System.out.println (“教书年限“+t.Year(10); /继承父类方法,输出结果: 正在教大学语文 正在教大学数学 教书年限10,55,class Teacher protected String name;public static String Teaching (String cla

38、ssName)return “正在教小学“+className;public int Year (int y)return y; ,class Professor extends Teacherpublic static String Teaching (String className) return “正在教大学“+className;,56,public class Demopublic static void main(String args)Professor p=new Professor();Teacher t=(Teacher)p; /t成为p的上转对象System.out.p

39、rintln (p.Teaching(“语文“); /继承父类方法System.out.println (t.Teaching(“数学”); /调用Teacher中的方法System.out.println (“教书年限“+t.Year(10); /继承父类方法,输出结果: 正在教大学语文 正在教小学数学 教书年限10,57,5.3 多态的概念,多态 多态性是指不同类型的对象可以响应相同的消息。如:父类的某个方法被其子类重写时,可以各自产生自己的功能行为 . 当一个类有很多子类时,并且这些子类都重写了父类中的某个方法。当把子类创建的对象的引用放到一个父类的对象中时,就得到了该对象的一个上转型对

40、象,这个上转的对象在调用这个方法时就可能具有多种形态,因为不同子类在重写父类方法时可能产生不同的行为。 例如 所有的Object类的对象都响应toString()方法 所有的BankAccount类的对象都响应deposit()方法,58,class 动物 void cry() System.out.print(“发出声“); class 狗 extends 动物 void cry() System.out.println(“汪汪.“); class 猫 extends 动物 void cry() System.out.println(“喵喵.“); ,class Example4_20 pu

41、blic static void main(String args) 动物 dongwu;/将子类创建的对象放到父类中 dongwu=new 狗();dongwu.cry(); dongwu=new 猫();dongwu.cry(); ,59,5.3.1 多态的目的,多态的目的 所有的对象都可被塑型为相同的类型,响应相同的消息。即,可将对象当作其基类对象对待。这样,从相同的基类派生出来的多个类型可被当着同一种类型对待,可对不同的类型进行同样的处理。 派生类对象响应同一方法时的行为是不一样的。如何知道派生类调用的方法,这需要在运行时进行动态绑定。,多态的概念,60,观查下面例子,理解多态 绘图直

42、接的方式 希望能够画出任意子类型对象的形状,可以在Shape 类中声明几个绘图方法,对不同的实际对象,采用不同的画法,5.3.1 多态的目的 一个例子,多态的概念,aString =aShape.getClass().getName();if(aString.equals(“Circle”)aShape.deawCircle();if(aString.equals(“Triangle”)aShape.deawTriangle();if(aString.equals(“Rectangle”)aShape.deawRectangle();,if (aShape instanceof Circle)

43、 aShape.drawCircle(); if (aShape instanceof Triangle) aShape.drawTriangle(); if (aShape instanceof Rectangle)aShape.drawRectangle();,62,绘图更好的方式 在每个子类中都声明同名的draw()方法,5.3.1 多态的目的 一个例子,多态的概念,63,if (aShape instanceof Circle) aShape.draw (); if (aShape instanceof Triangle) aShape.draw(); if (aShape insta

44、nceof Rectangle) aShape.draw ();,64,可将上面代码进行如下简化: Shape s = new Circle(); s.draw(); Circle属于Shape的一种,系统会执行自动塑型 当调用方法draw时,实际调用的是Circle.draw() 如何区别不同派生类对同一方法的调用?在程序运行时进行绑定,65,5.3.2 绑定的概念,绑定 指将一个方法调用同一个方法主体连接到一起。即,在主方法的循环体中确定调用方法。 根据绑定时期的不同,可分为 早期绑定 程序运行之前执行绑定 晚期绑定 也叫作“动态绑定”或“运行期绑定 基于对象的类别,在程序运行时执行绑定,

45、多态的概念,66,仍以绘图为例,所有类都放在binding包中 基类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,多态的概念,67,class Square extends Shape

46、 void draw() System.out.println(“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,多态的概念,68,对动态绑定进行测试如下 public class BindingTester

47、public static void main(String 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,多态的概念,69,运行结果 Square.draw() Triangle.draw() Circle.draw() Triangle.draw() Triangle.draw() Circle.draw() Square.draw() Circle.draw() Triangle.draw() 说明 编译时无法知道s数组元素的具体类型,运行时才能确定类型,所以是动态绑定 在主方法的循环体中,每次随机生成指向一个Circle、Square或者Triangle的引用,

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

当前位置:首页 > 中等教育 > 小学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报