java 中父类引用无法直接调用子类新增方法,因为编译期类型检查基于引用类型。必须使用向下转型(downcasting)将引用转换为子类类型,并配合 instanceof 进行安全校验。

如何安全地执行向下转型
在运行时通过 instanceof 判断对象实际类型,若匹配则强转为子类引用,从而访问子类特有方法。这样做可避免 ClassCastException。

public class Main {
public static void main(String[] args) {
Animal animal = new Dog();
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark(); // 调用子类新增方法
}
}
}
class Animal {
void eat() { System.out.println("Eating"); }
}
class Dog extends Animal {
void bark() { System.out.println("Barking"); }
}
运行输出:Barking。若未加 instanceof 检查而直接强转不兼容类型,程序将在运行时抛出异常。
立即学习“Java免费学习笔记(深入)”;
为什么不能直接调用子类方法
编译器仅根据引用声明的类型(父类)解析方法调用,子类新增方法不在父类定义中,因此代码无法通过编译。这是 Java 静态类型系统的核心机制。

public class Main {
public static void main(String[] args) {
Animal animal = new Dog();
// animal.bark(); // 编译错误:bark() 未在 Animal 中定义
}
}
class Animal {
void eat() { System.out.println("Eating"); }
}
class Dog extends Animal {
void bark() { System.out.println("Barking"); }
}
尝试取消注释 animal.bark() 会导致编译失败,错误信息提示方法不存在。这验证了多态中接口可见性由引用类型决定。
当子类新增方法与父类方法同名时如何处理
若子类重写了父类方法而非新增独立方法,则通过父类引用调用时会触发动态绑定,执行子类版本。但若子类新增了父类没有的方法,仍须向下转型才能访问。
public class Main {
public static void main(String[] args) {
Animal animal = new Cat();
animal.eat(); // 输出 "Cat Eating",因重写
if (animal instanceof Cat) {
Cat cat = (Cat) animal;
cat.meow(); // 调用子类新增方法
}
}
}
class Animal {
void eat() { System.out.println("Animal Eating"); }
}
class Cat extends Animal {
@Override
void eat() { System.out.println("Cat Eating"); }
void meow() { System.out.println("Meowing"); }
}
运行输出第一行为 Cat Eating,第二行为 Meowing。这表明重写方法支持多态,而新增方法需显式转型。


















