IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

Générique et interface


Sujet :

Langage Java

  1. #1
    Expert éminent sénior
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Points : 21 324
    Points
    21 324
    Par défaut Générique et interface
    Bonsoir,

    J'ai un petit doute sur l'utilisation des génériques et des interfaces...

    Je voulais faire quelque chose comme ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Stock<Data> x = new Stock<Genre>();
    Genre implémentant Data...

    Comme il est possible de faire :

    Je pensais qu'il était possible de faire de même avec les génériques, mais ca n'a pas l'air d'être le cas

    Quelqu'un a une explication et/ou une solution ?

    Merci d'avance

  2. #2
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Stock<? extends Data> x = new Stock<Genre>();

  3. #3
    Expert éminent sénior
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Points : 21 324
    Points
    21 324
    Par défaut
    Citation Envoyé par ®om
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Stock<? extends Data> x = new Stock<Genre>();
    Le problème c'est que j'implémente Data et n'en hérite pas, ca change quelque chose ?

    De plus, si je fais comme ca, est que j'aurais quand même les avantages de la généricité ou devrais-je m'amuser à tout caster ?

    Merci

  4. #4
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par wichtounet
    Le problème c'est que j'implémente Data et n'en hérite pas, ca change quelque chose ?

    De plus, si je fais comme ca, est que j'aurais quand même les avantages de la généricité ou devrais-je m'amuser à tout caster ?

    Merci
    Non tu devras t'amuser à tout caster...

    Mais bon si tu veux un stock de genre, tu fais Stock<Genre>

    C'est le même problème que List<Integer> ça n'hérite pas de List<Number>.
    En revanche, cela n'empêche pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    List<Number> numbers = new ArrayList<Number>();
    numbers.add(5); // ou .add(new Integer(5));

  5. #5
    Expert éminent sénior
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Points : 21 324
    Points
    21 324
    Par défaut
    Citation Envoyé par ®om
    Non tu devras t'amuser à tout caster...

    Mais bon si tu veux un stock de genre, tu fais Stock<Genre>

    C'est le même problème que List<Integer> ça n'hérite pas de List<Number>.
    En revanche, cela n'empêche pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    List<Number> numbers = new ArrayList<Number>();
    numbers.add(5); // ou .add(new Integer(5));
    Le problème, c'est que ma fonction devrait être générique...

    Et donc, la création de la variable se fera à l'intérieur d'un switch et j'en ai besoin après le Switch... Je ne peut donc pas savoir à l'avance de quelle classe sera remplie ma classe Stock, mais bon, s'il faut tout caster, je casterai le tout

  6. #6
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par wichtounet
    Le problème, c'est que ma fonction devrait être générique...

    Et donc, la création de la variable se fera à l'intérieur d'un switch et j'en ai besoin après le Switch... Je ne peut donc pas savoir à l'avance de quelle classe sera remplie ma classe Stock, mais bon, s'il faut tout caster, je casterai le tout
    Peux-tu montrer un bout de code (ou expliquer pourquoi tu as besoin de savoir que c'est un Genre et non Data uniquement)?

  7. #7
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,



    "L'héritage" (je ne sais pas si je peux appellé cela comme ca) sur les types paramétré n'est pas possible. En effet, contrairement au tableau la vérification des types est effectué à la compilation et non pas à l'exécution. Du coups ce type d'écriture est interdit afin d'éviter des erreurs incohérente et "bizarre" car elle peuvent être très difficile à déceler.

    Pour bien comprendre la différence il faut comparer avec les tableaux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        Number[] tab = new Integer[2];
     
        tab[0] = new Integer(0);
        tab[1] = new Double(0.0); // ArrayStoreException
    Ce code compile parfaitement sans erreur ni warning, mais provoquera une erreur à l'exécution car on essaye de mettre un Double dans un tableau d'Integer...


    A l'inverse le code suivant ne compile pas, et pose problème sur la première ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        List<Number> list = new ArrayList<Integer>(); // cannot convert ...
    
        list.add(new Integer(0));
        list.add(new Double(0.0));
    Mais si le compilateur authorisait ce code, le danger serait encore plus grand car la ligne qui ajoute le Double dans la liste ne provoquera pas d'erreur... mais elle ne surviendra que lorsque tu accèderas à l'élément...

    Ce bout de code le montre bien (et provoque d'ailleur un warning) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
            List<Integer> listInteger = new ArrayList<Integer>();
            List<Number> list = (List)listInteger; // warning
            
            list.add(new Integer(0));
            list.add(new Double(0.0));
            
            System.out.println("-----------------------------");
            
            for (Integer i : listInteger) { // ClassCastException
                System.out.println(i);
            }
    En général on peut utiliser les wilcards <? extends ...> ou <? super ...> (que ce soit une interface ou une classe) pour approcher ce principe "d'héritage"...
    Maintenant pour en revenir à ton problème, il faudrait savoir exactement pourquoi tu souhaite faire cela.

    a++

  8. #8
    Expert éminent sénior
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Points : 21 324
    Points
    21 324
    Par défaut
    Merci pour toutes ces explications

    C'est très clair.

    En fait pour mon problème, je suis en train de me rendre compte que ma solution n'était pas très faisable, donc je suis en train de partir sur autre chose...

  9. #9
    Expert éminent sénior
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Points : 21 324
    Points
    21 324
    Par défaut
    Je reviens à la charge avec ce problème, car j'ai un nouveau problème avec votre solution

    J'ai employé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Stock<? extends Data> items = null;
    Je le remplis ensuite en fonction de ce que j'ai besoin dedans, par exemple Film ou Realisateur. Par contre quand je veut employer la méthode getIdOf dont voici la signature :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public Integer getIdOf(T value){
    de la manière suivante :

    J'ai une erreur dans eclipse :

    The method getIdOf(capture-of ? extends Data) in the type Stock<capture-of ? extends Data> is not applicable for the arguments Film
    Il y a une manière de contourner ce problème ?

  10. #10
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Film extends Data?

  11. #11
    Expert éminent sénior
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Points : 21 324
    Points
    21 324
    Par défaut
    Citation Envoyé par ®om
    Film extends Data?
    Non, Film implémente Data...

    Au pire je me passerai des génériques, mais bon...

  12. #12
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    C'est normal car le <? extends ...> t'interdit d'utiliser les méthodes paramétré car tu ne connais pas le type exacte.

    <? extends ...> permet en effet une utilisation en "lecture seule" : comme tu ne connais pas exactement le type paramétré tu ne peux pas appeller les méthode qui l'utilise. Par contre tu peux utiliser les méthodes qui l'utilise seulement en type de retour, que tu casteras vers son type de base (puisque c'est forcément un type fils).

    A l'inverse <? super ...> permet une utilisation en écriture seule : comme tu connais le type de base tu peux utiliser les méthodes qui possèdent des paramètres paramétrés, mais par contre tu ne peut pas appeller les méthodes qui retourne un type paramétré car tu ne connais pas son type exact...



    Maintenant il faudrait que tu explique ce que tu veux faire, et non pas comment tu veux le faire.

    Que doit contenir items ?
    • Seulement des Films ? Alors utilises directement Stock<Film>
    • Seulement des Realisateurs ? Alors utilises directement Stock<Realisateur>
    • A la fois des Films et des Realisateurs ? Alors utilises directement Stock<Data>
    • Autre chose... expliques
    a++

  13. #13
    Expert éminent sénior
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Points : 21 324
    Points
    21 324
    Par défaut
    de ta réponse

    items doit contenir soit des Film soit des Realisateur soit d'autres classes implémentant Data. Le problème c'est que je ne sais pas à l'avance ce qu'il va contenir, ca dépend d'un paramètre dans le constructeur de la classe, en fonction de ce paramètre, je remplis items. Par exemple si c'est des films :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    items = films.getFilms();
    ou alors avec acteurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    items = acteurs.getActeurs();
    getFilms() renvoie un Stock<Film> et getActeurs un Stock<Acteur>.

    C'est pour ca que j'en ai besoin...

    Par contre, je viens de me rendre compte que je pourrais aussi travailler directement sur getFilms et ne pas en stocker une référence dans ma classe, même si je trouve que c'est moins beau....

  14. #14
    Expert éminent sénior
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Points : 21 324
    Points
    21 324
    Par défaut
    Bon, j'ai résolu le problème en employant toujours les méthodes getXXX qui me renvoient des Stock<XXX>.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. C# => VB.net classe, interface générique
    Par Gr@nd@x dans le forum VB.NET
    Réponses: 2
    Dernier message: 27/10/2008, 13h27
  2. Interfaces et contraintes génériques
    Par SaumonAgile dans le forum C#
    Réponses: 6
    Dernier message: 18/04/2008, 16h14
  3. Implémentation d'interface et génériques
    Par jsebfranck dans le forum Langage
    Réponses: 2
    Dernier message: 14/10/2007, 12h54
  4. Réponses: 3
    Dernier message: 11/05/2007, 17h29
  5. Réponses: 5
    Dernier message: 23/02/2006, 00h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo