Ковариантность и контравариантность (программирование): различия между версиями

[отпатрулированная версия][отпатрулированная версия]
Содержимое удалено Содержимое добавлено
уточнение
Изменено название языка на правильное англоязычное, без употребления транслитов.
Строка 51:
Ковариантность типов возврата методов реализована в [[Java]] начиная с [[Java Platform, Standard Edition|J2SE 5.0]]. В параметрах методов ковариантности нет: для перекрытия виртуального метода типы его параметров должны совпадать с определением в родительском классе, иначе вместо перекрытия будет определён новый [[Перегрузка процедур и функций|перегруженный метод]] с этими параметрами.
 
Массивы в ДжавеJava ковариантны с самой первой версии, когда в языке ещё не было [[Обобщённое программирование|обобщенных типов]]. (Если бы этого не было, то для использования, например, библиотечного метода, принимающего массив объектов <code>Object[]</code>, для работы с массивом строк <code>String[]</code>, требовалось бы его сначала скопировать в новый массив <code>Object[]</code>.) Поскольку, как было сказано выше, при записи элемента в такой массив можно обойти контроль типов, в [[JVM]] существует дополнительный контроль во время выполнения, генерирующий [[Обработка исключений|исключение]] при записи некорректного элемента.
 
Обобщённые типы в ДжавеJava инвариантны, поскольку вместо создания универсального метода, работающего с Object’ами, можно его параметризовать, превратив в обобщённый метод и сохранив контроль типов.
 
Вместе с тем в ДжавеJava можно реализовать своего рода ко- и контравариантность обобщенных типов, используя символ-джокер и уточняющие спецификаторы: <code>List<? extends Animal></code> будет ковариантен подставляемому типу, а <code>List<? super Animal></code> — контравариантен.
 
=== C# ===
В языке [[C Sharp|C#]], начиная с первой его версии, массивы ковариантны. Это было сделано для совместимости с языком Java<ref>{{cite web|url=http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx|title=Covariance and Contravariance in C#, Part Two|author=Eric Lippert|date=2007-10-17|accessdate=2013-06-22|archiveurl=http://www.webcitation.org/6Hhy8OCuN|archivedate=2013-06-28}}</ref>. При попытке записать в массив элемент неверного типа выбрасывается [[Обработка исключений|исключение]] во время выполнения.
 
Обобщённые классы и интерфейсы, появившиеся в C# 2.0, стали, как и в ДжавеJava, инвариантными по типу-параметру.
 
С введением обобщённых делегатов (параметризированных по типам аргументов и возвращаемым типам), язык позволил автоматическое преобразование обычных методов к обобщённым делегатам с ковариантностью по возвращаемым типам и контравариантностью по типам аргументов. Поэтому в C# 2.0 стал возможен код следующего вида: