《hinkinginJava07多态.ppt》由会员分享,可在线阅读,更多相关《hinkinginJava07多态.ppt(49页珍藏版)》请在三一办公上搜索。
1、Java编程思想,第七章:多态,面向对象的设计,数据抽象化、封装继承多态,多态,接口与实现分离:实现了“是什么”与“怎样做”两个模块的分离代码的组织以及可读性均能获得改善能创建易于扩充的程序多态性涉及对“类型”的分解:通过继承可将一个对象当作它自己的类型或者它自己的基础类型对待只需一段代码,即可对所有不同的类型(相同的基础类型中衍生出来的)进行同样的处理相似类型之间的区分是通过“函数的行为差异”实现而这些函数都可通过基础类函数唤起,向上转型,将某个 object reference 视为一个指向基类的 reference,class A,class B,/:Music.java(p220)/I
2、nheritance,/Wind objects are instruments/because they have the same interface:class Wind extends Instrument/Redefine interface method:public void play(Note n)System.out.println(Wind.play();public class Music public static void tune(Instrument i)/.i.play(Note.middleC);public static void main(String a
3、rgs)Wind flute=new Wind();tune(flute);/Upcasting/:Ans:Wind.play(),将对象的类型忘掉:为了扩充,/:c07:music2:Music2.java(p221)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);/Etc.class Instrument public void play(Note n
4、)System.out.println(Instrument.play();class Wind extends Instrument public void play(Note n)System.out.println(Wind.play();,class Stringed extends Instrument public void play(Note n)System.out.println(Stringed.play();class Brass extends Instrument public void play(Note n)System.out.println(Brass.pla
5、y();,public class Music2 public static void tune(Wind i)i.play(Note.MIDDLE_C);public static void tune(Stringed i)i.play(Note.MIDDLE_C);public static void tune(Brass i)i.play(Note.MIDDLE_C);public static void main(String args)Wind flute=new Wind();Stringed violin=new Stringed();Brass frenchHorn=new B
6、rass();tune(flute);/No upcasting,oveloading tune(violin);tune(frenchHorn);/:,Ans:Wind.playStringed.playBrass.play,函数调用绑定,Binding:建立函数调用和函数体的关联C:先期绑定Java:后期绑定(除声明为final外)动态绑定,执行期绑定final 关键字:关闭动态绑定,产生正确的行为,调用 base class 中的函数所有的 derived classes 会产生正确的行为将一条消息发给一个对象,让对象自行判断要做什么事情,Shape 及其子类,后期绑定:扩展性,/:Sh
7、apes.java(p225)/Polymorphism in Javaclass Shape void draw()void erase()class Circle extends Shape void draw()System.out.println(Circle.draw();void erase()System.out.println(Circle.erase();,class Square extends Shape void draw()System.out.println(Square.draw();void erase()System.out.println(Square.er
8、ase();class Triangle extends Shape void draw()System.out.println(Triangle.draw();void erase()System.out.println(Triangle.erase();,public class Shapes public static Shape randShape()switch(int)(Math.random()*3)default:/To quiet the compiler case 0:return new Circle();case 1:return new Square();case 2
9、:return new Triangle();public static void main(String args)Shape s=new Shape9;/Fill up the array with shapes:for(int i=0;i s.length;i+)si=randShape();/Make polymorphic method calls:for(int i=0;i s.length;i+)si.draw();/:,Ans:(答案不唯一)Circle.drawSquare.draw Triangle.drawTriangle.drawSquare.drawSquare.dr
10、awSquare.drawCircle.drawSquare.draw,扩充性,后来可加入更多的型别在围绕tune()方法的其他所有代码都发生变化的同时,tune()方法却丝毫不受它们的影响,依然正常工作。这正是利用多形性希望达到的目标。允许程序员“将发生改变的东西同没有发生改变的东西区分开”,Instrument 及其子类,/:Music3.java(p227)/An extensible programimport java.util.*;class Instrument public void play()System.out.println(Instrument.play();publ
11、ic String what()return Instrument;public void adjust()class Wind extends Instrument public void play()System.out.println(Wind.play();public String what()return Wind;public void adjust(),class Percussion extends Instrument public void play()System.out.println(Percussion.play();public String what()ret
12、urn Percussion;public void adjust()class Stringed extends Instrument public void play()System.out.println(Stringed.play();public String what()return Stringed;public void adjust()class Brass extends Wind public void play()System.out.println(Brass.play();public void adjust()System.out.println(Brass.ad
13、just();,class Woodwind extends Wind public void play()System.out.println(Woodwind.play();public String what()return Woodwind;public class Music/Doesnt care about type,so new types/added to the system still work right:static void tune(Instrument i)/.i.play();static void tuneAll(Instrument e)for(int i
14、=0;i e.length;i+)tune(ei);,public static void main(String args)Instrument orchestra=new Instrument5;int i=0;/Upcasting during addition to the array:orchestrai+=new Wind();orchestrai+=new Percussion();orchestrai+=new Stringed();orchestrai+=new Brass();orchestrai+=new Woodwind();tuneAll(orchestra);/:,
15、Ans:Wind.play()Percussion.play()Stringed.play()Brass.play()Woodwind.play(),覆写(重写)(overriding),在子类中,具有与父类相同名字、相同参数表和相同返回值的方法子类通过重写把父类的状态和行为改变为自身的状态和行为子类通过 super 实现对父类成员的访问 Java 通过方法重写来实现多态,覆写 vs.重载,/:c07:WindError.java 重载(p229)/Accidentally changing the interface.class NoteX public static final int M
16、IDDLE_C=0,C_SHARP=1,C_FLAT=2;class InstrumentX public void play(int NoteX)System.out.println(InstrumentX.play();,class WindX extends InstrumentX/OOPS!Changes the method interface:public void play(NoteX n)System.out.println(WindX.play(NoteX n);public class WindError public static void tune(Instrument
17、X i)/.i.play(NoteX.MIDDLE_C);public static void main(String args)WindX flute=new WindX();tune(flute);/Not the desired behavior!/:,Ans:InstumentX.play,Abstract classes(抽象类)和methods(抽象函数),抽象函数前面使用“abstract”关键字一种不完全的函数含有抽象函数的类为抽象类,前面必须使用 Abstract 修饰,即 Abstract class,abstract void f();,Instrument 及其子类,(
18、参阅 p232 Music4.java),构造函数调用顺序,1.调用基类构造函数:反复递归,直到最后一层子类之前2.依次将各个数据成员初始化3.调用子类构造函数本身,Sandwich 层次结构,Meal,Bread,Cheese,Lettuce,Lunch,PortableLunch,Sandwich,构造函数调用顺序,/:Sandwich.java(p234)/Order of constructor calls class Meal Meal()System.out.println(Meal();class Bread Bread()System.out.println(Bread();c
19、lass Cheese Cheese()System.out.println(Cheese();,class Lettuce Lettuce()System.out.println(Lettuce();class Lunch extends Meal Lunch()System.out.println(Lunch();class PortableLunch extends Lunch PortableLunch()System.out.println(PortableLunch();,class Sandwich extends PortableLunch Bread b=new Bread(
20、);Cheese c=new Cheese();Lettuce l=new Lettuce();Sandwich()System.out.println(Sandwich();public static void main(String args)new Sandwich();/:,Ans:Meal()Lunch()PortableLunch()Bread()CheeseLettuceSandwhch,将继承运用于设计,当我们以一个现有类为基础建立一个新类时,如首先选择继承,会使情况变得异常复杂。使用继承时要谨慎准则:使用继承表达行为上的差异,以数据成员表达状态上的变化组合手法较灵活,弹性大,
21、/:Transmogrify.java(p241)/Dynamically changing the behavior of/an object via composition.abstract class Actor abstract void act();class HappyActor extends Actor public void act()System.out.println(HappyActor);class SadActor extends Actor public void act()System.out.println(SadActor);,class Stage Act
22、or a=new HappyActor();void change()a=new SadActor();void go()a.act();public class Transmogrify public static void main(String args)Stage s=new Stage();s.go();/Prints HappyActor s.change();s.go();/Prints SadActor/:,Ans:HappyActorSadActor,纯粹继承 p242 图,只加以覆写“is-a”(是一种)关系纯取代,如下面这张图所示:,扩充 p243 图,“is-like-
23、a”(像是一个)关系关键字“extends”似乎也在鼓励这么做,向下转型与执行期型别辨识,RTTI:run-time type identification向上转型绝对安全向下转型可能会不安全,P244 图,/:c07:RTTI.java(p244)/Downcasting class Useful public void f()public void g()class MoreUseful extends Useful public void f()public void g()public void u()public void v()public void w(),public clas
24、s RTTI public static void main(String args)Useful x=new Useful(),new MoreUseful();x0.f();x1.g();/Compile-time:method not found in Useful:/!x1.u();(MoreUseful)x1).u();/Downcast/RTTI(MoreUseful)x0).u();/Exception thrown/:Ans:编译通过,运行时产生 ClassCastException 错误,执行期型别,使客户端得以发现对象的型别ClassCastException第12章,摘要,多态:不同的形式多态是后期绑定发现classes的共同性及彼此关系可扩充性是关键,作业,阅读第 7 章第 7章:2,9,14,谢谢,