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 :

Méthode implémentée ET surchargée


Sujet :

Langage Java

  1. #1
    Invité
    Invité(e)
    Par défaut Méthode implémentée ET surchargée
    Bonjour à tous,

    Je rencontre un dilemme sur une surcharge d'une méthode implémentée depuis une interface.

    Voici ce dilemme illustré par un exemple TRÈS simple.

    Une interface IA :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public interface IA {
    	void execute(Object o);
    }
    Une classe A avec 2 méthodes : la première méthode implémente IA#execute(Object) et la seconde méthode surcharge A#execute(Object) (donc la méthode implémentée) :

    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
     
    public class A implements IA {
     
    	/**
             * Implementing {@link IA#execute(Object)}.
             */
    	public void execute(Object o) {		
    		this.execute(o);
    	}
     
    	/**
             * Overloading {@link A#execute(Object)}.
             * 
             * @param a
             *            an instance of String
             */
    	public void execute(String s) {
    		/* do something stupid with s */
    		s = new String("another stupid string");
    	}
    }
    Et un main pour tester :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
            /**
             * A main method to test.
             * 
             * @param args
             *            an array of arguments. Not used here.
             */
    	public static void main(String args[]) {
                    IA a = new A();
    		a.execute(new String("just a stupid string"));
    	}
    Au runtime, la méthode implémentée (donc A#execute(Object)) reçoit une instance de la classe String.

    Ainsi, la ligne this.execute(o); devrait appeler la méthode surchargée public void execute(String s) de la classe courante.

    Ce n'est pas le cas : elle se rappelle elle même et donc boucle à l'infini !

    Une idée ?
    Un pattern disponible ?
    Merci à tous.

  2. #2
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 690
    Par défaut
    Le plus simple serai simplement de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        public void execute(Object o) {
            if (o instanceof String){
              o = new String("another stupid string");
            }
        }
    Attention cependant affecter un string de la sorte sera sans effet vu que la variable o est perdue dès la sortie de la méthode.

  3. #3
    Membre très actif
    Avatar de william44290
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Juin 2009
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 400
    Par défaut
    Bon est est d'accord exemple stupid mais

    est ce que cela boucle si tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public void execute(Object o) {		
    		this.execute((String) o);
    	}

  4. #4
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    Citation Envoyé par nicolas.chambon Voir le message
    Ainsi, la ligne this.execute(o); devrait appeler la méthode surchargée public void execute(String s) de la classe courante.
    absolument pas! la méthode appelée est de signature execute(Object) donc c'est celle là qui est appelée. Il n'y a pas de raison que ça marche comme tu penses.
    ainsi dans ton code tu peux avoir ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      void execute(Object o) {
       // effectivement tester si o est un String et alors
        this.execute((String) o) ;
     }
    et dans ce cas le compilateur choisira la bonne méthode.
    attention le compilateur décide à la compilation quelle signature de méthode rechercher, le polymorphisme joue ensuite mais avec cette signature.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Uther Voir le message
    Le plus simple serai simplement de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        public void execute(Object o) {
            if (o instanceof String){
              o = new String("another stupid string");
            }
        }
    Attention cependant affecter un string de la sorte sera sans effet vu que la variable o est perdue dès la sortie de la méthode.
    Oui je pense que c'est le plus simple. Plus précisément, on fera :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        public void execute(Object o) {
            if (o instance of String){
              this.execute((String)o);
            }
        }

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par william44290 Voir le message
    Bon est est d'accord exemple stupid mais

    est ce que cela boucle si tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public void execute(Object o) {		
    		this.execute((String) o);
    	}
    Non ca ne boucle pas. Mais ca voudrait dire que o est TOUJOURS une instance de String. Et parfois, je pourrais par exemple injecter dans la méthode public void execute(Object o) un Integer, ou un Float....

  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par professeur shadoko Voir le message
    absolument pas! la méthode appelée est de signature execute(Object) donc c'est celle là qui est appelée. Il n'y a pas de raison que ça marche comme tu penses.
    Et pourtant avec cette correction, ça marche :

    Mon main devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
             /**
             * A main method to test.
             * 
             * @param args
             *            an array of arguments. Not used here.
             */
    	public static void main(String args[]) {
                    A a = new A();
    		a.execute(new String("just a stupid string"));
    	}
    IA n'est plus utilisée. Et là, je tombe bien directement sur ma méthode surchargée public void execute(String s)

    C'est donc qu'au runtime, la méthode associé au vrai type de l'objet ne paramètre est appelée.

    Le souci est que je ne passe plus par mon Interface ; et comme j'utilise Spring IOC ....

  8. #8
    Membre très actif
    Avatar de william44290
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Juin 2009
    Messages
    400
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 400
    Par défaut
    En fait tu ne fais pas de surcharge de méthode. cela s'apparente à une problématique de polymorphisme.

  9. #9
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par nicolas.chambon Voir le message
    C'est donc qu'au runtime, la méthode associé au vrai type de l'objet ne paramètre est appelée.
    Lors d'une surcharge, le choix de la méthode ne s'effectue pas au runtime mais à la compilation, selon les informations à la disposition du compilateur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IA a = new A();
    a.execute(new String("just a stupid string"));
    On appelle la méthode execute() sur un objet déclaré en type IA : la seule méthode possible est la méthode execute(Object).


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    A a = new A();
    a.execute(new String("just a stupid string"));
    On appelle la méthode execute() sur un objet déclaré en type IA : on a deux méthodes possible, et c'est le type des paramètres qui va permettre au compilateur de préférer execute(String).



    Au runtime, la JVM se contente de recherche une redéfinition de la méthode dans une classe fille, mais en aucun cas d'une surcharge (qui peut alors être considéré comme une méthode avec un nom différent).




    Que veux tu faire précisément avec tout cela ???


    a++

    PS : Et à quoi servent tes new String("...") ???

  10. #10
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 690
    Par défaut
    Il faut séparer 2 problématique: le polymorphisme et la surcharge d'une méthode dans une classe.

    - Le polymorphisme a lieu lors de la réécriture d'une méthode dans la classe fille. Dans ce cas la c'est en effet le type réel de l'objet qui est utilisé pour savoir quelle méthode appeler.

    - La surcharge correspond a une méthode avec le même nom dans une classe, mais avec des paramètres de type et/ou de nombre différents. Dans ce cas la c'est le type déclaré qui est utilisé pour savoir laquelle de ces deux méthodes appeler.

  11. #11
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Février 2005
    Messages
    263
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2005
    Messages : 263
    Par défaut
    Bonjour,
    je rencontre un problème du même type.

    N'y a-t'il pas un moyen pour que le choix de la méthode soit fait à l'exécution? Car je n'ai pas vraiment envie de faire quelque centaines de test "instanceof"...

  12. #12
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 690
    Par défaut
    Non, du moins pas en utilisant directement le langage. Il te faudra passer par l'introspection pour faire cela:
    http://ricky81.developpez.com/tutori...api/reflection

Discussions similaires

  1. Réponses: 7
    Dernier message: 05/06/2014, 16h41
  2. Réponses: 1
    Dernier message: 28/06/2012, 10h33
  3. Méthode paint et surcharge
    Par Anduriel dans le forum 2D
    Réponses: 2
    Dernier message: 17/12/2011, 14h58
  4. Méthode implémentation SWT "MVC"
    Par threaded dans le forum SWT/JFace
    Réponses: 5
    Dernier message: 14/04/2011, 13h33
  5. utilisation par un fils d'une méthode qu'il surcharge ...
    Par money mark dans le forum Langage
    Réponses: 4
    Dernier message: 20/02/2006, 20h03

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