On this page:
Intro
Method Dispatch
Single Dispatch
A Rose by Another Name
Single Dispatch
Double Dispatch
6.12

Lab 11: Dispatching Enemies

Intro

You’ll work in this lab with your newly-assigned lab partners.

The two of you will work as a team to solve problems. At any time, one of you will be the Head and the other will be the Hands. The Head does the thinking and the Hands does the typing. Hands type only what the Head tells them to, but you’re free to discuss any issues that pop up. You should switch off during the lab to make sure each of you get practice problem solving, dealing with syntax, and getting finger exercises on the keyboard.

You must start this lab with this project skeleton. Unzip the file into your IdeaProjects directory and open it with IntelliJ to get started.

Method Dispatch

Which method gets called when we pass messages to objects? This section gives a few examples which may not act how you believe they should. Discuss what you expect should happen with your new partner before running the code to find out.

If you’ve never read Romeo and Juliet, let’s just say that the Montagues and the Capulets don’t get along very well.

We’ll represent the Montagues as an empty class.

class Montague {}

Romeo is of House Montague. As such, he extends the class Montague.

class Romeo extends Montague {}

Now the Capulets are known for starting trouble and tend to be rude when greeting Montagues. Note that if a Capulet sees Romeo, they’ll at least be rude to him by name.

class Capulet {

    String name;

    Capulet(String nm) { this.name = nm; }

 

    String greet(Montague m) {

        return name + ": I bite my thumb at you!";

    }

 

    String greet(Romeo m) {

        return name + ": I bite my thumb at you, Romeo!";

    }

}

Ex 1: If a Capulet greets a Montague, what will be said? Write down your expectation, then test this yourself with a checkExpect.

Capulet sampson = new Capulet("Sampson");

Montague abram = new Montague();

Romeo romeo = new Romeo();

 

sampson.greet(abram) => ???

sampson.greet(romeo) => ???

Single Dispatch

Juliet, of House Capulet, sees Romeo in a different light.

class Juliet extends Capulet {

    Juliet() { super("Juliet"); }

 

    String greet(Romeo m) {

        return name + ": Wherefore art thou, Romeo?";

    }

}

The class Juliet extends Capulet, and so shares the default, thumb-biting virtiol for any Montague in general. However, Juliet seems to greets Romeo in particular in loving, longing way. But does this happen when we run the code?

Ex 2: What happens when a Juliet greets a Montague in general?

Juliet juliet = new Juliet();

juliet.greet(abram) => ???

Ex 3: What happens when a Juliet greets Romeo in particular?

Juliet juliet = new Juliet();

juliet.greet(romeo) => ???

A Rose by Another Name

Will everything continue so nicely for Romeo & Juliet? Let’s see what happens when these ill-fated lovers put on some hooded cloaks. Or, in Java terms, let’s assign them to variables with the types of their super classes.

Capulet hoodedJuliet = juliet;

Montague hoodedRomeo = romeo;

Ex 4: What happens when our hooded Juliet greets a Montague in general? Should this be the same or different than the prior greeting?

hoodedJuliet.greet(abram) => ???

Ex 5: What happens when our hooded Juliet greets the unhooded Romeo? Should this be the same or different than the prior greeting?

hoodedJuliet.greet(romeo) => ???

Ex 6: What happens when our hooded Juliet greets our hooded Romeo? Should this be the same or different than the prior greeting? Doth it smell just as sweet?

hoodedJuliet.greet(hoodedRomeo) => ???

Let’s test one more case to shed some light on the issue.

Ex 7: What happens when our unhooded Juliet greets our hooded Romeo? Should this be the same or different than the prior greeting?

juliet.greet(hoodedRomeo) => ???

Single Dispatch

Oh no! Both the hooded and unhooded Juliets bit her thumb at the hooded Romeo! That’s not good. But why did it happen?

When Juliet only sees a hooded cloak with the Montague crest, she greets the hoodedRomeo as she would greet any Montague: with fightin’ words!

The problem is that Java doesn’t know statically that hoodedRomeo is of type Romeo, it sees it as any generic Montague. But if that’s the case, why does the hooded Juliet know how to correctly greet the unhooded Romeo?

Think about it this way: Juliet knows who she is regardless of whether she’s wearing a hood or not. So for both juliet and hoodedJuliet, the Juliet class handles greeting romeo in a loving manner. Java knows romeo to be of type Romeo, and the Juliet class dispatches the correct greet method dynamically.

How can we take advantage of the dynamic dispatch inherent to this to make sure Romeo & Juliet always greet each other kindly?

Double Dispatch

One solution is to dispatch twice: once inside each class.

Remember that the Juliet class knows to greet Romeo kindly. Let’s make sure that Romeo will always beGreeted properly.

Ex 8: Add the following method to both the Montague and Romeo classes.

String beGreeted(Capulet c){

    return c.greet(this);

}

Note that the method only calls the greet method inside the Capulet class. But importantly, inside both the Montague and Romeo classes the variable this knows exactly whether it is Romeo or not, regardless of the location where beGreeted was called.

Ex 9: What happens when romeo will beGreeteded by a general Capulet?

romeo.beGreeted(sampson) => ???

Ex 10: What happens when romeo will beGreeteded by a juliet in particular?

romeo.beGreeted(juliet) => ???

Ex 11: What happens when romeo will beGreeteded by a hoodedJuliet in particular?

romeo.beGreeted(hoodedJuliet) => ???

Ex 12: What happens when our hoodedRomeo will beGreeteded by juliet?

hoodedRomeo.beGreeted(juliet) => ???

Ex 13: What happens when our hoodedRomeo will beGreeteded by our hoodedJuliet?

hoodedRomeo.beGreeted(hoodedJuliet) => ???