java 中多态通过向上转型实现,即声明父类类型变量并赋值为子类对象实例。编译器在编译时依据变量声明的类型检查方法调用合法性,而在运行时依据对象的实际类型执行对应的方法逻辑,从而实现动态绑定。

向上转型的语法与编译期行为
向上转型是自动进行的隐式转换,无需强制类型转换符。当使用父类引用调用方法时,编译器只允许调用父类中定义的方法。如果子类重写了父类的方法,编译器依然认为该引用指向的是父类类型,因此不会报错,但也不会考虑子类特有的方法。

public class Animal {
public void eat() {
System.out.println("Animal eating...");
}
}
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("Dog eating bone...");
}
public void bark() {
System.out.println("Woof!");
}
}
public class Main {
public static void main(String[] args) {
// 向上转型:父类引用指向子类对象
Animal myPet = new Dog();
// 可以调用父类中定义的方法(实际执行子类重写后的版本)
myPet.eat();
// 编译错误:无法调用子类特有的方法
// myPet.bark();
}
}
在上述代码中,myPet 被声明为 Animal 类型,但实际指向 Dog 对象。调用 myPet.eat() 时,输出结果为 "Dog eating bone...",这证明了运行时多态的存在。若尝试调用 bark(),编译器会报错,因为 Animal 类中没有 bark() 方法。
向下转型与类型安全
当需要将父类引用还原为子类引用以访问子类特有功能时,必须进行向下转型。这是一个显式过程,需要使用强制类型转换符 (SubClass)。由于编译器无法静态确定父类引用是否真的指向某个特定的子类对象,因此在运行时会进行类型检查。如果类型不匹配,将抛出 ClassCastException。

public class Main {
public static void main(String[] args) {
Animal myPet = new Dog();
// 安全的向下转型
if (myPet instanceof Dog) {
Dog d = (Dog) myPet;
d.bark(); // 成功调用子类特有方法
}
// 错误的向下转型示例
Animal cat = new Cat(); // 假设存在Cat类
// Dog d2 = (Dog) cat; // 运行时抛出 ClassCastException
}
}
在使用向下转型前,务必使用 instanceof 关键字检查对象的实际类型,以确保类型安全。只有当父类引用确实指向目标子类对象时,强制转换才会成功,否则会在运行时引发异常。
基于程序中某个输入、条件或结果的具体问题
在程序运行过程中,如果父类引用指向的对象实际上是另一个未预期的子类(例如 Cat),而代码试图将其强制转换为 Dog 类型,将会导致 ClassCastException。这种异常发生在运行时,而非编译时,因为 Java 的多态机制允许在运行时动态决定对象的实际类型。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











