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 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.Scala trait linearization merges parent linearizations from right to left, deleting an earlier occurrence when that same ancestor occurs in a later appended parent linearization. Each class precedes its ancestors, and an ancestor appears once.[ref]
Scala 2.13 classes and objects specification. Class Linearization: concatenation replaces identical elements of its left operand with their occurrences in the right operand; the same rule is used for the Scala 2 code here
Ignoring the predefined roots gives| Type | Linearization, most specific first |
|---|---|
K | K |
I | I, K |
J | J, K |
G | G, I, K |
F | F, J, I, K |
H | H, J, K |
D | D, F, J, G, I, K |
E | E, H, J, K |
A | A, D, F, J, G, I, K |
B | B, E, H, D, F, J, G, I, K |
C | C, E, H, J, K |
Each override appends its letter after
super.m returns. Reading the method chain in reverse from K therefore yields the three output lines:KIGJFDA
KIGJFDHEB
KJHECIn particular, mixing
H into C again does not create another H or move it before its subclass E. Also, J lies between F and G in D's chain; super follows the final linearization, not simply one statically named parent. Articles by others on the same topic
There are currently no matching articles.