Skip to main content

Java 觀念 - Type Casting

Type Casting 跟物件繼承很有關係,只要子類別繼承父類別,那他們就有 Casting 的關係。

直接看以下範例:

class Animal {
    void speak(){
        System.out.println("Default speak");
    }
}

class Bird extends Animal {
    @Override
    void speak() {
        System.out.println("ㄐㄐ");
    }
}

class Dog extends Animal {
    @Override
    void speak() {
        System.out.println("吉娃娃");
    }
}

public class main {
    public static void main(String[] args) {
        Animal animal = new Animal();
        Bird bird = new Bird();
        Dog dog = new Dog();

        animal.speak();
        bird.speak();
        dog.speak();

        // Upcasting and Downcasting

        Animal animal2;
        animal2 = bird; // Upcasting
        animal2.speak(); // works normally

        Bird bird2;
//        bird2 = animal; // Down casing, compile error
//        bird2 = (Bird)animal; // Compile pass
//        bird2.speak(); // but throw ClassCastException error

        Dog dog2;
//        dog2 = bird; // Obviously not working for compiling
//        dog2 = (Dog)bird; // Cannot casting to another child class, compile error.
    }
}
  • Bird 可以 casting 成父類別 Animal,且也可以正常運作,這行為叫做 Upcasting。通常 Upcasting 不會有太大的問題。
  • 把 animal casting 成 Bird,在邏輯上說不通(你也不確定這個 Animal 到底是不是 Bird 呀),Compiler 也意識到這件事情,就不給你過
    • 這種行為叫做 Downcasting,通常 Compiler 檢查都不會讓你過
  • 但是可以用 (Bird)animal,其實這就是叫 Compiler 閉嘴,跟 Compiler 表示這動物就是鳥,於是 Compiler 兩手一攤,表示 OK 我不管你
    • 可是在這樣的狀況下,使用底下的方法就會跳出 ClassCastException 這個 Runtime error,JVM 跟你說「欸欸你不可以這樣跑啦」
  • 如果是 Animal 底下的繼承 class 互轉,很顯然地過不了(狗要怎麼變成鳥,鳥要怎麼變成狗?),而且也沒辦法叫 Compiler 閉嘴(Compiler:我要阻止倫理問題發生呀...)