创建新的子类对象时是否存在超类实例?

Mr.*_*Sky 2 java

JVM是否在创建新的子类对象时创建超类实例?在下面的例子中为什么super.setName("Buddy")成功?是否有Pet创建后的实例new Dog()

public class MainDemo {
    public static void main(String[] args) {
        Pet pet = new Dog();
        System.out.println(pet.getName());//it will print Buddy
    }
}
public class Pet {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
public class Dog extends Pet {
    public Dog() {
        super.setName("Buddy");
    }
}
Run Code Online (Sandbox Code Playgroud)

我改变了Dog and Pet的构造函数,如下所示

public Pet() {
    System.out.println("this is Pet's constructor");
}
public Dog() {       
    super.setName("Buddy");
    System.out.println("this is Dog's constructor");
}
Run Code Online (Sandbox Code Playgroud)

控制台的结果是

this is Pet's constructor
this is Dog's constructor
Buddy
Run Code Online (Sandbox Code Playgroud)

看起来jvm创造了一个宠物?

我再次将代码添加到宠物和狗中,如下所示

System.out.println(this.getClass().getName()+".hashCode="+this.hashCode());
Run Code Online (Sandbox Code Playgroud)

结果是

this is Pet's constructor
com.bt.java.project.Dog.hashCode=27189676
this is Dog's constructor
com.bt.java.project.Dog.hashCode=27189676
Buddy
Run Code Online (Sandbox Code Playgroud)

他们的hashCode是相同的.所以它意味着只有一个实例?

ars*_*jii 6

当你执行

new Dog()
Run Code Online (Sandbox Code Playgroud)

只有一个物理创建的对象,即Dog类的实例.但是,此实例还包含所有必需的信息,以便可以将其用作Pet.它继承了包含在其中的所有非私有字段/方法Pet,但也可以添加特定于狗的其他字段/方法.出于这个原因,一个对象也被称为其所有超类的一个实例,但这并没有改变只创建一个对象的事实(我认为这是你的问题,从根本上说).

你应该想到这样一个Dog对象:

+---------------+
|  +---------+  |
|  | Pet     |  |
|  | fields  |  |
|  | and     |  |
|  | methods |  |
|  +---------+  |
|               |
|  Dog          |
|  fields       |
|  and          |
|  methods      |
+---------------+

它仍然是一个对象,但您可以通过仅考虑上图中最内层的区域来将其视为一个对象.PetPet

  • @JeeshuMittal 是的,我认为您走在正确的轨道上。正如我所说,它包含将它用作“宠物”所需的所有信息以及一些特定于“狗”的附加信息。所有这些都被封装在一个对象中。 (2认同)