我有一个带有
形式的构造函数的抽象超类public classname(String name, int amount)
并且想要创建该抽象类的子类,而不是将String作为其第一个参数,而是采用表示给定String名称的整数值,例如, 0代表一些String,1代表另一个,依此类推。
当我尝试编写表单子类的构造函数(int number,int amount)时,我得到一个错误的形式“隐式超级构造函数未定义。必须显式调用另一个构造函数。”
为什么不能在子类中创建另一个不同的构造函数?
答案 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
或委托给子类)。
当然,请适应您的代码。
编辑:静态工厂方法的一个示例,它产生具有不同内部状态但行为相同的类:here。 SchemaKey
是抽象的,充当“接口”并且在其自身内部具有静态工厂方法以生成具体类。
答案 3 :(得分:0)
您需要在子类的构造函数中调用super()
,从而显式调用超类的构造函数。