JAVA语言程序设计 (2).ppt

上传人:牧羊曲112 文档编号:6510197 上传时间:2023-11-07 格式:PPT 页数:69 大小:359.50KB
返回 下载 相关 举报
JAVA语言程序设计 (2).ppt_第1页
第1页 / 共69页
JAVA语言程序设计 (2).ppt_第2页
第2页 / 共69页
JAVA语言程序设计 (2).ppt_第3页
第3页 / 共69页
JAVA语言程序设计 (2).ppt_第4页
第4页 / 共69页
JAVA语言程序设计 (2).ppt_第5页
第5页 / 共69页
点击查看更多>>
资源描述

《JAVA语言程序设计 (2).ppt》由会员分享,可在线阅读,更多相关《JAVA语言程序设计 (2).ppt(69页珍藏版)》请在三一办公上搜索。

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

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

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

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

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

6、的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 code here,7.1.2

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

8、Car)item).getMileage();/转型回原类,可调用此方法了,7.1.2 实现接口 对象转型,接口,13,7.1.2 实现接口 例7_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;public Rectangle(int w,int h)width=w;height=h;pu

9、blic 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=new Circle(2.0);System.out.println(Area of cir=+cir.area();运行结果

10、Area of rect=30.0Area of cir=12.56,7.1.2 实现接口 例7_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=+var1.area();var2=new Circle(2.0);System.out.println(Area of var2=+var2.area();输出结果

11、Area of var1=30.0Area of var2=12.56,7.1.2 实现接口 例7_5,接口,16,MovableObject接口定义了所有“可移动对象”能做的事情public interface MovableObject public boolean start();public void stop();public boolean turn(int degrees);public double fuelRemaining();public void changeSpeed(double kmPerHour);,7.1.2 实现接口 MovableObject接口,接口,1

12、7,Plane、Car、Train、Boat 分别实现 MovableObject 接口public class Plane implements MovableObject public int seatCapacity;public Company owner;public DatelastRepairDate;/实现MovalbelObject接口的所有方法 public boolean start()/启动飞机,成功则返回true public void stop()/停止 public boolean turn(int degrees)/转向,成功则返回true public dou

13、ble fuelRemaining()/返回燃料剩余量 public void changeSpeed(double kmPerHour)/改变速度/plane类自己的方法:public Date getLastRepairDate()/.public double calculateWindResistance()/.,7.1.2 实现接口 MovableObject接口的实现,接口,18,为 MovableObjects安装遥控器(remote control)public class RemoteControl private MovableObjectmachine;RemoteCon

14、trol(MovableObject m)machine=m;/按下“启动”按钮:public void start()boolean okay=machine.start();if(!okay)display(No Response on start);/.remote control 构造方法的形参类型为 MovableObject,它可以是Plane,Car,Train,Boat,等等,7.1.2 实现接口 RemoteControl类,接口,19,7.1.3 多重继承,多重继承Java的设计以简单实用为导向,不允许一个类有多个父类但允许一个类可以实现多个接口,通过这种机制可实现多重继承

15、一个类实现多个接口的语法如下类修饰符 class 类名称 implements 接口1,接口2,接口,20,Car类可以实现接口Insurable,Drivable,Sellablepublic class Car implements Insurable,Drivable,Sellable.,7.1.3 多重继承 Car的例子,接口,21,声明Circle类实现接口Shape2D和ColorShape2D具有pi与area()方法,用来计算面积Color则具有setColor方法,可用来赋值颜色通过实现这两个接口,Circle类得以同时拥有这两个接口的成员,达到了多重继承的目的interfa

16、ce Shape2D/声明Shape2D接口 final double pi=3.14;/数据成员一定要初始化 public abstract double area();/抽象方法interface Color void setColor(String str);/抽象方法,7.1.3 多重继承 例7_6,接口,22,class Circle implements Shape2D,Color/实现Circle类 double radius;String color;public Circle(double r)/构造方法 radius=r;public double area()/定义are

17、a()的处理方式 return(pi*radius*radius);public void setColor(String str)/定义setColor()的处理方式 color=str;System.out.println(color=+color);,接口,7.1.3 多重继承 例7_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=+c

18、ir.area();输出结果color=blueArea=12.56,接口,7.1.3 多重继承 例7_6运行结果,24,7.1.4 接口的扩展,接口的扩展接口可通过扩展的技术派生出新的接口原来的接口称为基本接口(base interface)或父接口(super interface)派生出的接口称为派生接口(derived interface)或子接口(sub interface)派生接口不仅可以保有父接口的成员,同时也可加入新成员以满足实际问题的需要实现接口的类也必须实现此接口的父接口接口扩展的语法interface 子接口的名称 extends 父接口的名称1,接口,25,Shape是父

19、接口,Shape2D与Shape3D是其子接口。Circle类及Rectangle类实现接口Shape2D,而Box类及Sphere类实现接口Shape3D,7.1.4 接口的扩展 例7_7,接口,26,部分代码如下/声明Shape接口interface Shape double pi=3.14;void setColor(String str);/声明Shape2D接口扩展了Shape接口interface Shape2D extends Shape double area();,7.1.4 接口的扩展 例7_7,接口,27,class Circle implements Shape2D d

20、ouble 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(2.0);cir.setColor(bl

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

22、surable接口都继承了Insurable接口实现它们类也必须实现Insurable接口中的所有方法public interface DepreciatingInsurable extends Insurable public double computeFairMarketValue();public interface FixedInsurable extends Insurable public int getEvaluationPeriod();,7.1.4 接口的扩展 Insurable接口的例子,接口,30,7.2 塑型,塑型(type-casting)又称为类型转换方式隐式(自

23、动)的类型转换显式(强制)的类型转换,31,7.2.1 塑型的概念,塑型的对象引用变量将对象暂时当成更一般的对象来对待,并不改变其类型只能被塑型为任何一个父类类型对象所属的类实现的一个接口被塑型为父类或接口后,再被塑型回其本身所在的类,塑型,32,Manager对象可以被塑型为Employee、Person、Object或Insurable,不能被塑型为Customer、Company或Car,7.2.1 塑型的概念 一个例子,塑型,33,引用变量被塑型成更一般的类Employee emp;emp=new Manager();Car jetta=new Car();Insurable item

24、=jetta;,7.2.1 塑型的概念 隐式(自动)的类型转换,塑型,34,7.2.1 塑型的概念 显式(强制)的类型转换,引用变量:还原为本来的类型Employee emp;Manager man;emp=new Manager();man=(Manager)emp;/将emp强制塑型为本来的类型,塑型,35,当一个类对象被塑型为其父类后,它提供的方法会减少当Manager对象被塑型为Employee之后,它只能接收getName()及getEmployeeNumber()方法,不能接收getSalary()方法将其塑型为本来的类型后,又能接收getSalary()方法了,7.2.2 塑型的

25、应用,塑型,36,7.2.3 方法的查找,如果在塑型前和塑型后的类中都提供了相同的方法,如果将此方法发送给塑型后的对象,那么系统将会调用哪一个类中的方法?实例方法类方法,塑型,37,Manager man=new Manager();Employee emp1=new Employee();Employee emp2=(Employee)man;putePay();/调用Employee类中的computePay()方法 putePay();/调用Manager类中的computePay()方法 putePay();/调用Manager类中的computePay()方法,7.2.3 方法的查找

26、 实例方法,塑型,38,总是在变量声明时所属的类中进行查找,Manager man=new Manager();Employee emp1=new Employee();Employee emp2=(Employee)man;man.expenseAllowance();/in Manager emp1.expenseAllowance();/in Employee emp2.expenseAllowance();/in Employee!,7.2.3 方法的查找 类方法,塑型,39,7.3 多态的概念,多态是指不同类型的对象可以响应相同的消息从相同的基类派生出来的多个类型可被当作同一种类型对

27、待,可对这些不同的类型进行同样的处理,由于多态性,这些不同派生类对象响应同一方法时的行为是有所差别的 例如所有的Object类的对象都响应toString()方法所有的BankAccount类的对象都响应deposit()方法,40,7.3.1 多态的目的,多态的目的所有的对象都可被塑型为相同的类型,响应相同的消息使代码变得简单且容易理解使程序具有很好的“扩展性”,多态的概念,41,绘图希望能够画出任意子类型对象的形状,可以在Shape 类中声明几个绘图方法,对不同的实际对象,采用不同的画法if(aShape instanceof Circle)aShape.drawCircle();if(a

28、Shape instanceof Triangle)aShape.drawTriangle();if(aShape instanceof Rectangle)aShape.drawRectangle();,7.3.1 多态的目的 一个例子,多态的概念,42,更好的方式在每个子类中都声明同名的draw()方法以后绘图可如下进行Shape s=new Circle();s.draw();Circle属于Shape的一种,系统会执行自动塑型当调用方法draw时,实际调用的是Circle.draw()在程序运行时才进行绑定,接下来介绍绑定的概念,7.3.1 多态的目的 一个例子,多态的概念,43,7.

29、3.2 绑定的概念,绑定指将一个方法调用同一个方法主体连接到一起根据绑定时期的不同,可分为早期绑定(静态绑定)方法的重载程序运行之前执行绑定晚期绑定(动态绑定)方法的重写也叫作“动态绑定”或“运行期绑定基于对象的类别,在程序运行时执行绑定,多态的概念,44,仍以绘图为例,所有类都放在binding包中基类Shape建立了一个通用接口class Shape void draw()void erase()派生类覆盖了draw方法,为每种特殊类型的几何形状都提供独一无二的行为class Circle extends Shape void draw()System.out.println(Circle

30、.draw();void erase()System.out.println(Circle.erase();,7.3.2 绑定的概念 例7_8,多态的概念,45,class Square extends Shape 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.prin

31、tln(Triangle.erase();,7.3.2 绑定的概念 例7_8,多态的概念,46,对动态绑定进行测试如下public class BindingTester 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=

32、0;i s.length;i+)si.draw();,7.3.2 绑定的概念 例7_8,多态的概念,47,运行结果Square.draw()Triangle.draw()Circle.draw()Triangle.draw()Triangle.draw()Circle.draw()Square.draw()Circle.draw()Triangle.draw()说明编译的时候是无法知道s数组元素的具体类型到底是什么运行的时候才能确定究竟是什么类型,所以是动态绑定在主方法的循环体中,每次根据运行时产生的随机数生成指向一个Circle、Square或者Triangle的引用,所以每次运行都可能有不

33、同的结果,7.3.2 绑定的概念 例7_8运行结果,多态的概念,48,7.4 多态的应用,多态的应用技术基础向上塑型技术:一个父类的引用变量可以指向不同的子类对象动态绑定技术:运行时根据父类引用变量所指对象的实际类型执行相应的子类方法,从而实现多态性,多态的概念,49,声明一个抽象类Driver及两个子类FemaleDriver及MaleDriver在Diver类中声明了抽象方法drives,在两个子类中对这个方法进行了重写public abstract class Driverpublic Driver()public abstract void drives();,7.4 多态的应用(续)

34、例7_9,多态的概念,50,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()System.out.println(A male driver drives a vehicle.);,7.4 多态的应用(续)例7_9,多态

35、的概念,51,public class Test1static 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.,7.4 多态的应用(续)例7_9,多态的概念,52,所有类都放在drive包中试想有不同种类的交通工具(vehicle),如公共汽车(bus)及小汽车(car),由此可以声明一个抽象类Ve

36、hicle及两个子类Bus及Car对前面的drives方法进行改进,使其接收一个Vehicle类的参数,当不同类型的交通工具被传送到此方法时,可以输出具体的交通工具,7.4 多态的应用(续)例7_9改进,多态的概念,53,测试代码可改写如下:public class DriverTest static public void main(String args)Driver a=new FemaleDriver();Driver b=new MaleDriver();Vehicle x=new Car();Vehicle y=new Bus();a.drives(x);b.drives(y);并

37、希望输出下面的结果A female driver drives a Car.A male driver drives a bus.,7.4 多态的应用(续)例7_9改进,多态的概念,54,Vehicle及其子类声明如下public abstract class Vehicleprivate String type;public Vehicle()public Vehicle(String s)type=s;public abstract void drivedByFemaleDriver();public abstract void drivedByMaleDriver();,7.4 多态的应

38、用(续)例7_9改进,多态的概念,55,public class Bus extends Vehicle public Bus()public void drivedByFemaleDriver()System.out.println(A female driver drives a bus.);public void drivedByMaleDriver()System.out.println(A male driver drives a bus.);public class Car extends Vehicle public Car()public void drivedByFemale

39、Driver()System.out.println(A Female driver drives a car.);public void drivedByMaleDriver()System.out.println(A Male driver drives a car.);,7.4 多态的应用(续)例7_9改进,多态的概念,56,对FemaleDriver及MaleDriver类中的drives方法进行改进,在drives方法的定义体中不直接输出结果,而是调用Bus及Car类中的相应方法public abstract class Driver public Driver()public ab

40、stract void drives(Vehicle v);public class FemaleDriver extends Driverpublic FemaleDriver()public void drives(Vehicle v)v.drivedByFemaleDriver();public class MaleDriver extends Driverpublic MaleDriver()public void drives(Vehicle v)v.drivedByMaleDriver();,7.4 多态的应用(续)例7_9改进,多态的概念,57,运行结果A Female driv

41、er drives a car.A male driver drives a bus.说明这种技术称为二次分发(“double dispatching”),即对输出消息的请求被分发两次首先根据驾驶员的类型被发送给一个类之后根据交通工具的类型被发送给另一个类,7.4 多态的应用(续)例7_9改进运行结果,多态的概念,58,7.6 内部类,内部类在另一个类或方法的定义中定义的类可访问其外部类中的所有数据成员和方法成员可对逻辑上相互联系的类进行分组对于同一个包中的其他类来说,能够隐藏可非常方便地编写事件驱动程序声明方式命名的内部类:可在类的内部多次使用匿名内部类:可在new关键字后声明内部类,并立即

42、创建一个对象假设外层类名为Myclass,则该类的内部类名为Myclass$c1.class(c1为命名的内部类名)Myclass$1.class(表示类中声明的第一个匿名内部类),59,public class Parcel1 class Contents/内部类 private int i=11;public int value()return i;class Destination/内部类 private String label;Destination(String whereTo)label=whereTo;String readLabel()return label;public

43、void ship(String dest)Contents c=new Contents();Destination d=new Destination(dest);System.out.println(d.readLabel();,7.6 内部类 Parcel1.java,内部类,60,public static void main(String args)Parcel1 p=new Parcel1();p.ship(Tanzania);说明在Parcel1类中声明了两个内部类Contents、Destination在ship方法中生成两个内部类对象,并调用了内部类中声明的一个方法,7.6

44、 内部类 Parcel1.java,内部类,61,外部类的方法可以返回内部类的引用变量public class Parcel2 class Contents private int i=11;public int value()return i;class Destination private String label;Destination(String whereTo)label=whereTo;String readLabel()return label;public Destination to(String s)return new Destination(s);public Co

45、ntents cont()return new Contents();,7.6 内部类 Parcel2.java,内部类,62,public void ship(String dest)Contents c=cont();Destination d=to(dest);System.out.println(d.readLabel();public static void main(String args)Parcel2 p=new Parcel2();p.ship(Tanzania);Parcel2 q=new Parcel2();Parcel2.Contents c=q.cont();Parc

46、el2.Destination d=q.to(Borneo);说明to()方法返回内部类Destination的引用cont()方法返回内部类Contents的引用,7.6 内部类 Parcel2.java,内部类,63,内部类实现接口可以完全不被看到,而且不能被调用可以方便实现“隐藏实现细则”。你所能得到的仅仅是指向基类(base class)或者接口的一个引用例子abstract class Contents abstract public int value();interface Destination String readLabel();,7.6 内部类 内部类实现接口,内部类,6

47、4,public class Parcel3 private class PContents extends Contents private int i=11;public int value()return i;protected class PDestination implements Destination private String label;private PDestination(String whereTo)label=whereTo;public String readLabel()return label;public Destination dest(String

48、s)return new PDestination(s);public Contents cont()return new PContents();,7.6 内部类 Parcel3.java,内部类,65,class Test public static void main(String args)Parcel3 p=new Parcel3();Contents c=p.cont();Destination d=p.dest(Tanzania);/Illegal-cant access private class:Parcel3.PContents c=p.new PContents();说明

49、内部类PContents实现了抽象类Contents内部类PDenstination实现了接口Destination外部类Test中不能声明对private的内部类的引用,7.6 内部类 Parcel3测试,内部类,66,在方法内定义一个内部类为实现某个接口,产生并返回一个引用为解决一个复杂问题,需要建立一个类,而又不想它为外界所用,7.6 内部类 方法中的内部类,内部类,67,public class Parcel6 public Contents cont()return new Contents()private int i=11;public int value()return i;p

50、ublic static void main(String args)Parcel6 p=new Parcel6();Contents c=p.cont();,7.6 内部类 匿名的内部类,内部类,68,基类需要一个含参数的构造方法例子public class Parcel7 public Wrapping wrap(int x)return new Wrapping(x)public int value()return super.value()*47;public static void main(String args)Parcel7 p=new Parcel7();Wrapping w

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

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号