一、初步了解继承的内存布局
(1) 继承内存布局初探
看下面拥有继承关系的代码,并画出内存布局图:
public class Person { public int age; public void smile() { System.out.println("Person_smile()_age_" + age); } } class Student extends Person { public double score; public void study() { System.out.println("Student_study()_score_" + score); } } class MainTest { public static void main(String[] args) { Student s = new Student(); s.score = 95.5; s.age = 8; // Person_smile()_age_8 s.smile(); // Student_study()_score_95.5 s.study(); Person p = new Person(); p.age = 15; // Person_smile()_age_15 p.smile(); } }
⌨️ 通过 上篇文章 Java 的访问修饰符public,protected,private(封装、继承)可以知道:Student 类通过 extends 关键字继承了 Person 类后,Student 类中便拥有了 Person 类中非 private 的成员变量和成员方法。因此,Student 对象的引用 student 可以访问到父类(Person)的 age 属性和 smile 方法
继承的内存布局图:
- Student 类继承 Person 类后会拥有 Person 类中的 age 属性,age 属性在 Student 对象的内存中也拥有一份
- Student 对象的内存和 Person 对象的内存各种独占,互不干扰
(2) Object 类
任何类最终都继承自 java.lang.Object
类(Object 类叫做基类)
The Object class, in the java.lang
package, sits at the top of the class hierarchy(层次体系) tree. Every class is a descendant(派生、后代), direct or indirect, of the Object class.
【翻译】 java.lang
包中的 Object 类位于类继承体系数的顶端。每一个类都是 Object 类的直接或间接派生类(子类)。
(3) 同名的成员变量
Java 允许子类定义和父类同名的成员变量(不推荐)
public class Person { public int money = 10000; } class Teacher extends Person { public int money = 22222; public void show() { System.out.println("money: " + money); System.out.println("this.money: " + this.money); System.out.println("super.money: " + super.money); } } class Main { public static void main(String[] args) { Teacher t = new Teacher(); t.show(); /* output: money: 22222 this.money: 22222 super.money: 10000 */ } }
上面代码的内存布局:
二、更复杂的继承的内存布局
看下面的代码,话它的内存布局图:
public class Test { public static void main(String[] args) { Son son = new Son(); } } class Grandfather { String name = "Grandfather_name"; String hobby = "Grandfather_hobby"; } class Father extends Grandfather { String name = "Father_name"; int money = 66666; } class Son extends Father { String name = "Son_name"; }
- ① 加载类信息: 会先加载当前类的父类的类信息(包括 Object 基类)
- ② Son 对象中会拥有其所有父类的属性: 父类属性和子类属性名字一样是可以的
- ③ 访问属性的时候:先看当前类中是否有该属性?若有,直接访问;
⚡ 若没有,查看直接父类是否有该属性,并且该属性是否可访问?若有并且属性没有被 private 修饰,可访问直接父类的属性;
⚡ 若有但属性被 private 修饰,直接报错;
⚡ 若没有,继续查找父类的父类是否有该属性,并且是否可访问 …【① 看自己有没有,有就直接用;若自己没有,就看父亲有没有,若父亲没有,就看爷爷有没有,… 一直向上找,直达找到 Object;② 若中途发现有一关系有该属性,但是不能被访问(被 private 修饰),直接报错,不继续往下找了】
- 1.父类的属性被 private 修饰,无法访问,但可通过其他方式访问(如:父类提供被 public 修饰的 get 方法)
- 2.私有的属性在内存中依然存在,只是无法被访问而已
到此这篇关于Java图文分析之继承内存布局的文章就介绍到这了,更多相关Java继承内存布局内容请搜索好代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持好代码网!