Scala中的泛型:实现两次接口/特征?

时间:2011-09-27 07:37:48

标签: c# java generics 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中实现这样的事情吗?

2 个答案:

答案 0 :(得分:12)

没有。只有在Scala(界面)用符合的类型进行参数化的2种类型中才能在Scala中混合使用相同的特征,并且特征不会混合到同一个类中两次直接即可。为确保两种类型相互一致,通常必须使类型参数协变(+)。

例如,不允许这样做:

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中的所有方法符合签名的签名将在一种方法中与最具体的签名融合,根据linearization rules选择方法,而不是每次混合特征时都使用一种方法。

答案 1 :(得分:10)

不,它不能。一般来说,我在这种情况下做的是

class C {
  object IInt extends I[Int] { ... }
  object IString extends I[String] { ... }
  ...
}