Use double dispatch. Each original overload first sends a dynamically dispatched message to its argument. The argument's selected body then calls an overloaded receiver method with All three
this, whose static type inside that body is the desired argument software class.class X {
def sendTo(m: M): String = m.receive(this)
}
class Y extends X {
override def sendTo(m: M): String = m.receive(this)
}
class Z extends Y {
override def sendTo(m: M): String = m.receive(this)
}
class M {
def f(x: X): String = x.sendTo(this)
def f(x: Y): String = x.sendTo(this)
def receive(x: X): String = "f with X at M"
def receive(x: Y): String = "f with Y at M"
def receive(x: Z): String = "f with Z at M"
}
class N extends M {
override def f(x: Y): String = x.sendTo(this)
def f(x: Z): String = x.sendTo(this)
override def receive(x: X): String = "f with X at N"
override def receive(x: Y): String = "f with Y at N"
override def receive(x: Z): String = "f with Z at N"
}receive overloads must be declared in M, because sendTo receives a parameter with static type M. Declaring the Z version only in N would repeat the original problem.Whatever original The result depends on both runtime types:For the stated
f signature is selected, it invokes sendTo on the actual argument. For a Z object, dynamic dispatch enters Z.sendTo; inside that body, this has static type Z, so method overloading selects receive(Z). The final call dynamically dispatches on the actual m, giving N.receive(Z) when m refers to N. Hencef with Z at N
f with Z at N
f with Z at NX, Y, Z hierarchy, the same construction reports each argument software class correctly for either receiver software class. Further subclasses would need their own dispatch protocol to distinguish additional runtime types. Articles by others on the same topic
There are currently no matching articles.