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

  1. #1
    Membre actif
    Avatar de mathk
    Inscrit en
    Décembre 2003
    Messages
    211
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 211
    Points : 233
    Points
    233
    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?
    Si grande est la faiblesse d'une âme, dont la raison est partie!
    Ne jamais embrouiller ni abasourdir par une foule d'images le génie intérieur qui réside au fonde de sa poitrine,...
    L'ambition est le rfuge de l'échec. "Oscar Wild"

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

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 108
    Points : 3 203
    Points
    3 203
    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?
    Systèmes d'Informations Géographiques
    - Projets : Unlicense.science - Apache.SIS

    Pour un monde sans BigBrother IxQuick ni censure RSF et Les moutons

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

    Z et Y ont une influance
    Si grande est la faiblesse d'une âme, dont la raison est partie!
    Ne jamais embrouiller ni abasourdir par une foule d'images le génie intérieur qui réside au fonde de sa poitrine,...
    L'ambition est le rfuge de l'échec. "Oscar Wild"

  4. #4
    Expert éminent
    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
    Points : 7 679
    Points
    7 679
    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 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 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 confirmé
    Inscrit en
    Mai 2007
    Messages
    335
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 335
    Points : 511
    Points
    511
    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.

  7. #7
    Membre actif
    Avatar de mathk
    Inscrit en
    Décembre 2003
    Messages
    211
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 211
    Points : 233
    Points
    233
    Par défaut
    Ok donc petite question subsidiaires:

    b.m(z)
    a.m(y)
    Si grande est la faiblesse d'une âme, dont la raison est partie!
    Ne jamais embrouiller ni abasourdir par une foule d'images le génie intérieur qui réside au fonde de sa poitrine,...
    L'ambition est le rfuge de l'échec. "Oscar Wild"

  8. #8
    Membre éclairé Avatar de bassim
    Homme Profil pro
    Ingénieur Réseaux
    Inscrit en
    Février 2005
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur Réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2005
    Messages : 666
    Points : 695
    Points
    695
    Par défaut
    si le résultat n'est pas : alors c'est quoi ??
    Where is my mind

  9. #9
    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 bassim
    si le résultat n'est pas : alors c'est quoi ??
    Seul la méthode foo(Z) peut être appelé, donc le résultat est forcément :
    Et cela implique que x et z soit des types compatibles avec Z.


    Sinon cela provoquera un erreur de compilation.


    Le pseudo-code est trompeur et manque de précision...

    a++

  10. #10
    Membre actif
    Avatar de mathk
    Inscrit en
    Décembre 2003
    Messages
    211
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 211
    Points : 233
    Points
    233
    Par défaut
    Citation Envoyé par adiGuba
    Le pseudo-code est trompeur et manque de précision...
    Quel tromperie

    Une petite conclusion a cela. Avant de passer au veritable problemes
    En Java le type statique influance l'execution.
    Si grande est la faiblesse d'une âme, dont la raison est partie!
    Ne jamais embrouiller ni abasourdir par une foule d'images le génie intérieur qui réside au fonde de sa poitrine,...
    L'ambition est le rfuge de l'échec. "Oscar Wild"

  11. #11
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par mathk
    Quel tromperie

    Une petite conclusion a cela. Avant de passer au veritable problemes
    En Java le type statique influance l'execution.
    Moi, je dirais surtout comme deltree:

    "c'est le type déclaré de la variable qui permet de retrouver la méthode appelée"

    Ou, en plus simple: Lorsqu'une instance est "castée" en interface, seules les methodes de l'interface sont accessibles.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     B b = new B()
     A a = new A()
     
     A bA = b
     
     bA.foo(y)
     bA.foo(z)
    comme "ba" est de type "A", les appels "ba.foo(...)" appeleront toujours "A.foo(...)".

    (Seule exception a la regle: l'overriding.)
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  12. #12
    Membre actif
    Avatar de mathk
    Inscrit en
    Décembre 2003
    Messages
    211
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 211
    Points : 233
    Points
    233
    Par défaut
    Citation Envoyé par pseudocode
    "c'est le type déclaré de la variable qui permet de retrouver la méthode appelée"
    Oui typer déclaré = type statique
    Si grande est la faiblesse d'une âme, dont la raison est partie!
    Ne jamais embrouiller ni abasourdir par une foule d'images le génie intérieur qui réside au fonde de sa poitrine,...
    L'ambition est le rfuge de l'échec. "Oscar Wild"

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