Java 物件轉換分為兩類:
ClassCastException。
public class TestObject {
public static void main(String[] args) {
Animal a = new Animal(); // 父類別實例
Dog d = new Dog("黃色"); // 子類別實例
d.setName("大黃");
System.out.println(a.print(d)); // 傳入 Dog 實例
System.out.println(a.print(a)); // 傳入 Animal 實例
}
}
class Animal {
String name;
public void setName(String n) { this.name = n; }
public String getName() { return this.name; }
// 核心方法:根據實際型別輸出不同資訊
public String print(Animal a) {
String result = "";
if (a instanceof Dog) {
Dog d = (Dog) a; // 向下轉型
result = "名稱:" + a.getName() + "\n毛色:" + d.getFurColor();
} else if (a instanceof Cat) {
Cat c = (Cat) a; // 向下轉型
result = "名稱:" + a.getName() + "\n瞳色:" + c.getEyeColor();
} else {
result = "名稱:" + a.getName(); // 純 Animal 實例
}
return result;
}
}
class Cat extends Animal {
String eyeColor;
public Cat(String e) { this.eyeColor = e; }
public void setEyeColor(String e) { this.eyeColor = e; }
public String getEyeColor() { return this.eyeColor; }
}
class Dog extends Animal {
String furColor;
public Dog(String f) { this.furColor = f; }
public void setFurColor(String f) { this.furColor = f; }
public String getFurColor() { return this.furColor; }
}
// 第一次呼叫 a.print(d) - 傳入 Dog 實例
名稱:大黃
毛色:黃色
// 第二次呼叫 a.print(a) - 傳入 Animal 實例
名稱:null
instanceof 運算子在向下轉型前檢查實際型別,避免 ClassCastException。此模式常用於:
上述 if-else instanceof 鏈雖然可行,但違反開閉原則。更優雅的做法是利用多態:
abstract class Animal {
String name;
public abstract String detail(); // 子類別自行實現
public String print() {
return "名稱:" + name + "\n" + detail();
}
}
class Dog extends Animal {
String furColor;
public Dog(String color) { this.furColor = color; }
@Override public String detail() { return "毛色:" + furColor; }
}
class Cat extends Animal {
String eyeColor;
public Cat(String color) { this.eyeColor = color; }
@Override public String detail() { return "瞳色:" + eyeColor; }
}
// 使用時
Animal a = new Dog("黃色");
a.setName("大黃");
System.out.println(a.print()); // 自動調用 Dog.detail()
| 錯誤場景 | 後果 | 正確做法 |
|---|---|---|
| 父類別實例強制轉子類別 | ClassCastException | 先用 instanceof 判斷 |
| 轉型後調用子類別獨有方法 | 編譯錯誤或運行異常 | 確認轉型成功後再調用 |
| 忽略 null 檢查 | NullPointerException | if (obj != null && obj instanceof Dog) |
instanceof 守護、僅用於存取子類別特有成員。