构造方法中super()的总结和理解

在类的继承中,子类构造方法中都会默认有一条super()语句,其作用相当于执行了父类构造方法中的语句,我们直接上代码:

class Extends_Demo {
    public static void main(String[] args) {
        Cat c = new Cat();            //---------------(1)
        System.out.println("-------------------");
        Cat c1 = new Cat("花花",4);   //----------------(2)
    }
}
class Animal {
    private String color;
    private int foot;

    public Animal(){
        System.out.println("我是父类无参数构造器");
    }

    public Animal(String color,int foot){
        System.out.println("我是父类有参数构造器");
        this.color = color;
        this.foot  = foot;
    }
}
class Cat extends Animal{

    public Cat(){
        super();                     //---------------可以省略
        System.out.println("我是子类无参数构造器");
    }

    public Cat(String color,int foot){              
        //super(color,foot);         //---------------(3)
        super();                     //---------------可以省略
        System.out.println("我是子类有参数构造器");
    }
}

执行结果为:

image

我想从结果上来看已经不用多说了,Cat类的两个构造方法中都分别执行父类Animal的构造方法

接下来将Cat(String color,int foot)方法中的super()注释掉,换为super(color,foot):

class Cat extends Animal{

    public Cat(){
        super();                    //----------------可以省略
        System.out.println("我是子类无参数构造器");
    }

    public Cat(String color,int foot){              
        super(color,foot);         //---------------(3)
        //super();
        System.out.println("我是子类有参数构造器");
    }
}

来看执行结果:

image

这次又执行了父类中的有参构造方法


上面是super()方法基本使用,但是为什么每次执行子类构造方法的时候都要调用父类的构造方法呢?第一次学习的时候只是知道了继承的一些特性之后就没有继续思考,下面来探究一下说一些自己的理解,可能存在有误之处,欢迎及时指正!

使用new关键字创建一个新的对象时,例如new Person();首先会检查常量池中是否存在new关键字后面的符号引用,

如果没有,就必须先执行类加载过程,在类加载过程中还会检查父类是否已经执行类加载过程,这个和目前所讲的是紧密相关的,

如果有能够定位到对应的符号引用,那么检查这个符号引用代表的类是否经历了加载、解析和初始化,类加载完毕之后,在堆中分配内存,所需内存大小在类加载完成之后便可以确定,然后进行使用构造方法进行初始化,最后返回这个对象的引用即可,

我们在这个过程中可以看到,调用子类的构造方法仅仅是在堆中产生了一个对象,但是子类构造方法中确确实实是调用了父类的构造方法,并且也执行了,那么父类的对象哪里去了呢?

我的理解是,这个对象可能存在于子类对象的实例数据部分,也就是子类对象隐式的持有了一个父类对象,这样子类对象既可以调用自己定义的方法,也可以调用父类中的可以继承的方法,

我们还可以从这个角度来理解:何为可继承?何为不可继承?

我们都知道,使用private修饰的变量和方法只能在本类中使用,在其他类中是不可使用对象.变量或对象.方法这样的形式来调用的,同样,既然父类对象是在子类中的,自然也不能使用这样形式调用,也就是所谓的不可以继承,不知道我说明白了没。

和this关键字的作用一样,那么在子类中如果存在和父类一样的方法,默认情况下使用子类对象调用的都是自己定义的,那么想要使用父类定义的怎么办呢,使用super关键字来调用

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://hadoo666.top/archives/构造方法中super的总结和理解md