例如我有这个:
class A{
private int mine = 0; //Some field...
public A(int a){mine+=a; /*Some operation1...*/}
}
class B extends A{
private int mine = 0; //Some field...
public B(int a){mine-=a; /*Some operation2...*/}
}
我得到了:
error: constructor A in class A cannot be applied to given types;
public B(int a){}
required: int
found: no arguments
reason: actual and formal argument lists differ in length
1 errors
我不明白这个错误?什么告诉我要做什么?
但是,如果“A”的构造函数没有参数,则代码可以工作。
但我需要做Operation1(又名mine+=a;
),所以我需要A的论据,但后来我失败了。
我在这个神奇的圈子里关闭了。我该怎么办?
答案 0 :(得分:9)
每个构造函数的第一条指令总是调用它的一个超类构造函数。如果您没有明确地执行此操作,编译器会为您插入此实例。构造函数
public B(int a) {
mine-=a;
/*Some operation2...*/
}
因此等同于
public B(int a) {
super(); // invoke the no-arg super constructor
mine-=a;
/*Some operation2...*/
}
由于A没有no-arg构造函数,因此编译失败。在这种情况下,您必须明确地调用其中一个超级构造函数:
public B(int a) {
super(a);
mine-=a;
/*Some operation2...*/
}
答案 1 :(得分:7)
每个构造函数必须首先调用超类构造函数。如果不通过super()
显式执行,编译器将隐式调用超类中的no-arts构造函数。但是在你的情况下,超类没有no-args构造函数,编译器就放弃了。
顺便说一下,在子类中重新声明一个字段通常是个坏主意,因为它会隐藏超类字段,但仍会有两个字段。
答案 2 :(得分:3)
我认为你需要从B构造函数中调用类A的构造函数,如下所示:
super(a);
答案 3 :(得分:1)
如果B扩展A,则B的构造函数的第一个操作是调用A的构造函数。
如果A中没有显式定义构造函数,则调用标准构造函数。如果不明确调用ctor,则会隐式调用它。
但是如果有一个明确的ctor,它接受参数,它就不会自动调用 - 它应该怎样 - 使用哪些参数?你必须自己打电话。
但你的班级hierarchie有点神秘。如果要在子类中访问我的,请将其保护或保持默认状态 - 不要将其设为私有。
如果将其设为私有,则具有相同名称的新引入属性会隐藏父属性,但这是错误的并且令人恼火。
在大多数情况下,可能通过方法(getter / setter)访问会更好,或者打开可见性。
或子类中事物的不同名称。