Java初探:向上轉型(Upcasting)與向下轉型(Downcasting)

在之前多型(Polymorphism)的範例中,我們用到的技巧其實就是向上轉型,因此這一篇我們來討論向上轉型(Upcasting)與向下轉型(Downcasting)的差異與使用方式。在討論向上或向下轉型前,我們要先確認一下「is a」、「has a」的觀念。

「is a」的觀念

//A.java
public class A
{
	public String cName;
}

//B.java
public class B extends A
{
	public String cAddress;
}

//C.java
public class C
{
	public static void main(String[] args)
	{
		A objA = new A();
		B objB = new B();
		
		if(objB instanceof A)
			System.out.println("objB is an A.");	//會印這一行
		else
			System.out.println("objB is not an A.");
			
		if(objA instanceof B)
			System.out.println("objA is a B.");
		else
			System.out.println("objA is not a B.");	//會印這一行
	}
}

「has a」的觀念

//A.java
public class A
{
	private B _objB;	//A類別裡面擁有B
}

//B.java
public class B
{
	public String cAddress;
}

我們都知道子類別一定擁有父類別的所有公開成員,但是父類別並不會繼承子類別所有的公開成員(廢話)。因此如果在確認彼此的「is a」關係下,向上轉型(子→父)的風險永遠比向下轉型(父→子)的風險小。事實上,你根本不可能直接在程式碼中進行向下轉型的動作,除非你先把子類別向上轉型,然後再做一次向下轉型。(脫褲子放屁)

public static void main(String[] args)
{
	String a = new String("TEST1");
	//Upcasting
	Object o1 = a;
	System.out.println(o1);
	
	//編譯時期就錯誤了 Downcasting ERROR!
	//因為「Object is not a b」
	//String b = new Object();
	
	//Downcasting RIGHT!
	String b = new String("TEST2");
	//因為「b is an Object」,因此會自動做Upcasting,要不要打(object)b都可以。
	Object o2 = b;
	//這裡就是真正所謂的向下轉型(Downcasting)
	String c = (String)o2;
	System.out.println(c);
}

向下轉型(Downcasting)在我的程式設計經驗中幾乎完全用不上,所以能夠避免就避免掉。且無論如何,如果要使用向上或向下轉型,勢必都要面對與承擔執行期(Runtime)出錯的風險。

Java SCJP Upcasting Downcasting Polymorphism