Search code examples
javadispatch

How to invoke most specific version of overloaded method?


I have a primitive collision system which checks every pair of objects to see if they are colliding.

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

The CollisionDetector and CollisionHandler both have generic and specific versions of their respective functions, e.g.

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

where Player, SolidRectangle, and Snowflake all extend Drawable. I would like the above loop to call the most specific version of each method available, but currently it will only call the one for the superclass Drawable. Is there some way to do this without manually checking what the classes are via instanceof?

I could see how this might not be possible from the following example: If B extends A and C extends A and I write the methods

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

then have

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

that the call of foo would be ambiguous, but I hope someone might have more insight into the matter than I do. Is there any way to get around this?


Solution

  • The Visitor Design Pattern offers an alternative to multiple dispatch in Java.

    Besides this, there are a few alternatives:

    There is an outdated MultiJava Project that implemented mutiple dispatch support in Java and there are a couple of other projects out there using reflection to support multimethods in Java: Java Multimethods, Java Multimethods Framework. Perhaps there are even more.

    You could also consider an alternative Java-based language which does support multimethods, like Clojure or Groovy (these links point to examples).