关于创建子类对象调用父类构造,父类构造中的this

 

先说结论,创建子类对象的时候不会创建父类对象,只是会调用父类的构造来初始化子类对象的属性。此时如果在父类的构造中引用this,这个this其实是子类对象而且是一个未初始化的对想。

上代码:首先证明父类构造中的this是子类对象,这个很简单

//父类
public class Parent {
    public Parent() {
        System.out.println("父类构造中的this="+this);
    }
}
//子类
public class Sub extends Parent {
    public Sub() {
        System.out.println("子类构造中的this"+this);
    }
    public static void main(String[] args) {
        new Sub();
        new Sub();
        new Sub();
    }
}


//打印结果

父类构造中的this=top.liuzhihong.polymorphic.a.Sub@1b6d3586
子类构造中的thistop.liuzhihong.polymorphic.a.Sub@1b6d3586
父类构造中的this=top.liuzhihong.polymorphic.a.Sub@4554617c
子类构造中的thistop.liuzhihong.polymorphic.a.Sub@4554617c
父类构造中的this=top.liuzhihong.polymorphic.a.Sub@74a14482
子类构造中的thistop.liuzhihong.polymorphic.a.Sub@74a14482

再来证明这个this是一个未初始化的对象(创建对象的开始其实先回分配给对象分配一块内存空间并且初始化成二进制的零,例如属性为int那么初始化为0,属性为对象为null等),其实很好理解,调用父类构造的目的就是初始化子类对象的属性,所以肯定先有一个空的子类对象然后去父类中初始化它的属性,然后再到子类中初始化属性并调用子类构造完成最后的初始化。

证明1:

//父类
public class Demo {
    public Demo() {
        System.out.println("父类构造");
        System.out.println("creating:" + this);
    }
}
//子类

public class DemoTest  extends  Demo{
    private static int counter = 0;
    private final int id = counter++;

    public DemoTest() {
        System.out.println(this.id);
        System.out.println(this);
    }

    @Override
    public String toString() {
        System.out.println(id);
        return "DemoTest  id=" + id;
    }
    public static void main(String[] args) {
        new DemoTest();
        System.out.println("---");
        new DemoTest();
        System.out.println("----");
        new DemoTest();
    }
}
//运行结果,我们发现传入父类的对象属性id始终为0,如果不是上面的结论证明了这个this就是子类对象这里可能会误解。

父类构造
0
creating:DemoTest id=0
0
0
DemoTest id=0
---
父类构造
0
creating:DemoTest id=0
1
1
DemoTest id=1
----
父类构造
0
creating:DemoTest id=0
2
2
DemoTest id=2

 

证明2:

//父类
public class Demo {
    private int num = 10;
    private int[] arrays = {1, 2, 3};
    public Demo() {
        System.out.println("父类构造");
        this.draw();
    }
    protected void draw(){
        System.out.println("父类的draw:num=" + num + "   arrays=" + arrays);
    }
}
//子类
public class DemoTest extends Demo {
    private int num = 10;
    private int[] arrays = {1, 2, 3};

    public DemoTest() {
        System.out.println("子类的构造");
    }

    @Override
    protected void draw() {
        System.out.println("子类的draw:num=" + num + "   arrays=" + Arrays.toString(arrays));
    }
    public static void main(String[] args) {
        new DemoTest().draw();
    }
}

//运行结果
父类构造
子类的draw:num=0 arrays=null
子类的构造
子类的draw:num=10 arrays=[1, 2, 3]

总结:构造器可以理解成为一个 static方法,而构造器不是用来创建对象的而是在创建对象后进行初始化属性的。而new是用来创建对象的,创建对象的过程中会调用这个构造器。

原文地址:https://www.cnblogs.com/chengxuyuan-liu/p/14051960.html