以下代码给出了错误:
package test
trait Base {
def method:String
}
trait Trait extends Base {
def method()(implicit i:String):String = { "2" }
}
object Object extends Trait {
}
Run Code Online (Sandbox Code Playgroud)
错误是"对象创建不可能,因为类型为Base的方法方法=>字符串未定义"
以下错误由以下代码修复
package test
trait Base {
def method:String
}
trait Trait extends Base {
def method:String = method()("String") // Over loading
def method()(implicit i:String):String = { "2" }
}
object Object extends Trait {
}
Run Code Online (Sandbox Code Playgroud)
现在我代替Scala类,当我定义一个Java接口时,如下所示:
// Java Code
package test;
public interface JBase {
String method();
}
// Scala Code
package test
trait Trait extends JBase {
def method:String = method()("10")
def method()(implicit i:String):String = { "2" }
}
object Object extends Trait {
}
Run Code Online (Sandbox Code Playgroud)
我得到一个错误"对重载定义的模糊引用,特征中的方法方法Traint of type()(隐式i:String)特征中的字符串和方法方法类型的特征()字符串匹配参数类型()"
这两种场景的不同之处在于编译器的行为方式有何不同?我该如何解决这个问题?
这是一个我认为清楚显示正在发生的事情的例子:
object Test extends App {
class A { def f(): String = "x" }
class B extends A { override def f: String = "y" }
class C { def f: String = "z" }
println { (new A).f() } // OK
println { (new B).f() } // OK
println { (new C).f() } // FAILS
}
Run Code Online (Sandbox Code Playgroud)
A:有括号的括号,一切都好.B:没有括号,但超类型确实有括号,所以仍然很好.这符合您的情况.C:没有括号,括号括起来,没有好处.基本上,Java方法总是被认为是"括号",因此,Trait超类型具有括号,因此使用括号method()("string")不足以阐明您的方法.
编辑:老实说,我认为你最好重命名方法.即使在没有歧义的情况下,行为也可能非常令人惊讶:
trait Trait {
def method: String = method()("x")
def method()(implicit i: String): String = i
}
val t = new Trait { }
implicit val s = "y"
println { t.method }
> "x"
println { t.method() }
> "y"
Run Code Online (Sandbox Code Playgroud)
此外,名称相同的事实并不是就多态性而购买任何东西:只有非隐式方法覆盖Base.method- 这只是一个美学决定,使名称相同.