我有一个原始的碰撞系统,它检查每对物体是否有碰撞。
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
的召唤是模棱两可的,但我希望有人可能比我更了解此事。有没有办法解决这个问题?
答案 0 :(得分:3)
Visitor Design Pattern提供了Java中multiple dispatch的替代方法。
除此之外,还有一些选择:
有一个过时的MultiJava Project在Java中实现了多个调度支持,还有一些其他项目使用反射来支持Java中的多方法:Java Multimethods,Java Multimethods Framework。也许还有更多。
答案 1 :(得分: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),但即便如此似乎不是很有效率。