2013-01-13 79 views
4

下面的代碼給出了一個錯誤:Scala和爪哇 - 隱參數和繼承

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接口作爲FOL低點:

// 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 { 

} 

我碰到一個錯誤「曖昧參照重載定義類型(性狀性狀,既方法方法)(隱式I:字符串)的類型()字符串匹配的性狀性狀字符串和方法方法參數類型()「

在這兩種情況下,編譯器的行爲有何不同?我該如何解決這個問題?

+3

帶圓括號的方法不能覆蓋沒有 – 4lex1v

+1

的方法另外,我會讓它成爲一個一般的經驗法則,如果你在Scala中重載,那麼你做錯了什麼.___ – Apocalisp

+0

什麼是重載的替代方法?這裏的java接口不受我控制,即它是庫的一部分。我認爲使用隱式是一種很酷的方式來維護api調用的庫簽名,同時增加額外的功能。 – 0n4li

回答

7

下面是我想展示了一個例子清楚是怎麼回事:

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 - 這只是一個美化決定,使名稱相同。

+0

那麼你會如何解決這個問題?我有一個來自編譯Jar的Java接口。我認爲隱式參數是一個很酷的技巧。我想維護接口的簽名,並添加一個我想隱式設置的參數。 – 0n4li

+0

@ 0n4li看我的編輯。也許你想要的將取決於'method()'的作用以及爲什麼你重寫'Base',但是因爲這對我來說看起來太冒險了,所以名稱保持不變。 – Owen