什么时候需要显式调用超类构造函数?

Posted

技术标签:

【中文标题】什么时候需要显式调用超类构造函数?【英文标题】:When do you need to explicitly call a superclass constructor? 【发布时间】:2011-09-13 04:50:11 【问题描述】:

假设我有一个扩展超类的子类。在什么情况下我需要显式键入super() 才能运行超类构造函数?

我正在看一本关于抽象类的书中的示例,当它们使用非抽象子类扩展它时,子类的默认构造函数是空白的,并且有一条注释说将调用超类的默认构造函数。同时,我也在这里看到有人的问题没有明确调用super() 的情况。

调用超类的默认/非默认构造函数和调用子类的默认/非默认构造函数有区别吗?

【问题讨论】:

是我还是没有一个答案解决了“为什么需要在子类中调用超类的构造函数”的问题 【参考方案1】:

如果您没有显式调用超级构造函数,则将调用参数更少的构造函数 (super())。这意味着如果超类没有可访问的无参数构造函数,您必须自己调用特定的构造函数。

但通常情况下,即使您可以使用默认构造函数,您仍然想要一个不同的构造函数 - 取决于您的代码。

还要注意,如果没有声明构造函数,编译器会自动生成一个公共的默认构造函数,但是一旦你编写了自己的构造函数,就不会再发生这种情况了。

【讨论】:

只是为了确保我理解。如果在我的超类中,我有一个构造函数,它不是默认构造函数(比如说它需要一个参数)。然后在我的子类的构造函数中,我需要显式调用 super(param) 因为编译器将不再为超类生成默认构造函数?【参考方案2】:

从不只需要

super();

如果您不指定其他任何内容,就会出现这种情况。你需要指定构造函数来调用if:

你想调用一个有参数的超类构造函数 您希望链接到同一类中的另一个构造函数,而不是超类构造函数

您声称:

同时,我也在这里看到有人的问题不是显式调用 super() 的实例。

你能举一些例子吗?我无法想象这怎么可能......

【讨论】:

是的,我应该更清楚。这是超级(有论据)。谢谢你的回答。 你是对的。但关于这一点:“同时,我也在这里看到有人的问题没有明确调用 super() 的实例。”当父构造函数没有 noarg 构造函数时会发生这种情况。在这种情况下,如果你没有显式调用 super(),你会得到一个错误。 @ACV:显式调用super() 在那里也不起作用。 使用非空参数列表调用超级构造函数会起作用,但仅使用super() 不会。 @JonSkeet 有时会在我使用的代码中看到很多super()s。每当我看到它们时,我几乎都会在临床上将它们移除。但是,我不禁想知道他们在那里是否有原因。你能想出一个你真正想要这些无参数构造函数的情况吗? @patrik:要求构造函数存在和要求显式委托给无参数的超级构造函数是有区别的。后者是风格问题 - 无论您喜欢明确/明显还是简短。【参考方案3】:

super() 方法总是在子类的构造函数中调用,即使它没有明确地写在代码中。

唯一需要编写的情况是超类中是否有多个super(...) 方法具有不同的初始化参数。

【讨论】:

"唯一需要编写的就是超类中是否有多个具有不同初始化参数的 super(...) 方法。"不对。只要有一个可访问的参数少的构造函数,你就可以有一百个其他构造函数没有任何问题。

以上是关于什么时候需要显式调用超类构造函数?的主要内容,如果未能解决你的问题,请参考以下文章

为啥总是调用超类构造函数[重复]

显式移动构造函数?

从构造函数的主体调用超类构造函数

C++中派生类的构造函数怎么显式调用基类构造函数?

为啥在声明子类的对象时会调用超类的构造函数? (爪哇)

Java 中的继承——创建子类的对象也会调用超类的构造函数。为啥?