Voici ma compréhension.
Supposons que nous ayons un type générique avec 2 méthodes
type L<T>
T get();
void set(T);
Supposons que nous avons un type super P
, et il a sous-types C1, C2 ... Cn
. (Pour plus de commodité, nous disons P
est un sous-type de lui-même, et est en fait l'un des Ci
)
Maintenant, nous avons également obtenu n types de béton L<C1>, L<C2> ... L<Cn>
, comme si nous avons écrit manuellement n types:
type L_Ci_
Ci get();
void set(Ci);
Nous n'avons pas eu à les écrire manuellement, c'est le point. Il n'y a pas les relations entre ces types
L<Ci> oi = ...;
L<Cj> oj = oi; // doesn't compile. L<Ci> and L<Cj> are not compatible types.
Pour le modèle de C, qui est la fin de l'histoire. Il s'agit essentiellement d'une macro-expansion - basée sur une classe "template", elle génère de nombreuses classes concrètes, sans aucune relation de type entre elles.
Pour Java, il y a plus. Nous avons également obtenu un type L<? extends P>
, il est un type super de tout L<Ci>
L<Ci> oi = ...;
L<? extends P> o = oi; // ok, assign subtype to supertype
Quel genre de méthode devrait exister dans L<? extends P>
? En tant que type super, n'importe laquelle de ses méthodes doit être cornée par ses sous-types. Cette méthode fonctionnerait:
type L<? extends P>
P get();
parce que dans l'un de ses sous-type L<Ci>
, il y a une méthode Ci get()
, qui est compatible avec P get()
- la méthode redéfinie a la même signature et le type de retour covariant.
Cela peut ne pas fonctionner pour set()
bien - nous ne pouvons pas trouver un type X
, de sorte que void set(X)
peut être surchargée par void set(Ci)
pour tout Ci
. Par conséquent, la méthode set()
n'existe pas dans L<? extends P>
. Il y a également un L<? super P>
qui va dans l'autre sens. Il a set(P)
, mais pas get()
. Si Si
est un super type de P
, L<? super P>
est un super type de L<Si>
.
type L<? super P>
void set(P);
type L<Si>
Si get();
void set(Si);
set(Si)
« » set(P)
pas overrides au sens habituel, mais le compilateur peut voir que toute invocation valable sur set(P)
est une invocation valide sur set(Si)
Mauvais exemple de polymorphisme, je pense? Un "enfant" n'est pas (toujours) un "parent". – justhalf
@justhalf: 'Parent' était dans la question, et suggère que' Child' est un exemple naturel d'une sous-classe. Pas les noms de classe que j'aurais choisis à partir de rien, mais assez clair en termes de contexte de la question. –
Ouais, je comprends, mais je pense qu'il aurait été préférable que l'exemple utilise ici "SingleParent" ou "NewParent" comme sous-classe =) – justhalf