Ковариантность — это сохранение иерархии наследования исходных типов в производных типах в том же порядке.
Например, если тип Кошка наследуется от типа Животное, что массив ЧитаемыйМассив<Кошка> будет потомком массива ЧитаемыйМассив<Животное>. Действительно, «список из пяти кошек» — это частный случай «списка из пяти животных».
В таком случае говорят, что тип ЧитаемыйМассив<T> ковариантен своему параметру-типу T.
Для обобщенных типов, допускающих запись объектов (например, тип Массив<>), ковариантность неприменима, так как позволяет обойти контроль типов.
Например, если бы массив Массив<Кошка> был ковариантен и являлся потомком Массив<Животное>, то в массив кошек можно было бы добавить собаку (которая тоже является животным), что привело бы к ошибке при работе с элементами массива (подробнее).
См. также