私は現在、シミュレーションプロジェクトのクラス階層を設計中です。これは、Element
インスタンスのツリーの離散事象シミュレーションになります。簡潔にするために(そして、私が問題のジェネリックの部分だけに興味があるので)ここではクラス/インタフェースのスケッチをここに提示するので、構文は完璧ではありません。始まるために何かを持っているために、要素は次のようになります。コンテナをジェネリックで制限する
public abstract class Element {
private Set<Element> children = new HashSet<Element>();
public Element getContainer();
public Collection<Element> getChildren() {
return Collections.unmodifiableSet(children);
}
public Position getPosition();
protected void add(Element e) { children.add(e); }
protected void remove(Element e) {children.remove(e); }
}
Position
の定義は本当に問題ではありませんし、どのような他の方法を行うことになっていることは自明私は願っています。
public abstract class Solid extends Element {
public Size getSize();
}
は再び、Size
の正確な意味は重要ではありません、Solid
はちょうどシミュレートされた世界で空間を満たす物理的なオブジェクトであるために仮定されています。私たちはプールに別のインターフェイスを投げる事が穏やかに面白くするために。今、私たちはここに、私たちは互いの上にそれらをスタックすることができます固形物を持っていることをStack
です:トラブルが始まる
public abstract class Stack extends Solid {
public void add(Solid s); // <- trouble ahead!
}
そして、ここです。私は本当にSolid
のインスタンスだけをStack
に追加したいと思っています。サイズがないオブジェクトを積み重ねるのは難しいため、Stack
にはSize
というものが必要です。したがって、私はこれを表現できるように、私のElement
をリワーク:ここ
public abstract class Element<E extends Element<?>> {
private final Set<E> children = new HashSet<E>();
public Element<?> getContainer();
public Collection<E> getChildren();
public Position getPosition();
public void add(E e);
public void remove(E e);
}
私の意図はElement
は、それが含まれている可能性がある(サブ)Element
の種類に制約を持つことができることを表明することにあります。これまでのところ、これはすべて機能します。しかし今は、コンテナの制限をElement
にする必要があると感じました。それはどう?
public interface Element<E extends Element<?,?>, C extends Element<?, ?>>
それとも、もっとこのように行くん:にそこに持って
- :
public interface Element<E extends Element<?,C>, C extends Element<E, ?>>
私はこれについて少しファジーを感じるように始めている、そしてゲームへのより多くのがあります要素をあるコンテナから別のコンテナに転送する「ポート」(
Input
およびOutput
)である必要があります。私はジェネリックの魔法を投げなければなりません。 - 私のToDoリストにモデル用のGUIエディタがあります。だから私は実行時にもこれらの小切手を利用可能にする必要があります。ですから、タイプリテラルなどがあり、
public boolean canAdd(Element<?, ?> e)
のようなエディタが頼りになるでしょう。このメソッドは非常に重要なので、私はそれをのクラスのメソッドにしたいと思っています。だから、酔っている開発者は午前4時に間違ってしまうことはありません。 - サブクラスが
Element
なら、のいずれかから完全一致と思われるので、Collection
クラスを使用していることを決定できます。- は私が再発明し、ホイールを午前:
だからここに私の質問ですか?私にはどのライブラリがそれをしていますか?
- これにジェネリックで取り組むことができますか? (答えが「はい」の場合:実装に関するいくつかのヒントは大歓迎です)
- これは少し過剰に設計されていますか?
- この質問には、より良いタイトルまたはタグがありますか? :-)
- 私はあなたのデザインの私の理解でこの答えを基づかてる
ここにあなたの考えがあります。 javaのジェネリックの目的はClassCastExceptionを防ぐことです。フルストップ。それは彼らが穏やかなやり方でする唯一のことです。あなたが何か他のもののためにそれらを使用しようとしているなら、その方法は狂気にあります。 – Affe
"そのやり方は狂気にある"と言っていました。私はタイプ消去を理解する前に、ジェネリックであらゆる種類のワイルド・トリックを試みていましたが、ほとんどの場合、ジェネリックの創造的な使用は失敗することになりました。要素のように本当に狂ったように見えたら、Cは要素を拡張します>あなたはそれらを使うことに懐疑的でなければなりません。これらの用途を概念化することは難しいです。 –
@Affe私がここでやろうとしていることの目的は、最終的にCCEの防止につながります。 Stackについて考えてみましょう。これは、getSize()を持つElementsでしか動作しません。つまり、Solidです。したがって、これを表現するためにジェネリックスを使用すると、コンパイラはそれが正常であることを確認します。それ以外の場合はキャストして、そのキャストが有効かどうかを確認する別の方法を見つける必要があります。 – Waldheinz