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 :

Override - Type dans la signature


Sujet :

Langage Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 53
    Points : 24
    Points
    24
    Par défaut Override - Type dans la signature
    Bonjour,

    J ai une question un peu d ordre general que je me posais a propos de l overrriden de fonctions, si j ai:

    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
     
    abstract public class A {...}
    public class A1 extends A {...}
    public class A2 extends A {...}
     
    abstract public class B {
       ...
       abstract public <T extends A> void function(T t);
       ...
    }
     
    public class B1 extends B {
       ...
       @Override
       public <T extends A1> void function(T t);
       ...
    }
     
    public class B2 extends B {
       ...
       @Override
       public <T extends A2> void function(T t);
       ...
    }
    pourquoi cela ne marche-t-il pas? Je sais que les fonctions doivent avoir la meme signature, et je ne comprend pas pourquoi ce n est pas le cas ici.

    Sinon, comment fait-on pour obtenir un resultat similaire?

    Merci

  2. #2
    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,

    Citation Envoyé par Malawi Voir le message
    Je sais que les fonctions doivent avoir la meme signature, et je ne comprend pas pourquoi ce n est pas le cas ici.
    Si le type des paramètres restent T, sont "rawtype" change puisqu'il passe de A à A1 puis A2.

    En clair ce n'est plus de la redéfinition mais de la surcharge (overload). C'est comme si tu avais les trois méthodes suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	public abstract void function(A t);
     
    	public abstract void function(A1 t);
     
    	public abstract void function(A2 t);
    a++

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 53
    Points : 24
    Points
    24
    Par défaut
    Merci pour ta reponse rapide,

    Je comprend bien, mais je ne trouve pas ca logique. A1 et A2 sont des extends de A, et sont donc aussi de type A.

    Si je fais 3 fonctions comme tu le dis dans la classe abstraite B, n y a t-il pas un probleme d appel apres: l appel a la fonction function(A1 t) doit elle aller chercher function(A t) ou function(A1 t)? Il n y a pas une confusion possible ici?

    De plus, si tu veux ajouter une troisieme classe A3 extends A plus tard, comment faire pour l ajouter sans reecrire la classe abstraite B?

    N y a t -il pas une solution pour implementer le type de chose que je cherche a faire?

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 53
    Points : 24
    Points
    24
    Par défaut
    J ai trouve une solution:

    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
    abstract public class A {...}
    public class A1 extends A {...}
    public class A2 extends A {...}
     
    abstract public class B<T extends A> {
       ...
       abstract public void function(T t);
       ...
    }
     
    public class B1 extends B<A1> {
       ...
       @Override
       public void function(A1 t);
       ...
    }
     
    public class B2 extends B<A2> {
       ...
       @Override
       public void function(A2 t);
       ...
    }
    C est un peu barbare, mais ca marche bien...

  5. #5
    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
    Lorsque tu hérites tu dois respecter la totalité du contrat du parent.

    Si ton code compilait sans erreurs que donnerait le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    B b = new B2();
     
    b.function(new A1()); // On appelle function(A)
    En effet ici on appelle function(A) qui est défini dans B et qui attend un paramètre de type A. Donc tout est correct mais on appelle une méthode qui n'existe pas puisque B2 ne déclare que function(A2)...


    En fait ton utilisation des Generics n'apporte strictement rien dans ce cas précis sur une seule et unique méthode...
    Bref tu pourrais remplacer ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    abstract public <T extends A> void function(T t);
    Par cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    abstract public void function(A t);

    La solution dans ton cas serait de passer par une surcharge :
    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
    abstract class B {
    	abstract public void function(A a);
    }
     
    class B1 extends B {
    	@Override
    	public void function(A a) {
    		// On renvoi l'appel vers l'autre méthode
    		// (en générant éventuellement une ClassCastException)
    		this.function( (A1) a );
    	}
     
    	// Surcharge :
    	public void function(A1 a) {
    		// ...
    	}
    }



    Une autre solution serait d'utiliser les Generics dans la déclaration de classe, en les spécialisant dans les sous-classes :
    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
    abstract class B<T extends A> {
    	abstract public void function(T t);
    }
     
    class B1<T extends A1> extends B<T> {
    	@Override
    	public void function(T t) {
     
    	}
    }
     
    class B2<T extends A1> extends B<T> {
    	@Override
    	public void function(T t) {
     
    	}
    }
    Les sous-classes redéfinissent le type de base et modifie donc le type du paramètre.

    En fait si on utilise la reflection on peut voir que c'est le compilateur qui s'occupe de générer la surcharge équivalente au code précédent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	for (Method method : B1.class.getDeclaredMethods()) {
    		System.out.println(method + " " + method.isBridge());
    	}
    Ceci en rajoutant une méthode dite "bridge" qui renvoi l'appel vers la nouvelle version (avec un cast bien sûr).


    a++


    [edit] Grillé !
    En fait ta solution est similaire puisqu'on a 3 possibilités lorsqu'on hérite d'une classe Generics :

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 53
    Points : 24
    Points
    24
    Par défaut
    En effet ici on appelle function(A) qui est défini dans B et qui attend un paramètre de type A. Donc tout est correct mais on appelle une méthode qui n'existe pas puisque B2 ne déclare que function(A2)...
    Bien sur ca fait une erreur, mais ca c est au developpeur de s en soucier...

    La solution de surcharge que tu proposes est la solution que j avais adoptee en 1er, mais je voulais eviter de passer par la pour laisser le code le plus clair possible.

    J ai donc utilise la 2nde methode que tu proposes (comme je l ai dit dans un post plus haut).

    J ai donc la reponse a ma question: pas de solution simple et clair...

    Merci

  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
    Citation Envoyé par Malawi Voir le message
    Bien sur ca fait une erreur, mais ca c est au developpeur de s en soucier...
    Disons que les spécifications du langage impliquent qu'il n'est pas possible d'appeler une méthode qui n'existe pas...


    Donc tu dois passer par de la surcharge (et éventuellement tu peux utiliser @Deprecated sur l'ancienne version de la méthode )

    a++

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 05/02/2009, 11h50
  2. Incompatibilité de types dans un formulaire
    Par ahage4x4 dans le forum ASP
    Réponses: 3
    Dernier message: 03/05/2005, 15h39
  3. "Différence de type dans une expression" Tquery
    Par Hakim dans le forum Bases de données
    Réponses: 3
    Dernier message: 20/04/2004, 00h22

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