200 likes | 402 Views
Double Dispatching. In Java. Single Dispatch. Uses polymorphism between base and derived classes Compiler registers container pointer to base class At run-time a dispatch vector is used to determine what the container is actually pointing to. Single Dispatch.
E N D
Double Dispatching In Java
Single Dispatch • Uses polymorphism between base and derived classes • Compiler registers container pointer to base class • At run-time a dispatch vector is used to determine what the container is actually pointing to
Single Dispatch • This can be either an object of base or derived type • But, if calling a method dynamically the signatures of the base and derived methods must be identical • If they are not the run-time system uses the static, not the dynamic type to determine the call.
An Example • My apartment in Yerevan has ants and cockroaches • I want to spray the ants with ant poison and the cockroaches with cockroach poison • The Public Health Department at the AUA comes up with the following hierarchy:
GenericPoison AntPoison CockroachPoison Insect Ant Cockroach
Single Dispatch • Poison is a kind of visitor to Insect • We want to have a method spray() in all three classes that is insect-specific • Start with the base class Poison • Use Insect as the parameter type of spray()
class Poison { public void spray(Insect a Bug){ …} } class AntPoison { public void spray( ???){…} }
Single Dispatch • Problem: we would like to spray ants with ant poison • Hence, if I have a declared Insect pointer that has a reference at run-time to an Ant object I would like to call the Ant’s spray() method • What is the parameter type for the Ant spray()?
First Attempt public class Poison { public void spray(Insect aBug){ System.out.println(“Generic Spray”); }; Public class AntPoison extends Poison { public void spray(Ant anAnt){ System.out.println(“Spraying ant with ant spray”); }; public class Insect{…}; public class Ant{…}; Try directly to apply ant poison to an ant:
Now try it • Make a container and try polymorphism: Poison container = new AntPoison(); container.spray(new Ant()); • Produces Generic Spray • !!!!! • What happened?
Just this • There is no method in Poison with the parameter of type Ant. • Therefore the Java run-time system reverts back to the static definition of the polymorphic container, i.e. Poison
Cheap way out: • Make the container point to AntPoison: AntPoison container = new AntPoison(); Container.spray(new Ant()); Container.spray(new Insect()); • Produces Spraying ant with ant spray Generic Spray
Caveat • There is no method in AntPoison to spray a generic insect • Hence the compiler reverts to the spray method in the super class, i.e. in poison • Way out: Need a spray method in Poison with an Ant parameter:
public class Poison{ public void spray(Insect aBug){ System.out.println(“Generic Spray”); } public void spray(Ant antBug){ System.out.println(“Generic Ant Spray”); } }; public class AntPoison extends Poison{ public void spray(Ant antBug){ System.out.println(“Spraying Ant with Ant spray”); } };
Test This Poison container = new AntPoison(); Insect bugType = new Ant(); container.spray(bugType); bugType = new Insect(); container.spray(bugType); Produces Generic Spray Generic Spray
Why? • Because there is no spray method in Ant with an insect parameter • But, calling Poison container = new AntPoison(); Container.spray(new Ant()); Container.spray(new Insect());
Single Dispatch • Produces Spraying ant with ant spray Generic spray • Which at least works on ants. • Doesn’t work properly on insects
Problem • We are only spraying with generic poison • In order to make use of a spray method in the AntPoison class we must repeat the spray() method with exactly the same signature in the AntPoison derived class • Furthermore, we need a beingSprayed() method of each poison type in both Insect and Ant