理解Java继承的本质

一、继承的细节问题

1、子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问;

2、子类没有继承父类的构造器,但必须调用父类的构造器,完成父类的初始化;

3、当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过。


二、探究 new 一个对象的时候,内存中发生的事

1)相关概念

1、堆内存(Heap Memory):所有的对象实例都存储在堆内存中。堆内存是动态分配的,用于存储对象的实例变量。当使用 new 关键字创建一个对象时,这个对象的内存空间就会被分配在堆内存中。
2、栈内存(Stack Memory):栈内存用于存储线程的方法调用和局部变量。当一个方法被调用时,会在栈内存中分配一个称为栈帧的区域,用于存储方法的参数、局部变量以及方法返回时的返回值。栈帧会在方法执行结束后被销毁。
3、对象引用:在 Java 中,对象的引用是指向堆中对象的指针。在栈内存中存储的是对象引用,而不是对象本身。当使用 new 关键字创建一个对象时,返回的是对象在堆中的地址,这个地址被存储在栈中的引用变量中。

* 对象在堆中加载,然后返回给栈中的对象引用。

2)子类创建的内存布局

解读:

i、当执行 new son();时,方法区类信息的加载顺序 Object --> Grandpa --> Father --> Son(加载的类之间有继承关系);

ii、类信息加载到方法区后,堆中会为 Son 对象分配地址空间------0x11为该空间的地址。

iii、该空间存储有"祖孙三代"的实例变量(包括基本数据类型的值、引用类型的地址-----如String类型、对象引用、数组引用等);

iv、当堆中的加载完成后,堆的地址就会被分配给主方法中的对象引用 son;

3)0x11为 son 对象,包含了众多实例变量,还有重名。该如何通过主栈的对象引用son正确访问?

通过对象引用访问实例成员属性,要按照查找关系来返回信息,如下:

(1)首先看子类是否有该属性;

(2)如果子类有这个属性,并且可以访问,则返回信息;

(3)如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息;

(4)如果父类没有就按照(3)的规则,继续找上级父类,直到 Object;

eg:

System.out.println(son.name);        //返回大头儿子

System.out.println(son.age);        //返回的就是39

System.out.println(son.hobby);        //返回的就是旅游

(注:父类中有age属性 private age = 30;Grandpa类中也有age属性 int age = 88;时,对 age的查找会止于父类; 堆中的对象实例 son 虽然父类的私有age存在,但无法访问。)

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值