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

Java方法重写特殊场景疑问:super调用为何触发子类方法?

为什么super.info()会调用子类的who()方法?

这是个非常经典的Java多态机制问题,我来给你拆解清楚前因后果,顺便解决你的后续需求。

先把你的代码贴出来方便大家参考:

Foo类

public class Foo {
    public Foo() {}
    public String who() { return "I'm foo "; }
    public String info() { return who() + "and i provide foo infos"; }
    public static void main(String[] args) {
        Foo bar = new Bar();
        System.out.println(bar.info());
    }
}

Bar类

public class Bar extends Foo {
    public Bar() { super(); }
    public String who(){ return "I'm bar "; }
    public String info(){ return super.info() + " about x"; }
}

你的预期输出是"I'm foo and i provide foo infos about x",但实际得到的是"I'm bar and i provide foo infos about x",核心问题出在Java的动态绑定规则和super关键字的作用范围上。

首先搞懂:super到底做了什么?

你以为super.info()会让整个父类方法的执行都“局限在父类对象里”,但其实不是——super只是帮你调用父类版本的info()方法,但执行这个方法的时候,当前对象的实际类型依然是Bar(因为你new的是Bar实例)。

Java里所有非private、非final、非static的实例方法,都是动态绑定的:调用哪个版本的方法,由对象的运行时实际类型决定,而不是当前代码所在的类。

所以当父类Foo的info()方法里调用who()时,JVM会检查当前对象是Bar,而Bar重写了who(),自然就调用了子类的who()方法,这就是为什么输出里会出现"I'm bar"。

那怎么实现调用父类的who()?

当然可行,给你几个实用方案:

方案1:把父类的who()设为private或final

如果父类的who()不需要被子类重写,直接用private或者final修饰:

public class Foo {
    // private方法不会被重写,也不参与动态绑定
    private String who() { return "I'm foo "; }
    public String info() { return who() + "and i provide foo infos"; }
}

这样Foo的info()里调用的who()永远是自己的版本,完全不受子类重写影响。

方案2:在父类info()里强制调用自身的who()逻辑

如果需要保留who()的可重写性,但想让info()固定用父类的who()内容,可以把父类的who()逻辑封装成一个private方法:

public class Foo {
    public String who() { return "I'm foo "; }
    public String info() { 
        // 调用仅父类可见的方法,避免动态绑定影响
        return getFooWho() + "and i provide foo infos"; 
    }
    
    private String getFooWho() {
        return super.who(); // Foo的父类是Object,所以super.who()就是Foo自己的who()
    }
}

方案3:在子类info()里手动拼接父类的who()

如果不想修改父类,也可以在子类的info()里直接调用super.who()来获取父类的内容,再拼接:

public class Bar extends Foo {
    public String who(){ return "I'm bar "; }
    public String info(){ 
        return super.who() + "and i provide foo infos about x"; 
    }
}

这样就能得到你预期的输出"I'm foo and i provide foo infos about x"了。


内容的提问来源于stack exchange,提问作者Jacques Martin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:39:42