6

私は持っています

class A {

    int var;
    public A(int x) {
        var = x;
    }
}


class B extends A {
     int var2;

     public B(int x, int y) {
         super(...);
         var2 = y;
         x = f(y);
     }
 }

サブクラスBの場合、Aのコンストラクターで使用される値xを計算する必要があります。super自分の下に自由に移動できる場合x=f(y)は、結果をA(スーパー)のコンストラクターに渡すことができます。ただし、superはBのコンストラクターの最初の行である必要があります。

初めてAを適切な値で初期化する方法はありますか?A.varが最終的なもので、構築後に戻って変更できなかった場合はどうなりますか?

確かに、置くことはできsuper(f(y))ますが、これが難しくなる場合を想像することができました。

4

4 に答える 4

10

varプライベートであり、コンストラクターで値を設定する必要があると仮定すると(これが問題のポイントのようです。それ以外の場合は簡単な解決策がたくさんあります)、静的なファクトリのようなメソッドでそれを行うだけです。

class B extends A {
     int var2;

     public static B createB(int x, int y) {
         x = f(y);
         return new B(x, y);
     }

     public B(x, y) {
         super(x);
         this.var2 = y;
     }
 }

そんな感じ。明示的なコンストラクターの呼び出しは、ラッピング コンストラクターの最初の行で行う必要があるため、選択の余地はありません。

于 2012-08-02T22:22:52.853 に答える
2

あなたはこのようにすることができます:

class B extends A {
    int var2;

    public B(int x, int y) {
        super(calculateX(y));
        var2 = y;
    }

    private static int calculateX(int y) {
        return y;
    }
}

スーパークラス コンストラクターを呼び出す前にできることは、静的メソッドを呼び出すことだけです。

于 2012-08-02T22:30:43.267 に答える
0

Alternative to hvgotcodes, since it looks like you also want to set A's variable...

class B extends A {
 int var2;

 public B(int x, int y) {
     super(x);
     var2 = y;
     x = f(y);
     super.var = ...;
 }
}
于 2012-08-02T22:25:38.480 に答える
0

別のアプローチは、遅延初期化に依存する A にパラメーターなしで保護されたコンストラクターを追加することです。

class A {
    int var;

    public A(int x) {
        var = x;
    }

    /**
    * Just use this constructor if you initialize var
    */
    protected A(int x) {
    }
}

class B extends A {
    int var2;

    public B(int x, int y) {
        super();
        var2 = y;
        var = f(y);
    }
}

しかし、それは文書化するのが難しく、チーム メンバーにはあまり明白ではなく、API に使用するべきではありません。

于 2012-08-02T22:54:44.477 に答える