Java父子类重载(Overloading)与重写(Overriding)共存调用报错求助
父类引用调用子类重载方法编译报错的原因解析
这是Java中编译时类型检查与运行时动态绑定机制共同作用的结果,核心逻辑可以拆解为以下几点:
1. 编译阶段:仅检查引用类型的方法列表
当你写出Parent p = new Child();这种父类引用指向子类对象的代码时,编译器处理方法调用时,只会去**引用类型(即Parent类)**的方法列表中查找匹配的方法签名:
- 调用
p.print()时,Parent类存在无参的print()方法,编译通过;运行阶段才会根据实际对象类型(Child)动态调用子类的重写实现。 - 调用
p.print(1)时,Parent类中不存在print(int)这个方法签名,编译器直接判定为“找不到方法”并报错终止——哪怕实际对象是Child且拥有该方法,也无法进入运行阶段,编译环节就会卡住。
2. 重载与重写的本质区别
你这里Child类的print(int)是重载,而非重写:
- 重写要求方法名、参数列表、返回值类型(协变情况除外)完全与父类一致,此时运行时会触发动态绑定,调用子类的实现。
- 重载只是方法名相同,但参数列表不同,属于子类新增的独立方法,和父类的
print()没有覆盖关系。编译器不会将子类的重载方法自动纳入父类的方法列表中。
3. 两种正常场景的原因
- 场景1:Parent添加print(int),Child重写:此时Parent类存在
print(int)方法签名,编译通过;运行时动态绑定到Child的重写实现,因此正常执行。 - 场景2:Parent有print(int),Child不重写:编译时能找到Parent的
print(int)方法,运行时直接调用父类的实现,自然不会报错。
代码示例验证
class Parent { public void print() { System.out.println("Parent print()"); } } class Child extends Parent { @Override public void print() { System.out.println("Child print()"); } // 子类新增的重载方法,父类无对应签名 public void print(int num) { System.out.println("Child print(int): " + num); } } public class Test { public static void main(String[] args) { Parent p = new Child(); p.print(); // 正常运行,输出Child print() // p.print(1); // 编译报错:找不到符号print(int) } }
内容的提问来源于stack exchange,提问作者Shubham Jaiswal
相关产品推荐
相关产品推荐

