父類的引用對象指向子類的對象
阿新 • • 發佈:2017-07-23
() exce png hole 虛擬機 end 類對象 -h 類型
在java的多態中,經常會看到父類的引用對象指向子類的對象,一開始很迷茫,因為按照之前所學的知識,父類的引用對象指向自身對象或者子類的引用對象指向自身對象都不難理解,因此為了方便理解,下面舉了一個例子:水杯和水壺的比喻。
下面的一段代碼來實現這個比喻:
1 public class Kettle { 2 public Kettle(){ 3 System.out.println("水壺容量有2升"); 4 } 5 } 6 7 public class Cup extends Kettle { 8 publicCup(){ 9 System.out.println("水杯容量為0.5升"); 10 } 11 } 12 13 public class Test { 14 public static void main(String[] args) { 15 Kettle k = new Kettle(); //父類的引用對象指向自身:把2升水倒入到水壺中,不會溢出 16 Cup c = new Cup();//子類的引用對象指向自身:把0.5升的水倒入到水杯中,不會溢出 17 Kettle k1 = new Cup(); //父類的引用對象指向子類:把0.5升的水倒入到水壺中,不會溢出18 Kettle k2 = (Kettle)c; //父類的引用對象指向子類中繼承父類的那一部分對象:把水杯中的0.5升水倒入到水壺中,不會溢出 19 Cup c2 = (Cup)k; //子類的引用對象指向父類對象,報錯,不能轉換類型:水壺裏面的水不能倒入到水杯中,會溢出 20 Cup c3 = (Cup)k2;//相當於Cup c3 = (Cup)(Kettle)c,子類的引用對象指向子類中繼承父類的那一部分對象:把水壺中0.5升的水倒入到水杯中,不會溢出 21 } 22 }
上面的代碼運行結果如下:
1 水壺容量有2升 2 水壺容量有2升3 水杯容量為0.5升 4 水壺容量有2升 5 水杯容量為0.5升 6 Exception in thread "main" java.lang.ClassCastException: mycom.Kettle cannot be cast to mycom.Cup 7 at mycom.Test.main(Test.java:9)
其中報錯的哪一行就是Cup c2 = (Cup)k,由於無法轉換類型。
下面來改寫一下代碼
1 public class Kettle { 2 public void holeWater(){ 3 System.out.println("水壺有裝水的功能"); 4 } 5 } 6 7 public class Cup extends Kettle { 8 public void holeWater(){ 9 System.out.println("水杯也有裝水的功能"); 10 } 11 public void drinkWater(){ 12 System.out.println("水杯可以拿來喝水的功能"); 13 } 14 } 15 16 17 public class Test { 18 public static void main(String[] args) { 19 Kettle k = new Cup(); //父類的引用對象指向子類 20 k.holeWater(); 21 k.darinkWater(); //報錯 22 } 23 }
首先,要實現多態,必須有三個條件:父類引用、子類對象、方法覆蓋,在上面的程序中,k調用holeWater方法可以正常編譯,因為滿足三個條件,而後面的drinkWater方法由於在父類中沒有,因此在調用時,會報錯,沒有滿足“方法覆蓋"的條件,多態實際上是一種機制,在編譯時刻,會生成一張虛擬表,來記錄所有覆蓋的方法,沒有被覆蓋的方法是不會記錄到這張表的.若一個父類引用調用了沒有覆蓋的子類方法,那麽是不符合該表的,那麽編譯時刻就會報錯. 在執行程序的時候,虛擬機會去這張虛擬表中找覆蓋的方法,比如引用中實際上存的是一個子類對象引用,那麽就會去找子類中的相應的覆蓋的方法來執行。
用父類的引用對象指向子類對象,可以隱藏各個對象不同的細節,專註於共同的屬性,這就是面向對象的思想。
父類的引用對象指向子類的對象