如何在Java中有条件地调用不同的构造函数?

时间:2012-02-10 23:07:48

标签: java constructor

假设有人为您提供了一个类Super,其中包含以下构造函数:

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);
    }
}

5 个答案:

答案 0 :(得分:8)

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

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 :(得分:4)

是的,@JohanSjöberg说的是什么。

看起来你的例子也是非常做作的。没有神奇的答案可以清除这个烂摊子:)

通常,如果你有一堆构造函数,那么将它们重构为四个独立的类(一个类应该只负责一种类型的东西)是个好主意。

答案 2 :(得分:1)

super必须是构造函数中的第一个语句,因此示例中的逻辑无效。

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

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

答案 3 :(得分: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);

答案 4 :(得分: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
    }
}