gnu*_*nce 9 oop methods scala overloading
在Scala中,您可以通过使用共享公共名称但具有不同arities或不同参数类型的方法来重载方法.我想知道为什么这也没有扩展到方法的返回类型?请考虑以下代码:
class C {
def m: Int = 42
def m: String = "forty two"
}
val c = new C
val i: Int = C.m
val s: String = C.m
Run Code Online (Sandbox Code Playgroud)
有什么理由不适用吗?
谢谢,
文森特.
实际上,你可以通过"隐含"的魔力使它发挥作用.如下:
scala> case class Result(i: Int,s: String)
scala> class C {
| def m: Result = Result(42,"forty two")
| }
scala> implicit def res2int(res: Result) = res.i
scala> implicit def res2str(res: Result) = res.s
scala> val c = new C
scala> val i: Int = c.m
i: Int = 42
scala> val s: String = c.m
s: String = forty two
scala>
Run Code Online (Sandbox Code Playgroud)
你当然可以有超载的,其返回类型不同,只是不适合哪些不同方法的方法只有通过返回类型.例如,这很好:
def foo(s: String) : String = s + "Hello"
def foo(i: Int) : Int = i + 1
Run Code Online (Sandbox Code Playgroud)
除此之外,你的问题的答案显然是一个设计决定:返回类型是方法签名的一部分,因为任何有经验的人都AbstractMethodError可以告诉你.
但是请考虑如何允许这样的重载可以与子类型一起使用:
class A {
def foo: Int = 1
}
val a: A = //...lookup an A
val b = a.foo
Run Code Online (Sandbox Code Playgroud)
这当然是完全有效的代码,并且javac将唯一地解析方法调用.但是如果我将子类分类A如下:
class B extends A {
def foo: String = "Hello"
}
Run Code Online (Sandbox Code Playgroud)
这会导致原始代码解析被调用的方法被破坏.应该b是什么?我通过对某些现有类进行子类型化来逻辑地破坏了一些现有代码,即使我没有更改该代码或该类.
小智 6
主要原因是复杂性问题:使用"正常"编译器方法,从内到外(从内部表达式到外部范围),逐步构建二进制文件; 如果添加仅返回类型的区分,则需要更改为回溯方法,这会大大增加编译时间,编译器复杂性(=错误!).
此外,如果您返回一个可以自动转换为另一个的子类型或类型,您应该选择哪种方法?您会为完全有效的代码提供歧义错误.
不值得麻烦.
总而言之,您可以轻松地重构代码以避免仅返回类型的重载,例如通过添加要返回的类型的虚拟参数.