你在构造函数的开头放置了super()调用吗?

7
这是关于编码风格和推荐实践的问题:
如在无需在构造函数中放置super()吗?问题的答案中所解释的那样,如果您为一个类编写构造函数,该类应使用超类的默认(无参数)构造函数,则可以在构造函数开头调用super()
public MyClass(int parm){
  super(); // leaving this out makes no difference
  // do stuff...
}

但你也可以省略这个调用; 在这两种情况下,编译器都会表现得好像有super()调用。

那么,你是否要在构造函数中放入调用呢?

一方面,有人可能会认为包含super()会使事情更加明确。另一方面,我总是不喜欢写冗余的代码,所以个人倾向于将其省略; 然而,我经常在别人的代码中看到它。

您有什么经验吗?在一种或另一种方法上是否有问题?您是否有编码指南规定一种方法?

顺便说一句:相关问题(仅供参考):

当没有其他构造函数时,有必要明确编写默认构造函数吗?


我不确定,但可能是因为我读过的(并且从中学到的)几乎所有代码都没有这样做。我可能只是在延续我所学到的不好的风格。 - President James K. Polk
9个回答

21

我不写super()调用的原因和我不写不必要的强制转换一样:

它会在代码中增加噪音,而不提供任何额外的信息(既不对编译器有用,也不对读取我的代码的开发人员有用)。


4

一些版本的IDE的默认设置会自动生成它,这可能是你看到它的原因之一。

是否编写它取决于将要阅读它的人。我倾向于不添加它,但如果你不确定团队成员是否理解编译器的工作原理以及对象构造的过程,你可以“以防万一”添加它。


7
如果你不能确定团队成员是否理解编译器的作用,那么你可能面临更加严重的问题。 - sleske

4

我不这么认为,但是在大学时给我的理由是这样做可以使事情更加明确,这样你就不会“忘记”调用超类构造函数。

然而,我并没有看到这样做的必要性。


3

只有当构造函数super()需要参数时,我才会使用super()


3
当然,但那是完全不同的情况:如果您需要传递参数,您 必须 显式调用super(parms),因此这不再是编码风格的问题... - sleske

2

你有什么经验吗?你是否在某种方法上遇到问题?

我从未调用过默认构造函数(显式),也从未遇到任何问题。


1

我从来没有添加过它,当一个同事不理解隐式调用超类时,我深感震惊,也许我应该开始这样做。


9
也许你应该开始教育你的同事,让他们明白这个问题。;-) - Péter Török

1

优点:任何阅读您的代码的人都知道您真正想调用默认构造函数,您没有因疏忽而遗漏调用。

缺点:您的代码会被无关紧要的信息所淹没。

通常,如果一种语言允许您省略某些指令,那么这样做并不是不好的风格。我认为这是权衡利弊的问题。例如,在您的构造函数具有参数且基类也有可带参数的构造函数时,显式编写super()可能是个好主意。


0

实际上,我加入了super()调用,因为我发现它是一个有用的记忆辅助工具。当我几个月前编写了一段代码并返回时,super()会在我查看构造函数时提醒我,我编写的类继承自某些东西。


4
“extends”在类的开头不就足够说明了吗?;-) - sleske
如果构造函数和类定义可以同时查看,那就太好了,但这并不总是情况。我通常会在我的方法之前放置所有属性。 - Chris J

0

我尽量避免编写需要调用super()的代码,因为我更喜欢组合而不是继承。

如果我必须从另一个类派生,我会尝试将它们都放在自己的接口后面,并将其中一个作为依赖项传递给另一个。

然而,如果我有一个库类,无法给它额外的依赖项,那么我首先尝试使用装饰器。

如果这不起作用,我必须从实现中派生,我认为是否编写super()并不重要,因为这种情况很少发生 ;)

总之,我认为这个问题毫无意义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接