“嗨,阿米戈!今天課程的主題是擴大和縮小類型轉換。你很久以前就學習了擴大和縮小原始類型。在第 10 級。今天我們將討論它如何適用於引用類型,即類的實例。”

事實上,這一切都很簡單。想像一個類的繼承鏈:類、它的父類、父類的父類等等,一直回到 Object 類。因為一個類包含它繼承的類的所有成員方法,所以類的一個實例可以保存在一個變量中,該變量的類型是它的任何一個父類的類型。

這是一個例子:

代碼 描述
class Animal
{
public void doAnimalActions();
}class Cat extends Animal
{
public void doCatActions();
}class Tiger extends Cat
{
public void doTigerActions();
}
這裡我們有三個類聲明:Animal、Cat 和 Tiger。貓繼承動物。Tiger 繼承了 Cat。
public static void main(String[] args)
{
Tiger tiger = new Tiger();
Cat cat = new Tiger();
Animal animal = new Tiger();
Object obj = new Tiger();
}
Tiger 對象總是可以分配給一個變量,該變量的類型是其祖先之一的類型。對於 Tiger 類,它們是 Cat、Animal 和 Object。

現在讓我們看一下擴大和縮小轉換。

如果賦​​值操作導致我們向上移動繼承鏈(朝向 Object 類),那麼我們正在處理擴大轉換(也稱為向上轉型)。如果我們沿著鏈向下移動到對象的類型,那麼它就是一個縮小轉換(也稱為向下轉型)。

在繼承鏈上向上移動稱為拓寬,因為它會導致更通用的類型。然而,這樣做我們失去了調用通過繼承添加到類中的方法的能力。

代碼 描述
public static void main(String[] args)
{
Object obj = new Tiger();
Animal animal = (Animal) obj;
Cat cat = (Cat) obj;
Tiger tiger = (Tiger) animal;
Tiger tiger2 = (Tiger) cat;
}
在縮小類型時,需要使用類型轉換運算符,即我們進行顯式轉換。

這會導致 Java 機器檢查對像是否真的繼承了我們要將其轉換成的類型。

這個小創新大大減少了類型轉換錯誤的數量,並顯著提高了 Java 程序的穩定性。

代碼 描述
public static void main(String[] args)
{
Object obj = new Tiger();
if (obj instanceof Cat)
{
Cat cat = (Cat) obj;
cat.doCatActions();
}}
更好的是,使用 instanceof檢查
public static void main(String[] args)
{
Animal animal = new Tiger();
doAllAction(animal);

Animal animal2 = new Cat();
doAllAction(animal2);

Animal animal3 = new Animal();
doAllAction(animal3);
}

public static void doAllAction(Animal animal)
{
if (animal instanceof Tiger)
{
Tiger tiger = (Tiger) animal;
tiger.doTigerActions();
}

if (animal instanceof Cat)
{
Cat cat = (Cat) animal;
cat.doCatActions();
}

animal.doAnimalActions();
}
這就是為什麼。看看左邊的例子。

我們(我們的代碼)並不總是知道我們正在使用什麼類型的對象。它可以是與變量 (Animal) 或任何後代類型(Cat、Tiger)相同類型的對象。

考慮 doAllAction 方法。無論傳入的對像類型如何,它都能正常工作。

換句話說,它適用於所有三種類型:Animal、Cat 和 Tiger。

public static void main(String[] args)
{
Cat cat = new Tiger();
Animal animal = cat;
Object obj = cat;
}
這裡我們有三個賦值操作。所有這些都是擴大轉化率的例子。

這裡不需要類型轉換運算符,因為不需要檢查。 對象引用始終可以存儲在類型為其祖先之一的變量中。

“哦,倒數第二個例子說明了一切:為什麼需要檢查,為什麼需要類型轉換。”

“我希望如此。我想提請你注意這個事實:”

這些都不會導致對像以任何方式發生變化!唯一改變的是在特定引用變量上調用的方法的數量。

例如,Cat 變量允許您調用 doAnimalActions 和 doCatActions 方法。它對 doTigerActions 方法一無所知,即使它指向一個 Tiger 對象。

“是的,我明白了。這比我想像的要容易。”