2012-02-10 57 views
7

比方说,有人给你一个类,Super,用下面的构造函数:如何在Java中有条件地调用不同的构造函数?

public class Super 
{ 
    public Super(); 
    public Super(int arg); 
    public Super(String arg); 
    public Super(int[] arg); 
} 

而且我们说你要创建一个子类Derived。你如何在Super有条件地调用构造函数?

换句话说,什么是“正确”的方式来做这样的工作?

public class Derived extends Super 
{ 
    public Derived(int arg) 
    { 
     if (some_condition_1) 
      super(); 
     else if (some_condition_2) 
      super("Hi!"); 
     else if (some_condition_3) 
      super(new int[] { 5 }); 
     else 
      super(arg); 
    } 
} 
+0

什么是“some_external_condition”的一些例子吗?看起来好像任何这样的情况必须在* super之后被检查*。 – ggreiner 2012-02-10 23:09:38

+0

@ggreiner:实际上它不一定是外部的。我稍微改变了这个例子。它可以简单地基于用户的参数(这可能更适合作为枚举而不是整数,但这有点不相关)。 – Mehrdad 2012-02-10 23:11:12

回答

4

是的,@JohanSjöberg说。

也看起来你的例子是高度设计的。有没有什么神奇的答案可以清除这个混乱:)

通常,如果你有这样一堆构造函数,将它们重构为四个单独的类是一个好主意(一个类应该只负责一种类型的事物)。

+0

是的,我不知道......这是我的一个朋友显然遇到的问题,而不是我遇到的问题。完全同意第三段。 +1 – Mehrdad 2012-02-10 23:21:31

+3

我在实际代码中遇到了这个问题:为android编写向后兼容的代码:LinearLayout具有不同的构造函数,具体取决于android.os.Build.VERSION.SDK_INT的值。 – Timmmm 2012-11-01 11:18:52

1

super必须在构造函数中的第一条语句,因此你的样品中的逻辑是无效的。

正确的方法是在您的扩展类中创建相同的 4个构造函数。如果您需要验证逻辑,则可以使用例如builder模式。您也可以按照@davidfrancis的意见中所建议的将所有构造私有并提供静态工厂方法。例如,

public static Derived newInstance(int arg) { 
     if (some condition) { 
     return new Derived(arg); 
     } 
     // etc 
} 
+0

那么你如何检查条件? – Mehrdad 2012-02-10 23:10:26

+1

@Merhdad,你把它留给构建对象的类。如果你想执行特定的检查,这可以是例如“builder”。 – 2012-02-10 23:11:18

+0

或者对一个接受条件的类有一个静态方法,检查它,然后实例化并返回该类的一个实例。 Derived上的“额外”构造函数在这种情况下可能是私有的。这不一定是一种方式,只是另一个配方。 – 2012-02-10 23:12:42

0

不能这样做super必须是构造函数中的第一条语句。

正确的选择是构建器类,并且在超类的每个构造器的派生类中都有一个构造器。

例如。

Derived d = new DerivedBuilder().setArg(1).createInstance(); 

public class DerivedBuilder { 

    private int arg; 

    // constructor, getters and setters for all needed parameters 

    public Derived createInstance() { 
     // use appropriate constructor based on parameters 
     // calling additional setters if need be 
    } 
} 
4

使用静态工厂和四个私有的构造。

class Foo { 
public static Foo makeFoo(arguments) { 
    if (whatever) { 
     return new Foo(args1); 
    } else if (something else) { 
     return new Foo(args2); 
    } 
    etc... 
    } 
    private Foo(constructor1) { 
    ... 
    } 
    ... 
} 
1

你不能这样做,但你可以调用您的类的代码做到这一点:

 if (some_condition_1) 
      new Super(); 
     else if (some_condition_2) 
      new Super("Hi!"); 
     else if (some_condition_3) 
      new Super(new int[] { 5 }); 
     else 
      new Super(arg); 
相关问题