0

まず、質問のタイトルで申し訳ありませんが、私の問題を説明するのにこれ以上のタイトルは考えられません。お気軽に変更してください:)

Boxいくつかのプライベート変数にいくつかのコンストラクター、メソッド、その他を実装するこの抽象クラスがあるとしましょう。次に、とのようなサブクラスがいくつかBoxAありBoxBます。これらは両方とも余分なものを実装します。

これで、別の抽象クラスと、およびShapeのようないくつかのサブクラスができました。SquareCircle

両方ともBoxA、オブジェクトBoxBのリストが必要ですが、オブジェクトのみがのリストに含まれ、オブジェクトのみがのリストに含まShapeれるようにする必要があります。SquareBoxACircleBoxB

そのリスト(各ボックス)には、get()andset()メソッドとaメソッドaddShape()が必要removeShape()です。

知っておくべきもう1つの重要なことは、作成された各ボックスについて、またはのいずれBoxABoxBで、それぞれShapeのリストがまったく同じであることです。Squareの名前付きオブジェクトと名前付きのls2つのオブジェクトのリストを作成するとします。いずれにせよ、との両方が同じリストを持っている必要があります。BoxAboxA1boxA2boxA1boxA2ls

これは私の考えです:

public abstract class Box {
    // private instance variables

    public Box() {
        // constructor stuff
    }

    // public instance methods
}

public class BoxA extends Box {
    // private instance variables

    private static List<Shape> list;

    public BoxA() {
        // constructor stuff
    }

    // public instance methods

    public static List<Square> getList() {
        List<Square> aux = new ArrayList<Square>();

        for(Square s : list.values()) {
            aux.add(s.clone()); // I know what I'm doing with this clone, don't worry about it
        }

        return aux;
    }

    public static void setList(List<Square> newList) {
        list = new ArrayList<Square>(newList);
    }

    public static void addShape(Square s) {
        list.add(s);
    }

    public static void removeShape(Square s) {
        list.remove(list.indexOf(s));
    }
}

リストはそのタイプのオブジェクトで同じである必要があるため、私はそれをとして宣言しstatic、そのリストで機能するすべてのメソッドもstaticです。さて、BoxBクラスはリストのものに関してほとんど同じでしょう。に置き換えるだけSquareTriangle問題は解決しました。BoxAしたがって、作成されたオブジェクトごとに、リストは1つだけで同じになります。作成された各BoxBオブジェクトについても同じことが起こりますが、もちろん異なるタイプのリストがあります。

それで、あなたが尋ねる私の問題は何ですか?ええと、私はコードが好きではありません...、、、getList()およびメソッドは基本的setList()にとに対して繰り返され、リストが保持するオブジェクトのタイプのみが異なります。どういうわけか、これらすべてのメソッドの「重複」を避けたかったのです。addShape()removeShape()BoxABoxB

Box代わりにスーパークラスでそれを行う方法を考えることはできません。またはShapeの代わりにを使用して静的に実行しようとしても、リストはすべてのオブジェクトに対して1つだけであり、のサブクラスごとに1つだけである必要があるため、機能しません。SquareTriangleBoxABoxBBox

どうすればこれを別の方法でより良く行うことができますか?

PS:自分がやっていることに英語で正しい単語がわからないので、実際の例を説明できませんでした。そこで、ボックスと図形の例を使用しましたが、基本的には同じです。

4

1 に答える 1

1

次のようなものを試すことができます:

abstract class Box<E extends Shape> {

    abstract protected List<E> getList();

    abstract protected void setList(List<E> list);

    protected static <T extends Shape> List<T> getCommon(Box<T> box) {
        List<T> aux = new ArrayList<T>();
        for (T s : box.getList()) {
            aux.add((T) s.clone());
        }
        return aux;
    }

    protected static <T extends Shape> void setCommon(Box<T> box, List<T> newList) {
        // do something on newList here if needed as common functionality
        box.setList(new ArrayList<T>(newList));
    }
}
class BoxA extends Box<Square> {
    private static List<Square> list;

    @Override
    protected List<Square> getList() {
        return list;
    }

    @Override
    protected void setList(List<Square> list) {
        this.list = list;
    }

    public static List<Square> get() {
        return getCommon(new BoxA());
    }

    public static void set(List<Square> newList) {
        setCommon(new BoxA(), newList);
    }
}

少しハックですが、親クラスを使用していくつかの共通機能を保持できます。子クラスにはまだ最終メソッドが必要ですが、それらで行うことは、現在のクラスの新しいインスタンスを与える親メソッドを呼び出して、親メソッドがそこからジェネリック型を推測できるようにすることだけです。getList()setList()は、Box の型パラメーターを持つことができるように静的ではなく、保護されているため、外部からは見えないことに注意してください。これらは、プライベートな静的変数 (各拡張クラスが持つ必要がある) のゲッター セッターとして機能し、親にアクセスして、子に属する変数で共通の作業を実行できるようにします。

get()andset()メソッドは、(new BoxA()またはnew BoxB()) を使用して静的リストへのアクセスを許可すると同時に、型パラメーターを親に渡します。リストは静的であるため、どのインスタンスがそれを返すかは問題ではありません。一般的なメソッドには、クラスが持っているものではない独自の型パラメーターがあります。実際getCommon(new BoxB())には BoxA 内から呼び出すことができるので、正しいものを呼び出すようにするのはあなたの仕事です。

于 2010-05-28T17:18:39.087 に答える