每当在任何派生类中调用任何构造函数时,任务只能通过最终隐式或显式调用基类构造函数来完成(如果我在这里错了,请纠正我)。
由于我们打算创建派生类的实例,但由于基类的构造函数最终被调用。
那么,尽管调用了基类的构造函数,但如何构造派生类的实例呢?
每当在任何派生类中调用任何构造函数时,任务只能通过最终隐式或显式调用基类构造函数来完成(如果我在这里错了,请纠正我)。
由于我们打算创建派生类的实例,但由于基类的构造函数最终被调用。
那么,尽管调用了基类的构造函数,但如何构造派生类的实例呢?
不要将构造函数视为创建实例。将其视为针对该特定类的初始化实例。
所以初始化过程看起来像:
java.lang.Object
your.package.Superclass
your.package.Subclass
(即使您从调用 开始new Subclass(...)
,超类构造函数体也会首先执行。)
JLS 第 12.5 节中给出了对象初始化的详细信息。
构造函数不是很幸运的名字。它可能暗示它负责创建(构造)对象,但实际上它负责初始化已经存在的对象。
对象由new
操作员创建。但是该对象已“设置”为使其所有字段都填充默认值:null、false、0(取决于类型)。为了使这样的对象在我们的应用程序中可用,我们需要正确地“设置”(初始化),这就是构造函数的工作。
但是由于类可以扩展其他类,因此子类的构造函数需要仅在执行超类的构造函数后才执行其代码(例如,确保所有继承的字段都已正确初始化,因此我们可以在构造函数中使用实际使用的继承方法那些超类字段)。这就是为什么super(..)
call 在每个构造函数的开头显式或隐式放置的原因(Object
类除外,因为它不扩展其他类)。