2011-09-27 68 views
12

給定一個通用接口,如下面Scala中的泛型:實現一個接口/特徵兩次?

interface I<T> { 
    void m(T t); 
} 

我可以在C#創建實現予兩次(或更多個)與T,例如提供不同類型的一個類

class C : I<int>, I<String> { 
    public void m(int i) { } 
    public void m(String s) { } 
} 

這不能在Java中完成,因爲擦除了泛型類型信息,但是在Scala中可以實現類似的功能嗎?

+0

您能在Scala代碼中描述您想要做什麼嗎?這裏的很多人都不熟悉C#。 – Jus12

+0

那麼,我並不是那麼熟悉Scala(試圖學習:))。但是,只要知道此設置中的「C類」之後的「:」表示Java中的「實現」,上述代碼對於任何瞭解Java的人都應該很容易理解。我在Scala中嘗試的是讓我成爲一個特性(只需用「trait」替換「interface」),然後將C定義爲「class C用I {...」擴展I ,但這不起作用。 – Eyvind

+0

在Scala中,泛型類型包含在'[]'中,所以你可以這樣做'I [Int]'和'I [String]'。你有沒有在聲明中使用'ClassManifest'? – Jus12

回答

12

號混合是唯一可能的,如果2種與性狀(接口)與符合彼此和參數化類型該特性不會混入同一班級兩次直接。爲確保兩種類型相互一致,您通常必須使類型參數協變(+)。

例如,這是不允許的:

scala> trait A[+T] { def foo: T = sys.error() } 
defined trait A 

scala> class C extends A[AnyRef] with A[String] 
<console>:8: error: trait A is inherited twice 
     class C extends A[AnyRef] with A[String] 

但這是:

scala> trait A[+T] { def foo: T = sys.error() } 
defined trait A 

scala> class C extends A[AnyRef] 
defined class C 

scala> class B extends C with A[String] 
defined class B 

注意,在這種情況下,你不會得到超載語義是用C#的情況下,但是覆蓋了語義 - 具有符合簽名的A中的所有方法都將在一種方法中與最具體的簽名融合,選擇方法d根據linearization rules,而不是每次混入特質時都有一種方法。

10

不,它不能。一般我在這種情況下做Scala是在同一性狀

class C { 
    object IInt extends I[Int] { ... } 
    object IString extends I[String] { ... } 
    ... 
} 
相關問題