Wednesday, September 15, 2010

Double dispatch to solve compile method resolution issues in Java

I usually don't chain posts, but it was going to be very long so... this post is a continuation of the previous one.

Here's how to use double dispatch for the compile time method resolution case. Note that the doubleDispatch method must be defined both for Mammal and for Dog.


public class OverloadingExamples {

public static class Mammal {
public void sayHello() {
System.out.println("Hi, I'm a mammal!");
}

public void doubleDispatch(OverloadingExamples example) {
example.makeSayHello(this);
}
}

public static class Dog extends Mammal {
@Override
public void sayHello() {
System.out.println("Hi, I'm a mammal - in fact I'm a dog!");
}

@Override
public void doubleDispatch(OverloadingExamples example) {
example.makeSayHello(this);
}
}

private Dog getADog() {
return new Dog();
}

public void runExample() {

Mammal aMammal = getADog();

System.out.println("Run time method resolution");
aMammal.sayHello();

System.out.println();

System.out.println("Double dispatch resolutions");
aMammal.doubleDispatch(this);

Dog aDog = (Dog) aMammal;
aDog.doubleDispatch(this);
}

public void makeSayHello(Mammal aMammal) {
System.out.println("Compile time method resolution for a MAMMAL");
System.out.print("Corresponding run time method resolution: ");
aMammal.sayHello();
}

public void makeSayHello(Dog aDog) {
System.out.println("Compile time method resolution for a DOG");
System.out.print("Corresponding run time method resolution: ");
aDog.sayHello();
}

public static void main(String args[]) {
new OverloadingExamples().runExample();
}
}


Now here's the output:

Run time method resolution
Hi, I'm a mammal - in fact I'm a dog!

Double dispatch resolutions
Compile time method resolution for a DOG
Corresponding run time method resolution: Hi, I'm a mammal - in fact I'm a dog!
Compile time method resolution for a DOG
Corresponding run time method resolution: Hi, I'm a mammal - in fact I'm a dog!

And the makeSayHello(Mammal) implementation was not used.

1 comment:

matt said...

A colleague pointed out to me that the examples could be further refined on to include this version of sayHello() for Dog:

@Override
public void sayHello() {
super.sayHello();
System.out.println("In fact I'm a dog!");
}

Thanks!