Upload
everett-shields
View
213
Download
1
Embed Size (px)
Citation preview
Double DispatchingDouble Dispatching
In JavaIn Java
Single DispatchSingle Dispatch
Uses polymorphism between base and Uses polymorphism between base and derived classesderived classes
Compiler registers container pointer to base Compiler registers container pointer to base classclass
At run-time a dispatch vector is used to At run-time a dispatch vector is used to determine what the container is actually determine what the container is actually pointing topointing to
Single DispatchSingle Dispatch
This can be either an object of base or This can be either an object of base or derived typederived type
ButBut, if calling a method dynamically , if calling a method dynamically the the signatures of the base and derived methods signatures of the base and derived methods must be identicalmust be identical
If they are not the run-time system uses the If they are not the run-time system uses the static, not the dynamic type to determine the static, not the dynamic type to determine the call.call.
An ExampleAn Example
My apartment in Yerevan has ants and My apartment in Yerevan has ants and cockroachescockroaches
I want to spray the ants with ant poison and I want to spray the ants with ant poison and the cockroaches with cockroach poisonthe cockroaches with cockroach poison
The Public Health Department at the AUA The Public Health Department at the AUA comes up with the following hierarchy:comes up with the following hierarchy:
GenericPoison
AntPoison CockroachPoison
Insect
Ant Cockroach
Single DispatchSingle Dispatch
PoisonPoison is a kind of visitor to is a kind of visitor to InsectInsect We want to have a method We want to have a method spray() spray() in all in all
three classes that is insect-specificthree classes that is insect-specific Start with the base class Start with the base class PoisonPoison Use Use InsectInsect as the parameter type of as the parameter type of spray()spray()
class Poison{ public void spray(Insect a Bug){ …}}
class AntPoison{ public void spray( ???){…}}
Single DispatchSingle Dispatch
Problem: we would like to spray ants with Problem: we would like to spray ants with ant poisonant poison
Hence, if I have a declared Hence, if I have a declared InsectInsect pointer pointer that has a reference at run-time to an that has a reference at run-time to an AntAnt object I would like to call the Ant’s object I would like to call the Ant’s spray() spray() methodmethod
What is the parameter type for the What is the parameter type for the Ant Ant spray()?spray()?
First AttemptFirst Attempt
Try directly to apply Try directly to apply ant poison ant poison to an to an ant:ant: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{…};
Now try itNow try it
Make a container and try polymorphism:Make a container and try polymorphism:Poison container = new AntPoison();Poison container = new AntPoison();
container.spray(new Ant());container.spray(new Ant()); ProducesProduces
Generic SprayGeneric Spray !!!!!!!!!! What happened?What happened?
Just thisJust this
• There is no method in There is no method in PoisonPoison with the with the parameter of type Ant.parameter of type Ant.
• Therefore the Java run-time system reverts Therefore the Java run-time system reverts back to the static definition of the back to the static definition of the polymorphic container, i.e. polymorphic container, i.e. PoisonPoison
Cheap way out:Cheap way out:
Make the container point to Make the container point to AntPoisonAntPoison::AntPoison container = new AntPoison container = new AntPoison();AntPoison();
Container.spray(new Ant());Container.spray(new Ant());Container.spray(new Insect());Container.spray(new Insect()); ProducesProducesSpraying ant with ant spraySpraying ant with ant sprayGeneric SprayGeneric Spray
CaveatCaveat
There is no method in There is no method in AntPoisonAntPoison to spray to spray a generic insecta generic insect
Hence the compiler reverts to the Hence the compiler reverts to the sprayspray method in the super class, i.e. in method in the super class, i.e. in poisonpoison
Way out: Need a Way out: Need a sprayspray method in method in PoisonPoison with an with an AntAnt parameter: 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 ThisTest This
Poison container = new AntPoison();Poison container = new AntPoison();
Insect bugType = new Ant();Insect bugType = new Ant();
container.spray(bugType);container.spray(bugType);
bugType = new Insect();bugType = new Insect();
container.spray(bugType);container.spray(bugType);
ProducesProduces
Generic SprayGeneric Spray
Generic SprayGeneric Spray
Why?Why?
Because there is no Because there is no sprayspray method in method in AntAnt with an insect parameterwith an insect parameter
But, callingBut, callingPoison container = new AntPoison();Poison container = new AntPoison();
Container.spray(new Ant());Container.spray(new Ant());
Container.spray(new Container.spray(new Insect());Insect());
Single DispatchSingle Dispatch
• ProducesProduces
Spraying ant with ant spraySpraying ant with ant spray
Generic sprayGeneric spray Which at least works on ants.Which at least works on ants. Doesn’t work properly on insectsDoesn’t work properly on insects
ProblemProblem
• We are only spraying with generic poisonWe are only spraying with generic poison• In order to make use of a In order to make use of a spray spray method in method in
the AntPoison class we must repeat the the AntPoison class we must repeat the spray() spray() method with exactly the same method with exactly the same signature in the signature in the AntPoisonAntPoison derived class derived class
• Furthermore, we need a Furthermore, we need a beingSprayed() beingSprayed() method of each poison type in both method of each poison type in both InsectInsect and and AntAnt