JAVA 继承 父类子类 内存分配

本文深入解析Java中的继承机制,包括单继承特性、成员变量及方法的继承规则、super关键字的作用等核心概念。并通过实例详细说明了子类如何继承父类成员,以及父类私有成员变量的处理方式。

继承的基本概念:
(1)Java不支持多继承,也就是说子类至多只能有一个父类。
(2)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法。
(3)子类中定义的成员变量和父类中定义的成员变量相同时,则父类中的成员变量不能被继承。
(4)子类中定义的成员方法,并且这个方法的名字返回类型,以及参数个数和类型与父类的某个成员方法完全相同,则父类的成员方法不能被继承。

分析以上程序示例,主要疑惑点是“子类继承父类的成员变量,父类对象是否会实例化?私有成员变量是否会被继承?被继承的成员变量在哪里分配空间?”
1:虚拟机加载ExtendsDemo类,提取类型信息到方法区。
2:通过保存在方法区的字节码,虚拟机开始执行main方法,main方法入栈。
3:执行main方法的第一条指令,new Student(); 这句话就是给Student实例对象分配堆空间。因为Student继承Person父类,所以,虚拟机首先加载Person类到方法区,并在堆中为父类成员变量在子类空间中初始化。然后加载Student类到方法区,为Student类的成员变量分配空间并初始化默认值。将Student类的实例对象地址赋值给引用变量s。
4:接下来两条语句为成员变量赋值,由于name跟age是从父类继承而来,会被保存在子类父对象中(见图中堆中在子类实例对象中为父类成员变量分配了空间并保存了父类的引用,并没有实例化父类。),所以就根据引用变量s持有的引用找到堆中的对象(子类对象),然后给name跟age赋值。
4:调用say()方法,通过引用变量s持有的引用找到堆中的实例对象,通过实例对象持有的本类在方法区的引用,找到本类的类型信息,定位到say()方法。say()方法入栈。开始执行say()方法中的字节码。
5:say()方法执行完毕,say方法出栈,程序回到main方法,main方法执行完毕出栈,主线程消亡,虚拟机实例消亡,程序结束。

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

super关键字在java中的作用是使被屏蔽的成员变量或者成员方法变为可见,或者说用来引用被屏蔽的成员变量或成员方法,super只是记录在对象内部的父类特征(属性和方法)的一个引用。啥叫被屏蔽的成员变量或成员方法?就是被子类重写了的方法和定义了跟父类相同的成员变量,由于不能被继承,所以就称作被屏蔽。
说到这里,上面提出的疑惑也就解开了。

<think>嗯,用户问的是Java父类子类继承子类应该在哪里建立。首先,我需要确定用户的问题核心是什么。看起来用户可能刚开始学习Java继承机制,对如何创建子类的位置不太清楚。可能他们是在实际编码时遇到了问题,比如子类应该放在同一个文件还是不同的文件中,或者是关于包结构的问题。 首先,我应该回忆Java的基础知识。在Java中,每个类通常都是一个独立的.java文件,除非是内部类。所以,父类子类通常应该分别放在不同的文件中,并且属于同一个包,或者在需要时通过import语句引入。但如果是内部类的话,子类也可以作为父类的内部类存在,不过这种情况相对少见,尤其是对于初学者来说。 接下来,用户可能不太清楚如何组织他们的代码结构。比如,他们可能把父类子类放在同一个文件里,导致编译错误。这时候需要说明正确的做法:每个公共类都应该有自己的文件,并且文件名与类名一致。如果子类父类同一个包中,子类可以直接继承父类,无需额外导入。如果不在同一个包,就需要使用import语句。 然后,考虑到用户可能是新手,可能需要具体的例子来帮助理解。应该给出一个简单的示例,展示父类子类如何分开放置,并说明文件结构。例如,父类Animal在Animal.java中,子类Dog在Dog.java中,并且它们位于同一个包com.example.animals里。 另外,用户可能想知道内部类的情况,虽然这种情况较少,但为了全面性还是应该提及。比如,子类作为父类的内部类,这种情况下子类可以放在父类的文件中,但通常不建议这样做,除非有特定的理由。 还需要注意访问权限的问题,比如父类的方法和字段如果是private的话,子类是无法直接访问的,应该使用protected或public修饰符。这也是初学者常犯的错误,可能在示例中提到这一点,帮助用户避免常见陷阱。 总结下来,回答的结构应该是先解释基本规则,然后给出具体的步骤和示例,最后提到可能的注意事项和常见问题。这样用户能够逐步理解如何正确地在Java中建立子类,并知道应该将子类放在哪里,以及相关的文件组织和包管理知识。</think>Java父类子类继承关系需要通过合理的位置规划来组织代码结构,以下是分步说明: 1. **基础规则** - 每个.java文件只能有一个`public`类 - 建议父类子类分开存放(特殊设计需求除外) - 推荐包(package)组织方式管理类文件 2. **推荐实现步骤** ① 创建父类文件:`ParentClassName.java` ```java // ParentClassName.java public class ParentClassName { // 父类属性与方法 protected void parentMethod() { System.out.println("父类方法"); } } ``` ② 创建子类文件(推荐与父类同包) ```java // ChildClassName.java public class ChildClassName extends ParentClassName { @Override protected void parentMethod() { super.parentMethod(); // 调用父类方法 System.out.println("子类扩展内容"); } } ``` 3. **文件位置建议** - 同一包内:直接继承(推荐) - 不同包时:需使用`import`语句 ```java // 子类在不同包时 package com.child.pkg; import com.parent.pkg.ParentClassName; public class ChildClassName extends ParentClassName { // 子类实现 } ``` 4. **特殊场景处理** - **内部类继承**:可直接在父类内部定义 ```java public class OuterClass { class ParentInner { /* 父内部类 */ } class ChildInner extends ParentInner { /* 子内部类 */ } } ``` - **匿名子类**:适用于临时实现 ```java ParentClassName obj = new ParentClassName() { @Override protected void parentMethod() { // 匿名子类实现 } }; ``` 5. **验证继承有效性** - 检查编译错误:确保访问权限正确(父类需有`protected`或`public`修饰符) - 验证继承关系: ```java System.out.println(childObj instanceof ParentClassName); // 应输出true ``` **最佳实践建议**: 1. 父子类文件应存放在相同包路径下 2. 使用Maven/Gradle标准目录结构: ``` src/main/java ├── com │ └── example │ ├── ParentClassName.java │ └── child │ └── ChildClassName.java ``` 3. 当需要跨模块继承时,需配置模块依赖关系 通过这种组织方式,既能保证代码可维护性,也符合Java的OOP设计规范。建议初学者优先采用标准包结构进行类文件管理。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值