Le problème n'est pas la covariance elle-même. (En particulier, s'il y avait contra-variance, Design-by-Contract serait impossible, car les types d'arguments dans les caractéristiques des classes descendantes n'auraient pas forcément de caractéristiques disponibles chez leurs parents, avec covariance il n'y a pas de problème.)
Problematic est une combinaison de covariance et de polymorphisme. Par exemple.
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
maintenant le code suivant plantait:
a: A; b: B
...
create b
a := b
a.foo (create {A})
En effet, a.foo
appellerait la version (2) parce que a
est attaché à un objet de type B
. Toutefois, l'argument transmis à cette fonctionnalité sera de type A
. Et A
n'a aucune fonctionnalité qux
qui conduit à une erreur d'exécution. Ce type d'erreur est appelé appel CAT (Modification de la disponibilité ou type).
Une solution à ce problème consiste à éviter d'utiliser la covariance avec le polymorphisme, c'est-à-dire qu'un appel ne devrait pas être polymorphe ou qu'il ne devrait pas y avoir de redéclaration d'arguments covariante. Le travail sur cette solution est en cours.