1. 程式人生 > >java基礎之向上造型與多型

java基礎之向上造型與多型

最近瀏覽部落格的時候看到一個題,主要講多型的,看了之後仔細研究了一下,發現自己出了不少問題,由於題主沒有詳細的解釋點選開啟連結聽說體面的人抄襲都要放人家連結,因此在這裡分享一下自己遇到的問題也方便大家理解:

如何理解多型?

例項解析:

(一)相關類
 
class A ...{  
         public String show(D obj)...{  
                return ("A and D");  
         }   
         public String show(A obj)...{  
                return ("A and A");  
         }   
}   
class B extends A...{  
         public String show(B obj)...{  
                return ("B and B");  
         }  
         public String show(A obj)...{  
                return ("B and A");  
         }   
}  
class C extends B...{}   
class D extends B...{}  
 
 
(二)問題:以下輸出結果是什麼?
 
A a1 = new A();  
        A a2 = new B();  
        B b = new B();  
        C c = new C();   
        D d = new D();   
        System.out.println(a1.show(b));   ①  
        System.out.println(a1.show(c));   ②  
        System.out.println(a1.show(d));   ③  
        System.out.println(a2.show(b));   ④  
        System.out.println(a2.show(c));   ⑤  
        System.out.println(a2.show(d));   ⑥  
        System.out.println(b.show(b));    ⑦  
        System.out.println(b.show(c));    ⑧  
        System.out.println(b.show(d));    ⑨     
 
 
(三)答案
 
①   A and A
②   A and A
③   A and D
④   B and A
⑤   B and A
⑥   A and D
⑦   B and B
⑧   B and B
⑨   A and D

相信很多道友跟我一樣看了答案之後都有點懵,當然大佬除外,下面看我娓娓道來:

首先理解上述問題你需要知道什麼是多型?什麼是向上造型?

多型:即不同的物件對同一訊息能做出不同的反應

向上造型:父類變數可以指向子類物件,能自動轉換   Father f = new Son();

向上造型:子類的變數不能指向父類物件,需要強制轉換

這是某位博主分享的答案:

①,②,③呼叫a1.show()方法,a1 屬於A類,A類有兩個方法show(Dobj)和show(A obj)。①a1.show(b),引數b為A類的子類物件,這裡為向上轉型,相當於A obj=b;所以呼叫show(A obj)方法,得到A and A結果。②同理,③引數為d,呼叫show(D obj),得到A and D。
④,⑤,⑥呼叫a2.show()方法,A a2 = new B();是向上轉型,所以對a2方法的呼叫,使用A1類的方法show(D obj)和show(A obj),但此時show(A obj)已經被重寫為return ("B and A"), ④a2.show(b),呼叫show(Aobj),得到B and A。⑤同理,⑥呼叫show(D obj),得到A and D。
⑦,⑧,⑨呼叫b.show()方法,b為B類,B類的show方法有繼承的show(D obj),自己的兩個show(B obj)、show(A obj)。
⑦呼叫show(B obj),得到B and B,⑧向上轉型,呼叫show(B obj),得到B and B⑨show(D obj),得到A and D


如果看完上述解析你還很迷惑,來看看是不是遇到了和我一樣的問題:

下面列出了自己或者你可能遇到的一些問題進行解釋說明:

System.out.println(a1.show(b));   //①   輸出 A and A
        System.out.println(a1.show(c));  // ②   輸出 A and A
        System.out.println(a1.show(d));   //③   輸出 A and D

        /** 1
         *  對於③的中的方法引數變數,D繼承自B,B繼承自A,為什麼該物件變數沒有向上造型輸出A and A  ?
        *
        * 原因:我猜想這與java中函式引數的匹配有關,在進行動態繫結時,首先肯定是匹配與引數同類型的變數,
        * 不能匹配時然後才會考慮它的派生類,並且也遵循就近原則(繼承關係離的比較近),可以自己寫程式碼認證
        *
        * */


        System.out.println(a2.show(b));   //④   輸出 B and A
        System.out.println(a2.show(c));   //⑤   輸出 B and A
        System.out.println(a2.show(d));  // ⑥   輸出 A and D

        /** 2
         * 此處要注意的是向上造型後變數呼叫的方法是子類的方法還是父類的方法:
         * 向上造型後呼叫的是父類的方法,但當父類中的方法被子類重寫後,就需要呼叫重寫後的方法
         */


        System.out.println(b.show(b));    //⑦   輸出 B and B
        System.out.println(b.show(c));    //⑧   輸出 B and B
        System.out.println(b.show(d));    //⑨   輸出 A and D

        /** 3
         * 此處要注意的問題與第一組資料的情況類似,就是向上造型函式引數的匹配應遵循“就近原則”
         * 比如對於⑧來說,變數c是向上造型成了B型別,而不是A型別,而C->B->A,它離B較近,所以也就造型成了B類型別
         */




錯誤與不足之處還請各位指正!還有問題的歡迎留言分享交流