如果我创建子类的对象,那么还会创建继承子类的超类对象吗?如果不是,那么如何通过创建 Thread 类的子类(在多线程中)调用 Thread 类构造函数并创建一个 Thread 对象?
6 回答
子类的实例是超类的实例。仅创建一个对象,但作为该创建的一部分,构造函数调用一直链接在一起直到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
- 我们创建的对象也是
Superclass
- 我们创建的单个对象具有两个字段 (
superclassField
和subclassField
)。即使字段是私有的(它们通常是私有的)也是如此 - 中的代码Subclass
将无法访问中声明的私有字段Superclass
,但该字段仍然存在 - 并且仍然可以访问Superclass
.
我们有一个具有所有状态(超类和子类)和所有行为(其中声明的任何方法Superclass
仍然可以在 的实例上使用Subclass
,尽管有些可能被更专业的行为覆盖)的单个对象这一事实至关重要了解 Java 的多态性方法。
当您创建一个对象时,它会获得一块内存和一组变量来保存其所有数据。
子类将包含来自子类的字段和来自其祖先的任何字段。所以它是一个像孩子和它的祖先一样的单一对象。创建子类时没有创建父类对象。
当您创建另一个对象的子类时,您只创建一个对象。它是子类及其所有父类的实例。例如,我创建了一个 cat 对象。它是一只猫,同时也是一只猫科动物、哺乳动物和动物,以及一个物体。
不,那里只有一个对象。有一种误解,认为构造函数是用来创建对象的。但它实际上是为了初始化一个对象。因此,当我们与子类构造函数一起创建子类对象时,父类构造函数也会执行,因为子类构造函数的第一行是this()
or 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。
在这里,我用一个例子来缩写
如果创建了子类对象,是否会自动创建超类对象?
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
正在打印相同的对象。因此,这意味着只创建了一个对象。
现在,如何初始化父类对象?
在这个例子中,只创建了一个对象,它是子类的一个实例,但是有两个构造函数(父类和子类)正在执行。但是构造函数只是在子类的上下文中。
没有。它不会创建父类的实例。但它肯定会创建一个实例。并将对象引用传递给子类。因此实例在父类中创建并由子类构造函数调用。子类方法运行。