eager2learn
eager2learn

Reputation: 1488

Different constructor for subclass

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

Answers (4)

fge
fge

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

Pshemo
Pshemo

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

Smutje
Smutje

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

Martin Dinov
Martin Dinov

Reputation: 8825

You need to call super() in your subclass's constructor and hence explicitly call the super class's constructor.

Upvotes: 0

Related Questions