Rol*_*all 10 java inheritance instantiation instance-variables
假设我有这段代码:
class Animal {
int legs = 4;
int head = 1;
}
public class Dog extends Animal {
public static void main (String []args) {
Dog dog = new Dog();
}
}
Run Code Online (Sandbox Code Playgroud)
我知道super()隐式置于no-args构造函数的第一行,所以我知道Animal构造函数将被执行,因此Animal将设置实例变量.
为了这个目的,我想,了解如果一旦这些变量已经被超级构造函数(初始化Animal),这些实例变量会在动物对象有保留或复制到子类(Dog).
在第一种情况下,对象Animal将被隐式实例化,super();并且每当实例Dog需要访问其中一个变量时,它将访问实例中保存的变量Animal(在后台创建).或者第二种情况,如果对象Animal将被临时创建,则将所有实例变量(in Animal)复制到Dog实例,然后删除Animal临时创建的实例.
我个人认为,例如,一个Dog对象将直接链接到一个Animal直接连接到一个对象的对象.
是这样的吗?
Jon*_*eet 16
只有一个对象,它立即(从一开始就是)一个Dog实例.它有所有的领域Dog(不是你在这里)和所有的领域Animal.
最初,所有变量都将设置为默认值(0,null等).然后,当您到达每个类的构造函数体(在调用超类构造函数之后)时,将执行实例变量初始值设定项,然后执行该类的构造函数体.
不需要复制,因为只有一个对象.例如,如果您要编写如下Animal构造函数:
public Animal() {
System.out.println(this.getClass());
}
Run Code Online (Sandbox Code Playgroud)
...它会打印出来Dog,因为该对象已经是一个Dog,即使它的Dog构造函数还没有被执行.
您的Dog扩展Animal,并且head,legs变量是不是私人的,所以你会在访问这些Dog实例.
在实践中,会发生以下情况:
Dog实例,也是一个Animalhead和之后的属性Animal)Dog被调用(它调用super())Animal被调用结果是一个对象,它是一个Dog,但也隐含着一个Animal.
一个如何Dog对象看起来像(让我们忘掉Object类的例子的缘故).我们假设Dog也有一个public String name;属性.
这是Dog实例的内存映射:
Addr Type Name Defined in:
------------------------
| 0 | int | legs | Animal
| 1 | int | head | Animal
| 2 | String | name | Dog
------------------------
Run Code Online (Sandbox Code Playgroud)
Animal,你可以访问地址1head的变量,Dog,则访问地址2name处的变量,Dog,则head在地址1处访问变量在Animal类体中运行的代码只能看到地址0-1.在Dog类中运行的代码可以访问地址0-2.如果属性是private超类,则该子地址将被禁止该地址.
这种内存映射可以非常容易地向下转换对象:使用相同的内存映射,只有处理(代码和可见性)不同.
我希望它澄清一点.
| 归档时间: |
|
| 查看次数: |
1022 次 |
| 最近记录: |