重载构造函数如何同时调用super(...)和this(...)?

16

我以前从未需要过这样做,但由于两者都必须是构造函数中的“第一”行,应该如何解决?在这种情况下,最好的重构方法是什么?

下面是一个示例:

public class Agreement extends Postable {


public Agreement(User user, Data dataCovered)
{
    super(user);
    this(user,dataCovered,null);

}

public Agreement(User user,Data dataCovered, Price price)
{
    super(user);

    if(price!=null)
        this.price = price;

    this.dataCovered = dataCovered;


}
   ...
}

调用super(user)是绝对必要的。在这种情况下如何处理“可选参数”?我能想到的唯一方法是重复,即根本不调用this(...)。只需在每个构造函数中执行赋值操作。


2
在第一个方法中不需要使用 super(user),你可以通过调用 this(user, dataCovered, null) 来调用它。 - Eng.Fouad
1
最简单的方法当然是根本不提供第一个构造函数,如果第二个构造函数已经包含了所有必要的内容。只需记录“Price”可以传递空值即可。 - Mat
4个回答

22

你不能同时调用super(..)和this(...)。你可以重新设计重载的构造函数结构,使得最后一个被调用的构造函数会调用super(...)。

如果这不是一个选项,那么你就必须在每个构造函数中进行赋值操作。


我知道它一定是这么简单的事情!!当然!我想我已经在使用supers()进行重构了,因此感到困惑!! - PhD
我喜欢使用一个私有的void initialize方法,来进行构造函数的常见初始化。 - dannydk

8
如果你调用 this(user,dataCovered,null),那么第二个构造函数将被调用,它将首先调用父类的构造函数。因此,第一个构造函数中的 super(user); 这一行是不必要的。

你和S.L的答案只相差4秒!我还是会标记S.L的答案,这可以提高他/她的评分...希望你不介意 :) - PhD
@Nupul 将更好的答案标记为解决方案;当前评分不应超过答案质量。 - dlev
我同意这个观点。@Nupul,感谢你的礼貌想法。但请标记你认为最好的答案。 - S.L. Barth
@dlev:同意。在我看来,两个答案的质量/信息完全相同,S.L也提到了如果他的选项不可行该怎么办的情况。我永远不会因为提高某人的评分而标记一个答案!!!只是我必须在两个相距4秒的答案之间做出选择,并想让Mark(和其他人)知道我的选择。 - PhD
@S.L. 注意,我并不是在评论这些答案的相对质量 :). 我只是说一般来说,最高质量的答案(实际上解决了你的问题)应该被标记为解决方案。 - dlev
显示剩余2条评论

0
我建议你将构造函数中需要执行的逻辑分离到类中的一个静态方法中,并从两个构造函数中调用它,以避免重复。但是,在你的情况下,你可以在第一个构造函数中跳过对super(user)的调用,第二个构造函数会为你调用它 :)。我还建议你反转构造函数之间的“依赖关系”,像这样:
public class Agreement extends Postable {


public Agreement(User user, Data dataCovered)
{
    super(user);
    setDataCovered(dataCovered);

}

public Agreement(User user, Data dataCovered, Price price)
{
    this(user, dataCovered);

    if(price!=null)
        setPrice(price);

}

private static void setDataCovered(Data dataCovered) {
     this.dataCovered = dataCovered;
}

private staitc void setPrice(Price price) {
     this.price = price;
}
}

那么你会将price和dataCovered更改为静态字段吗? - Stefan Schubert-Peters
@Erik:有趣的想法。但是在“链”中调用最后一个“called”构造函数上的super似乎是一个更简单的选项! - PhD

0
在构造函数中有三个限制(除了像从super或this调用非实例方法之类的):
  • 每个构造函数只能调用一次super(...)this(...)
  • superthis始终必须是方法中的第一条语句
  • 如果你没有提供任何一个,那么在构造函数开始处会有一个隐式的super()
原因是一个对象只能被创建一次。当使用super时,通过调用重载的构造函数来创建对象,而使用this则是将对象委托给同一类的另一个构造函数。
正如另一个答案所说,在你的情况中,你不需要第一个super,因为你的this语句正在委托给已经调用了super(user)的其他构造函数。

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