为什么此代码中对重载定义的引用不明确?



为什么此代码中对重载定义的引用不明确?

class A {
def m(a1: A, o2: Any): A = {
print("1")
a1
}
def m(a1: A, a2: A): A = {
print("2")
a1
}
def m(o1: Any, o2: Any): Any = {
print("3")
o1
}
def m(o: Any): Any = {
print("4")
o
}
}
class B extends A {
def m(b1: B, o2: Any): A = {
print("5")
b1
}
override def m(a: A, o2: Any): B = {
print("6")
this
}
override def m(o1: Any, o2: Any): Any = {
print("7")
o1
}
def m(i: Int): Unit = { print("8") }
}
val a = new A
val b = new B
b.m(a, a)

上面的代码给出了编译错误:

对重载定义的模糊引用,

[错误] 类型 B 中的两个方法 m (a: A, o2: Any(B

类型 A 中的 [错误]和方法 m (a1: A, a2: A(A [错误] 匹配 参数类型(A、B(

但我的理解是method m in class A of type (a1: A, a2: A)A更具体 比method m in class B of type (a: A, o2: Any)B

任何提示都值得赞赏。

你说得完全正确 -Am的版本更具体,这实际上是问题所在。

由于您实际上是在b实例上调用m(即。b.m(a, a)(编译器首先检查是否存在与B中的签名匹配的方法。由于B确实有一个通过类型检查的方法(即。m(a: A, o2: Any): B(到目前为止一切顺利。但是,虽然编译器也检查超类A但它会找到更具体的m版本(即。m(a1: A, a2: A): A(。

问题是您在B实例上调用了m,但您显式要求编译器找到一个接受两个类型为A的参数的方法。编译器现在不确定您实际打算执行哪个版本,因此会出现编译错误。

更好的编译消息可能是:

"嘿,我在A中找到了一个更符合您要求的层次结构m版本,但我看到您是在B(不是A(上显式调用m,所以我真的不知道现在该选择哪一个 - 你最好检查一下,否则如果我只选择一个,你可能无法得到你在运行时想要的结果。">

最新更新