Java中指定调用父类方法为何执行子类重写的方法?
Java继承方法调用的问题与解决
问题场景
我编写了以下Java代码,期望main方法输出A类method1(int arg)的内容"I'm A class",但实际输出的是B类的"I'm B class",想知道问题出在哪以及如何修复。
代码示例
A类
public class A { public void method1(String arg) { // some number passed, not important this.method1(1); } public void method1(int arg) { System.out.println("I'm A class"); } }
B类
public class B extends A{ @Override public void method1(String arg) { super.method1(arg); } @Override public void method1(int arg) { System.out.println("I'm B class"); } }
MainAB类
public class MainAB { public static void main(String[] args) { B b = new B(); // some string passed, not important b.method1("HI"); } }
问题原因
你误解了Java的动态绑定机制:this关键字指向的是运行时实际创建的对象实例,而非当前代码所在类的实例。
在你的代码中,main方法创建的是B类实例,调用流程实际为:
b.method1("HI")进入B类的method1(String arg),通过super.method1(arg)进入A类的同名方法;- A类的
method1(String arg)执行this.method1(1),此时this仍然指向B类实例; - 由于B类重写了
method1(int arg),Java会调用B类的该方法,因此输出"I'm B class"。
解决方案
这里提供两种可行的修复方式:
方式1:将A类的method1(int arg)声明为final
final修饰的方法无法被子类重写,无论运行时对象是什么类型,调用该方法都会执行A类的实现:
public class A { public void method1(String arg) { this.method1(1); } // 用final修饰,阻止子类重写 public final void method1(int arg) { System.out.println("I'm A class"); } }
方式2:用私有方法封装核心逻辑
私有方法不能被子类重写,在A类的method1(String arg)中直接调用私有方法,绕过动态绑定:
public class A { public void method1(String arg) { // 直接调用私有方法,确保执行A类的逻辑 printAClassMessage(); } public void method1(int arg) { printAClassMessage(); } // 私有方法,子类无法重写 private void printAClassMessage() { System.out.println("I'm A class"); } }
内容的提问来源于stack exchange,提问作者Diego López
相关产品推荐
相关产品推荐

