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

avec Java Discussion :

Problème sur le Polymorphisme


Sujet :

avec Java

  1. #1
    Membre régulier
    Inscrit en
    Janvier 2007
    Messages
    265
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 265
    Points : 98
    Points
    98
    Par défaut Problème sur le Polymorphisme
    Bonjour j'ai un soucis avec le polymorphisme j'ai en fait cet exemple là


    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
     
    public class Animal {
    	public static void direQuelqueChose() {
    		System.out.print(" Un Animal");
    	}
    }
     
    class Bovins extends Animal {
    	public static void direQuelqueChose() {
    		System.out.print(" Un Bovin!");
    	}
     
    	public static void main(String[] args) {
    		Animal[] animals = { new Animal(), new Bovins() };
    		for (Animal a : animals) {
    			a.direQuelqueChose();
    		}
    		new Bovins().direQuelqueChose();
    	}
    }
    Je m'attendais à cette sortie :

    un Animal Un Bovin Un Animal

    Or c'est la sortie du programme me fait tourner en bourrique !
    elle donne :
    Un Animal Un Animal Un Bovin!

    Si j'ai bien compris normalement, -dites le moi si je me trompe- le polymorphisme ne s'applique pas pour pour des membres static. Pourquoi que j'ai ce résultat ?
    Un Animal Un Animal Un Bovin!
    Soit j'ai rien compris au polymorphisme et à Java, soit il y a quelque chose qui cloche, mais je ne sais pas d'où ça peut venir

    Bien cordialement.

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2004
    Messages : 46
    Points : 61
    Points
    61
    Par défaut
    je ne suis pas sur de ma réponse. Mais généralement en java tu appelles une méthode statique par sa classe.

    par exemple dans ton cas tu devrais plutôt avoir : Animal.direQuelquechose();

    il se peut donc que la JVM ou qu'une optimisation au moment de la compilation transforme ton a.direquelquechose() en Animal.direquelquechose()

    c'est à vérifier. Mais dans tout les cas il serait plus propre de passer par des méthodes non statiques car tu utilises des objets instanciés.

  3. #3
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 570
    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 570
    Points : 15 535
    Points
    15 535
    Par défaut
    En effet le polymorphisme ne s'applique pas pour les méthodes statiques.

    C'est pour cela qu'il est conseillé d'utiliser NomDeClasse.méthode() pour les méthodes statiques. on pout ainsi spécifier la méthode de quelle classe on souhaites utiliser. C'est aussi plus logique car la méthode ne porte pas directement sur l'objet lui même mais sur la sa classe.

    Si tu utilises nomObjet.méthode() c'est le type déclaré qui sera utilisé et non le type effectif de l'objet (comme une pour une méthode non virtual en C++).

    Pour avoir un comportement comme tu le souhaite il faut utiliser des méthodes non statiques.

  4. #4
    Membre régulier
    Inscrit en
    Janvier 2007
    Messages
    265
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 265
    Points : 98
    Points
    98
    Par défaut
    Merci pour vos réponses
    Citation Envoyé par Uther Voir le message

    Si tu utilises nomObjet.méthode() c'est le type déclaré qui sera utilisé et non le type effectif de l'objet (comme une pour une méthode non virtual en C++).
    Vous voulez dire que les méthodes statiques ne regardent que les références, et pas l'objet déclaré sur le tas ?


    Citation Envoyé par Uther Voir le message
    Pour avoir un comportement comme tu le souhaite il faut utiliser des méthodes non statiques.
    Pour ma part quand j'appellle une méthode statique, c'est toujours maclasse.methodestatique();
    Que voulez vous que je vous dise ? j'ai bien conscience que c'est une question stupide, pour pas dire débile, mais étant donné que je dois passer le scjp bientôt, cette kholle figurait dans un des tests. Je ne comprenais pas l'explication du résultat. Sun n'a que ça à faire, pour valider des connaissances ridicules, il faut que la bête passe par des tests d'intelligence qui n'apporte rien de concret, mais qu'alimenter un certain genre de commerce, celui des pseudos-formations. Je n'aime pas ces tests, pour être franc, mais hélas, on ne me demande pas mon avis. J'ai pris quatres semaines de conger pour cette saloperie de certif. C'est vous dire mon point d'exaspération.
    En tout cas merci pour votre aide les amis, ça me réconforte, c'est déja ça.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2004
    Messages : 46
    Points : 61
    Points
    61
    Par défaut
    haaa les certifs. dans ce cas va faire un tour sur java black belt http://www.blackbeltfactory.com/Home.wwa tu y trouveras toutes sortes de tests

  6. #6
    Expert éminent sénior Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 570
    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 570
    Points : 15 535
    Points
    15 535
    Par défaut
    Vous voulez dire que les méthodes statiques ne regardent que les références, et pas l'objet déclaré sur le tas ?
    Tout a fait.

    Pour ma part quand j'appellle une méthode statique, c'est toujours maclasse.methodestatique();
    Rien ne l'interdit mais, si les normes de codage officielles le déconseillent, c'est justement parce que ca peut être trompeur dans ce cas.

  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,

    Citation Envoyé par Uther Voir le message
    Rien ne l'interdit mais, si les normes de codage officielles le déconseillent, c'est justement parce que ca peut être trompeur dans ce cas.
    D'ailleurs certains compilateurs comme eclipse peuvent génèrer un warning dans ce cas là.



    Pour comprendre ce phénomène il faut comprendre les différents modes d'invocation de méthode.

    Par exemple prenons le cas suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Type t = ...;
     
    t.uneMethode();
    Selon le type Type et la méthode, on peut se retrouver dans plusieurs cas :

    • Si Type est une interface, à la compilation cela génèrera un invokeinterface. Ce qui signifie qu'à l'exécution le type réel de l'objet sera obligatoirement vérifié afin de déterminé la méthode qui sera exécuté.
    • Si Type est une classe et qu'il s'agit d'une méthode d'instance, la compilation génèrera un invokevirtual sur Type.uneMethode().
      A l'exécution le type réel de l'objet est vérifié dans le cas où la méthode serait redéfinie (c'est cette dernière qui sera alors réellement appelé).
    • Si Type est une classe et qu'il s'agit d'une méthode static, la compilation génèrera un invokestatic sur Type.uneMethode() sans qu'il n'y ait aucun lien avec l'instance utilisé.
      A l'exécution sera se traduit par un appel simple de méthode, sans aucune vérification du typeage.

    (a noter qu'il y a aussi invokespecial pour les méthodes super/private/constructeur, et prochainement un invokedynamic pour des résolutions dynamiques de méthodes spécifiques aux langages de scripts)


    Dans ton code on distingue deux types d'appel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    a.direQuelqueChose(); // a déclaré comme Animal
    Ici le compilateur traduit cela comme ceci en se basant uniquement sur le type déclaré de "a" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Animal.direQuelqueChose();

    A l'inverse lorsque tu fais ceci il se base sur le type Bovins :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new Bovins().direQuelqueChose();
    Et traduira cela comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Bovins.direQuelqueChose();

    En clair on a deux appel de méthode bien distinct, où tout est décidé dès la compilation (comme toujours pour les méthodes static).

    a++

  8. #8
    Membre régulier
    Inscrit en
    Janvier 2007
    Messages
    265
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 265
    Points : 98
    Points
    98
    Par défaut
    Merci à tous pour vos réponses, vos explications, et vos liens.

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

Discussions similaires

  1. Problème sur la recherche fulltext en v4 !
    Par poppa dans le forum Requêtes
    Réponses: 3
    Dernier message: 13/05/2004, 23h06
  2. Problème sur fiche MDIchild
    Par nivet dans le forum Composants VCL
    Réponses: 6
    Dernier message: 23/01/2004, 08h07
  3. Problème sur GetPrivateProfileString ???
    Par Bordelique dans le forum Langage
    Réponses: 7
    Dernier message: 25/06/2003, 22h15
  4. Problème sur une requête INSERT
    Par Marion dans le forum Langage SQL
    Réponses: 3
    Dernier message: 17/06/2003, 08h45
  5. problème sur une requête!!!!!
    Par Mcgrady_01 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 13/06/2003, 01h17

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