2009-09-24 68 views
4

假設我們有以下的Java接口:如何在Scala中擴展包含泛型方法的Java接口?

// Java 
public interface Foo { 
    <T> T bar(Class<T> c); 
} 

我應該如何在斯卡拉其擴展?寫

// Scala 
class FooString extends Foo { 
    override def bar(c: Class[String]): String = "hello, world"; 
} 

將導致編譯拋出「類FooString需要是抽象的,因爲在類型的性狀的Foo [T ]沒有定義(類[T])T法吧」。

在此先感謝!

更新: 醜陋的真相是:我錯誤地理解了Java中的泛型。

在任何情況下,我的困境的解決方案都顯示在Nicolas和Walter的答案中,儘管我更喜歡Walter的答案,因爲它不那麼冗長。

+0

你終於明白了!很高興你已經理解你對泛型的錯誤。 不客氣。 – Nicolas 2009-09-30 15:01:56

回答

3

這工作:

class FooString extends Foo { 
    def bar[String](c: Class[String]): String = "hello world".asInstanceOf[String] 
} 

val fs = new FooString 
println(fs.bar(classOf[String])) 

編輯:

從@Eastsun的意見是正確的。由於bar是類型參數爲T的泛型方法,因此Scala中bar的實現也必須是一個通用方法。我認爲在Scala中實現Foo的正確方法如下:

class FooString extends Foo { 
    def bar[T](c: Class[T]): T = c.newInstance.asInstanceOf[T] // c gotta have a default constructor 
} 

val fs = new FooString 
println(fs.bar(classOf[String]).getClass) // prints "class java.lang.String" 
println(fs.bar(classOf[java.util.Date]).getClass) // prints "class java.util.Date" 
+1

實際上,它並不像您期望的那樣工作。 FooString#bar方法中的「String」不是java.lang.String類型,而是Foo中的類型參數「T」。 所以你可以寫一些像fs.bar(classOf [Int])並編譯OK,但運行時會出現異常。 – Eastsun 2009-09-24 16:38:40

1

你可以改變這樣的:

public interface Foo<T> { 
    T bar(Class<T> c); 
} 

class FooString extends Foo[String] { 
    override def bar(c: Class[String]): String = "hello, world"; 
} 
+1

實際上,Java接口是第三方API,所以我必須照原樣使用它。 – shaolang 2009-09-25 01:01:12

+0

據我所知,沒有辦法用一種特殊的類型方法覆蓋泛型方法。 – Eastsun 2009-09-25 08:38:03

6

它不起作用,因爲您沒有正確實現接口。你的方法N階的siganture必須是:

def bar[T](c:Class[T]):T 

您可以修復只是如果你想噸實現富絃樂的行爲。

三試,根據我們的討論:

def bar[T](c:Class[T]):T = { 
    // Some stuff 
    val o:Any = myUntypedFunction(env) 
    c.cast(o) 
} 

按照myUntypedFunction將創建一個對象的背景,然後你使用類參數來投你的結果,並獲得一件T對象。 再一次:在java和scala中這種行爲是一樣的。

+0

這是我的問題:我如何進行簽名比賽? – shaolang 2009-09-25 08:29:26

+0

你不能。您嘗試更改界面,這不是一個scala問題,它是一個編程問題。接口說:「接受任何類並返回這個類的結果」,你的實現說「接受任何字符串類並返回一個字符串」。 bar的實現必須使用cast(),newInstance或一個構造函數來從對象c構建一個T. – Nicolas 2009-09-25 08:42:07

+0

這只是一個人爲的例子;我遇到的實際問題需要我實現一個包含參數化類型的Java接口,類似於我給出的示例。 如果沒有辦法做到這一點,即使這可能是一個邊緣情況,那麼它是一個scala問題,因爲它不完全兼容Java。 – shaolang 2009-09-25 09:51:03