what You are doing in your code is a single dispatch (not a double dispatch – explanation below) because only one concrete sub type evaluated at runtime is affecting the result (object wich passes itself as this
).
In addition ComposantOrdi
and Montage
provide different methods (check the parameters: ComposantOrdi
gets ComposantOrdi
while Montage
gets Montage
). If you call the superclass' equiv
method there is no way to get a result like Montage - Montage because every passed Montage
is implicitly casted to a ComposantOrdi
. Like this calling superclass' method the second part of your result cannot be anything else the ComposantOrdi.
Furthermore if you call the superclass' method the keyword this
in
Equivalence.equiv(this, c);
is triggered by the superclass which means even if the object is a Montage
it passes itself as ComposantOrdi
.
So: Calling the superclass' method can only produce the output ComposantOrdi - ComposantOrdi.
For an output like Montage - Montage you need to call the sub class' method equiv
which means:
- you need to reference the receiver of the
equiv
call as Montage
(see m2
in your main, not m3
)
- you have to pass in a
Montage
object
Because then the keyword this
is triggered in Montage
the first part of the output must be Montage. The second part is also Montage because Java does not implicitly cast objects if not neccessary. Thats why the overloaded method with to Montages
as Parameters is selected.
So: Calling the sub class' method can only produce the output Montage - Montage.
The mixed version of the Equivalence's equiv
method is never called.
EXPLAINING THE DOUBLE DISPATCH MECHANISM:
I think there is a fundamental misunderstanding of the double dispatch mechanism. So let me explain it. I will start explaining a single dispatch before moving on to the double dispatch mechanism.
SINGLE DISPATCH:
A Single dispatch means you call a method of an object and the performed behaviour (the result of the method call) depends on the concrete type of the object. Generally this is called polymorphism and is implemented using abstract methods or method overriding.
Assumed you have a class system according to the picture below. The Client
holds a list of Shapes
. To paint all of them it loops through the list and calls paint
on each Shape
. While a the class Triangle
paints a triangle on the screen a Square
paints a square. By not considering of which concrete sub type the Shapes
are, the performed behaviour is determined at runtime.
In other words the result of the paint method's call depends on the concrete sub type of the derivatives of the Shape
interface. The call of the paint method is a single dispatch because there is only one concrete subtype which determines the performed behaviour at runtime.

DOUBLE DISPATCH: Using the double dispatch mechanism the performed behaviour is affected by two concrete sub types at runtime. Like this you span a behaviour matrix which is evaluated dynamically.
If you modify the class system according to the picture below the paint mechanism triggered by the client is dependent on two objects – Shape
and a Painter
. The client calls the paint
method and injects its Painter
. Then the Shape
passes itself as this
in one of the overloaded methods of the Painter
.
Like this the Client
triggers the paint mechanism without knowing what kind of shape in what color is painted. If for example its painter is a GreenPainter
and the Shape
is a Triangle
then a green triangle appears on the screen.
In this example the double dispatch mechanism is triggered by the call of the Shapes
' paint
method.
You should have a look at the visitor pattern which uses the double dispatch mechanism.
