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ériques, imposer une contravariance


Sujet :

Langage Java

  1. #1
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Points : 5 943
    Points
    5 943
    Par défaut Génériques, imposer une contravariance
    Bonjour tout le monde,

    bon le titre n'est peut être pas très parlant, voici mon problème :

    Soit les classes suivantes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class Foo<T> {
      T value;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Bar<A> {
     
        // le type B doit être un super type de A
        <B> B bar(Foo<B> foo) {
            return foo.value;
        }
    }
    Pour la méthode bar, je voudrais imposer que le type B soit un super type du type A défini pour la classe. Un peu comme si on pouvait définir <B super A> (ce qui n'est pas le cas).
    Savez vous comment faire ?

    Merci d'avance.

    le y@m's
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  2. #2
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

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

    Informations forums :
    Inscription : Août 2006
    Messages : 4 073
    Points : 7 977
    Points
    7 977
    Par défaut
    Je n'ai pas bien compris toute la question, donc j'y réponds surement pas la bonne réponse, mais pour faire <B super A> tu dois utiliser extends a la place du mot super <B extends A>.
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Points : 5 943
    Points
    5 943
    Par défaut
    Citation Envoyé par wax78 Voir le message
    Je n'ai pas bien compris toute la question, donc j'y réponds surement pas la bonne réponse, mais pour faire <B super A> tu dois utiliser extends a la place du mot super <B extends A>.
    <B extends A> indique que le type B doit être un sous-type de A (B une classe fille de A). Moi je veux l'inverse, je veux que B soit un super-type de A (B une classe parente de A).
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  4. #4
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

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

    Informations forums :
    Inscription : Août 2006
    Messages : 4 073
    Points : 7 977
    Points
    7 977
    Par défaut
    Autant pour moi j'avais bien mal compris
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Points : 5 943
    Points
    5 943
    Par défaut
    Une "presque solution" est d'utiliser le wildcard ? super mais le problème c'est que le type parent n'est pas "explicite" et donc ne peut être utiliser pour donner le type de retour de la méthode qui devient Object.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Object bar(Foo<? super A> foo) {
        return foo.value;
    }
    Mais je voudrais conserver le type B pour le type de retour de la méthode.
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  6. #6
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    À ma connaissance les génériques ne peuvent pas exprimer de contrainte dans les deux sens, même s'il existe des cas où ça aurait du sens.

    Voilà ce que j'ai fait une fois :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    public interface FFoo<T1, T2> {
      T1 getValue();
      void accept(T2 t2);
    }
     
    public class Foo<T> implements FFoo<T, T> {
      T value;
      T getValue() {
        return value;
      }
      void accept(T t) {
     
      }
    }
     
    public class Bar<A> {
      A value;
      <B> B bar(FFoo<B, ? super A> foo) {
        foo.accept(value);
        return foo.getValue();
      }
     
      public static void main(String[] args) {
        Bar<Integer> bar = new Bar<Integer>();
        bar.value = 1;
     
        Foo<Number> foo = new Foo<Number>();
        foo.value = 2;
        Number n = bar.bar(foo);
      }
    }
    Mais la seule manière que je connaisse d'imposer que FFoo<T1, T2> soit en réalité un Foo<T>, c'est une vérification au runtime.
    Pas de solution idéale.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre confirmé
    Homme Profil pro
    Ed Nat
    Inscrit en
    Janvier 2013
    Messages
    325
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ed Nat
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 325
    Points : 559
    Points
    559
    Par défaut
    Bonjour,
    Effectivement, pour faire en sorte que le type B soit un super-type de A,
    la déclaration suivante (bien tentante) n'est pas possible :
    <B super A>
    peut-être avec java 8...

    En attendant, si l'objectif est de créer une méthode qui utilise un generic B super type de A, il est possible de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public class Bar<A> {
    	// le type B doit être un super type de A
    	public static <B, A extends B> B foo(Foo<B> foo, A dValue) {
    		return foo.value != null ? foo.value : dValue;
    	}
    }
    L'inconvénient est l'obligation d'utiliser le static (pour ne pas masquer le generic A),
    et l'utilisation d'une valeur par défaut (qui permet d'interdire toute compilation si les paramètres passés ne respectent pas l'arbre d'héritage)

    Le static est le plus problématique, puisqu'il force un appel où la généricité définie sur Bar (le A), n'est plus contrôlé que par le dValue (puisque pas de generic dans une méthode statique)...

    Le résultat est presque satisfaisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Foo<Integer> foo = new Foo<>();
    foo.value = 5;
    Bar<String> b = new Bar<>();
    Integer i=Bar.foo(foo, "");//ne compile pas puisque String n'est pas une super-classe de Integer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Foo<Integer> foo = new Foo<>();
    foo.value = 5;
    Bar<Number> b = new Bar<>();
    Integer i=Bar.foo(foo, 0);//Compilation ok : Number super classe de Integer
    Le problème est seulement que l'appel de foo ne peut-être associé à une instance particulière de BAR...

  8. #8
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Points : 5 943
    Points
    5 943
    Par défaut
    Citation Envoyé par kox2ee Voir le message
    Bonjour,
    Effectivement, pour faire en sorte que le type B soit un super-type de A,
    la déclaration suivante (bien tentante) n'est pas possible :


    peut-être avec java 8...
    Tu dis peut-être avec java 8 comme ça ou c'est quelque chose de vraiment prévu (j'avoue ne pas m'être trop penché sur les nouveautés de java 8) ?

    Citation Envoyé par kox2ee Voir le message
    En attendant, si l'objectif est de créer une méthode qui utilise un generic B super type de A, il est possible de faire :

    ...

    Le problème est seulement que l'appel de foo ne peut-être associé à une instance particulière de BAR...
    J'avais effectivement trouvé cette façon de faire, à vrai dire cela a même été mon point de départ. D'une méthode statique j'ai voulu en faire une méthode d'instance pour un confort d'utilisation. Mais bon visiblement, comme je le craignais, ce n'est pas possible.


    En tout cas merci à tous de vous y être penché dessus, je laisse le sujet non résolu, toute nouvelle réflexion y est la bienvenue
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  9. #9
    Membre confirmé
    Homme Profil pro
    Ed Nat
    Inscrit en
    Janvier 2013
    Messages
    325
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ed Nat
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 325
    Points : 559
    Points
    559
    Par défaut
    Affirmation sans fondement pour Java 8...
    Je n'ai pas lu ça sur le sujet.

    Je voulais simplement dire qu'il se pourrait qu'on y arrive un jour, à la possible implémentation de ce <A super B> qui a un sens conceptuel

Discussions similaires

  1. Imposer une valeur dans une ligne "identity" d'une
    Par mibo94 dans le forum Access
    Réponses: 1
    Dernier message: 26/11/2005, 16h59
  2. imposer une hauteur de div meme si le texte est plus long
    Par bébé dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 24/08/2005, 11h29
  3. [wxPython] Imposer une hauteur minimum à une wxFrame
    Par Falken dans le forum wxPython
    Réponses: 3
    Dernier message: 07/04/2005, 20h57
  4. Imposer une taille à un composant en conception
    Par teryen dans le forum Composants VCL
    Réponses: 14
    Dernier message: 28/06/2004, 15h06
  5. [Batch] Imposer une entree de password
    Par ludovic.fernandez dans le forum Scripts/Batch
    Réponses: 4
    Dernier message: 07/05/2004, 17h52

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