当前位置: 首页 > 面试题库 >

通过继承继承创建了多少个对象?

广亮
2023-03-14
问题内容

假设我有三节课:

class A {
    A() {
        // super(); 
        System.out.println("class A");
    }
}
class B extends A {
    B() {
        // super(); 
        System.out.println("class B");
    }
}
class C extends B {
    public static void main(String args[]) {
        C c = new C(); //Parent constructor will get called
    }
}

当我创建类C的实例时,它将调用超类的构造函数。那么,是否有多个对象正在创建?如果仅创建一个对象,那么super()像另一个类的构造函数如何?super()方法是否在内部创建对象?我所知道的是,构造函数也是一种方法(我可能错了)。

我的问题是:

  1. 在这种情况下创建了多少个对象?
  2. 如果创建了一个对象,那么Super()如何在内部调用父类的构造函数?

问题答案:

好问题。您要探究的是Java如何 初始化对象 -涉及许多步骤。

我知道构造函数也是一种方法(也许我错了)。

几乎是正确的。构造函数是一种特殊的方法。如果您反编译一个类文件,则会看到构造函数被重命名为<init><init>与其他方法的处理方式不同,例如,除非通过使用关键字newor,否则不能显式调用它super。这是如此基础,以至于它是在JVM本身中实现的,而不是用Java语言定义的。

在这种情况下,将创建多少个对象。

创建了一个对象-的实例C

C是另外地和同时的一个实例B和实例A,并且还Object

如果创建了一个对象,则在内部如何super()调用Parent类Constructor。Super如何调用父类的构造函数。

这是我们进行初始化的地方-初始化是JVM如何创建对象的新实例并设置所有成员值-特定类的成员值和超类的成员值。涉及几个阶段:

  • 加载所有引用的类并初始化这些类。类初始化本身并不简单,因此在此不做介绍。值得一读。
  • 分配的内存块用于保存实例的成员,其中包括的所有成员AB以及C注意, 这解释了问题的一个方面:基类及其子类的构造函数如何更新或引用相同的对象- 所有类的实例的所有成员都一个接一个地存储在同一块内存中
  • 将所有成员初始化为其 默认值 。例如,intfloat成员将设置为0和0.0f。
  • 执行或计算成员初始化器,例如:
        private int a = 10;
    private int b = a * 5;
    private String c = Singleton.getInstance().getValue();
  • 注意(1)成员初始化严格按照在类中声明成员的顺序进行。这意味着声明后面对成员的引用已损坏:
        private int a = b * 5; // Forward reference; won't compile
    private int b = 10;
  • 注意(2)Java中有一个未充分使用的工具,可以 执行构造函数 之前 运行任意代码以初始化值。这些代码块现在再次严格按照声明的顺序执行:
        private int a;
    private int b = 1;
    {
        // Initization occurs after b but before c.
        // c cannot be referenced here at all
        int i = SomeClass.getSomeStatic();
        a = i * 2;
    }
    private int c = 99;
  • 执行的构造函数C。构造函数必须直接从超类调用构造函数,否则编译器将自动添加super()为构造函数的第一行。这意味着构造函数严格按顺序执行

    1. Object
    2. A
    3. B
    4. C

现在,该对象已初始化并可以使用。如果使用实例方法初始化值,则可能会做一些危险的事情:

    public class Wrong {
        int a = getB(); // Don't do this!
        int b = 10;
        public int getB() {
             return b;
        }
    }

在这里,a被初始化为0。这是因为在getB()调用该点时,Java已将值清除为b默认值(0),但尚未10在初始化的第二阶段将其设置为。

总而言之-只有一个对象,并且它是分阶段创建和初始化的。在那些阶段中,根据定义,对象没有完全定义。



 类似资料:
  • 主要内容:多继承下的构造函数,命名冲突在前面的例子中,派生类都只有一个基类,称为 单继承(Single Inheritance)。除此之外, C++也支持 多继承(Multiple Inheritance),即一个派生类可以有两个或多个基类。 多继承容易让代码逻辑复杂、思路混乱,一直备受争议,中小型项目中较少使用,后来的 Java、 C#、 PHP 等干脆取消了多继承。 多继承的语法也很简单,将多个基类用逗号隔开即可。例如已声明了类A

  • 创建对象的几种方式 通过Object <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>01_Object构造函数模式</title> </head> <body> <!-- 方式一: Object构造函数模式 * 套路: 先创建空Object对象, 再动态添加属性/方法 * 适用场景

  • 在面向对象的程序设计中,定义一个新的 class 的时候,可以从某个现有的 class 继承,新的 class 称为子类,而被继承的 class 称为基类、父类或超类。 Python 中继承的语法如下: class Parent: pass class Child(Parent): pass 在第 1 行,定义了父类 Parent; 在第 4 行,定义了子类 Child,语法

  • 继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能。 回忆一下Animal类层次的设计,假设我们要实现以下4种动物: Dog - 狗狗; Bat - 蝙蝠; Parrot - 鹦鹉; Ostrich - 鸵鸟。 如果按照哺乳动物和鸟类归类,我们可以设计出这样的类的层次: 但是如果按照“能跑”和“能飞”来归类,我们就应该设计出这样的类的层次: 如果要把上面的两种分类都包含进来

  • 继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能。 回忆一下Animal类层次的设计,假设我们要实现以下4种动物: Dog - 狗狗; Bat - 蝙蝠; Parrot - 鹦鹉; Ostrich - 鸵鸟。 如果按照哺乳动物和鸟类归类,我们可以设计出这样的类的层次: ┌───────────────┐ │

  • FAQs in section [24]: [24.1] 如何表示“私有继承”? [24.2] 私有继承和组合(composition)有什么类似? [24.3] 我应该选谁:组合还是私有继承? [24.4] 从私有继承类到父类需要指针类型转换吗? [24.5] 保护继承和私有继承的关系是什么? [24.6] 私有继承和保护继承的访问规则是什么? 24.1 如何表示“私有继承”? 用 : priv