[java] Pourquoi n'y a-t-il pas de paramètre contre-variance pour la substitution?


2 Answers

class A {
    public void f(String s) {...}
    public void f(Integer i) {...}
}

class B extends A {
    public void f(Object o) {...} // Which A.f should this override?
}
Question

C ++ et Java prennent en charge la covariance de type retour lors du remplacement de méthodes.

Cependant, ni l'un ni l'autre ne prend en charge la contre-variance dans les types de paramètres - à la place, cela se traduit par une surcharge (Java) ou un masquage (C ++).

Pourquoi c'est ça ? Il me semble qu'il n'y a pas de mal à permettre cela. Je peux trouver une raison pour cela en Java - car de toute façon il a le mécanisme de "choisir la version la plus spécifique" pour la surcharge - mais ne peut penser à aucune raison pour C ++.

Exemple (Java):

class A {
    public void f(String s) {...}
}
class B extends A {
    public void f(Object o) {...} // Why doesn't this override A.f?
}



Grâce aux réponses de donroby et de David, je crois comprendre que le principal problème de l’introduction de la contre-variance des paramètres est l’ intégration au mécanisme de surcharge .

Donc, non seulement il y a un problème avec une seule substitution pour plusieurs méthodes, mais également dans l'autre sens:

class A {
    public void f(String s) {...}
}

class B extends A {
    public void f(String s) {...} // this can override A.f
    public void f(Object o) {...} // with contra-variance, so can this!
}

Et maintenant, il y a deux substitutions valides pour la même méthode:

A a = new B();
a.f(); // which f is called?

Outre les problèmes de surcharge, je ne pouvais penser à rien d’autre.

Edit: J'ai depuis trouvé cette entrée FQA C ++ (20.8) qui correspond à ce qui précède - la présence de surcharge crée un problème sérieux pour la contre-variance des paramètres.




Bien que ce soit un beau langage dans n'importe quel langage, je dois toujours l'appliquer à mon travail actuel.

Peut-être n'y en a-t-il pas vraiment besoin.




Related