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();
    }
}

运行结果:
【Java】从一道题管窥多态性-LMLPHP
解释:
class D继承自class Bnew D()创建D类对象,先跑去对父类class B的部分进行构造,

// 默认生成
public D() {
  super();
}

B()中调用func(),而class D中对func()进行了重写(Override),
最终发生多态调用:

  1. 继承关系是向上转型
  2. 子类和父类有同名的重写/覆盖方法
  3. 通过父类对象的引用去调用这个重写的方法

所以,最终调用的还是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();
    }
}

执行结果:
【Java】从一道题管窥多态性-LMLPHP
从测试结果来看,a对象的创建过程中,实例代码块部分先执行,然后是就地初始化,再之后是构造方法的调用。

05-13 06:22