2013-03-06 72 views
4

这感觉真的很基础;我很抱歉。“压倒一切”继承差异

考虑

trait Foo[+T] { def t : T } 
trait Bar[+S,+T] extends Foo[T] { def s : S } 
trait Baz[+S,T] extends Foo[T] { def s : S } 

是否T在富协方差自动适用于巴兹,即使T IN巴兹没有标记为协变? Bar和Baz的行为会有什么有意义的区别吗?如果它们是相同的,不知何故,它觉得肮脏,巴兹形式不会警告或表示错误,因为单看巴兹,你会期望T不会出现)

+0

编译器将执行一定的方差,你将不能够使用任何通用类与它们的方差不一致的方式(即,值轴承其类型参数)。 – 2013-03-06 02:53:46

+0

谢谢! (我想我明白了;见下面的回答,如果你想了解什么使我困惑。) – 2013-03-06 02:57:18

回答

5

不,Baz[T]不会继承Foo[+T]的协方差。协变性必须明确标记。下面是一个例子,作为指定

class Foo[+T] {} 
class Baz[T] extends Foo[T] {} 

(new Foo[String]) : Foo[Any] // Ok: Foo[+T] is covariant 
(new Baz[String]) : Foo[Any] // Ok: Baz[String] <: Foo[String] <: Foo[Any] 
(new Baz[String]) : Baz[Any] // Error: Baz[T] is invariant in type T 
+0

谢谢!我想我看到了我的困惑。方差不会被覆盖也不会继承 - 它只与Foo类型保持一致,但与子类型Baz无关。所以Baz [String]符合Foo [Any],但不符合Baz [Any]。我没有考虑这种可能性:我推测如果它在Foo中保持协变,它也会在Baz中协变。我将不得不修改一些关于继承的错误的直觉。 – 2013-03-06 02:53:33

+0

对。用不变的'Baz'子类化协变'Foo'不能去除'Foo'的协变性。 – 2013-03-06 02:59:03