• 13、Java 继承的内存布局(图文分析)


    一、初步了解继承的内存布局

    (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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    ⌨️ 通过 上篇文章 可以知道: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
             */
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    上面代码的内存布局:
    在这里插入图片描述

    二、更复杂的继承的内存布局

    看下面的代码,话它的内存布局图:

    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";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    🍀 ① 加载类信息: 会先加载当前类的父类的类信息(包括 Object 基类)
    🍀 ② Son 对象中会拥有其所有父类的属性: 父类属性和子类属性名字一样是可以的
    🍀 ③ 访问属性的时候:先看当前类中是否有该属性?若有,直接访问;⚡ 若没有,查看直接父类是否有该属性,并且该属性是否可访问?若有并且属性没有被 private 修饰,可访问直接父类的属性;⚡ 若有但属性被 private 修饰,直接报错;⚡ 若没有,继续查找父类的父类是否有该属性,并且是否可访问 …【① 看自己有没有,有就直接用;若自己没有,就看父亲有没有,若父亲没有,就看爷爷有没有,… 一直向上找,直达找到 Object;② 若中途发现有一关系有该属性,但是不能被访问(被 private 修饰),直接报错,不继续往下找了

    1.父类的属性被 private 修饰,无法访问,但可通过其他方式访问(如:父类提供被 public 修饰的 get 方法)
    2.私有的属性在内存中依然存在,只是无法被访问而已

    🎈再见!若有错误,请不吝赐教!🎈

  • 相关阅读:
    神经网络模型如何使用的,神经网络模型是干嘛的
    JavaPTA练习题 7-3 身体质量指数(BMI)测算
    windowCPU虚拟化已禁用解决方案
    请求转发 [JavaWeb][Servlet]
    低功耗设计—level shifter
    树状数组&线段树 的奇妙用法
    el-table换页后如何取得所有的选中行数据
    为什么ASP.NET Core的路由处理器可以使用一个任意类型的Delegate
    122页6万字消防大数据平台建设方案
    胰蛋白酶中英文说明书
  • 原文地址:https://blog.csdn.net/m0_54189068/article/details/126758450