1. 程式人生 > >理解“向上轉型”和“向下轉型”的簡單例子

理解“向上轉型”和“向下轉型”的簡單例子

import static net.mindview.util.Print.*;

class Useful{
    public void f(){print("Useful:f()");}
    public void g(){print("Useful:g()");}
}

class MoreUseful extends Useful{
    public void f(){print("MoreUseful:f()");}
    public void g(){print("MoreUseful:g()");}
    public void u(){print("MoreUseful:u()"
);} public void v(){print("MoreUseful:v()");} public void w(){print("MoreUseful:w()");} } public class RTTI{ public static void main(String[] args){ Useful[] x = { new Useful(), new MoreUseful(), }; try { x[0].f(); x[1
].g(); // 找不到方法u() // x[1].u(); // downcast/RTTI ((MoreUseful)x[1]).u(); // Exception in thread "main" java.lang.ClassCastException: Useful cannot be cast to MoreUseful ((MoreUseful)x[0]).u(); } catch (ClassCastException e ) { print(e); } } }/*Output: Useful:f() MoreUseful:g() MoreUseful:u() java.lang.ClassCastException: Useful cannot be cast to MoreUseful */

程式碼參考Bruce Eckel《Think in Java》Fourth Edition

上面的例子可以很好解釋java面向物件程式設計中的“向上轉型”與“向下轉型”的特點,首先應該明白,這種“轉型”發生在具有繼承關係的基類和匯出類之間,這也是區別何時選擇繼承,何時選擇組合產生新類的方法之一。向上轉型是指由匯出類轉型為基類,在繼承圖中由下向上轉型;向下轉型是指由基類轉型為匯出類,在繼承圖中由上向下轉型;需要格外注意的是,向上轉型和向下轉型並不總是讓人隨心所欲,向上轉型會丟失具體的型別資訊,向下轉型也會出現型別轉化異常,主要是因為基類不會具有大於匯出類的介面。
繼承圖
Useful型別陣列中出現了向上轉型(隱式),MoreUseful型別轉換為它的父類Useful,當我試圖呼叫陣列中物件的方法u()時,編譯器告訴我找不到u(),u()是MoreUseful類的擴充套件方法,Useful類不包含此方法的資訊,可見,MoreUseful型別轉換成Useful型別後把擴充套件的方法資訊“丟失”了,通過向下轉型後可以獲取方法u()的資訊,Useful類建立的物件本身不包含方法u(),程式執行時會對其進行檢查,檢查時發現它不能夠得到我們所希望的型別,就會丟擲異常。