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()方法。