2016-07-05 107 views
0

我想我想要的是根本不可能的,但我想确保。说我有在Java中调用默认和超级构造函数

public class bar { 
    public bar() { 

    } 
    public bar(Object stuff) { 
     // something done with stuff. 
    } 
} 

和扩展

public class foobar extends bar { 
    public foobar() { 
     super(); 
     // some additional foobar logic here.  
    } 
    public foobar(Object stuff) { 
     // Do both the 
     // "some additional foobar logic" and 
     // "something done with stuff" here. 
    } 
} 

我怎样才能让foobar的(对象的东西)尽可能地简单,同时也避免重复的代码?我不能简单地调用超级(东西),因为“一些额外的foobar逻辑”没有完成,我不能调用这个(),因为我不做我想要做的事情“东西”。

注: 我意识到我实际上并不需要做到这一点在这种情况下,所以这是现在这里只是理论上的目的。

+0

调用'super(stuff)'**和** *然后*在调用之后做一些额外的foobar逻辑。 –

+0

你可以在'foobar(Object)'中做所有的逻辑,并检查参数为null。然后在'foobar()'中调用'this(null)'。 – Thomas

+0

如果你更具体(和使用传统的名字),这将真的有帮助。你需要从'foobar(Object)'构造函数调用'bar(Object)'构造函数吗? –

回答

5

您只能链接到一个构造函数。通常最好的办法是对于“少特定的”构造(那些具有较少的参数),以链的“更具体的”的,具有单个“主”构造,其是与在逻辑唯一的一个:

public class FooBar extends Bar { 
    public FooBar() { 
     this(null); // Or whatever value you want for "stuff" 
    } 

    public FooBar(Object stuff) { 
     super(stuff); 

     // Initialization logic 
    } 
} 
+0

但是在使用'sutff''之前,可能会产生'''null'''检查。由于没有公共代码的参数,调用初始化方法或使用初始化块是否更有意义? –

+0

@JornVernee:它取决于确切的情况 - 但非常普遍的一个无参数构造函数*用于提供默认值。请注意,初始化方法不能写入'final'字段。一个初始化块*可能*有意义...它实际上取决于上下文,并且OP没有提供太多:( –

+0

是的,这可能是一个解决方案。但是,如果存在例如两个构造函数FooBar(Object stuff)和FooBar(OtherObject otherObject)都需要做和FooBar()一样的操作,init块可以是一个选项,但是我意识到我实际上并不需要同时调用基本的无参数构造函数和超级,这是现在的理论在我的情况下......或实际上 – Jeffed

2

如果你添加一个明确的init()函数,它可能会导致更干净的代码,它封装了你想在构造函数之间共享的东西。特别是在你的情况下,你试图在构造函数之间跳转。

在提供的答案中,super()构造函数未执行。虽然super()在您的示例中为空,但未来不会如此。

此外,您依靠super(foo)妥善处理foo == null。尽管为超类设置IllegalArgumentException可能是完全可以接受的,但它并不适合您的使用情况。你基本上是扩展契约来正确地初始化超类,使用参数化的构造函数和一个空参数。

使用init-方法,可以减少代码重复并且超类没有扩展契约。虽然你可能不喜欢这种风格。构造函数链避免了额外的方法。

public class foobar extends bar { 
    public foobar() { 
     super(); 
     initFooBar(null); 
    } 

    public foobar(Object stuff) { 
     super(stuff); 
     initFooBar(stuff); 
    } 

    public void initFooBar(Object stuff) { 
     // some additional foobar logic here.  
     // "something done with stuff" here.    
    } 
} 
+0

是的,谢谢你的建议。实际上我也有一个init方法,不管使用什么构造函数,都会调用它,但它只是用于一个稍微不同的目的。尽管如此,让另外一个用于输入参数的初始化也是有意义的。 – Jeffed