子类的初始化以及super关键字的作用

很早前就看过继承关系中的初始化顺序如下:

父类对象---》父类属性初始化---》父类构造方法(无参)----》子类对象----》子类属性初始化--》子类构造方法


这次来验证一下

父类:

public class Parent {
    public String name;
    private int code;
    public Parent parent;
    //定义几个父类成员属性,parent将指向this父类对象
    public Parent()
    {
        //parent指向this,就是当前实例的父类对象,并输出hashcode和给code属性赋值
        parent=this;
        code=101;
        System.out.println("调用了父类无参构造方法 Parent's code is:"+code);
        System.out.println("Parent hashcode is:"+this.hashCode());
    }
    //定义一个重载的构造方法,用于测试使用了哪个父类构造方法
    public Parent(String name){
        parent=this;
        this.name=name;
        System.out.println("Parent's name is"+name);
        code=102;
        System.out.println("Parent's code is"+code);

        System.out.println("Parent hashcode is:"+this.hashCode());
    }
    public int getCode()
    {

        System.out.println("Parent :print code :"+code);
        return code;
    }
}
子类:

public class Child extends Parent {
    public String childName;
    private int childCode;

    public Child(String childName)
    {
        this.childName=childName;
        //输出属性值,和类的hashcode值
        System.out.println("child's childName is:"+childName);
        System.out.println("child hashcode is:"+this.hashCode());
    }
    public Child(){
        System.out.println("调用了子类无参构造方法  child hashcode is:"+this.hashCode());
    }
    //测试方法
    public void test()
    {
        //通过super获取父类中的parent,这个成员就表示了父类对象。
        Child testChild=(Child)super.parent;
        //强转parent为子类类型。并输出子类中定义的属性,和获取父类getCode()方法
        System.out.println("testChild name is:"+testChild.childName);
        testChild.getCode();
    }
    public static void main(String[] args) {
        //调用无参
        Child c=new Child();
        c.test();
        //调用有参
        Child d =new Child("hello");
        d.test();
    }
}

运行结果如下:

调用了父类无参构造方法 Parent's code is:101
Parent hashcode is:1163157884
调用了子类无参构造方法  child hashcode is:1163157884
testChild name is:null
Parent :print code :101
调用了父类无参构造方法 Parent's code is:101
Parent hashcode is:1956725890
child's childName is:hello
child hashcode is:1956725890
testChild name is:hello
Parent :print code :101

运行结果分析:

  1. 对于子类带参和无参的构造方法,先调用的都是父类的无参构造法。实际上,子类的构造方法必须先调用父类的构造方法,完了才能干别的初始化工作。如果子类没有显式调用语句,编译器会隐式帮你加上。
  2. 父类的this对象和子类实例的对象,hashcode码是相同的。从上面可以看出super这个关键字所表示的引用父类对象,其实和当前实例化的子类对象在内存中是同一个对象,虽然不知道sun 的虚拟机是如何实现这个关键字的,但是这个super的等同效果就是(Parent)this,这里的this是当前代表当前实例化的子类对象。
  3. java说明中指出,super是代表父类对象的引用,而super()表示应用父类的默认构造方法,看起来这个super和c中的define有点相同作用的效果。在这个例子中,super代表的父类对象的引用,和父类中parent代表的都是父类对象的引用,parent其实就是当前内存中子类对象的引用,如同(Parent)this一样,这样就可以解释为什么使用(Child)super.parent可以得到子类成员childName。

    回到开始的问题,super.getClass().getName(),这样,就很容易解释他为什么是输出当前类的名称了,因为构造一个实例化对象,其中,在父类和子类构造方法中,引用的对象都是同一个,都是当前实例化的子类对象。super关键字应该充当了一个类型转化的作用。


所以,可以理解为super等同于(超类)this,强制类型转换this引用为父类引用


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值