Let\'s say someone gives you a class, Super
, with the following constructors:
public class Super
{
public Super();
public Super(int arg)
You can't do that, but you can do this from the code that calls your class:
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);
Can't be done as such as super must be first statement in a constructor.
The proper alternative is a builder class and to have one constructor in the derived class for each constructor in the super class.
eg.
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
}
}
Yeah, what @Johan Sjöberg said.
Also looks like your example is highly contrived. There's no magical answer which would clear this mess :)
Usually, if you have such a bunch of constructors it would be a good idea to refactor them as four separate classes (a class should be only responsible for one type of thing).
Use static factories, and four private constructors.
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) {
...
}
...
}
super
must be the first statement in a constructor, hence the logic in your sample is not valid.
The proper way is to create the same 4 constructors in your extending class. If you need validation logic you can use e.g., the builder
pattern. You can also as suggested in the comments by @davidfrancis make all constructs private and supply a static factory method. E.g.,
public static Derived newInstance(int arg) {
if (some condition) {
return new Derived(arg);
}
// etc
}