考虑这个 Scala 代码:
class X {
def m(a:A) = a.f(this) + ", " + "m(a:A) in X"
}
class Y extends X {
override def m(a:A) = a.f(this) + ", " + "m(a:A) in Y"
}
class Z extends Y
class A {
def f(x:X):String = "f(x:X) in A"
def f(y:Y):String = "f(y:Y) in A"
}
class B extends A {
override def f(x:X):String = "f(x:X) in B"
def f(z:Z):String = "f(z:Z) in B"
def g(x:X):String = super.f(x) + ", " + "g(x:X) in B"
def h(y:Y):String = B.g(y) + ", " + "h(y:Y) in B"
}
object B {
def f(x:X) = "f(x:X) in ObjB"
def g(y:Y) = f(y) + ", " + "g(y:Y) in ObjB"
def g(z:Z) = f(z) + ", " + "g(z:Z) in ObjB"
}
class C extends B {
override def f(y:Y):String = "f(y:Y) in C"
def h(z:Z):String = super.h(z) + ", " + "h(z:Z) in C"
def k(x:X):String = x.m(this) + ", " + "k(x:X) in C"
}
给出的问题是:给出运行以下程序的输出:
val z: Z = new Z; val x: X = new Y
val c: C = new C; val a: A = new B
println(a.f(x)); println(a.f(z))
println(c.g(z)); println(c.h(z))
println(c.k(x))
我似乎无法完全理解给出的输出。这是我认为会发生的事情:
println(a.f(x)) = "f(x:X) in B"
println(a.f(z)) = "f(z:Z) in B"
println(c.g(z)) = "f(y:Y) in A, g(x:X) in B"
println(c.h(z)) = "f(y:Y) in A, g(y:Y) in ObjB, h(y:Y) in B, h(z:Z) in C"
println(c.k(x)) = "f(y:Y) in C, m(a:A) in Y, k(x:X) in C"
然而,当我真正将代码放入 REPL 时,我得到了不同的结果:
println(a.f(x)) = "f(x:X) in B"
println(a.f(z)) = "f(y:Y) in A"
println(c.g(z)) = "f(x:X) in A, g(x:X) in B"
println(c.h(z)) = "f(x:X) in ObjB, g(y:Y) in ObjB, h(y:Y) in B, h(z:Z) in C"
println(c.k(x)) = "f(y:Y) in C, m(a:A) in Y, k(x:X) in C"
为什么是这样?我知道这与如何选择重载方法有关,但我找不到一个资源来精确指定如何确定选择哪些方法以及何时选择。如果有人可以解释确切的过程,我将不胜感激。