1、定义函数
向上转型:子类对象转为父类,父类能够是接口。 如:Father f = new Son();spa
向下 转型:父类对象转为子类。 如: Son s = (Son)f; code
注:括号内容为强制转型,向下转型必须要这样作。向上转型则不须要这样作对象
2、 向上转型使用举例blog
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..get
结果分析:编译器
向上转型会丢失子类特有的方法(如,上述例子中的h.speak()),可是子类重写了父类的方法,子类方法有效,向上转型只能引用父类对象的属性,要引用子类对象属性,则要写getter函数。要想使用子类特有的方法,则须要将其向下转型。编译
注意:只有非private方法才能够被覆盖,若子类对父类的private方法进行重载,则,当使用向上转型时,编译器将不会报错,而且将子类重载的方式视为新的子类方法。class
问题:
既然向上转型使用起来这么麻烦,而且在使用过程当中会丢失子类特有的方法,在使用子类特有的方法时,还必须对其进行向下转型,为何在使用时不直接定义Son s = new Son();呢??
3、向上转型使用举例二
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()方法。