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 :

[Generics] Possibilité d'alléger ceci


Sujet :

Langage Java

  1. #1
    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
    Par défaut [Generics] Possibilité d'alléger ceci
    Salut,

    J'ai pas mal de generics dans mon code, parfois ça devient vraiment très long.

    Par exemple, j'ai une classe Job qui a 2 paramètres : S le type de flux, M le type de "plateforme multimédia" (lecteur, enregistreur ...).

    Donc à chaque fois que je le trimbale, j'ai:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Job<? extends Stream, ? extends MultimediaCenter> job;
    (et oui car:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Job<?,?> job = ...;
    job.getStream(); //retourne un Object
    )

    Donc déjà c'est un peu lourd.
    Maintenant, on peut programmer des "jobs", en ayant une plateforme multimédia préférée (qui n'est pas forcément égale à celle du Job, mais du même type).

    Donc ma classe programmation est déclarée comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public class Programmation<J extends Job<? extends Stream, M>, M extends MultimediaCenter>
    Bon là, vous voyez le bordel pour déclarer une variable de type programmation !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Programmation<? extends Job<? extends Stream, ? extends MultimediaCenter>, ? extends MultimediaCenter> programmation;
    Je ne vous explique pas les Collections de programmations lol...

    N'y aurait-il pas comme sur les méthodes (generic de méthode) un générique de classe, du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public <M extends MultimediaCenter> class Programmation<? extends Job<?, M>>
    (évidemment ceci ne marche pas)

    On gagnerait déjà un paramètre (qui est toujours le même que le 2e de Job).


    EDIT: Il y aurait bien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public class Programmation<S extends Stream, M extends MultimediaCenter>
    et utiliser Job<S,M> au lieu de J, mais ça n'est pas équivalent...


    EDIT 2: En pratique, je pense que je vais simplement virer les generics, et juste utiliser la covariance pr avoir le bon type, car on ne manipule que le type réel à chaque fois, qui n'a pas de generics (car PlayingJob extends Job<Playable,Player> en gros). Le problème se poserait pour d'éventuels setters...
    Mais sur le principe ça m'intéresse d'avoir des idées de conception.

  2. #2
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Par défaut
    Dans l'usage des génériques, as-tu vraiment besoin de toujours mettre ? extends Toto ? Moi j'observe que, la plupart du temps, Toto suffit, et donc cela deviendrait chez toi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Job<Stream, MultimediaCenter> job;
    Peut être vas-tu me dire que c'est moins... générique. Oui, mais suffisant dans 95% des cas, selon mon expérience. Et même mieux, souvent.

    Et pour toi ?

  3. #3
    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
    Par défaut
    Citation Envoyé par gifffftane
    Dans l'usage des génériques, as-tu vraiment besoin de toujours mettre ? extends Toto ? Moi j'observe que, la plupart du temps, Toto suffit, et donc cela deviendrait chez toi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Job<Stream, MultimediaCenter> job;
    Peut être vas-tu me dire que c'est moins... générique. Oui, mais suffisant dans 95% des cas, selon mon expérience. Et même mieux, souvent.

    Et pour toi ?
    Non parce que typiquement ici, prenons le cas d'une activité de lecture:
    PlayJob, avec Playable comme sous type de Stream, et Player comme MultimediaCenter.

    ça donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class PlayJob extends Job<Playable,Player> {...}
    Et ça ça n'est pas affectale à une variable de type Job<Stream,MultimediaCenter>...

  4. #4
    Membre expérimenté
    Inscrit en
    Juin 2003
    Messages
    292
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 292
    Par défaut
    Je ne crois pas que tu peux faire grand chose dans ton code.
    Des leur sorties il y a eu pas mal de contreverse sur ce sujet...
    Mais bon je crois que l avantage de safety type est vraiment important...

  5. #5
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Par défaut
    Soit PlayJob nécessite vraiment de se caler sur <Playable,Player> et donc, selon les génériques, il est heureux que l'on ne puisse pas l'affecter à un <Stream,MultimediaCenter>. Ici le générique casse l'héritage, au moins dans la souplesse de déclaration ; il me semble que cela a été voulu ainsi par les concepteurs des génériques.

    Soit l'extension par Playable,Player ne se justifie pas vraiment, c'est juste un exercice de rigueur gratuit, et alors pour te simplifier la vie tu seras conduit à remplacer ta déclaration de classe par <Stream,MultimediaCenter>...

    De mon coté, je dois t'avouer que je n'ai pas encore fait ma religion pour l'usage des génériques dans un contexte d'héritage. Je l'utilise pour simplifier des déclarations qui deviennent compliquées, et ces complications sont souvent l'indice que je me trompe quelque part dans la conception des héritages ou des génériques.

    J'ai l'impression (mais seulement une impression) que cela marche mieux dans l'autre sens : tu définis une classe non générique qui assure les principaux services, puis tu crées une classe générique qui hérite de la précédente ; ainsi il y a moins de tintoins pour l'affecter à une variable générique (en l'affectant à la classe... non générique), et tu peux retrouver la souplesse et la rigueur en redescendant au niveau générique.

    Et lorsque les déclarations génériques deviennent trop prises de tête, alors je crée une nouvelle classe, incluant les complications (en les simplifiant), et héritant du niveau non générique.

    Cependant, je ne suis pas encore sûr que ce soit la bonne approche. On verra.

  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
    Par défaut
    En fait, la conclusion à laquelle je suis arrivé la semaine dernière concernant ce problème, c'est que les generics doit apporter quelque chose A L'EXTERIEUR de l'API (enfin du package ou du petit module qu'on développe).

    Là, en l'occurrence, ils n'apportent qu'une simplification interne : par exemple le type de retour de getMultimediaCenter était automatiquement remplacé par Player dans le cas du PlayJob... Et dans ce cas il vaut mieux ne pas utiliser les générics mais utiliser la covariance pour retourner le bon type...
    Il reste encore le problème pour les setters (et pour les paramètres de méthodes en général), mais parfois ça ne se justifie pas de transporter dans le type apparent tous les types "génériques internes"...

    Mais bon je ne sais pas si ma (nouvelle) vision est correcte... le temps me le dira

  7. #7
    Membre expérimenté
    Inscrit en
    Juin 2003
    Messages
    292
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 292
    Par défaut
    juste une question:

    tu as ecrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public class Programmation<J extends Job<? extends Stream, M>, M extends MultimediaCenter>
    ceci ne marche pas?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public class Programmation<J extends Job<E, M>, M extends MultimediaCenter>
    mais puisque tu as deja declare ton job:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public class Job<? extends Stream, ? extends MultimediaCenter>
    puisque dans ta declaration de Job tu fais extends Steam et MultimediaCenter , non?

  8. #8
    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
    Par défaut
    Citation Envoyé par jhaythem
    juste une question:

    tu as ecrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public class Programmation<J extends Job<? extends Stream, M>, M extends MultimediaCenter>
    ceci ne marche pas?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public class Programmation<J extends Job<E, M>, M extends MultimediaCenter>
    mais puisque tu as deja declare ton job:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public class Job<? extends Stream, ? extends MultimediaCenter>
    puisque dans ta declaration de Job tu fais extends Steam et MultimediaCenter , non?
    Si j'ai bien compris ta question, tu demandes si le "extends QuelqueChose" est utile si la classe est déjà déclarée comme ça (en remplaçant ton E par ? pour que ça soit correct).

    Pour simplifier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class UneClasse<N extends Number> {
        private N number;
        UneClasse(N n) { number = n; }
        public N getNumber() { return n; }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    UneClasse<? extends Number> o1 = new UneClasse<Integer>();
    UneClasse<?> o2 = o1;
    Number n1 = o1.getNumber();
    //Number n2 = o2.getNumber(); //retourne Object, pas Number.

  9. #9
    Membre expérimenté
    Inscrit en
    Juin 2003
    Messages
    292
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 292
    Par défaut
    dabord je vois pas la differance entre ? et E dans ce cas.
    Personellement je trouve le E pour Element ou T pour Type est plus facile pour la lecture du code que des ? ca me fait mal aux yeux

    Et oui tu as tres bien compris ma questions, je vois pas l'interet a chaque fois tu declare que Jobs<? extends Stream... puisuque tu l as deja declare comme ca, non?

    Et pour ton exemple c est vrai que ca retourne un Objet et plus precisement ca retourne an Integer bein on sait bien que les generics ils sont supprime lors du runtime donc si ton o1 contient UneClasse<Integer> ca ne va pas changer. ca va te retourner un Integer lorsque tu fais getNumber().

    Voila ce que j ai compris personnelement des ma lecture du SCJP dtudy guide.
    Les generics assure le type safety, compare aux Arrays qui ont une behavior different et sachant que les Arrays ont l Exception ArrayStoreException qui te permet de ne pas mettre dans un tableau de Cat des Dog que les deux extends Animals. et cette securite tu ne peux l avoir qu avec des Generics.

    Encore une questions a tu essaye de declarer comme ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public class Programmation<J extends Job<?, M>, M extends MultimediaCenter>
    avec le ?

  10. #10
    Membre expérimenté
    Inscrit en
    Juin 2003
    Messages
    292
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 292
    Par défaut
    encore un petit truc,
    dans ton exemple je vois pas l interet de faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    UneClasse<? extends Number> o1 = new UneClasse<Integer>();
    ceci ests suffisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    UneClasse<Intege> o1 = new UneClasse<Integer>();
    le wildcard ? est utilise lors de la declaration mais je trouve qu il est plus interessant lors des methods generics et les classes.

  11. #11
    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
    Par défaut
    Citation Envoyé par jhaythem
    encore un petit truc,
    dans ton exemple je vois pas l interet de faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    UneClasse<? extends Number> o1 = new UneClasse<Integer>();
    ceci ests suffisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    UneClasse<Intege> o1 = new UneClasse<Integer>();
    le wildcard ? est utilise lors de la declaration mais je trouve qu il est plus interessant lors des methods generics et les classes.
    Ça dépend, car tu peux vouloir mettre UneClasse<Integer>, UneClasse<Double>, etc... dans ta variable... mais pas UneClasse<String>

  12. #12
    Membre expérimenté
    Inscrit en
    Juin 2003
    Messages
    292
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 292
    Par défaut
    bein oui evidament, tu ne peux pas mettre String puisque tu as mis extends Number et tu ne peux pas mettre Object non plus. Pour mettre Object il faudra mettre super Number mais la tu ne peux plus mettre d'integer...

    Je suis entrain de preparer la SCJP et j ai un de ses mal de tete en lisant ce chapitre.......

Discussions similaires

  1. Possibilite de replication partielle ?
    Par Mupps dans le forum Requêtes
    Réponses: 5
    Dernier message: 19/03/2004, 15h54
  2. Recherche d'une possibilite
    Par Invité dans le forum Langage SQL
    Réponses: 8
    Dernier message: 29/01/2004, 23h46
  3. Les possibilité que C++ offre par rapport à Pascal Objet
    Par Riko dans le forum Langages de programmation
    Réponses: 13
    Dernier message: 01/02/2003, 21h38
  4. quels sont les possibilitées???
    Par lolo-d dans le forum OpenGL
    Réponses: 11
    Dernier message: 16/05/2002, 00h41

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