Aujourd'hui, j'ai lu quelques articles sur la Covariance, la Contravariance (et l'Invariance) en Java. J'ai lu l'article de Wikipédia en anglais et en allemand, ainsi que d'autres articles de blog et articles d'IBM.
Mais je suis toujours un peu confus sur ce que c'est exactement? Certains disent qu'il s'agit de la relation entre les types et les sous-types, certains disent qu'il s'agit de conversion de type et certains disent qu'elle est utilisée pour décider si une méthode est remplacée ou surchargée.
Je cherche donc une explication simple en anglais simple, qui montre à un débutant ce que sont la covariance et la contravariance (et l'invariance). Point plus pour un exemple simple.
Réponses:
Tout ce qui précède.
Au fond, ces termes décrivent comment la relation de sous-type est affectée par les transformations de type. Autrement dit, si
A
etB
sont des types,f
est une transformation de type, et ≤ la relation de sous-type (c'est-à-direA ≤ B
signifie queA
c'est un sous-type deB
), nous avonsf
est covariant si celaA ≤ B
implique quef(A) ≤ f(B)
f
est contravariant si celaA ≤ B
implique quef(B) ≤ f(A)
f
est invariant si aucune des réponses ci-dessus ne tientPrenons un exemple. Soit
f(A) = List<A>
oùList
est déclaré parEst-ce
f
covariant, contravariant ou invariant? Covariant signifierait que aList<String>
est un sous-type deList<Object>
, contravariant que aList<Object>
est un sous-type deList<String>
et invariant que ni l'un ni l'autre n'est un sous-type de l'autre, c'estList<String>
-à- dire etList<Object>
sont des types inconvertibles. En Java, ce dernier est vrai, nous disons (de manière informelle) que les génériques sont invariants.Un autre exemple. Laissez
f(A) = A[]
. Est-cef
covariant, contravariant ou invariant? Autrement dit, String [] est-il un sous-type de Object [], Object [] un sous-type de String [], ou n'est-il pas un sous-type de l'autre? (Réponse: en Java, les tableaux sont covariants)C'était encore assez abstrait. Pour le rendre plus concret, regardons quelles opérations en Java sont définies en termes de relation de sous-type. L'exemple le plus simple est l'affectation. La déclaration
ne compilera que si
typeof(y) ≤ typeof(x)
. Autrement dit, nous venons d'apprendre que les déclarationsne compilera pas en Java, mais
volonté.
Un autre exemple où la relation de sous-type est importante est une expression d'invocation de méthode:
De manière informelle, cette instruction est évaluée en attribuant la valeur de
a
au premier paramètre de la méthode, puis en exécutant le corps de la méthode, puis en affectant la valeur de retour des méthodes àresult
. Comme l'affectation simple dans le dernier exemple, le "côté droit" doit être un sous-type du "côté gauche", c'est-à-dire que cette déclaration ne peut être valide que sitypeof(a) ≤ typeof(parameter(method))
etreturntype(method) ≤ typeof(result)
. Autrement dit, si la méthode est déclarée par:aucune des expressions suivantes ne sera compilée:
mais
volonté.
Un autre exemple où le sous-typage est primordial. Considérer:
où
De manière informelle, le runtime réécrira ceci pour:
Pour que la ligne marquée soit compilée, le paramètre de méthode de la méthode de remplacement doit être un supertype du paramètre de méthode de la méthode remplacée et le type de retour un sous-type de celui de la méthode remplacée. Formellement parlant,
f(A) = parametertype(method asdeclaredin(A))
doit au moins être contravariante, et si ellef(A) = returntype(method asdeclaredin(A))
doit au moins être covariante.Notez le "au moins" ci-dessus. Ce sont des exigences minimales que tout langage de programmation orienté objet sécurisé de type statique raisonnable imposera, mais un langage de programmation peut choisir d'être plus strict. Dans le cas de Java 1.4, les types de paramètres et les types de retour de méthode doivent être identiques (sauf pour l'effacement de type) lors de la substitution de méthodes, c'est-
parametertype(method asdeclaredin(A)) = parametertype(method asdeclaredin(B))
à- dire lors de la substitution. Depuis Java 1.5, les types de retour covariants sont autorisés lors de la substitution, c'est-à-dire que les éléments suivants seront compilés en Java 1.5, mais pas en Java 1.4:J'espère que j'ai tout couvert - ou plutôt, rayé la surface. J'espère toujours que cela aidera à comprendre le concept abstrait mais important de la variance de type.
la source
A ≤ B
. Cette notation rend les choses beaucoup plus simples et significatives. Bonne lecture ...Prenant le système de type java, puis les classes:
Tout objet d'un certain type T peut être remplacé par un objet d'un sous-type de T.
VARIANCE DE TYPE - LES MÉTHODES DE CLASSE ONT LES CONSÉQUENCES SUIVANTES
On peut voir que:
Maintenant co- et contre- se rapportent au sous-type B de A. Les typages plus forts suivants peuvent être introduits avec des connaissances plus spécifiques. Dans le sous-type.
La covariance (disponible en Java) est utile, pour dire que l'on renvoie un résultat plus spécifique dans le sous-type; surtout vu quand A = T et B = S. Contravariance dit que vous êtes prêt à gérer un argument plus général.
la source
La variance concerne les relations entre les classes avec différents paramètres génériques. Leurs relations sont la raison pour laquelle nous pouvons les lancer.
La variance Co et Contra sont des choses assez logiques. Le système de type de langage nous oblige à prendre en charge la logique réelle. C'est facile à comprendre par l'exemple.
Covariance
Par exemple, vous voulez acheter une fleur et vous avez deux magasins de fleurs dans votre ville: un magasin de roses et un magasin de marguerites.
Si vous demandez à quelqu'un "où est le magasin de fleurs?" et quelqu'un vous dit où est le magasin de roses, est-ce que ça ira? oui, parce que la rose est une fleur, si vous voulez acheter une fleur, vous pouvez acheter une rose. Il en va de même si quelqu'un vous a répondu avec l'adresse de la marguerite. Voici un exemple de covariance : vous êtes autorisé à effectuer un cast
A<C>
versA<B>
, oùC
est une sous-classe deB
, siA
produit des valeurs génériques (retourne comme résultat de la fonction). La covariance concerne les producteurs.Les types:
La question est "où est le magasin de fleurs?", La réponse est "magasin de roses là-bas":
Contravariance
Par exemple, vous souhaitez offrir une fleur à votre petite amie. Si votre petite amie aime une fleur, pouvez-vous la considérer comme une personne qui aime les roses ou comme une personne qui aime les marguerites? oui, car si elle aime une fleur, elle aimerait à la fois la rose et la marguerite. Voici un exemple de contravariance : vous êtes autorisé à effectuer un cast
A<B>
versA<C>
, oùC
est la sous-classe deB
, siA
consomme une valeur générique. La contravariance concerne les consommateurs.Les types:
Vous considérez votre petite amie qui aime toutes les fleurs comme quelqu'un qui aime les roses et vous lui donnez une rose:
Vous pouvez en trouver plus à la Source .
la source