0

オブジェクトのすべてのペアをチェックして、それらが衝突しているかどうかを確認するプリミティブ衝突システムがあります。

int size = drawables.size();
for(int i = 0; i < size; ++i)
{
    for(int j = i+1; j < size; ++j)
    {
        Drawable drawable = drawables.get(i);
        Drawable drawable2 = drawables.get(j);
        if(CollisionDetector.areColliding(drawable, drawable2))
        {
            CollisionHandler.handleCollision(drawable, drawable2);
        }
    }
}

CollisionDetectorおよびCollisionHandler両方には、それぞれの機能の汎用バージョンと特定バージョンがあります。

public static boolean handleCollision(Drawable drawable1, Drawable drawable2)
public static boolean handleCollision(Player player, SolidRectangle rectangle)
public static boolean handleCollision(Player player, Snowflake snowflake)

ここPlayerで、、、SolidRectangleおよびSnowflakeすべてが。を拡張しDrawableます。上記のループで、使用可能な各メソッドの最も具体的なバージョンを呼び出したいのですが、現在はスーパークラスのメソッドのみを呼び出しますDrawable。クラスが何を介しているかを手動でチェックせずにこれを行う方法はありinstanceofますか?

次の例から、これが不可能な場合があることがわかりました。メソッドを記述したB extends A場合C extends A

public void foo(A a, C c)
public void foo(B b, A a)

その後、

A objectB = new B();
A objectC = new C();
foo(objectB, objectC);

の呼びかけはfoo曖昧ですが、誰かが私よりも問題についてより多くの洞察を持っていることを願っています。これを回避する方法はありますか?

4

2 に答える 2

3

ビジターデザインパターンは、Javaでの複数のディスパッチに代わるものを提供します。

これに加えて、いくつかの選択肢があります。

Javaで多重ディスパッチサポートを実装した古いMultiJavaプロジェクトがあり、Javaでマルチメソッドをサポートするためにリフレクションを使用している他のプロジェクトがいくつかあります:Java MultimethodsJavaMultimethodsFramework。おそらくもっとたくさんあります。

また、 ClojureGroovyなどのマルチメソッドをサポートする代替のJavaベースの言語を検討することもできます(これらのリンクは例を示しています)。

于 2012-07-21T02:58:30.517 に答える
1

CollisionHandler.handleCollision(a,b)また、それがと同等であることを確認する必要がありますCollisionHandler.handleCollision(b,a)。問題の半分は、通常のメソッドディスパッチで解決されます。

drawable.handleCollision(drawable2)

equals()しかし、それを正しく行うことは、異なるタイプのオブジェクト間で機能するために必要な(少し面倒な)チェックを実装しようとすることに少し似ています。

概念的には、ランタイムタイプの(順序付けされていない)ペアに基づいて呼び出す関数を選択する方法を探しているようです。のようなものですがHashMap<Set<Class>,CollisionHandler>、最後にJavaがジェネリックジェネリックをサポートしていないことを確認しました(そしてセットはおそらくそれほど効率的ではありません)。これらの線に沿った最も効率的な解決策は、HashMap<ClassPair,CollisionHandlerFunctor>ビアリフレクションを設定することです(ClassPair(Player.class、Snowflake.class)とClassPair(Snowflake.class、Player.class)の両方を取得するようにしてください)が、それでもそうではないようです。非常に効率的です。

于 2012-07-21T04:13:47.177 に答える