簡體   English   中英

Scala和Java - 隱式參數和繼承

[英]Scala and Java - Implicit Parameters and Inheritance

以下代碼給出了錯誤:

package test

trait Base {
  def method:String
}

trait Trait extends Base {
  def method()(implicit i:String):String = { "2" }
}

object Object extends Trait {

}

錯誤是“對象創建不可能,因為類型為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 {

}

現在我代替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 {

}

我得到一個錯誤“對重載定義的模糊引用,特征中的方法方法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
}
  • 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"

此外,名稱相同的事實並不是就多態性而購買任何東西:只有非隱式方法會覆蓋Base.method - 這只是一個美學決定,使名稱相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM