当前位置: 首页 > news >正文

Java继承机制深度解析:子类如何继承父类及内存原理解析

Java的继承机制是面向对象编程的核心特性之一,但许多开发者对“子类究竟能继承父类哪些内容”存在误解。例如,为什么子类不能继承父类的构造方法?为什么私有成员变量可以继承却无法直接访问?本文将通过继承规则解析内存模型拆解,为你揭示Java继承的本质逻辑。


一、继承规则全景解析

1. 构造方法:禁止继承的设计
  • 规则
    无论父类的构造方法是publicprotected还是private,​子类均不能继承父类的构造方法

  • 代码验证

class Parent {
    public Parent() {}
    private Parent(int x) {} 
}

class Child extends Parent {
    // 必须显式定义构造方法
    public Child() {
        super(); // 必须主动调用父类构造方法
    }
}

编译报错:若父类没有无参构造方法且子类未显式调用super(...),将直接导致编译失败。

2. 成员变量:隐式继承但访问受限
  • 规则
    父类的所有成员变量(包括private修饰的)​都会被继承,但访问权限由修饰符控制:

    • public/protected/默认:子类可直接访问
    • private:子类无法直接访问(需通过父类提供的公共方法)
  • 反编译验证
    使用javap -private Child查看子类字节码,会发现父类私有变量privateVar存在于子类的字段列表中,但访问时报错"has private access"

3. 成员方法:继承与权限挂钩
  • 规则

    • public/protected/默认方法:子类可直接继承并重写(Override
    • private方法:​无法被继承,子类中定义同名方法视为新方法(与重写无关)
  • 示例

class Parent {
    private void privateMethod() {} 
    public void publicMethod() {}
}

class Child extends Parent {
    // 此方法与父类privateMethod无关联
    public void privateMethod() {} 
}

 二、内存模型深度拆解 

1.为什么构造方法无法被继承

原因很简单因为子类如果继承了父类的构造方法,就会违背构造方法的定义规则,如图.

2.关于成员变量的继承

如图当代码执行到z.name这一行的时候,它会先寻找堆上001空间里的子类成成员变量,没有就会寻找001空间中的父类成员变量,图上Fu类里的成员变量是私有的所以无法访问,同理如果不是私有的就能够访问

3.关于成员方法的继承

非私有方法的继承机制

虚方法表(vtable)​
JVM为每个类维护一个虚方法表,记录该类所有可被继承的方法(非private、非static)。

  • 子类虚方法表中包含:
    • 从父类继承的非私有方法(直接复制父类方法地址)
    • 子类新增的方法
    • 子类重写(Override)的方法(覆盖父类方法地址)

动态绑定示例

class Parent {
    public void show() { System.out.println("Parent"); }
}
class Child extends Parent {
    @Override
    public void show() { System.out.println("Child"); }
}

Parent obj = new Child();
obj.show(); // 输出"Child"(动态绑定到子类方法)
私有方法的隔离性

编译期静态绑定
private方法在编译期直接绑定到定义它的类,​不会进入虚方法表

  • 子类对象内存中虽然包含父类私有方法(物理存在),但子类方法表中无入口,因此无法调用。
  • 子类定义同名方法视为全新方法,与父类无关。
class Parent {
    private void secret() { System.out.println("Parent secret"); }
}
class Child extends Parent {
    // 这是一个新方法,与父类secret()无关
    public void secret() { System.out.println("Child secret"); }
}

总结 

Java的继承机制通过内存预分配权限分层控制,实现了代码复用与安全性的平衡。理解其背后的内存模型,能帮助我们:

  1. 避免因权限问题导致的诡异Bug(如误认为子类不包含父类私有变量)
  2. 优化代码结构(例如合理选择protectedfinal修饰符)
  3. 深入掌握多态的实现原理(虚方法表与动态绑定)

下次面对继承问题时,不妨从内存布局的视角重新审视,或许会有豁然开朗的体验!

相关文章:

  • 《A Gentle Introduction to Graph Neural Networks》-GNN的综述性论文
  • 玩转python:掌握Python数据结构之Trie树
  • Django部署Filemanagement
  • Next.js介绍(React框架)
  • 32- 两数之和 II - 输入有序数组
  • AutoGen学习笔记系列(十四)Advanced - Serializing Components
  • OpenSSL 的主要功能及其示例命令
  • Python 文件和异常(存储数据)
  • tomcat部署springboot+vue(不使用nginx)
  • 【深度学习】多源物料融合算法(一):量纲对齐常见方法
  • 贪心算法(5)(java)k次取反后最大化的数组和
  • git 撤销某次提交的上交到远程服务器的commit提交,此提交后面的commit需要保留【deeepseek生成】
  • 【SOC 芯片设计 DFT 学习专栏 -- Scan chain 和 SDFFs及 EDT】
  • sqli-lab靶场学习(八)——Less26-28
  • Android ANR 监控方法与事件分发耗时优化实战
  • vue的 props 与 $emit 以及 provide 与 inject 的 组件之间的传值对比
  • docker修改了daemon.js文件还是下载不了镜像
  • Android 自定义View之底部导航栏
  • LanceDB快速入门之基本操作与API一览
  • 基于VMware的Ubuntu22.04系统安装和配置以及解决Ubuntu共享文件夹无法实现的问题
  • 屈晓华履新四川省社科联党组书记,此前担任省国动办主任
  • 美众议院通过法案将“墨西哥湾”更名为“美国湾”
  • 牛市早报|国家发改委:今年将推出约3万亿元优质项目,支持民营企业参与
  • 体坛联播|曼联热刺会师欧联杯决赛,多哈世乒赛首日赛程出炉
  • 复旦大学文科杰出教授裘锡圭逝世,享年90岁
  • 视频丨习近平同普京会谈:共同弘扬正确二战史观,维护联合国权威和地位