0

カプセル化を壊さずにこれを行う方法があるかどうか疑問に思っています。抽象クラスは、実装するサブクラスで定義されたパラメーターに依存する必要があります。そのようです:

public abstract class Parent {

    private int size;
    private List<String> someList;

    public Parent() {
        size = getSize();
        someList = new ArrayList<String>(size);
    }

    public abstract int getSize();

}

public class Child extends Parent {

    @Override
    public int getSize() {
        return 5;
    }

}

これは醜いですか?より良い方法はありますか?そしておそらくもっと重要なことは、これは良い考えでしょうか?

編集:

クラスはフレームワークのコンテキストで作成されるため、デフォルトのパラメーターなしのコンストラクターが常に呼び出されます (実際、Parent クラスは別のクラスを拡張します)。size パラメーターは説明目的で使用されているだけであり、List の実装に使用する予定はありません。

4

3 に答える 3

4

いいえ、醜いではありません。このパターンを「テンプレート法」と名付けました。ただし、通常は、メソッドが単純な getter ではなく、ビジネス ロジックを実装するものである場合に便利です。

あなたの場合、他の解決策は、親クラスで保護されたコンストラクターを定義し、子から関連するパラメーターでそれを呼び出すことです:

public abstract class Parent {

    private int size;
    private List<String> someList;

    protected Parent(int size) {
        this.size = size;
        someList = new ArrayList<String>(size);
    }

    public int getSize() {
        return size;
    }

}

public class Child extends Parent {
    public Child() {
        super(5);
    }
}
于 2012-09-23T09:42:08.033 に答える
2

コンストラクターを使用する唯一の場所である場合はgetSize()、コンストラクターのパラメーターとしてそれを必要とします。

しかし、もっと重要なのは、なぜサイズを気にするのですか? 問題があることがわかっていない限り、他の人と同じようにデフォルトのサイズを使用してください。

public abstract class Parent {

    private List<String> someList = new ArrayList<String>();

    // use default constructor    
}
于 2012-09-23T09:39:27.440 に答える
1

コンストラクターで使用しようとする場合を除いて、パターンは見苦しくありません。これにより、予想外の結果になるように Child を変更できます。

public class Child extends Parent {

    private int mySize = 5;

    @Override
    public int getSize() {
        // The -1 is only to help clarify what happens
        return mySize - 1;
    }

}

ここで Child のインスタンスを作成すると、負の容量が許可されないため、実際には例外がスローされます。クラスのプロパティは、親コンストラクターが終了した後にのみ初期化されることに注意してください。(そして、プロパティが Parent コンストラクターを使用して設定され、 Child で定義されたデフォルト値を持つ場合、 Parent() で設定した値を喜んで上書きします)

于 2012-09-23T14:29:06.173 に答える