子类的不同构造函数

时间:2014-02-20 20:29:09

标签: java inheritance constructor

我有一个带有

形式的构造函数的抽象超类
public classname(String name, int amount)

并且想要创建该抽象类的子类,而不是将String作为其第一个参数,而是采用表示给定String名称的整数值,例如, 0代表一些String,1代表另一个,依此类推。

当我尝试编写表单子类的构造函数(int number,int amount)时,我得到一个错误的形式“隐式超级构造函数未定义。必须显式调用另一个构造函数。”

为什么不能在子类中创建另一个不同的构造函数?

4 个答案:

答案 0 :(得分:4)

错误的问题,你可以在子类中编写另一个构造函数,但由于超类没有默认/无参数构造函数,你来明确地调用你提到的超类的构造函数确保超级班的不变性。

答案 1 :(得分:3)

如派生类中的其他人所述,您需要使用super(arguments)调用其超类的构造函数。此调用也必须是构造函数中的第一条指令,因此您可能会遇到问题,在调用构造函数之前需要确定要放置为name的值,如

MyClass(int id, int amount){
    super("???",amount);
}

在这里,我们还不知道使用什么价值代替"???"。很遗憾,您无法使用

MyClass(int id, int amount){
    if (id==1) super("foo",amount);
    else super("bar",amount);
}

可能的解决方案之一是创建单独的方法,该方法将根据id返回正确的名称,并将其用作super参数,如

MyClass(int id, int amount){
    super(choseName(id),amount);
}

private static String choseName(int id){
    if (id==1) 
        return "foo";
    else 
        return "bar";        
}

答案 2 :(得分:2)

一种解决方案是使用静态工厂方法。考虑一下:

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;
    }
}

然后,在同一个包中:

final class IdBasedAmount
    extends Amount
{
    IdBasedAccount(final String identifier, final int amount)
    {
        super(identifier, amount);
    }
}

来自代码:

final Amount amount = Amount.forIdentifierNumber(0, 20100);

之后,只需要定义Amount类中所需的任何方法(final或委托给子类)。

当然,请适应您的代码。

编辑:静态工厂方法的一个示例,它产生具有不同内部状态但行为相同的类:hereSchemaKey是抽象的,充当“接口”并且在其自身内部具有静态工厂方法以生成具体类。

答案 3 :(得分:0)

您需要在子类的构造函数中调用super(),从而显式调用超类的构造函数。