can someone explain why the code below doesn't work?
scala> abstract class A[T] {}
defined class A
scala> class B {}
defined class B
scala> object C extends A[B] {}
defined object C
scala> def method(arg: A[Any]): Unit = {}
method: (arg: A[Any])Unit
scala> method(C)
<console>:14: error: type mismatch;
found : C.type
required: A[Any]
Note: B <: Any (and C.type <: A[B]), but class A is invariant in type T.
You may wish to define T as +T instead. (SLS 4.5)
method(C)
A
method
public void method(A<?> arg) {}
?
+
+T
The code does not work because if you want to use generics in variant or contravariant in Scala, you have to declare it explicitly. Otherwise, the Java invariant behaviour is implemented.
Java is by default invariant. This means that if A
<
B
, thenList[A]
and List[B]
do not have any hierachical relationship between them.
Scala lets you to use declare generic type as covariant or contravariant, which means
A
<
B
, thenList[A]
<
List[B]
. To do this, you have to declare the generic using the syntax class A[+T]
A
<
B
, thenList[A]
>
List[B]
. To do this, you have to declare the generic using the syntax class A[-T]