Проблема не в самой ковариации. (В частности, если бы это была контрвариантность, проектирование по контракту было бы невозможно, потому что типы аргументов в функциях классов-потомков не обязательно имели бы функции, доступные в их родителях. С ковариантностью такой проблемы нет.)
Проблемным является сочетание ковариантности с полиморфизмом. Например.
class A feature
foo (a: A) do a.bar end -- (1)
bar do end
end
class B inherit A redefine foo end feature
foo (a: B) do a.qux end -- (2)
qux do end
end
Теперь следующий код вылетит:
a: A; b: B
...
create b
a := b
a.foo (create {A})
Действительно, a.foo
вызовет версию (2), потому что a
присоединен к объекту типа B
. Однако аргумент, передаваемый этой функции, будет иметь тип A
. И A
не имеет функции qux
, которая приводит к ошибке во время выполнения. Такая ошибка называется CAT-вызовом (Изменение доступности или типа).
Решение этой проблемы состоит в том, чтобы избежать использования ковариантности вместе с полиморфизмом, т. е. вызов не должен быть полиморфным или не должно быть ковариантного переобъявления аргументов. Работа над этим решением продолжается.
person
Alexander Kogtenkov
schedule
13.12.2016