在多处解释中,都说明继承时只创建一个对象。但是,在从超类继承期间,子类不会继承其父类的私有属性。
然而,当子类调用其父类的非静态 getter 方法时,它显然是从某个父对象而不是类获取值。那么似乎当您创建子类对象时,也会创建一个存储这些私有属性的超类对象。
那么继承的方法和属性本质上有两个副本吗?例如,如果一个超类对象A有一个子类对象B。那么B内部同时存在一个super.attribute和一个this.attribute,因为还创建了一个隐藏的A对象?那么构造函数如何知道属性之间的区别呢?例如,A 有一个构造函数,将公共属性设置为 4。然后 B 调用该构造函数并将相同的属性设置为 5。但是 B 也继承了该属性,不是吗?那么它会重置为4吗?或者 super.attribute = 4 和 this.attribute = 5 吗?因此,属性的值不是继承的,但它的存在是吗?
当您创建任何类的新实例时,Java 始终只创建一个对象,无论它扩展了多少个其他类。
当对象被实例化时,它包含所有公共和私有字段,但它们仅在其特定范围内可用。
如果您需要了解有关对象如何存储在内存中的更多信息,请参阅以下示例:
class A {
private boolean attribute;
}
class B extends A {
private boolean attribute;
}
B inst = new B();
Run Code Online (Sandbox Code Playgroud)
在这种情况下,inst将是一个包含两个私有字段的单个对象 - 一个只能在 A 内部访问,另一个 - 只能在 B 内部访问。JVM 不会按名称存储字段 - 字段只是内存的一部分,JVM 会处理它们分别地。
如果您想了解有关类的内部表示的更多信息,我强烈建议您使用 Java 对象布局工具(https://github.com/openjdk/jol)或 IntelliJ Idea 的相关扩展(https://github.com/stokito ) /想法乔尔)。在此示例中,它显示生成的类在内存中如下所示:
Instance size 24 Losses total 10 Losses internal 3 Losses external 7
Offset Size Type Class Field
0 12 (object header)
12 1 boolean A attribute < private field of A
13 3 (alignment/padding)
16 1 boolean B attribute < private field of B
17 7 (loss due to the next object)
Run Code Online (Sandbox Code Playgroud)