Generics in Scala: implementing an interface/trait twice?
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] { ... }
...
}
精彩评论