Как условно вызвать другой конструктор в Java? - PullRequest
11 голосов
/ 11 февраля 2012

Допустим, кто-то дает вам класс 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 ]

8 голосов
/ 11 февраля 2012

Используйте статические фабрики и четыре частных конструктора.

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) { 
    ...
  }
  ...
}
4 голосов
/ 11 февраля 2012

Да, что сказал @Johan Sjöberg.

Также похоже, что ваш пример очень надуманный. Там нет волшебного ответа, который бы очистил этот беспорядок :)

Обычно, если у вас есть такая куча конструкторов, было бы неплохо реорганизовать их в четыре отдельных класса (класс должен отвечать только за один тип вещей).

2 голосов
/ 11 февраля 2012

super должно быть первым оператором в конструкторе, поэтому логика в вашем образце недопустима.

Правильный способ - создать одинаковых 4 конструкторов в вашем расширяющем классе. Если вам нужна логика проверки, вы можете использовать, например, шаблон builder. Вы также можете, как предложено в комментариях @davidfrancis, сделать все конструкции приватными и предоставить статический метод фабрики. Например,

public static Derived newInstance(int arg) {
      if (some condition) {
         return new Derived(arg);
      }
      // etc
}
1 голос
/ 11 февраля 2012

Вы не можете сделать это, но вы можете сделать это из кода, который вызывает ваш класс:

        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);
0 голосов
/ 11 февраля 2012

Не может быть сделано как таковое, поскольку 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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...