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 :

Petite devinette sur l'overloading


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Avatar de mathk
    Inscrit en
    Décembre 2003
    Messages
    211
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 211
    Par défaut Petite devinette sur l'overloading
    bonjour,

    Une petite devinette pour les amoureux des types:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class A
         public foo(Z z)
             print  "a.foo"
     
    class B extend A
     
        public foo(Y y)
             print "b.foo"

    Y herite de Z

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     B b = new B()
     A a = new A()
     
     A bA = b
     
     bA.foo(y)
     bA.foo(z)
    Donc quelqu'un sias t'il quel est le resultat des 2 dernieres instructions (sans utiliser de VM)?

    Quelqu'un sais t'il l'expliquer?

  2. #2
    Rédacteur
    Avatar de eclesia
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    2 111
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 111
    Par défaut
    Z et Y sont des classes inconnues qui n'ont aucune incidence sur le code présenté.

    la procédure foo n'est pas un constructeur et pas de d'appelle a la fonction parente vu qu'il n'y a pas de "super()"

    bA même s'il est traité comme un objet de classe A est toujours un objet de classe B, donc pour "bA.foo(y)" on utilise la methode de la classe B.

    alors je dirais pour ca :
    bA.foo(y)
    bA.foo(z)

    donne :
    b.foob.foo


    non?

  3. #3
    Membre expérimenté
    Avatar de mathk
    Inscrit en
    Décembre 2003
    Messages
    211
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 211
    Par défaut
    Non
    D'autre tentative.

    Z et Y ont une influance

  4. #4
    Expert confirmé
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Par défaut
    Logiquement, le résultat devrait être :
    explication :
    bA.foo(y) est en fait B.foo car sa signature correspond.
    bA.foo(z) est en fait A.foo car sa signature correspond, malgré le fait que bA soit instancié avec B mais Java garde toujours trace de toute l'hiérarchie des méthodes redéfinies.

    mais c'est faux ! j'ai essayé ce bout de code sur la JVM 6.0 et c'est pas le bon résultat !
    J'ai beau me creuser les méninges, je n'arrive pas à trouver l'explication ... ça remet en cause les fondements du mécanisme des méthodes virtuelles de Java ...
    Voilou ! C'est un méchant méchant piège mathk !

  5. #5
    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 Modjo
    ça remet en cause les fondements du mécanisme des méthodes virtuelles de Java ...
    Non : Les deux méthodes n'ont pas la même signature ! Il n'y a donc pas d'héritage.

    Comme c'est dit dans le titre il s'agit overloading (surcharge) et non pas d'overriding (redéfinition) : il s'agit donc de deux méthodes distinctes qui n'ont pas de lien de parenté, ce qui n'implique pas de mécanisme d'héritage...

    D'ailleurs on peut bien voir cela avec Java 5.0 et + en utilisant l'annotation @Overrides sur foo(Y), qui génèrera une erreur car justement elle ne redéfinit pas une méthode parente...


    En fait c'est comme si on avait deux méthodes avec des noms différents : fooY() et fooZ(), sauf que c'est le compilateur qui gère cette différence selon le type des paramètres...


    Donc lorsque le compilateur voit le code suivant :
    Il recherche les méthodes à appelées, et là on a deux cas distinct :
    • Les classes Y et Z n'ont aucun lien de parenté, et le compilateur émettra une erreur car la classe A ne définit aucune méthode foo(Y) (ou "compatible").
    • La classe Y hérite de Z, et dans ce cas le compilateur effectuera un appel de la méthode foo(Z) en lui passant une instance de Y.



    a++

  6. #6
    Membre expérimenté
    Inscrit en
    Mai 2007
    Messages
    335
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 335
    Par défaut
    Je ne saurais mieux dire
    Cet exemple met simplement en évidence la différence fondamentale entre surcharge et redéfinition en Java.

    Il y a plusieurs moyen de se rappeler simplement l'impact d'une surcharge:
    -"La surcharge est résolue à la compilation": donc c'est le type déclaré de la variable qui permet de retrouver la méthode appelée et non pas le type de l'objet au Runtime. (donc comme si c'était 2 méhode différentes)

    -"La redéfinition est résolue à l'exécution (au Runtime)": c'est la base du mécanisme du polymorphisme, et des avantages de l'objet.

    La leçon à retenir de l'exercice, c'est que lorsqu'on veut du polymorphisme, il faut bien passer par une redéfinition (et donc bien choisir la signature de la méthode à surcharger) et jamais par une surcharge.

    Il y a un moyen d'être quand même polymorphe avec une surcharge, en les faisant toutes au niveau de la classe de base, et en testant les instanceOf mais comme tous les moyens détournés, c'est fortement déconseillé, mieux vaut utiliser le polymorphisme Java tel qu'il est prévu et en accepter les règles AMHA.

Discussions similaires

  1. [Visuel XP] Petite question sur le theme XP...
    Par ZoumZoumMan dans le forum C++Builder
    Réponses: 12
    Dernier message: 20/01/2005, 14h41
  2. Petite aide sur les triggers ?
    Par krimson dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 16/04/2004, 16h28
  3. [Kylix] Petit Récapitulatif sur Kylix3
    Par PtitD@v dans le forum EDI
    Réponses: 1
    Dernier message: 24/02/2004, 14h46
  4. [jointure] Petit problème sur le type de jointure...
    Par SteelBox dans le forum Langage SQL
    Réponses: 13
    Dernier message: 13/02/2004, 18h55
  5. Petite question sur les performances de Postgres ...
    Par cb44 dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 13/01/2004, 13h49

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