= Solution
Replace the overloaded entry point by one forwarding method and add a virtual callback on the drink. The callbacks choose a reaction overload using the concrete drink class's statically known `this` type:
``
class Drink {
def serveTo(b: Boy): Unit = b.react(this)
}
class Milk extends Drink {
override def serveTo(b: Boy): Unit = b.react(this)
}
class Boy {
def concept(d: Drink): Unit = d.serveTo(this)
def react(d: Drink): Unit = println("Drink")
def react(m: Milk): Unit = println("Milk")
}
class Baby extends Boy {
override def react(d: Drink): Unit = println("Food")
override def react(m: Milk): Unit = println("White drink")
}
``
The original `b.concept(d)` call now dynamically selects `Milk.serveTo`. Inside that method `this` has static type `Milk`, selecting `react(Milk)`; virtual dispatch on `b` then selects `Baby.react(Milk)`. Thus the output is \b[`White drink`]. This is <double dispatch>: changing only an overload's parameter name or the reference's runtime object would not change static overload selection.
Back to article page