Как условно вызывать другой конструктор в Java?
Скажем, кто-то дает вам класс 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);
}
}
Ответы
Ответ 1
Да, что @Johan Sjöberg сказал.
Также выглядит так, что ваш пример очень надуман. Там нет волшебного ответа, который бы очистил этот беспорядок:)
Обычно, если у вас есть такая группа конструкторов, было бы неплохо реорганизовать их как четыре отдельных класса (класс должен отвечать только за один тип вещей).
Ответ 2
Используйте статические фабрики и четыре частных конструктора.
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) {
...
}
...
}
Ответ 3
super
должен быть первым оператором в конструкторе, поэтому логика в вашем примере недопустима.
Правильный способ - создать те же 4 конструктора в вашем расширяющемся классе. Если вам нужна логика проверки, вы можете использовать, например, шаблон builder
. Вы также можете, как было предложено в комментариях @davidfrancis, сделать все конструкции частными и предоставить статический метод factory. Например,
public static Derived newInstance(int arg) {
if (some condition) {
return new Derived(arg);
}
// etc
}
Ответ 4
Вы не можете этого сделать, но вы можете сделать это из кода, который вызывает ваш класс:
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);
Ответ 5
Невозможно сделать так, как супер должен быть первым выражением в конструкторе.
Правильная альтернатива - это класс строителя и иметь один конструктор в производном классе для каждого конструктора в суперклассе.
например.
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
}
}