向上轉型VS。 Java 中的向下轉型
一、簡介
了解如何處理 Java 類型層次結構中的物件對於編寫靈活且可維護的程式碼至關重要。該領域的兩個基本概念是向轉型和向下轉型。
在本教程中,我們將深入研究這些概念,探索它們的差異,並查看它們在 Java 中如何運作的實際範例。
2. Java 中的型別轉換簡介
Java 是一種物件導向的程式語言,允許在其類型系統內將一種類型轉換為另一種類型。轉換是將一種類別類型的參考轉換為另一種類類型的過程。具體來說,Java 中有兩種主要的類型轉換:向上類型轉換和向下類型轉換。
為了說明這些概念,假設我們有一個類別層次結構,其中Dog
是Animal
的子類別。下圖顯示了向轉型和向下轉型如何在此層次結構中運作:
向上轉換箭頭從Dog
類移動到Animal
類,顯示如何將子類引用 ( Dog
) 泛化為超類引用 ( Animal
)。另一方面,向下轉型箭頭從Animal
類移回到Dog
類,指示如何可以將超類引用 ( Animal
) 再次指定為子類引用 ( Dog
)。
但是,嘗試使用Animal
引用實例化Dog
物件會因為類型不相容而導致編譯時錯誤。
3. Java 中的向上轉換
向上轉換是指將子類別引用轉換為超類別引用。這種類型的轉換是隱式發生的,我們在處理多態性時經常使用它。向上轉換允許我們將子類別的物件視為其超類別之一的物件:
class Animal {
public void makeSound() {
System.out.println("Animal sound");
}
}
class Dog extends Animal {
public void makeSound() {
System.out.println("Bark");
}
public void fetch() {
System.out.println("Dog fetches");
}
}
在這裡,我們定義了兩個類別: Animal
和Dog
。 Animal
類別有一個方法makeSound()
列印“ Animal sound
”,而Dog
類別擴展了Animal
,重寫了makeSound()
方法來列印“ Bark
”,並引入了一個新方法fetch()
列印“ Dog fetches
” 。
Animal myDog = new Dog();
myDog.makeSound();
在提供的程式碼片段中,我們建立Dog
類別的實例並將其指派給Animal
類型的變數。當我們呼叫myDog
上的makeSound()
方法時,它會呼叫Dog
類別中的重寫方法,將「 Bark
」列印到控制台。
4. Java中的向下轉型
相反,向下轉型涉及將超類引用轉換回子類引用。與向上轉型不同,向下轉型是顯性的,需要仔細處理。因此,我們必須確保被轉換的物件與目標類型匹配,以避免ClassCastException
。當我們需要存取超類別中不可用的子類別特定方法或欄位時,我們使用向下轉型:
Animal myAnimal = new Dog();
Dog myDog2 = (Dog) myAnimal;
myDog2.makeSound();
myDog2.fetch();
在這裡,我們首先將Dog
物件向上轉換為Animal
引用。然後,我們將其向下轉換回Dog
引用。這種方法允許我們呼叫makeSound()
方法(繼承自Animal
類別)和fetch()
方法(特定於Dog
類別)。
透過向下轉型,我們重新獲得對子類別的方法和欄位的存取。
5. 向上轉型與向下轉型的比較
讓我們在下表中總結它們的主要特徵,以便更好地理解向上轉型和向下轉型之間的差異。這種比較將有助於闡明何時以及如何有效地使用每種技巧:
特徵 | 往上轉型 | 貶低 |
---|---|---|
定義 | 將子類別引用轉換為超類別引用 | 將超類別引用轉換為子類別引用 |
隱式或顯式 | 隱含的 | 顯式的 |
常見用法 | 用於多態性以泛化對象 | 用於存取子類別特定的功能 |
類型安全 | 安全且不需要類型檢查 | 需要類型檢查以避免ClassCastException |
訪問子類別方法 | 不,只能存取超類別方法 | 是的,允許存取特定於子類別的方法和字段 |
範例場景 | 將Dog 物件傳遞給需要Animal 參數的方法 |
將Animal 引用強制轉換回Dog 以呼叫Dog 特定的方法 |
表現 | 由於運行時缺乏類型檢查,通常效率更高 | 由於運行時類型檢查,效率稍低 |
六,結論
總之,向上轉型和向下轉型都是 Java 類型系統不可或缺的一部分,透過繼承和多態性促進靈活且可重複使用的程式碼。
與往常一樣,隨附的源代碼可以在 GitHub 上找到。