Generics in Scala: implementing an interface/trait twice?

前端 未结 2 2027
無奈伤痛
無奈伤痛 2021-02-19 21:09

Given a generic interface such as the following

interface I {
    void m(T t);
}

I can in C# create a class that implements I twice (o

相关标签:
2条回答
  • 2021-02-19 21:19

    No. Mixing in the same trait is only possible in Scala if the 2 types with which the trait (interface) is parametrized with types that conform to each other and the trait is not mixed into the same class twice directly. To ensure that the 2 types conform to each other, you will generally have to make the type parameter covariant (+).

    For example, this is not allowed:

    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]
    

    But this is:

    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
    

    Note that in this case you will not obtain the overloading semantics as is the case with C#, but the overriding semantics - all the methods in A with the conforming signature will be fused in one method with the most specific signature, choosing the method according to linearization rules, rather than having one method for each time you've mixed the trait in.

    0 讨论(0)
  • 2021-02-19 21:34

    No, it can't. Generally what I do in this case is

    class C {
      object IInt extends I[Int] { ... }
      object IString extends I[String] { ... }
      ...
    }
    
    0 讨论(0)
提交回复
热议问题