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

时间:2013-05-11 14:37:27

标签: java inheritance

如果我创建了一个子类的对象,那么还会创建继承子类的超类对象吗?如果没有,那么如何通过创建Thread类的子类(在多线程中)调用Thread类构造函数并创建一个Thread对象?

6 个答案:

答案 0 :(得分:12)

子类的一个实例是超类的一个实例。只创建了一个对象,但作为该创建的一部分,构造函数调用一直链接到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中的代码。

事实上我们有一个单独的对象 all 状态(超类和子类)和所有行为(在{{1}中声明的任何方法}仍然可以在Superclass的实例上使用,虽然有些可能重写且具有更多的特殊行为)对于理解Java的多态性方法至关重要。

答案 1 :(得分:2)

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

答案 2 :(得分:1)

当你创建一个对象时,它会获得一个带有一组变量的内存来保存它的所有数据。

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

答案 3 :(得分:0)

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

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

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
   }     
}

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

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

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

答案 4 :(得分:0)

没有那里只有一个对象。有一种误解,即构造函数用于创建对象。但它实际上是用于初始化对象。因此,当我们创建子类对象以及子类构造函数时,由于子类构造函数的第一行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。You can see The hashCodes are same

答案 5 :(得分:-1)

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