2011-09-27 66 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] { ... } 
    ... 
} 
相关问题