2

例如我有这个:

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 的论点,但后来我失败了。

我封闭在这个魔法圈里。我该怎么办?

4

4 回答 4

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 没有无参数构造函数,因此编译失败。在这种情况下,您必须显式调用超级构造函数之一:

public B(int a) {
    super(a);
    mine-=a; 
    /*Some operation2...*/
}
于 2012-05-06T22:13:14.567 回答
7

每个构造函数都必须首先调用超类构造函数。如果您没有通过 显式执行此操作super(),编译器将隐式调用超类中的 no-arts 构造函数。但是在您的情况下,超类没有无参数构造函数,此时编译器放弃了。

顺便说一句,在子类中重新声明一个字段通常是一个非常糟糕的主意,因为它会隐藏超类字段,但仍然会有两个字段。

于 2012-05-06T22:12:48.647 回答
3

我认为您需要从 B 构造函数调用 A 类的构造函数,如下所示: super(a);

于 2012-05-06T22:12:19.643 回答
1

如果 B 扩展了 A,那么 B 的构造函数的第一个操作就是调用 A 的构造函数。

如果 A 中没有显式定义构造函数,则调用标准构造函数。如果您不显式调用 ctor,则会隐式调用它。

但是,如果有一个显式的 ctor,它接受参数,它不会自动调用 - 它应该如何 - 使用哪些参数?你必须自己调用它。

但是您的班级层次结构有些神秘。如果您想在子类中访问我的,请将其设置为受保护或保持默认状态 - 不要将其设为私有。

如果将其设为私有,则新引入的同名属性会隐藏父属性,但这容易出错且令人讨厌。

在大多数情况下,可能通过方法(getter/setter)访问会更好,或者打开可见性。

或者子类中事物的不同名称。

于 2012-05-06T22:13:39.857 回答