You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的多态规则:

  1. 如果子类重写了父类的Print方法,只要父类引用指向子类对象,调用Print方法时会自动执行子类的实现(这就是动态绑定的核心特性)。
  2. 如果是子类特有的重载方法(比如你最初写的Print(Son)),父类代码无法直接调用,除非你把参数向下转型为Son类型——但这种方式不推荐,会破坏封装性和多态设计,还容易抛出ClassCastException。

总结来说,正确利用方法重写和多态,就能让父类代码自然调用到子类的方法实现。

内容的提问来源于stack exchange,提问作者R. Thomes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:03:35