18

私は次のように損傷可能なインターフェースを持っています

public interface Damageable {
    public void handleCollision(float impulse);
}

このインターフェースを実装するクラス、BaseObject

public class BaseObject implements Damageable

3番目のクラスには、BaseObject型のArrayListがあります。

public class ObjectManager {    
    public ArrayList<BaseObject> bodies;

私がやろうとしているのは、ArrayList本体をArrayListを受け入れる別のクラスのメソッドに渡すことです。

public CollisionManager( ArrayList<Damageable> _bodies) {
        bodies = _bodies;
}

Javaでは、bodyがArrayList型で、BaseObjectがDamageableを実装している新しいCollisionManager(body)を実行できません。

キャストしてみました。ArrayList<BaseObject>からArrayListにキャストできないと 言います。また、を使用してみClass<? extends Damageable>ましたが、Damaageableインターフェイスで宣言されたメソッドを呼び出すことができません。ArrayListを渡すにはどうすればよいですか?

4

3 に答える 3

43

ジェネリックスを明示する必要があります。したがって、ジェネリック型はそれ自体である必要はなく、拡張できることをコンパイラに通知する必要があります。Damagable Damagable

public CollisionManager(ArrayList<? extends Damagable> bodies) {

ちなみに、変数をbodiesではなくに変更したことに注意してください_bodies。アンダースコアは、標準のJavaコーディング規則の一部ではありません。


OPのコメントに応じて編集する

インターフェイスの代わりに、という具体的なクラスがあったとしましょうDamagable。コンパイラ<? extends Damagable>に、それがのインスタンスである必要はないことを伝えますDamagable。タイプが拡張されても問題ありません。それ以外の場合、コンパイラはあなたが正確にを持っていると想定します。 DamagableDamagable

Damagableのインスタンスがある場合はないので、インターフェースとして考えるときはあまり意味がありませんDamagable。しかし、それらは本質的に同じように機能します。

クラスではなく、Javaタイプを使用していることを覚えておく必要があります。Javaの型の構文と構造は、クラス構造よりも堅牢ではありません。implementsタイプに関しては、概念はありません。


編集の最終ラウンド

最後に、メソッド/コンストラクターのパラメーターとメソッドの戻り型にはインターフェースを使用する方が一般的に良いことに注意する必要があります。これにより、あなたとあなたのメソッドを使用する人々は、あなたが好きな実装を使用することができ、あなたはあなたが好きなようにあなたの実装を変更することができます。

したがって、これらのリビジョンを使用すると、次のようになります。

public CollisionManager(List<? extends Damagable> bodies) {
于 2012-05-23T02:15:15.020 に答える
2

他の人は間違いなくJava構文の観点から技術的な解決策を指摘するでしょう。

おそらく考慮すべきいくつかの設計上の問題について説明します。

  • BaseObjectはDamaableを実装しています。これは、すべてのBaseObjectが損傷可能であることを意味します。それなら、ただ作ってみませんCollisionManager(ArrayList<BaseObject>)か?他の場所でDamageableを使用する場合(つまり、Damageableであるが、BaseObjectsではないものがある場合)を除いて、それは不要な抽象化のように見えます。
  • 通常、ゲーム/シミュレーションでの衝突検出では、ArrayListではなく、衝突検出に空間データ構造(Octree、Quadtree、AABBツリーなど)を使用する必要があります。ArrayListでの衝突の検索は、O(n ^ 2)アルゴリズムです。ライブオブジェクトがたくさんある場合、これは大きな問題になります。
  • 機能は損傷ではなく衝突検出に関連しているため、損傷可能は悪い名前のように思われます-衝突可能の方が優れているのではないでしょうか?
于 2012-05-23T02:20:35.110 に答える
2

試してみてくださいArrayList<? extends Damageable > _bodies

Classこれは、拡張する(適切に実装される)で構成されるArrayListが必要であることを示していますDamageable

于 2012-05-23T02:12:56.003 に答える