美好的一天,Javarash 人。我開始收到有關在 Java 中轉換引用類型的問題。為了不每次都重複同樣的事情,我決定寫一篇短文。
首先,我們來看看什麼是類型轉換。
類型轉換(類型轉換)是將一種類型的變數值轉換為另一種類型的值。讓我們看一個例子來了解它是什麼以及它與什麼一起吃。我們有一些類別層次結構(參見圖 1)。這裡可以看到層次結構的所有類,誰繼承了誰,以及每個類別的方法。 有擴張內收和收縮內收。我們看到該類別Cat
是該類別的後代Pet
。Pet
反過來,又是班上的繼承人Animal
。當我們寫:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
這是一種擴展的演員陣容(或隱式的演員陣容)。我們擴展了鏈接animalCat
和animalDog
。它們指的是物件Cat
和Dog
。透過這樣的強制轉換,我們無法animalCat/animalDog
透過位於 中Cat/Dog
但不在 中的引用來呼叫方法Animal
。 縮小(或顯式)強制轉換發生在相反的方向:
Animal animalCat = new Cat();
Animal animalDog = new YorkshireTerrier();
Cat cat =(Cat)animalCat;
YorkshireTerrier dog = (YorkshireTerrier) animalDog;
我們已經清楚地表明了我們想要將此物件轉換為什麼類型。 不過要小心!!! 如果你這樣做:
Animal animalCat = new Cat();
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
編譯器將跳過這段程式碼。但RunTime
它會向你拋出:
Exception in thread "main" java.lang.ClassCastException: Animals.Cat cannot be cast to Animals.YorkshireTerrier
RunTime
看到Cat
有YorkshireTerrier
兩個不同的類別。為了避免在縮小轉換期間出現ClassCastExceptioninstanceof
,請使用.
Animal animalCat = new Cat();
if (animalCat instanceof YorkshireTerrier)
{
YorkshireTerrier dog = (YorkshireTerrier) animalCat;
}
如果animalCat
是YorkshireTerrier
,則分配將會發生,如果不是,則什麼也不會發生。
現在,如果我們丟失方法並可能出現此類錯誤,為什麼這是必要的
讓我們來看看我根據圖 1 中的圖表編寫的程式碼。1 . 班級Animal
public abstract class Animal
{
String name;
int age;
String nameOfClass = getClass().getSimpleName();
public void eat(){
System.out.println(nameOfClass + ": Omnomnom");
}
public void sleep(){
System.out.println(nameOfClass + ": Z-z-z-z");
}
}
一個WildAnimal
繼承自的類別Animal
public abstract class WildAnimal extends Animal
{
public void steelChicken()
{
System.out.println(nameOfClass+": Muhaha,I stole a chicken!");
}
}
一個Pet
繼承自的類別Animal
public abstract class Pet extends Animal
{
public void peeInTray(){
System.out.println(nameOfClass + ": Master, I peed");
}
}
一個Fox
繼承自的類別WildAnimal
public class Fox extends WildAnimal
{
public void eatColobok(){
System.out.println(nameOfClass + ": I will eat you, Colobok");
}
}
一個Wolf
繼承自的類別WildAnimal
public class Wolf extends WildAnimal
{
public void hawlAtTheMoon(){
System.out.println(nameOfClass + ": Ouuuuu!!!Ouuuu!!!");
}
}
一個Cat
繼承自的類別Pet
public class Cat extends Pet
{
public void sleepOnKeyboard(){
System.out.println(nameOfClass + ": Master, stop working!!I wanna sleep on your keyboard");
}
}
一個YorkshireTerrier
繼承自的類別Pet
public class YorkshireTerrier extends Pet
{
public void bark(){
System.out.println(nameOfClass + ": Meow!!! Meow!!!");
}
}
想像一下情況。我們需要將所有動物收集在一個清單中,餵養牠們,然後讓它們上床睡覺。如果我們創造動物,這很容易做到ArrayList
(Animal
)。然後我們為每個動物呼叫相應的方法:
public class ZOO
{
public static void main(String[] args)
{
List<Animal> allAnimals = new ArrayList<>();
allAnimals.add(new Cat());
allAnimals.add(new Wolf());
allAnimals.add(new Fox());
allAnimals.add(new YorkshireTerrier());
for (Animal animal : allAnimals)
{
animal.eat();
animal.sleep();
}
}
}
我無法animal
調用該方法bark()
或sleepOnKeyboard()
. 因為表格allAnimals
包含一隻貓、一隻狼、一隻約里克和一隻狐狸,但它們被簡化為Animal
。而且他們只有 中的方法Animal
。這很好,因為如果我們可以調用所有的方法,那麼為什麼我們需要一隻睡在鍵盤上的狼,或者一個偷雞的約里克呢?感謝您的關注。我希望這篇文章對您有用。歡迎批評和指正)
GO TO FULL VERSION