Java多態之向下轉型
往期回顧:我們學習了向上轉型和動態綁定的概念,可以知道在繼承關系中,將一個子類對象賦值給父類的引用變量,調用父類的方法,在實際運行時,就可以根據子類中重寫的方法執行不同的操作。其中有一個弊端,就是在向上轉型的過程中,其實丟失了一部分子類特有的功能,畢竟它只允許調用父類中的方法。那么,如何在這時調用子類中的方法呢,這時就需要與向上轉型相對應的方法,就是所謂的:向下轉型。
向上轉型是自動就能完成的,向下轉型則需要強制類型轉換。
強制類型轉換
我們前面提到過基本數據類型的強制轉換,可以查看之前的文章:基本數據類型轉換
引用變量的強制類型轉換與基本數據類型類似,都需要用到類型轉換運算符:()
。
//將變量強制轉換為type類型
type p = (type)變量
特別注意:
- 基本數據類型中,數值類型和布爾類型無法進行類型轉換。
//錯誤!
boolean boo = true;
int in = (int)boo;
- 不在繼承關系中的兩個類型無法進行強制類型轉換。
//假設Person類和Dog類不具有繼承關系,則下面會出錯
Person p = new Person();
Dog dog = (Dog)p;
- 就算在繼承關系中,也不能把父類的實例轉換成子類類型。(也就是說,引用變量必須編譯時是父類類型,運行時是子類類型才可以)注意,編譯時是不會報錯的,只有運行時才會報錯。
//假設Student繼承於Person類
//編譯時正常,運行時出錯
Person p = new Person();
Student s = (Student)p;
instanceof
將一個父類引用賦給一個子類變量時,必須經過強制類型轉換。如果出現強制類型轉換雙方不匹配的話,運行時通過(RTTI Run-Time Type Identification)
,即運行時類型識別,檢查並返回ClassCastException
,即類型轉換異常。
為了避免這一尷尬的問題發生,我們可以用instanceof
運算符來檢查,確保程序的健壯性。
instance
是實例的意思,可想而知,instanceof
表示判斷前面的對象是否是后面的類,或者子類,實現類的實例。如果是就返回true,否則就false。
[引用類型變量] instanceof [類(接口)]
從上面諸多錯誤例子中隨便舉一個:
//在強制類型轉換前加上instanceof語句判斷
Person p = new Person();
if (p instanceof Student) {
Student s = ((Student) p);
}
這時,if判斷語句中為false,里面自然無法執行,也就避免程序報錯,保證了程序的健壯性。