多態建立在繼承/實現基礎上,包含兩個維度:
class Animal { void sound() { System.out.println("Animal sound"); } }
class Cat extends Animal { @Override void sound() { System.out.println("Meow"); } }
class Dog extends Animal { @Override void sound() { System.out.println("Woof"); } }
// 向上轉型:子類對象賦值給父類引用
Animal a1 = new Cat(); // 編譯類型 Animal,運行類型 Cat
Animal a2 = new Dog(); // 編譯類型 Animal,運行類型 Dog
Animal a3 = new Animal(); // 編譯/運行均 Animal
System.out.println(a1 instanceof Animal); // true
System.out.println(a1 instanceof Cat); // true
System.out.println(a1 instanceof Dog); // false
// JDK 14+ 模式匹配
if (a1 instanceof Cat c) { c.sound(); } // 同時檢查並轉型
Animal[] zoo = new Animal[3];
zoo[0] = new Cat();
zoo[1] = new Dog();
zoo[2] = new Cat();
// 新增子類無需修改數組代碼
// 單一方法處理所有子類
public void feed(Animal a) { a.sound(); }
feed(new Cat()); // Meow
feed(new Dog()); // Woof
// 返回類型多態
public Animal create(String type) {
return switch (type) {
case "cat" -> new Cat();
case "dog" -> new Dog();
default -> new Animal();
};
}
調用 a1.sound() 時:
Animal 有 sound() 方法 → 通過。Cat)在方法表中查找並調用 Cat.sound()。static/private/final/構造器不參與)。public class PolyDemo {
public static void main(String[] args) {
Animal a = new Animal();
Animal c = new Cat();
Animal d = new Dog();
Animal c2 = new Cat(); // 向上轉型
test(a); // Animal sound
test(c); // Meow
test(d); // Woof
test(c2); // Meow
}
static void test(Animal a) {
a.sound(); // 動態分發
}
}
/* 輸出:
Animal sound
Meow
Woof
Meow
*/
Animal a = new Cat();
// Cat c = a; // 編譯錯誤:父類引用不可隱式賦值給子類變量
if (a instanceof Cat) {
Cat c = (Cat) a; // 向下轉型:需運行期檢查
c.catchMouse(); // 調用子類特有方法
}
instanceof 防 ClassCastException。if (a instanceof Cat c) 合二為一。
public sealed class Shape permits Circle, Rectangle, Triangle { }
final class Circle extends Shape { }
final class Rectangle extends Shape { }
non-sealed class Triangle extends Shape { } // 允許繼續繼承
switch 可窮盡性檢查,無需 default。子類必須能替換父類且不破壞程序正確性。
違反例:Square extends Rectangle導致setWidth/setHeight邏輯衝突。
解決:組合優於繼承,或重新設計繼承層次。