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

父类构造器调用print方法为何执行子类重写方法?

Java代码输出解释与疑问解答

代码示例

父类A

public class A { 
    public A() { 
        this.print(); 
    }

    public void print() {
        System.out.println("A");
    }
}

子类B

public class B extends A { 
    int i; 

    public B() { 
        i=4; 
    }
        
    @Override
    public void print() {
        System.out.println("calling B.print");
        System.out.println(i);
    }
}

测试类Tester

public class Tester { 
    public static void main(String[] args) { 
        A obj = new B(); 
        obj.print(); 
    }
}

程序输出

calling B.print
0
calling B.print
4

疑问解答与原理说明

1. 为什么父类构造器的this.print()调用了子类的方法?

Java中非私有实例方法的调用是基于运行时对象的实际类型,而非编译时的声明类型。当你执行new B()创建对象时,this在父类构造器里指向的是正在初始化的子类B对象,而非父类A的对象。由于子类B重写了print()方法,所以运行时会调用子类的版本,而不是父类的print()。

2. 为什么第一次输出的i是0?

子类对象的初始化遵循固定顺序:

  • 先执行父类构造器,此时子类的成员变量还处于默认初始化状态(int类型的默认值是0)
  • 父类构造器调用子类的print()时,子类构造器里的i=4还没执行,所以输出0
  • 父类构造执行完成后,才会执行子类B的构造器,将i赋值为4
  • 最后调用obj.print()时,i已经完成赋值,所以输出4

总结

父类构造器中的this.print()调用子类方法,是Java多态机制的核心特性——运行时根据对象实际类型匹配方法;而第一次输出0,是因为子类成员变量的显式初始化在父类构造执行之后才完成。

内容的提问来源于stack exchange,提问作者Roushan Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 00:15:29