Ответ 1
В примере 1 +A
не является ограничением на A. Любой тип может быть параметром Foo. Это ограничение на Foo
. Это означает, что в интерфейсе Foo
, A
может появляться только в ковариантной позиции (в скором времени это может быть результат метода, но не параметр метода).
Наличие Bar
не ковариантного означает, что интерфейс Bar не удовлетворяет одному и тому же ограничению (или, по крайней мере, не рекламирует его), поэтому, возможно, в Bar
был добавлен метод с параметром A
. Это довольно часто. Например, существует collection.Seq[+A]
, и оно расширяется на collection.mutable.Seq[A]
. Это не создает проблем. Если Y <: X
, a Bar[Y]
не является Bar[X]
, но все равно a Foo[X]
.
С другой стороны, в примере 2 A[+_]
является ограничением на A
. Только типы с параметром ковариантного типа могут быть параметрами Foo. Код Foo
, вероятно, использует это ограничение, например назначение A[String]
в A[Any]
где-то в коде Foo
.
Тогда разрешение Bar
на создание нековариантного типа было бы необоснованным. Код, унаследованный от Foo
, все еще можно вызвать и присвоить A[String]
A[Any]
, когда A
больше не ковариантно.
Очень похожая проблема со звуком будет возникать в любое время, когда вы позволите снять ограничение на общий параметр. Предположим, что у вас есть Foo[X <: Ordered[X]]
(или Foo[X : ordering]
), и у вас есть метод sort
в Foo
. Предположим, что Bar[X] extends Foo
разрешено. Возможно, ничто в коде Bar
не требует X
для упорядочивания, но тем не менее sort
будет вызываемым, и, несомненно, будет неверно работать с элементами, которые нельзя упорядочить.
Относительно вашего вопроса в комментарии с помощью Traversable [+ Elem, + Col [+ _]] и расширения этого в make mutable class:
технически, да, вы можете расширить его и поместить в него var youCanMutateThat : Elem = _
. Наверное, это не то, что вы ищете. Но я предполагаю, что ваш план позволит использовать расширение с изменчивым Col, и я не думаю, что вы можете это сделать по указанной выше причине. Но почему, почему у вас есть ограничение Col [+ _] в первую очередь?