0 0

java类实现继承时,内存中父类和子类是怎样分配的?10

我觉得java的一些特性与对象在内存中的分配方式是密切相关的。
比如说:Java的多态,正是因为new出的对象是在堆中分配的,而这种内存分配方式在编译期无需知道此对象所需要的空间和生存周期。

现在我很困惑的是,java类实现继承时,内存中父类和子类是怎样分配的?或者说有着怎样的联系呢。

例如:
父类:Father
public class Father {
	protected String classname = "Father";
	
	public Father(){
	}
	
	public Father(String cn){
		setClassName(cn);
	}
	protected String getClassName(){
		return classname;
	}
	
	protected void setClassName(String cn){
		classname = cn;
	}
}


子类:Child
public class Child extends Father{

	public Child(){
	}
	
	public Child(String cn){
		super(cn);
	}
	
	private String cname = "Child";
	
	public String getCname() {
		return cname;
	}

	public void setCname(String cname) {
		this.cname = cname;
	}
}


此时,我写测试代码:
public class FatherChildTest {
	public static void main(String args[]){
		System.out.println(new Child().getClassName());
		System.out.println(new Child("be changed in constructor!").getClassName());
	}
}


输出内容很明显:
Father
be changed in constructor!

想问的是,测试代码中,
new Child().getClassName()
动作时,
我创建的是Child对象,而它有父类的方法,且可以返回父类中定义的变量。
那Child继承Father,是不是相当于JVM加载类时,保存的类信息中不仅仅是Child的信息,还包括Father的那些对子类可见的信息?
比如,其实JVM加载类Child时,保存的类信息其实是这样的一个类的信息:
public class Child{
	
	public Child(){
	}
	
	public Child(String cn){
		setClassName(cn);
	}
	
	private String cname = "Child";
	
	//-------------来自父类 begin----------------
	protected String classname = "Father";
	
	protected String getClassName(){
		return classname;
	}
	
	protected void setClassName(String cn){
		classname = cn;
	}
	//-------------来自父类 End----------------
	
	public String getCname() {
		return cname;
	}

	public void setCname(String cname) {
		this.cname = cname;
	}
}

此类留有父类对子类可见的信息。


还是说,有另外一种方式,可以把子类与父类联系起来。

请指点!

我想知道原理,但可能表达的不太清楚,见谅!

问题补充:
我觉得java的一些特性与对象在内存中的分配方式是密切相关的。
比如说:Java的多态,正是因为new出的对象是在堆中分配的,而这种内存分配方式在编译期无需知道此对象所需要的空间和生存周期。

现在我很困惑的是,java类实现继承时,内存中父类和子类是怎样分配的?或者说有着怎样的联系呢。

例如:
父类:Father
<pre name="code" class="java">
public class Father {
protected String classname = "Father";

public Father(){
}

public Father(String cn){
setClassName(cn);
}
protected String getClassName(){
return classname;
}

protected void setClassName(String cn){
classname = cn;
}
}
</pre>

子类:Child
<pre name="code" class="java">
public class Child extends Father{

public Child(){
}

public Child(String cn){
super(cn);
}

private String cname = "Child";

public String getCname() {
return cname;
}

public void setCname(String cname) {
this.cname = cname;
}
}</pre>

此时,我写测试代码:
<pre name="code" class="java">
public class FatherChildTest {
public static void main(String args[]){
System.out.println(new Child().getClassName());
System.out.println(new Child("be changed in constructor!").getClassName());
}
}
</pre>

输出内容很明显:
Father
be changed in constructor!

想问的是,测试代码中,<pre name="code" class="java">new Child().getClassName()</pre>动作时,
我创建的是Child对象,而它有父类的方法,且可以返回父类中定义的变量。
那Child继承Father,是不是相当于JVM加载类时,保存的类信息中不仅仅是Child的信息,还包括Father的那些对子类可见的信息?
比如,其实JVM加载类Child时,保存的类信息其实是这样的一个类的信息:
<pre name="code" class="java">
public class Child{

public Child(){
}

public Child(String cn){
setClassName(cn);
}

private String cname = "Child";

//-------------来自父类 begin----------------
protected String classname = "Father";

protected String getClassName(){
return classname;
}

protected void setClassName(String cn){
classname = cn;
}
//-------------来自父类 End----------------

public String getCname() {
return cname;
}

public void setCname(String cname) {
this.cname = cname;
}
}
</pre>
此类留有父类对子类可见的信息。


还是说,有另外一种方式,可以把子类与父类联系起来。

请指点!

我想知道原理,但可能表达的不太清楚,见谅!


-------------------补充------------------

以下是mccxj所说,我没太懂:

【子类里有一个区域放的父类的实例,子类内存区里有一个this指针,指向了这个内存区里包括的父类实例区,当把引用付给父类时,是把子类内存区里面的父类实例区域的引用给了父类的实例.】

子类内存区里this指针不是指向它自己的吗?
而super指针才是指向了父类的实例?
后面那句 【当把引用付给父类时,是把子类内存区里面的父类实例区域的引用给了父类的实例.】,同样不太懂,感觉很模糊。
是不是说,当把引用付给父类时,这个引用体现的其实是子类中父类实例的属性?
问题补充:
我觉得java的一些特性与对象在内存中的分配方式是密切相关的。
比如说:Java的多态,正是因为new出的对象是在堆中分配的,而这种内存分配方式在编译期无需知道此对象所需要的空间和生存周期。

现在我很困惑的是,java类实现继承时,内存中父类和子类是怎样分配的?或者说有着怎样的联系呢。

例如:
父类:Father
<pre name="code" class="java">
public class Father {
protected String classname = "Father";

public Father(){
}

public Father(String cn){
setClassName(cn);
}
protected String getClassName(){
return classname;
}

protected void setClassName(String cn){
classname = cn;
}
}
</pre>

子类:Child
<pre name="code" class="java">
public class Child extends Father{

public Child(){
}

public Child(String cn){
super(cn);
}

private String cname = "Child";

public String getCname() {
return cname;
}

public void setCname(String cname) {
this.cname = cname;
}
}</pre>

此时,我写测试代码:
<pre name="code" class="java">
public class FatherChildTest {
public static void main(String args[]){
System.out.println(new Child().getClassName());
System.out.println(new Child("be changed in constructor!").getClassName());
}
}
</pre>

输出内容很明显:
Father
be changed in constructor!

想问的是,测试代码中,<pre name="code" class="java">new Child().getClassName()</pre>动作时,
我创建的是Child对象,而它有父类的方法,且可以返回父类中定义的变量。
那Child继承Father,是不是相当于JVM加载类时,保存的类信息中不仅仅是Child的信息,还包括Father的那些对子类可见的信息?
比如,其实JVM加载类Child时,保存的类信息其实是这样的一个类的信息:
<pre name="code" class="java">
public class Child{

public Child(){
}

public Child(String cn){
setClassName(cn);
}

private String cname = "Child";

//-------------来自父类 begin----------------
protected String classname = "Father";

protected String getClassName(){
return classname;
}

protected void setClassName(String cn){
classname = cn;
}
//-------------来自父类 End----------------

public String getCname() {
return cname;
}

public void setCname(String cname) {
this.cname = cname;
}
}
</pre>
此类留有父类对子类可见的信息。


还是说,有另外一种方式,可以把子类与父类联系起来。

请指点!

我想知道原理,但可能表达的不太清楚,见谅!

<strong>问题补充:</strong>
我觉得java的一些特性与对象在内存中的分配方式是密切相关的。
比如说:Java的多态,正是因为new出的对象是在堆中分配的,而这种内存分配方式在编译期无需知道此对象所需要的空间和生存周期。

现在我很困惑的是,java类实现继承时,内存中父类和子类是怎样分配的?或者说有着怎样的联系呢。

例如:
父类:Father
&lt;pre name="code" class="java">
public class Father {
protected String classname = "Father";

public Father(){
}

public Father(String cn){
setClassName(cn);
}
protected String getClassName(){
return classname;
}

protected void setClassName(String cn){
classname = cn;
}
}
&lt;/pre>

子类:Child
&lt;pre name="code" class="java">
public class Child extends Father{

public Child(){
}

public Child(String cn){
super(cn);
}

private String cname = "Child";

public String getCname() {
return cname;
}

public void setCname(String cname) {
this.cname = cname;
}
}&lt;/pre>

此时,我写测试代码:
&lt;pre name="code" class="java">
public class FatherChildTest {
public static void main(String args[]){
System.out.println(new Child().getClassName());
System.out.println(new Child("be changed in constructor!").getClassName());
}
}
&lt;/pre>

输出内容很明显:
Father
be changed in constructor!

想问的是,测试代码中,&lt;pre name="code" class="java">new Child().getClassName()&lt;/pre>动作时,
我创建的是Child对象,而它有父类的方法,且可以返回父类中定义的变量。
那Child继承Father,是不是相当于JVM加载类时,保存的类信息中不仅仅是Child的信息,还包括Father的那些对子类可见的信息?
比如,其实JVM加载类Child时,保存的类信息其实是这样的一个类的信息:
&lt;pre name="code" class="java">
public class Child{

public Child(){
}

public Child(String cn){
setClassName(cn);
}

private String cname = "Child";

//-------------来自父类 begin----------------
protected String classname = "Father";

protected String getClassName(){
return classname;
}

protected void setClassName(String cn){
classname = cn;
}
//-------------来自父类 End----------------

public String getCname() {
return cname;
}

public void setCname(String cname) {
this.cname = cname;
}
}
&lt;/pre>
此类留有父类对子类可见的信息。


还是说,有另外一种方式,可以把子类与父类联系起来。

请指点!

我想知道原理,但可能表达的不太清楚,见谅!


-------------------补充------------------

以下是mccxj所说,我没太懂:

【子类里有一个区域放的父类的实例,子类内存区里有一个this指针,指向了这个内存区里包括的父类实例区,当把引用付给父类时,是把子类内存区里面的父类实例区域的引用给了父类的实例.】

子类内存区里this指针不是指向它自己的吗?
而super指针才是指向了父类的实例?
后面那句 【当把引用付给父类时,是把子类内存区里面的父类实例区域的引用给了父类的实例.】,同样不太懂,感觉很模糊。
是不是说,当把引用付给父类时,这个引用体现的其实是子类中父类实例的属性?


-------------------------再补充--------------------------
一下为bohemia 所说:
【super相当于指向父类示例的一个指针; 子类只保存子类的信息和super指针; 具体调用,先查找当前子类,然后查找父类是否有实现; 】

既然先查找子类,为何变量会找到父类呢?
(我查了,跟java的编译期绑定和运行时绑定有关)
想听听大家的理解。

问题补充:
-------------------补充------------------

以下是mccxj所说,我没太懂:

【子类里有一个区域放的父类的实例,子类内存区里有一个this指针,指向了这个内存区里包括的父类实例区,当把引用付给父类时,是把子类内存区里面的父类实例区域的引用给了父类的实例.】

子类内存区里this指针不是指向它自己的吗?
而super指针才是指向了父类的实例?
后面那句 【当把引用付给父类时,是把子类内存区里面的父类实例区域的引用给了父类的实例.】,同样不太懂,感觉很模糊。
是不是说,当把引用付给父类时,这个引用体现的其实是子类中父类实例的属性?


-------------------------再补充--------------------------
一下为bohemia 所说:
【super相当于指向父类示例的一个指针; 子类只保存子类的信息和super指针; 具体调用,先查找当前子类,然后查找父类是否有实现; 】

既然先查找子类,为何变量会找到父类呢?
(我查了,跟java的编译期绑定和运行时绑定有关)
想听听大家的理解。
OO 
2008年11月14日 00:42

6个答案 按时间排序 按投票排序

0 0

采纳的答案

子类里有一个区域放的父类的实例,子类内存区里有一个this指针,指向了这个内存区里包括的父类实例区,当把引用付给父类时,是把子类内存区里面的父类实例区域的引用给了父类的实例.

2008年11月14日 07:37
0 0

说到底还是乱七八糟的指针的东西。。。只是虚拟机给偶们屏蔽得很好。。。

貌似bohemia说的那本书很好很强大

2008年11月16日 10:16
0 0

引用
既然先查找子类,为何变量会找到父类呢?


你有点糊涂了把?子类只是有个父类的引用。。那找父类有什么奇怪的?

2008年11月16日 10:12
0 0

当JVM加载一个子类的时候也会把它的父类一同加载的,子类内部通过super保存父类的一个引用,详细情况可以看看《Thinking in java》,里面已经说的非常详尽了

2008年11月14日 10:08
0 0

mccxj说的对的;

super相当于指向父类示例的一个指针; 子类只保存子类的信息和super指针;
具体调用,先查找当前子类,然后查找父类是否有实现;

概念和语言实现的问题,建议可以看下 <深度探索C++对象模型>,这本书;

应该就对这些机制有了深入的理解和了解了.

2008年11月14日 08:49
0 0

除了要能取到父类的东西,而且还要区分哪些是父类的东西。全部都放到一起,不好区分把

2008年11月14日 07:38

相关推荐

    论JAVA继承机制中父类与子类的关系

    文章围绕子类继承父类成员的过程、成员变量及方法的赋值、重写、覆盖等问题展开讨论,旨在帮助读者更好地理解Java继承中的重点与难点。 #### 关键词 - 继承机制 - 父类 - 子类 #### 一、超类的属性或方法在继承...

    在父类获取子类属性

    这个主题涉及到面向对象编程的基本原理,特别是子类继承父类后如何访问和操作子类特有的属性。下面我们将深入探讨这个话题。 首先,我们了解基本的继承概念。在Java中,一个类(子类)可以继承另一个类(父类),...

    java中的继承(子类调用父类构造方法还不懂).doc

    在 Java 中,使用 `extends` 关键字可以实现继承关系,子类可以继承父类的属性和方法,并可以重写父类的方法。使用 `super` 关键字可以引用父类的成分,访问父类中定义的属性和方法。 在 Java 中,可以使用多态性来...

    java 子类对象赋值给父类对象的使用

    在Java编程语言中,子类继承父类是一种常见的特性,它允许子类扩展或复用父类的功能。当我们创建一个子类对象并将其赋值给父类引用时,这种行为被称为向上转型(Upcasting)。这一过程是自动且安全的,因为子类对象...

    将子类引用赋给父类对象时,java虚拟主机并没有将那些非继承成员丢弃

    子类B不仅可以继承父类A的所有公有(public)和受保护(protected)成员,还可以有自己的特有成员。当我们声明一个父类类型的引用并将其赋值为子类的对象时,如`Car car = new SportsCar();`,这里的`car`引用虽然...

    java多态性详解——父类引用子类对象

    方法的重写发生在子类中,当子类继承父类后,可以重新定义父类中的方法。这种情况下,当调用子类对象的方法时,实际上执行的是子类中重写后的方法,而不是父类中的同名方法。这是多态性中最为重要的一个方面,因为它...

    java反射获取所有属性,获取所有get方法,包括子类父类

    总结,Java反射机制为我们提供了强大的动态性,能够方便地获取和操作类的属性和方法,包括私有成员和子类父类中的成员。通过熟练掌握反射技术,开发者可以实现更灵活、更动态的代码,但也需要谨慎使用,以避免潜在的...

    Java父类继承代码示例

    在Java编程语言中,继承是面向对象编程的一个关键特性,它允许一个类(子类)继承另一个类(父类)的属性和方法。这有助于实现代码重用,并且可以创建层次结构的类系统,使代码更加模块化。下面我们将深入探讨Java中...

    Java 实现继承实例代码

    这种设计模式有助于代码重用,使得子类可以继承父类的属性和方法,并且可以添加新的功能或覆盖已有的行为。本实例将通过`Tryextend.java`文件展示如何在Java中实现继承。 首先,让我们理解继承的基本语法。在Java中...

    java中与继承有关的程序内存分析

    在Java编程语言中,继承是面向对象特性的重要组成部分,它允许一个类(子类)从另一个类(父类)继承属性和方法。这种机制有助于代码重用和构建复杂的类层次结构。当我们谈论“java中与继承有关的程序内存分析”时,...

    Java中父类和子类之间的转换操作示例

    Java中父类和子类之间的转换操作示例 Java 中父类和子类之间的转换操作是面向对象编程(OOP)中一个重要的概念。它允许开发者在不同的类之间进行类型转换,以便更好地实现继承和多态性。在 Java 中,父类和子类之间...

    java定义父类和子类.doc

    Java 中的继承机制和多态性 在 Java 编程语言中,继承机制是面向对象编程(OOP)的一个重要概念。继承机制允许一个类从另一个类继承其属性和方法,从而实现代码复用和提高开发效率。多态性是继承机制的自然延伸,它...

    JAVA 子类继承父类的范例 可直接运行

    在Java中,继承是面向对象编程的核心特征之一,它允许我们创建一个新类(子类)基于一个已经存在的类(父类或超类)的结构。这样可以复用现有类的代码,并可添加或覆盖特性来形成新的类。本文将通过具体的代码范例,...

    再次详细说明在继承中的程序执行顺序,子类与父类到底哪个先执行

    它允许子类从父类中继承属性和方法,从而实现代码的重用和扩展。本文将深入探讨在继承中的程序执行顺序,以及子类与父类的执行顺序问题。 首先,我们需要了解Java或Python等面向对象语言中类的构造过程。当一个类...

    Java 接口与继承

    Java中的继承和接口是面向对象编程的关键特性,它们在软件设计中扮演着至关重要的角色,实现了代码的重用和类的层次结构。 继承是Java中创建新类的一种方式,它允许一个子类(SubClass)从一个已存在的父类...

    java,定义父类和子类.pdf

    在Java编程语言中,继承是一种强大的特性,它允许我们创建新的类,这些新类会继承已有类的属性和行为。这种机制不仅能够提高代码的复用性,还能使得类之间的关系更加清晰、易于理解。本文将通过具体的例子来详细介绍...

    父类引用指向子类对象

    当`main`方法在父类中,或者在与父类同包的其他类中时,可以访问父类和子类的`default`、`protected`、`public`属性和方法。如果`main`在其他包中,只能访问`public`属性和方法。 总的来说,父类引用指向子类对象是...

    java多态性详解——父类引用子类对象.pdf

    多态性是 Java 面向对象编程的精髓所在,它可以通过父类类型的引用指向子类的对象、方法的重写和重载、动态连接来实现。多态性可以提高程序的灵活性和可扩展性,使得程序更加灵活和强大。 知识点: 1. 多态性是 ...

Global site tag (gtag.js) - Google Analytics