Scala in Depth给出了这个关于协方差的例子。
使用协变参数定义类T
。协变意味着实例化T[+A]
是合法的,前提是参数是子类型或等于A
的类型。
scala> class T[+A] {}
defined class T
使用 AnyRef
实例化T[...]
。
scala> val x = new T[AnyRef]
x: T[AnyRef] = T@11e55d39
然后,将x
分配给T[Any]
。 Any
是AnyRef
的父级。
因此,我们可以创建一个带有T[AnyRef]
的T[Any]
,因为AnyRef
是 Any
的子类型 .
scala> val y : T[Any] = x
y: T[Any] = T@11e55d39
但是,我们不能对T[String]
做同样的事情,因为Any
不是"字符串"的子类型。
scala> val z : T[String] = x
<console>:7: error: type mismatch;
found : T[AnyRef]
required: T[String]
val z : T[String] = x
这种理解正确吗?
你基本上是对的。我只想这样说:
- 由于
String
是AnyRef
的一个子类型,T[String]
是T[AnyRef]
的一个子类型。 - 由于
Integer
是AnyRef
的子类型,T[Integer]
是T[AnyRef]
的子类型。
所以我可以说
var s:T[AnyRef] = new T[String]
val i:T[AnyRef] = new T[Integer]
s = i
其实,不,我不能说第三行。
我不应该被允许这样做,因为这可能意味着T
正在做一些仅适用于Integer
的事情,而它现在可以对String
做的事情。
因此,您可以使用类型边界来解决它。