Différence entre et en Java [dupliquer]

Cette question a déjà une réponse ici:

Quelle est la différence entre List<? super T> et List<? extends T> ?

J'ai l'habitude d'utiliser List<? extends T>, mais il ne me permet pas d'ajouter des éléments list.add(e), alors que la List<? super T> ne.

605
demandé sur Lonely Neuron 2010-12-03 09:57:06

15 réponses

extends

La déclaration générique de List<? extends Number> foo3 signifie que l'une de ces cessions est légale:

List<? extends Number> foo3 = new ArrayList<Number>();  // Number "extends" Number (in this context)
List<? extends Number> foo3 = new ArrayList<Integer>(); // Integer extends Number
List<? extends Number> foo3 = new ArrayList<Double>();  // Double extends Number
  1. Lecture - compte tenu des affectations possibles ci-dessus, quel type d'objet êtes-vous assuré de lire à partir de List foo3:

    • , Vous pouvez lire un Number parce que l'une des listes qui pourraient être affectés à foo3 contient un Number, ou une sous-classe de Number.
    • vous ne pouvez pas lire un Integer parce que {[7] } pourrait pointer vers un List<Double>.
    • vous ne pouvez pas lire un Double parce que {[7] } pourrait pointer vers un List<Integer>.
  2. Écrit, Donnée ci-dessus affectations possibles, quel type d'objet, pourriez-vous ajouter à List foo3, ce qui serait légale pour tous les ci-dessus possible ArrayList affectations:

    • Vous ne pouvez pas ajouter un Integer, car foo3 peut être interprété à une List<Double>.
    • vous ne pouvez pas ajouter un Double Car {[7] } pourrait pointer vers un List<Integer>.
    • vous ne pouvez pas ajouter a Number parce que {[7] } pourrait pointer vers un List<Integer>.

vous ne pouvez pas ajouter d'objet à List<? extends T> parce que vous ne pouvez pas garantir quel type de List Il pointe vraiment, donc vous ne pouvez pas garantir que l'objet est autorisé dans ce List. La seule "garantie" est que vous ne pouvez lire et vous obtiendrez un T ou sous-classe de T.

super

Considérons Maintenant List <? super T>.

La déclaration générique de List<? super Integer> foo3 signifie que l'un des ce sont des missions légales:

List<? super Integer> foo3 = new ArrayList<Integer>();  // Integer is a "superclass" of Integer (in this context)
List<? super Integer> foo3 = new ArrayList<Number>();   // Number is a superclass of Integer
List<? super Integer> foo3 = new ArrayList<Object>();   // Object is a superclass of Integer
  1. Lecture - compte tenu des affectations possibles ci-dessus, quel type d'objet êtes-vous assuré de recevoir lorsque vous lisez à partir de List foo3:

    • vous n'êtes pas garanti un Integer parce que {[7] } pourrait pointer vers un List<Number> ou List<Object>.
    • vous n'êtes pas garanti un Number parce que {[7] } pourrait pointer vers un List<Object>.
    • Le seulement garantir est que vous obtenez une instance d'un Object ou sous-classe de Object (mais vous ne savez pas quelle sous-classe).
  2. Écrit, Donnée ci-dessus affectations possibles, quel type d'objet, pourriez-vous ajouter à List foo3, ce qui serait légale pour tous les ci-dessus possible ArrayList affectations:

    • , Vous pouvez ajouter un Integer, car un Integer est autorisée dans aucune des listes ci-dessus.
    • , Vous pouvez ajouter une instance d'une sous-classe de Integer, car une instance d'une sous-classe de Integer est autorisé dans l'un de ci-dessus liste.
    • vous ne pouvez pas ajouter un Double Car {[7] } pourrait pointer vers un ArrayList<Integer>.
    • vous ne pouvez pas ajouter un Number Car {[7] } pourrait pointer vers un ArrayList<Integer>.
    • Vous ne pouvez pas ajouter un Object, car foo3 peut être pointant sur un ArrayList<Integer>.

PECS

Rappelez-vous PECS: "producteur étend, Super consommateur" .

  • "Producteur s'Étend" - Si vous avez besoin d'un List pour produire T valeurs (vous voulez lire Ts de la liste), vous devez le déclarer avec ? extends T, par exemple List<? extends Integer>. Mais vous ne pouvez pas ajouter à cette liste.

  • "la Consommation de Super" - Si vous avez besoin d'un List consommer T valeurs (vous voulez écrire Ts dans la liste), vous devez le déclarer avec ? super T, par exemple List<? super Integer>. Mais il n'y a aucune garantie sur le type d'objet que vous pouvez lire dans cette liste.

  • Si vous devez à la fois lire et écrire dans une liste, vous devez la déclarer exactement sans caractères génériques, par exemple List<Integer>.

Exemple

Notez cet exemple de la FAQ Java Generics. Notez comment la liste source src (la liste de production) utilise extends, et la liste de destination dest (la liste de consommation) utilise super:

public class Collections { 
  public static <T> void copy(List<? super T> dest, List<? extends T> src) {
      for (int i = 0; i < src.size(); i++) 
        dest.set(i, src.get(i)); 
  } 
}

Voir Aussi Comment puis-je ajouter à la liste étend nombre > structures de données?

1142
répondu Bert F 2017-10-07 05:21:18

Imaginez avoir cette hiérarchie

entrez la description de l'image ici

1. S'étend

En écrivant

    List<? extends C2> list;

Vous dites que list pourra référencer un objet de type (par exemple) ArrayList dont le type générique est l'un des 7 sous-types de C2 (C2 inclus):

  1. C2: new ArrayList<C2>();, (un objet qui permet de stocker C2 ou sous-types) ou
  2. D1: new ArrayList<D1>();, (un objet qui peut stocker D1 ou sous-types) ou
  3. D2: new ArrayList<D2>();, (un objet qui peut stocker D2 ou sous-types) ou...

Et ainsi de suite. Sept cas différents:

    1) new ArrayList<C2>(): can store C2 D1 D2 E1 E2 E3 E4
    2) new ArrayList<D1>(): can store    D1    E1 E2  
    3) new ArrayList<D2>(): can store       D2       E3 E4
    4) new ArrayList<E1>(): can store          E1             
    5) new ArrayList<E2>(): can store             E2             
    6) new ArrayList<E3>(): can store                E3             
    7) new ArrayList<E4>(): can store                   E4             

Nous avons un ensemble de types "stockables" pour chaque cas possible: 7 ensembles (rouges) ici représentés graphiquement

entrez la description de l'image ici

Comme vous pouvez le voir, il n'y a pas de type safe commun à tous les cas:

  • Vous ne pouvez pas list.add(new C2(){}); parce que cela pourrait être list = new ArrayList<D1>();
  • Vous ne pouvez pas list.add(new D1(){}); parce qu'il pourrait être list = new ArrayList<D2>();

Et ainsi de suite.

2. Super

En écrivant

    List<? super C2> list;

Vous dites que list sera en mesure de faire référence à un objet de type (par exemple) ArrayList, dont le type générique est l'une des 7 aux supertypes de C2 (C2 inclus):

  • A1: new ArrayList<A1>();, (un objet qui permet de stocker A1 ou sous-types) ou
  • A2: new ArrayList<A2>();, (un objet qui permet de stocker A2 ou sous-types) ou
  • A3: new ArrayList<A3>();, (un objet qui peut stocker A3 ou sous-types) ou...

Et ainsi de suite. Sept cas différents:

    1) new ArrayList<A1>(): can store A1          B1 B2       C1 C2    D1 D2 E1 E2 E3 E4
    2) new ArrayList<A2>(): can store    A2          B2       C1 C2    D1 D2 E1 E2 E3 E4
    3) new ArrayList<A3>(): can store       A3          B3       C2 C3 D1 D2 E1 E2 E3 E4
    4) new ArrayList<A4>(): can store          A4       B3 B4    C2 C3 D1 D2 E1 E2 E3 E4
    5) new ArrayList<B2>(): can store                B2       C1 C2    D1 D2 E1 E2 E3 E4
    6) new ArrayList<B3>(): can store                   B3       C2 C3 D1 D2 E1 E2 E3 E4
    7) new ArrayList<C2>(): can store                            C2    D1 D2 E1 E2 E3 E4

Nous avons un ensemble de types "stockables" pour chaque cas possible: 7 ensembles (rouges) ici représentés graphiquement

entrez la description de l'image ici

Comme vous pouvez le voir, ici, nous avons sept sûr types de qui sont communes à tous les cas: C2, D1, D2, E1, E2, E3, E4.

  • Vous pouvez list.add(new C2(){}); parce que, quel que soit le type de liste que nous sommes référencement, C2 est autorisé
  • vous pouvez list.add(new D1(){});, car, quel que soit le type de Liste que nous utilisons, D1 est autorisé

Et ainsi de suite. Vous avez probablement remarqué que ces types correspondent à la hiérarchie à partir de type C2.

Notes

Ici, la hiérarchie complète si vous souhaitez faire quelques tests

interface A1{}
interface A2{}
interface A3{}
interface A4{}

interface B1 extends A1{}
interface B2 extends A1,A2{}
interface B3 extends A3,A4{}
interface B4 extends A4{}

interface C1 extends B2{}
interface C2 extends B2,B3{}
interface C3 extends B3{}

interface D1 extends C1,C2{}
interface D2 extends C2{}

interface E1 extends D1{}
interface E2 extends D1{}
interface E3 extends D2{}
interface E4 extends D2{}
177
répondu Luigi Cortese 2016-06-15 13:51:29

J'aime la réponse de @Bert F mais c'est la façon dont mon cerveau voit.

J'ai un X dans ma main. Si je veux écrire mon X dans une Liste, celle-ci doit être soit une Liste de X ou une Liste de choses que mon X peut être sortie comme je les écris en tout superclasse de X...

List<? super   X>

Si j'obtiens une liste et que je veux Lire Un X de cette liste, il vaut mieux être une liste de X ou une liste de choses qui peuvent être mises à jour à X pendant que je les lis, c'est-à-dire n'importe quoi que étend X

List<? extends X>

J'espère que cela aide.

60
répondu Michael Dausmann 2015-12-03 22:05:16

Basé sur la réponse de Bert F je voudrais expliquer ma compréhension.

Disons que nous avons 3 classes comme

public class Fruit{}

public class Melon extends Fruit{}

public class WaterMelon extends Melon{}

Ici nous avons

List<? extends Fruit> fruitExtendedList = …

//Says that I can be a list of any object as long as this object extends Fruit.

Ok essayons maintenant d'obtenir de la valeur à partir de fruitExtendedList

Fruit fruit = fruitExtendedList.get(position)

//This is valid as it can only return Fruit or its subclass.

Encore une fois essayons

Melon melon = fruitExtendedList.get(position)

//This is not valid because fruitExtendedList can be a list of Fruit only, it may not be 
//list of Melon or WaterMelon and in java we cannot assign sub class object to 
//super class object reference without explicitly casting it.

Il en va de même pour

WaterMelon waterMelon = fruitExtendedList.get(position)

Essayons maintenant de définir un objet dans fruitExtendedList

Ajout d'un objet fruit

fruitExtendedList.add(new Fruit())

//This in not valid because as we know fruitExtendedList can be a list of any 
//object as long as this object extends Fruit. So what if it was the list of  
//WaterMelon or Melon you cannot add Fruit to the list of WaterMelon or Melon.

Ajout d'un objet Melon

fruitExtendedList.add(new Melon())

//This would be valid if fruitExtendedList was the list of Fruit but it may 
//not be, as it can also be the list of WaterMelon object. So, we see an invalid 
//condition already.

Enfin laisser essayez d'ajouter un objet pastèque

fruitExtendedList.add(new WaterMelon())

//Ok, we got it now we can finally write to fruitExtendedList as WaterMelon 
//can be added to the list of Fruit or Melon as any superclass reference can point 
//to its subclass object.

mais attendez Que faire si quelqu'un décide de faire un nouveau type de citron disons pour des arguments bien SaltyLemon comme

public class SaltyLemon extends Lemon{}

maintenant fruitExtendedList peut être une liste de fruits, Melon, pastèque ou SaltyLemon.

Donc, notre déclaration

fruitExtendedList.add(new WaterMelon())

N'Est pas valide non plus.

Fondamentalement, nous pouvons dire que nous ne pouvons rien écrire à un fruitExtendedList.

Cela résume List<? extends Fruit>

Voyons Maintenant

List<? super Melon> melonSuperList= …

//Says that I can be a list of anything as long as its object has super class of Melon.

Essayons maintenant d'obtenir une valeur de melonSuperList

Fruit fruit = melonSuperList.get(position)

//This is not valid as melonSuperList can be a list of Object as in java all 
//the object extends from Object class. So, Object can be super class of Melon and 
//melonSuperList can be a list of Object type

de même, le Melon, la pastèque ou tout autre objet ne peuvent pas être lus.

Mais notez que nous pouvons lire les instances de type D'objet

Object myObject = melonSuperList.get(position)

//This is valid because Object cannot have any super class and above statement 
//can return only Fruit, Melon, WaterMelon or Object they all can be referenced by
//Object type reference.

Maintenant, essayons de définir une valeur à partir de melonSuperList.

Ajout d'un type d'objet objet

melonSuperList.add(new Object())

//This is not valid as melonSuperList can be a list of Fruit or Melon.
//Note that Melon itself can be considered as super class of Melon.

Ajout d'un objet de Type Fruit

melonSuperList.add(new Fruit())

//This is also not valid as melonSuperList can be list of Melon

Ajout du type de Melon objet

melonSuperList.add(new Melon())

//This is valid because melonSuperList can be list of Object, Fruit or Melon and in 
//this entire list we can add Melon type object.

Ajout d'un objet de type pastèque

melonSuperList.add(new WaterMelon())

//This is also valid because of same reason as adding Melon

Pour résumer, nous pouvons ajouter Melon ou sa sous-classe dans melonSuperList et en lecture seule type d'objet objet.

17
répondu Sushant 2017-05-23 12:26:36

Super est une limite inférieure, et s'étend est une limite supérieure.

Selon http://download.oracle.com/javase/tutorial/extra/generics/morefun.html :

La solution consiste à utiliser une forme de Joker délimité que nous n'avons pas encore vu: caractères génériques avec une limite inférieure. Le la syntaxe ? super T dénote une inconnue type qui est un supertype de T (ou T lui-même; rappelez-vous que le supertype la relation est réflexive). C'est le double parmi les caractères génériques délimités nous avons été utiliser, où nous utiliser ? étend T à désigner un type inconnu qui est un sous-type de T.

14
répondu Istao 2010-12-03 07:04:21

En utilisant extends vous ne pouvez obtenir que de la collection. Vous ne pouvez pas mettre en elle. En outre, bien que super permette à la fois get et put, le type de retour pendant get est ? super T .

3
répondu Sai Sunder 2018-08-04 22:36:39

La chose la plus déroutante ici est que quelles que soient les restrictions de type que nous spécifions, l'affectation ne fonctionne que d'une manière:

baseClassInstance = derivedClassInstance;

Vous pouvez penser que Integer extends Number et qu'un {[3] } ferait comme un <? extends Number>, mais le compilateur vous dira que <? extends Number> cannot be converted to Integer (c'est-à-dire, dans le langage humain, Il est faux que tout ce qui étend le nombre puisse être converti en entier):

class Holder<T> {
    T v;
    T get() { return v; }
    void set(T n) { v=n; }
}
class A {
    public static void main(String[]args) {
        Holder<? extends Number> he = new Holder();
        Holder<? super Number> hs = new Holder();

        Integer i;
        Number n;
        Object o;

        // Producer Super: always gives an error except
        //       when consumer expects just Object
        i = hs.get(); // <? super Number> cannot be converted to Integer
        n = hs.get(); // <? super Number> cannot be converted to Number
                      // <? super Number> cannot be converted to ... (but
                      //       there is no class between Number and Object)
        o = hs.get();

        // Consumer Super
        hs.set(i);
        hs.set(n);
        hs.set(o); // Object cannot be converted to <? super Number>

        // Producer Extends
        i = he.get(); // <? extends Number> cannot be converted to Integer
        n = he.get();
        o = he.get();

        // Consumer Extends: always gives an error
        he.set(i); // Integer cannot be converted to <? extends Number>
        he.set(n); // Number cannot be converted to <? extends Number>
        he.set(o); // Object cannot be converted to <? extends Number>
    }
}

hs.set(i); est ok parce que Integer peuvent être convertis en une super-classe de Number (et non pas parce que Integer est un superclasse de Number, ce qui n'est pas vrai).

EDIT a ajouté un commentaire sur Consumer Extends et Producer Super - ils ne sont pas significatifs car ils spécifient, en conséquence, rien et juste Object. Il est conseillé de se souvenir de PECS parce que les cèpes ne sont jamais utiles.

2
répondu 18446744073709551615 2017-09-26 11:03:56

Les caractères génériques ciblent deux besoins principaux:

Lecture d'une collection générique Insertion dans une collection générique Il existe trois façons de définir une collection (variable) à l'aide de caractères génériques. Ce sont:

List<?>           listUknown = new ArrayList<A>();
List<? extends A> listUknown = new ArrayList<A>();
List<? super   A> listUknown = new ArrayList<A>();

List<?> signifie une liste tapée à un type inconnu. Cela pourrait être un List<A>, un List<B>, un List<String> etc.

List<? extends A> signifie une liste d'objets qui sont des instances de class A, ou subclasses of A (par exemple B et C). List<? super A> signifie que la liste est tapée sur A class, ou un superclass of A.

Lire la suite : http://tutorials.jenkov.com/java-generics/wildcards.html

1
répondu Vaibhav Gupta 2015-08-23 13:25:09

Quand utiliser étend et super

Les caractères génériques sont les plus utiles dans les paramètres de méthode. Ils permettent la flexibilité nécessaire dans les interfaces de méthode.

Les gens sont souvent confus quand utiliser extends et quand utiliser Super bounds. La règle de base est le principe get-put. Si vous obtenez quelque chose d'un conteneur paramétré, utilisez extends.

int totalFuel(List<? extends Vehicle> list) {
int total = 0;
for(Vehicle v : list) {
    total += v.getFuel();
}
return total;}

La méthode totalFuel obtient les véhicules de la liste, leur demande combien de carburant ils ont, et calcule total. Si vous placez des objets dans un conteneur paramétré, utilisez super.

int totalValue(Valuer<? super Vehicle> valuer) {
int total = 0;
for(Vehicle v : vehicles) {
    total += valuer.evaluate(v);
}
return total;}

La méthode totalValue place les véhicules dans L'Évaluateur. Il est utile de savoir que extends bound est beaucoup plus commun que super.

1
répondu Kevin STS 2017-06-01 22:20:38

Vous pouvez parcourir toutes les réponses ci-dessus pour comprendre pourquoi le .add() est limité à '<?>', '<? extends>', et en partie à '<? super>'.

Mais voici la conclusion de tout cela si vous voulez vous en souvenir, et ne voulez pas aller explorer la réponse à chaque fois:

List<? extends A> signifie que ce accepte toutes les List de A et sous-classe de A. Mais vous ne pouvez rien ajouter à cette liste. Même pas les objets de type A.

List<? super A> signifie que cela acceptera toute liste de A et superclasse de A. Vous pouvez ajouter des objets de type A et ses sous-classes.

1
répondu jforex78 2017-09-14 10:37:29

Les réponses votées par l'up couvrent les détails sur de nombreux aspects. Cependant, j'essaierais de répondre à cela de manière différente.

Il y a 2 choses que nous devons considérer,

1. Affectation à la variable de liste

List<? extends X> listvar;

Ici, toute liste de X ou liste de sous-classes de X peut être assignée à listvar.

List<? extends Number> listvar; listvar = new ArrayList<Number>(); listvar = new ArrayList<Integer>();


List<? super X> listvar;

Ici, toute liste de X ou liste de superclasses de X peut être assignée à listvar.

List<? super Number> listvar; listvar = new ArrayList<Number>(); listvar = new ArrayList<Object>();

2. Effectuer une opération de lecture ou D'écriture sur la variable de liste

`List<? extends X> listvar;`

Vous pouvez utiliser cette fonctionnalité pour accepter une liste dans les arguments de méthode et effectuer toutes les opérations sur type X (Note: vous pouvez lire uniquement les objets de type X dans la liste).

`List<? super Number> listvar;

Vous pouvez utiliser cette fonctionnalité pour accepter une liste dans les arguments de méthode et effectuer toutes les opérations sur Type Object car vous pouvez lire uniquement les objets de type Object à partir du liste. Mais oui, la chose supplémentaire ici est, vous pouvez ajouter des objets de type X dans la liste.

1
répondu Shailesh Pratapwar 2018-03-31 04:20:18

Liste ne permet pas d'ajouter quoi que ce soit, sauf null, dans la liste.

Liste permet d'ajouter tout ce qui est-un X (X ou sa sous-classe), ou null.

1
répondu elyor 2018-09-07 12:24:45

J'aimerais visualiser la différence. Supposons que nous ayons:

class A { }
class B extends A { }
class C extends B { }

List<? extends T> - Lecture et affectation:

|-------------------------|-------------------|---------------------------------|
|         wildcard        |        get        |              assign             |
|-------------------------|-------------------|---------------------------------|
|    List<? extends C>    |    A    B    C    |   List<C>                       |
|-------------------------|-------------------|---------------------------------|
|    List<? extends B>    |    A    B         |   List<B>   List<C>             |
|-------------------------|-------------------|---------------------------------|
|    List<? extends A>    |    A              |   List<A>   List<B>   List<C>   |
|-------------------------|-------------------|---------------------------------|

List<? super T> - écriture et affectation:

|-------------------------|-------------------|--------------------------------------------|
|         wildcard        |        add        |                   assign                   |
|-------------------------|-------------------|--------------------------------------------|
|     List<? super C>     |    C              |  List<Object>  List<A>  List<B>   List<C>  |
|-------------------------|-------------------|--------------------------------------------|
|     List<? super B>     |    B    C         |  List<Object>  List<A>  List<B>            |
|-------------------------|-------------------|--------------------------------------------|
|     List<? super A>     |    A    B    C    |  List<Object>  List<A>                     |
|-------------------------|-------------------|--------------------------------------------|

Dans tous les cas:

  • Vous pouvez toujours obtenir Object à partir d'une liste quel que soit le caractère générique.
  • , vous pouvez toujours ajouter null pour une mutable liste quel que soit le générique.
1
répondu Oleksandr 2018-09-23 17:46:55
                                       |
                                       v

Liste ? peut être tout sous-classe de X ou X.

Liste ? peut être tout superclasse de X ou X.

                                      ^
                                      |
0
répondu snr 2018-08-11 07:35:35

Exemple, L'ordre d'héritage est supposé comme O > S > T > U > V

En utilisant le mot-clé extends,

exact:

List<? extends T> Object = new List<T>();
List<? extends T> Object = new List<U>();
List<? extends T> Object = new List<V>();

InCorrect:

List<? extends T> Object = new List<S>();
List<? extends T> Object = new List<O>();

Super Mot-Clé:

exact:

List<? super T> Object = new List<T>();
List<? super T> Object = new List<S>();
List<? super T> Object = new List<O>();

InCorrect:

List<? super T> Object = new List<U>();
List<? super T> Object = new List<V>();

Ajout d'un objet: Objet List = Nouvelle Liste ();

Object.add(new T()); //error

Mais pourquoi erreur ? Regardons les Possibilités de initialisations de L'objet Liste

List<? extends T> Object = new List<T>();
List<? extends T> Object = new List<U>();
List<? extends T> Object = new List<V>();

Si nous utilisons Object.add (new T ()); alors il ne sera correct que si

List<? extends T> Object = new List<T>(); 

Mais il y a deux possibilités supplémentaires

Objet List = nouvelle liste(); Objet List = nouvelle liste(); Si nous essayons d'ajouter (new T ()) aux deux possibilités ci-dessus, cela donnera une erreur car T est la classe supérieure de U et V. nous essayons d'ajouter un objet T [qui est (new T ())] à la liste des types U et V. L'objet de classe supérieure(classe de Base) ne peut pas être passé à la classe inférieure Objet (sous-classe).

En raison des deux possibilités supplémentaires , Java vous donne une erreur même si vous utilisez la possilibité correcte car Java ne sait pas à quel objet vous faites référence. vous ne pouvez donc pas ajouter d'objets à List Object = New List (); car il y a des possibilités qui ne sont pas valides.

Ajout d'un objet: Objet List = Nouvelle Liste ();

Object.add(new T()); // compiles fine without error
Object.add(new U()); // compiles fine without error
Object.add(new V()); // compiles fine without error

Object.add(new S()); //  error
Object.add(new O()); //  error

Mais pourquoi l'erreur se produit dans les deux ci-dessus ? nous pouvons utiliser l'Objet.Ajouter (nouveau T ()); seulement sur les possibilités ci-dessous,

List<? super T> Object = new List<T>();
List<? super T> Object = new List<S>();
List<? super T> Object = new List<O>();

Si nous avons essayé d'utiliser Objet.Ajouter (nouveau T ()) dans Objet List = nouvelle liste(); et Objet List = nouvelle liste(); il donnera l'erreur C'est parce que Nous ne pouvons pas ajouter t object [qui est new T ()] à la liste Object = new List (); car c'est un objet de type U. Nous ne pouvons pas ajouter un objet T [qui est new T()] à L'objet U Car T est une classe de base et U est une sous-classe . Nous ne pouvons pas ajouter de classe de base à la sous-classe et c'est pourquoi une erreur se produit . C'est de même pour l'autre cas .

-1
répondu Crox 2018-07-22 17:57:34