class B {
public B() {
func();
}
public void func() {
System.out.println("B.func()");
}
}
class D extends B {
private int num = 1;
@Override
public void func() {
System.out.println("D.func() " + num);
}
}
public class Test {
public static void main(String[] args) {
D d = new D();
}
}
运行结果:
解释:
class D
继承自class B
,new D()
创建D
类对象,先跑去对父类class B
的部分进行构造,
// 默认生成
public D() {
super();
}
B()
中调用func()
,而class D
中对func()
进行了重写(Override),
最终发生多态调用:
- 继承关系是向上转型
- 子类和父类有同名的重写/覆盖方法
- 通过父类对象的引用去调用这个重写的方法
所以,最终调用的还是class D
中的func()
,
也就是在B()
中调用的是class D
中的func()
,此时正处于构造class B
的部分,
而只有父类在构造(方法)执行之后,才会对num
就地初始化为1,这时也就得到D.func() 0
的执行结果。
拓展:
class A {
{
System.out.println("实例代码块 begin");
System.out.println(this.num);
this.num = 1;
System.out.println(this.num);
System.out.println("实例代码块 end");
}
public A() {
System.out.println("构造方法 begin");
System.out.println(this.num);
this.num = 3;
System.out.println(this.num);
System.out.println("构造方法 end");
}
public int num = 2;
}
public class Test {
public static void main(String[] args) {
A a = new A();
}
}
执行结果:
从测试结果来看,a
对象的创建过程中,实例代码块
部分先执行,然后是就地初始化
,再之后是构造方法
的调用。