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);
        }
    }
}

CollisionDetectorCollisionHandler都有各自功能的通用和特定版本,例如

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

我可以从以下示例中看到这可能是不可能的: If B extends Aand C extends Aand I write the methods

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中的多分派提供了一种替代方案。

除此之外,还有一些选择:

有一个过时的MultiJava 项目在 Java 中实现了多分派支持,还有几个其他项目使用反射来支持 Java 中的多方法:Java MultimethodsJava Multimethods Framework。也许还有更多。

您还可以考虑另一种支持多方法的基于 Java 的语言,例如ClojureGroovy(这些链接指向示例)。

于 2012-07-21T02:58:30.517 回答
1

您还需要确保它CollisionHandler.handleCollision(a,b)等同于CollisionHandler.handleCollision(b,a). 使用正常的方法分派解决了一半的问题:

drawable.handleCollision(drawable2)

但要做到这一点有点像尝试实现在equals()不同类型的对象之间工作所需的(有点乏味的)检查。

从概念上讲,您似乎正在寻找一种方法来选择基于(无序)运行时类型对调用的函数。类似 a 的东西HashMap<Set<Class>,CollisionHandler>,除了最后我检查了 Java 不支持泛型泛型(而且 Set 可能效率不高)。沿着这些思路最有效的解决方案是HashMap<ClassPair,CollisionHandlerFunctor>通过反射填充(确保您同时获得 ClassPair(Player.class,Snowflake.class) 和 ClassPair(Snowflake.class,Player.class),但即便如此它看起来也不像它可以非常有效。

于 2012-07-21T04:13:47.177 回答