首页 文章

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

提问于
浏览
12

给定一个通用接口,如下所示

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 回答

  • 12

    不可以在Scala中进行混合只有在Scala中才能进行混合(如果2种类型,其中特征(接口)被参数化为彼此的类型 conform 并且特征没有被混合到同一个类中两次 directly . 为确保两种类型相互一致,通常必须使类型参数协变( + ) .

    例如,这是不允许的:

    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#那样获得 overloading 语义,但 overriding 语义 - 具有符合签名的 A 中的所有方法将在具有最特定签名的一种方法中融合,根据方法选择方法linearization rules,而不是每次混合特征时都有一种方法 .

  • 10

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

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

相关问题