Java多态:向上转型
一、定义
向上转型:子类对象转为父类,父类可以是接口。 如:Father f = new Son();
向下 转型:父类对象转为子类。 如: Son s = (Son)f;
注:括号内容为强制转型,向下转型必需要这样做。向上转型则不需要这样做
二、 向上转型使用举例
1 public class Human { 2 3 public void sleep() { 4 System.out.println("Human sleep.."); 5 } 6 7 public static void main(String[] args) { 8 Human h = new Male();// 向上转型 9 h.sleep(); 10 Male m = new Male(); 11 m.sleep(); 12 // h.speak();此方法不能编译,报错说Human类没有此方法 13 } 14 } 15 16 class Male extends Human { 17 public void sleep() { 18 System.out.println("Male sleep.."); 19 } 20 21 public void speak() { 22 System.out.println("I am Male"); 23 } 24 }
运行结果:
Male sleep..
Male sleep..
结果分析:
向上转型会丢失子类特有的方法(如,上述例子中的h.speak()),但是子类重写了父类的方法,子类方法有效,向上转型只能引用父类对象的属性,要引用子类对象属性,则要写getter函数。要想使用子类特有的方法,则需要将其向下转型。
注意:只有非private方法才可以被覆盖,若子类对父类的private方法进行重载,则,当使用向上转型时,编译器将不会报错,并且将子类重载的方式视为新的子类方法。
问题:
既然向上转型使用起来这么麻烦,并且在使用过程中会丢失子类特有的方法,在使用子类特有的方法时,还必须对其进行向下转型,为什么在使用时不直接定义Son s = new Son();呢??
三、向上转型使用举例二
1 package polymorphism.music; 2 3 public enum Note 4 { 5 MIDDLE_C, C_SHARP, B_FLAT; 6 } 7 8 ///////////////////////////////////////////// 9 10 package polymorphism.music; 11 12 class Instrument 13 { 14 public void play(Note n) 15 { 16 System.out.println("Instrument.play()"); 17 } 18 } 19 20 ///////////////////////////////////////////// 21 22 package polymorphism.music; 23 24 public class Wind extends Instrument 25 { 26 public void play(Note n) 27 { 28 System.out.println("Wind.play()" + n); 29 } 30 } 31 32 ///////////////////////////////////////////// 33 34 package polymorphism.music; 35 36 public class Music 37 { 38 public static void tune(Instrument i) 39 { 40 i.play(Note.MIDDLE_C); 41 } 42 43 public static void main(String[] args) 44 { 45 Wind flute = new Wind(); 46 tune(flute); 47 } 48 }
运行结果:
Wind.play()MIDDLE_C
结果分析:
Music.tune()方法接收一个Instrument的引用,同时也接受任何导出的Instrument的类。在main中,当一个Wind引用tune()方法时,便出现了该情况,因此不需要任何类型转化。其中,tune(flute)便是一个向上转型。
在进行向上转型时会出现忘记对象类型这种情况。虽然让tune()方法直接接受一个Wind引用作为自己参数更为直观,但是这样会产生一个问题:如果这样做了,就需要对Instrument的每种类型都编写一个新的tune()方法。