Java:如何让父类方法调用子类重载的Print方法?
问题分析与解决方案
先看你给出的代码片段:
Father.java
public class Father { public void DoSmth(Father object) { // Do something else and print Print(object); } public void Print(Father object) { System.out.println("Father"); } }
Son.java
public class Son extends Father { public void Print(Son object) { System.out.println("Son"); } }
Main.java
public class Main { public static void main(String[] args) { Father o1 = new Father(); Son o2 = new Son(); o1.DoSmth(o1); o1.DoSmth(o2); } }
你期望输出是Father Son,但实际得到Father Father,核心问题出在方法重载与重写的混淆,以及Java的方法绑定规则上:
为什么调用o1.DoSmth(o2)时执行父类的Print方法?
Son类里的Print(Son object)并不是重写(Override)父类的Print(Father object),而是重载(Overload)——因为两个方法的参数列表不一样(父类参数是Father类型,子类是Son类型)。
在Father类的DoSmth方法中,调用Print(object)时,object的声明类型是Father。编译器在编译阶段只会根据参数的声明类型匹配方法,所以只会找到父类的Print(Father)方法。运行时,哪怕object的实际类型是Son,由于子类没有重写这个方法,依然会执行父类的Print实现。
如何实现期望输出?
要让程序根据对象的实际类型触发对应的打印逻辑,你需要让Son类重写父类的Print方法,保持方法签名完全一致:
修改Son.java:
public class Son extends Father { // 用@Override注解明确标记这是重写方法 @Override public void Print(Father object) { // 判断传入对象的实际类型,输出对应内容 if (object instanceof Son) { System.out.println("Son"); } else { // 兼容父类逻辑,也可以直接调用父类实现 super.Print(object); } } }
这样,当o1.DoSmth(o2)执行时,虽然DoSmth是父类方法,但调用Print(object)时会触发动态绑定:因为object的实际类型是Son,且Son重写了Print方法,所以会执行子类的实现,输出"Son"。
能否在父类中调用子类的Print方法?
当然可以,但要遵循Java的多态规则:
- 如果子类重写了父类的Print方法,只要父类引用指向子类对象,调用Print方法时会自动执行子类的实现(这就是动态绑定的核心特性)。
- 如果是子类特有的重载方法(比如你最初写的
Print(Son)),父类代码无法直接调用,除非你把参数向下转型为Son类型——但这种方式不推荐,会破坏封装性和多态设计,还容易抛出ClassCastException。
总结来说,正确利用方法重写和多态,就能让父类代码自然调用到子类的方法实现。
内容的提问来源于stack exchange,提问作者R. Thomes
相关产品推荐
相关产品推荐

