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

Java父类调用的影响:新手关于OOP继承概念的技术问询

嘿,作为Java新手刚接触面向对象的继承,碰到这种类之间的调用逻辑困惑太正常啦!咱们来一步步拆解你给出的Foo和Bar两个类,把父类调用的影响说清楚。

首先先把你的代码规整展示出来:

public class Foo { 
    protected String rawData; 
    public String getSomething(String rawData) { 
        // ... 
        this.rawData = rawData; 
        prepareData(); 
        return rawData; 
    } 
    protected void prepareData() { 
        // do something with class rawData 
    } 
} 

public class Bar extends Foo { 
    @Override 
    public String getSomething(String rawData) { 
        // ... 
        return super.rawData; 
    } 
    @Override 
    protected void prepareData() { 
        //... 
    }
}
拆解父类调用的影响

1. 先搞懂父类Foo的原始逻辑

在Foo中,getSomething方法做了三件核心事:

  • 把传入的**参数rawData**赋值给类的实例变量this.rawData
  • 调用自己的prepareData方法(这个方法是protected的,子类可以重写扩展)
  • 最后返回的是传入的参数rawData(注意不是实例变量this.rawData)

2. 子类Bar重写后的行为(当前代码的问题)

你写的Bar类重写了两个方法,但关键是没有调用super.getSomething(rawData),这会直接导致父类的核心逻辑完全丢失:

  • 实例变量rawData(不管用this.rawData还是super.rawData)不会被赋值为传入的参数,所以返回的super.rawData默认是null(因为String是引用类型,默认初始化值为null)
  • 你重写的prepareData方法根本不会被执行——因为父类getSomething里的prepareData()调用是依附于父类方法执行的,子类没触发父类方法,这步就直接跳过了

3. 如果Bar调用了super.getSomething(rawData)会发生什么?

要是把Bar的getSomething改成这样:

@Override
public String getSomething(String rawData) {
    // 先调用父类的方法
    super.getSomething(rawData);
    // 再返回实例变量
    return super.rawData;
}

那情况就完全不同了:

  • 父类的逻辑会被完整执行:参数rawData会被赋值给实例变量this.rawData
  • 这里的prepareData()调用会触发动态绑定——因为Bar重写了这个方法,所以实际执行的是Bar里的prepareData,而不是Foo的原始实现
  • 最后返回的super.rawData就是已经被父类赋值、且经过Bar的prepareData处理后的实例变量值

新手容易踩的两个坑

  • 重写方法时不要忽略super调用:如果父类方法有必要的初始化或业务逻辑,跳过super调用会导致对象状态异常(比如这里的rawData没赋值)
  • 理解动态绑定的规则:当父类方法中调用一个可重写的方法时,JVM会在运行时根据实际对象的类型(而不是声明类型)选择执行子类的实现——哪怕这个调用写在父类代码里

内容的提问来源于stack exchange,提问作者Augusto Dias

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:54:54