从物理上讲,您创建了一个对象,但从概念上讲,您创建了 2 个。这就像,比如说,一个女婴出生:物理上她只是一个,但从概念上讲,一个新的女性已经出生,一个新的人类已经出生,一个新的众生诞生了,地球上的新居民诞生了,等等。是的,没错。这里也有继承关系(subTyping),我是故意的。为避免混淆,最好说只有一个对象具有多个面;一个同时属于不同(超)类的对象。
现在,关于逻辑部分说得够多了,让我们来看看物理部分。在内存中使用以下结构创建单个(物理)对象
+--------------------------+----------------------------+
| B | C' +
+--------------------------+----------------------------+
第一部分 (B) 包含从 C 的超类 B 继承的所有字段(如果有)。第二部分(C',我'
用于“补充”)包含所有属于 C 的“专有”字段(即不是从 B 继承,而是在 C 本身中定义)。重要的是要注意创建的对象不是从 C' 开始,而是从 B 开始。继承的字段与新字段的组合构成了完整的对象。
现在,如果 B 有自己的超类 A,那么结构应该是这样的:
+--------+-----------------+----------------------------+
| A | B' | C' +
+--------+-----------------+----------------------------+
这里需要注意的重要一点是B == A + B'
. 换句话说,C 不需要知道 A。它只关心它的直接超类 B,它隐藏了它的内部结构。
要回答具体问题:
在这种情况下,构造函数是否只初始化变量 i 而没有创建类的具体对象?
与上面的 A、B 和 C 在结构上链接的方式相同,它们在初始化期间也是链接的。如果不是这样,就像我最初示例中的女孩出生时没有任何其他我们知道的东西一样,根据定义,她也是。不可能。完全矛盾。于是,两个类的构造过程都进行了,包括:将字段初始化为“零”值(null
对于引用和false
对于boolean
's),并执行一个构造函数(可以调用其他构造函数)。
在这种特殊情况下, fieldi
被初始化,Inheritance
构造函数被执行,TestInheritance
' 的字段(如果有的话)将被初始化,然后 aTestInheritance
的构造函数将被执行。我们如何才能准确地知道每个类的构造函数是什么?比较简单。引发一切的是new TestInheritance()
。这显然表明TestInheritance
' 的构造函数没有任何参数(存在;否则会出现编译错误)。但是,此构造函数没有显式调用超类的任何构造函数(通过关键字super(...)
)。正如我们在上面看到的,这是不可能的,编译器会自动插入等价于super()
,即不带参数调用超类的构造函数 (Inheritance()
)。同样,这个构造函数存在,一切都很好。输出将是:
I am in base class 0
I am in derived class
没有参数的构造函数被称为“默认构造函数”主要有 3 个原因: - 它们通常非常简单,因为它们没有参数。- 当子类的构造函数没有显式调用任何超类构造函数时,它们会被自动调用。- 它们是为那些类自动提供的,无需程序员显式编写任何构造函数。在这种情况下,构造函数什么都不做,只进行初始化。
从我目前所读到的,只创建了一个对象——派生类中包含 i 变量的对象。
这并不完全正确。从物理上讲,确实只创建了一个对象,但它对应于与new
( TestInheritance
) 一起使用的类,在这种情况下恰好没有字段,但这无关紧要。事实上,两条输出线都被打印出来了。从概念上讲……我们已经提到了这一点。
但是从调用基类的构造函数到调用派生类的构造函数的时间点,我是如何/在哪里存储在内存中的?
当new TestInheritance()
执行时,在调用构造函数之前,甚至在执行初始化之前,发生的第一件事就是为整个对象分配内存。- 通常这个内存是“脏的”,这就是它需要初始化的原因。- TestInheritance
'字段,其超类'字段等有空间。甚至每个字段在内存中对象内的位置都是预先知道的。
因此,即使在调用基类的构造函数之前,已经为i
任何其他字段分配了内存,只是它们是“脏的”(未初始化)。
基类是抽象类的情况会怎样。
没有区别。唯一的问题是您不能自己创建抽象类的对象。您将它们创建为(具体)子类的一部分。这类似于一个新人类不能由他/她自己出生的事实。要么是女婴,要么是男婴。
如果我能知道在不同时间点内存中发生了什么,我将不胜感激。
我希望我做到了。
如果我说了一些根本不正确的话,请告诉我。我真的很想知道这件事是如何运作的。
没有什么“根本不正确”。