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 (aka mine+=a;) を実行する必要があるため、A の引数が必要ですが、失敗します。

私はこの魔法陣に閉じ込められています。何をすればよいでしょうか?

4

4 に答える 4

9

すべてのコンストラクターの最初の命令は、常にそのスーパークラスコンストラクターの1つを呼び出すことです。明示的に行わない場合、コンパイラはこのインストラクションを挿入します。コンストラクター

 public B(int a) {
     mine-=a; 
     /*Some operation2...*/
 }

したがって、

public B(int a) {
    super(); // invoke the no-arg super constructor
    mine-=a; 
    /*Some operation2...*/
}

Aには引数なしのコンストラクターがないため、コンパイルは失敗します。この場合、スーパーコンストラクターの1つを明示的に呼び出す必要があります。

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

すべてのコンストラクターは、最初に行うこととしてスーパークラスコンストラクターを呼び出す必要があります。を介して明示的に行わない場合super()、コンパイラはスーパークラスのno-artsコンストラクタを暗黙的に呼び出します。しかし、あなたの場合、スーパークラスには引数なしのコンストラクターがなく、その時点でコンパイラーはあきらめます。

ちなみに、スーパークラスフィールドを非表示にするため、サブクラスでフィールドを再宣言することは一般的に非常に悪い考えですが、それでも2つのフィールドがあります。

于 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 に答える