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
相关产品推荐
相关产品推荐

