• 关于创建子类对象调用父类构造,父类构造中的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是用来创建对象的,创建对象的过程中会调用这个构造器。

  • 相关阅读:
    20169220 2016-2017-2 <网络攻防实践> 课程总结
    20169220 <网络攻防实践> 第十四周实验—免杀
    20169220 <网络攻防实践> 第十二周实验—SQL注入
    20169220 <网络攻防实践> 第十一周实验—SQL注入+TCP/IP攻击
    20169220 <网络攻防实践> 第十周实验—Nmap+Wireshark+缓冲区溢出漏洞
    20169220 <网络攻防实践> 第九周实验——Nmap
    20169220 <网络攻防实践> 第八周实验——网络攻防虚拟机环境搭建
    20169220 <网络攻防实践> 第七周学习总结
    20169220 <网络攻防实践> 第六周学习总结
    20169220 <网络攻防实践> 第五周学习总结
  • 原文地址:https://www.cnblogs.com/chengxuyuan-liu/p/14051960.html
Copyright © 2020-2023  润新知