子类的初始化过程、内存结构

一、首先先看引例

public class Father {
     public Father() {  
        say();  
    }  

    public void say() {  
        System.out.println("I'm father");  
    }  
}
public class Son extends Father{
    private int i = 11;  

    public Son() {
    }

    @Override  
    public void say() {  
        System.out.println("I'm son " + i);  
    }  
}
public class Test {
    public static void main(String[] args) {
        Son son = new Son();  
    }
}

打印如下:这里写图片描述

二、分析

  • 首先要明确一点,类和【加载】和【初始化,又称实例化】不是一个概念,

    • 类加载后并不一定实例化,但是类初始化前需要先被加载。

      • 对于上面这个程序,请问【 Father会被初始化吗?】
    • 下面开始分析:
    • ①类加载器加载Test类到方法区。
    • ②开始执行main方法,main方法入栈。
    • ③由程序计数器获取第一条指令。
    • ④new Son();
    • –>需要初始化Son,但是由于Son继承Father,所以类加载器先加载Father到方法区。
    • 并在new Son()的堆内存中分一部分用来保存继承自父类Father的成员变量信息,暂称为子类父空间。
    • –>然后加载Son到方法区。调用父类的构造方法,调用自己的构造方法。

      • 我们知道:
    • ①子类中定义的成员变量和父类中定义的成员变量相同时,则父类中的成员变量不能被继承。
    • ②子类中定义的成员方法,并且这个方法的名字返回类型,以及参数个数和类型与父类的某个成员方法完全相同,则父类的成员方法不能被继承。

      总结相同的方法会被重写,变量没有重写之说,如果子类声明了跟父类一样的变量,那意味着子类将有两个相同名称的变量。一个存放在子类对象中,一个存放在子类父空间中。父类的private变量,也会被继承并且初始化在子类父对象中,只不过对外不可见。所以,子类和父类的方法都是放在子类对象的内存中,而不是子类父空间中。

这里写图片描述

其实对于Father类来说,不也可以说的被初始化了吗?被Son对象初始化了?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值