创建子类的实例是否会自动创建其超类对象?

如果我创建子类的对象,那么还将创建从inheritance子类的超类对象吗? 如果没有,那么如何通过创建Thread类的子类(在multithreading中)调用Thread类构造函数并创建一个Thread对象?

子类的实例是超类的实例。 只创建了一个对象,但作为该创建的一部分,构造函数调用一直链接到java.lang.Object 。 例如:

 public class Superclass { // Note: I wouldn't normally use public variables. // It's just for the sake of the example. public int superclassField = 10; public Superclass() { System.out.println("Superclass constructor"); } } public class Subclass extends Superclass { public int subclassField = 20; public Subclass() { super(); // Implicit if you leave it out. Chains to superclass constructor System.out.println("Subclass constructor"); } } ... Subclass x = new Subclass(); System.out.println(x instanceof Subclass); System.out.println(x instanceof Superclass); System.out.println(x.superclassField); System.out.println(x.subclassField); 

这个输出是:

 Superclass constructor Subclass constructor true true 10 20 

……因为:

  • 任何构造函数做的第一件事是调用同一个类中的另一个构造函数,或者调用超类构造函数。 所以我们在输出中的“Subclass constructor”之前看到“Superclass constructor”。
  • 我们创建的对象(显然)是Subclass一个实例
  • 我们创建的对象也是 Superclass一个实例
  • 我们创建的单个对象包含两个字段( superclassFieldsubclassField )。 即使字段是私有的(通常也是这样),这也是如此 – Subclass的代码将无法访问Superclass声明的私有字段,但该字段仍然存在 – 并且仍然可以访问代码在Superclass

事实上我们有一个具有所有状态(包括超类和子类)的单个对象以及所有行为(在Superclass声明的任何方法仍然可以在Subclass的实例上使用,尽管有些可能会更多的特殊行为覆盖 )对于理解Java的多态性方法至关重要。

您只在创建另一个的子类时创建一个对象。 它是子类及其所有父类的实例。 例如,我创建了一个cat对象。 它是一只猫,同时也是猫科动物,哺乳动物,动物和物体。

当您创建一个对象时,它会获得一个内存,其中包含一组变量来保存其所有数据。

子类将包含来自子项的字段以及来自其祖先的任何字段。 所以这是一个像儿童及其祖先一样的单一物体。 创建子类时没有创建父类对象。

在这里,我用一个例子来缩写

如果创建了子类对象,它是否会自动创建超类对象?

 class P{ P(){ System.out.println(this.hashCode()); // it will print 2430287 } } class C extends P{ C(){ System.out.println(this.hashCode()); // it will also print 2430287 } } public class Test{ public static void main(String... args){ C obj = new C(); System.out.println(c.hashCode()); //Again, it will print 2430287 } } 

如果您编译并运行此代码,您将发现正在打印相同的Object hashCode 。 因此,这意味着只创建了一个对象。

现在,父类对象是如何初始化的?

在此示例中,仅创建一个对象,该对象是子类的实例,但是有两个构造函数(父级和子级)正在执行。 但构造函数只是在子类的上下文中。

没有那里只有一个对象。 有一种误解,即构造函数用于创建对象。 但它实际上是用于初始化对象。 因此,当我们创建子类对象以及子类构造函数时,父类构造函数也会执行,因为子类构造函数的第一行是this()super() 。 现在,看看下面的代码。

 Public class P{ public P(){ System.out.println(this.hashCode()); // Parent class Constructor } } public class C extends P{ public C(){ System.out.println(this.hashCode()); // Child Class constructor } } public class Test{ public static void main(String [] args){ C c = new C(); System.out.println(c.hashCode()); } } 

如果您运行代码,您可以看到只有一个HashCode。 一个对象只有一个hashCode。 如果将创建父类对象,则该对象必须有另一个hashCode。 您可以看到hashCodes是相同的

不。 它不会创建父类的实例。 但肯定会创建一个实例。并将对象引用传递给子类。 因此,实例在父类中创建,并由子类构造函数调用。 和子类方法操作。