开发者

Generics in Scala: implementing an interface/trait twice?

开发者 https://www.devze.com 2023-04-08 20:51 出处:网络
Given a generic interface such as the following interface I<T> { void m(T t); } I can in C# create a class that implements I twice (or more) with different types supplied for T, e.g.

Given a generic interface such as the following

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

I can in C# create a class that implements I twice (or more) with different types supplied for T, e.g.

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

This cannot be done in Java due to erasure of the generic type info, but can something like this be 开发者_如何学运维achieved in Scala?


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.


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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号