Reputation: 1488
I have an abstract superclass with a constructor of the form
public classname(String name, int amount)
and want to create a subclass of that abstract class that instead of taking a String as its first parameter takes an integer value that represents a given String name, so e.g. 0 stands for some String, 1 for another and so on.
When I try to write a constructor of the form subclass(int number, int amount) I get an error of the form "implicit super constructor is undefined. Must explicitly invoke another constructor."
Why is it not possible to create another, different constructor in the subclass?
Upvotes: 1
Views: 255
Reputation: 121710
One solution is to use static factory methods. Consider this:
public abstract class Amount
{
protected static final List<String> IDENTIFIERS
= Arrays.asList("idfor0", "idfor1" /* etc */);
protected final String identifier;
protected final int amount;
public static Amount forIdentifierNumber(final int number, final int amount)
{
return new IdBasedAmount(IDENTIFIERS.get(number), amount);
}
protected Amount(final String identifier, final int amount)
{
this.identifier = identifier;
this.amount = amount;
}
}
Then, in the same package:
final class IdBasedAmount
extends Amount
{
IdBasedAccount(final String identifier, final int amount)
{
super(identifier, amount);
}
}
Call from code:
final Amount amount = Amount.forIdentifierNumber(0, 20100);
After that, it is only a matter of defining whatever methods are needed in the Amount
class (either final
or delegated to subclasses).
Of course, adapt to your code.
Edit: an example of static factory methods yielding classes with different internal state but the same behaviour: here. SchemaKey
is abstract, acts as an "interface" and has static factory methods within itself to generate concrete classes.
Upvotes: 2
Reputation: 124225
As mentioned by others in derived class you need to invoke constructor of its super class using super(arguments)
. Also this call must be first instruction in your constructor so you will probably face problem where you will need to determine value you want to place as name
before calling constructor like
MyClass(int id, int amount){
super("???",amount);
}
here we don't know yet what value to use in place of "???"
. Unfortunately you can't use
MyClass(int id, int amount){
if (id==1) super("foo",amount);
else super("bar",amount);
}
One of possible solutions is to create separate method which will return correct name based on id
and use it as super
parameter like
MyClass(int id, int amount){
super(choseName(id),amount);
}
private static String choseName(int id){
if (id==1)
return "foo";
else
return "bar";
}
Upvotes: 3
Reputation: 18143
Wrong question, you can write another constructor in the subclass, but as the super class has no default/no-argument constructor, you have to explicitely call the constructor of the super class you mentioned to ensure the invariance of the super class.
Upvotes: 4
Reputation: 8825
You need to call super()
in your subclass's constructor and hence explicitly call the super class's constructor.
Upvotes: 0