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 :

le typage en java et la recherche de la méthode en cas d'une redéfinition


Sujet :

avec Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    12
    Inscrit en
    Mai 2014
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : 12
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 67
    Par défaut le typage en java et la recherche de la méthode en cas d'une redéfinition
    bonsoir à tous,

    dans le cas d'un héritage avec une redéfinition des méthodes comment est ce que java cherche la bonne méthode ? moi j'ai rien pigé!et c'est la raison derrière les questions suivantes :


    soit A la classe mère de B :

    question 1 : dans l'instruction A a = new B(); est ce cela veut dire qu'on ne crée dans a que la partie de B qui n'existe pas en A ?!

    question 2 : A a = (B) b ;
    c'est quoi la différence entre cette écriture et celle-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    A a = new A();
    B b = new B();
    a=b;
    dans le cours le prof a écris que A a = (B) b n'est correcte que si la classe B est une sous-classe de A,(je comprends ça) mais il a ajouté que ( le type déclaré de b est une superclasse de B ) il est où le type déclaré de b dans l'instruction A a = (B) b ? (mes questions sont stupides? desolé mais je viens de commencer le cours)

    3 ème question : recherche de la méthode à exécuter :
    soit le code suivant :
    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
    25
     
    class A{
      void m(A a){
        System.out.println("m de A");
      }
      void n(A a){
        System.out.println("n de A");
      }
    }
     
     
    class B extends A{
      void m(A a){
        System.out.println("m de B");
      }
      void n(B b){
        System.out.println("n de B");
      }
      public static void main(String[] argv){
        A a = new B();
        B b = new B();
        a.m(b);
        a.n(b);
      }
    }
    qu'est ce qu'affichera l'exécution de la méthode main de B ?

    Réponse:

    m de B
    n de A

    pourquoi ce choix de méthodes ?

  2. #2
    Membre confirmé
    Homme Profil pro
    12
    Inscrit en
    Mai 2014
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : 12
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 67
    Par défaut
    voilà la procédure trouvée sur le net :
    Pour le premier envoi de message a.m(b) :
    – etape ´ 1 : la classe ou` chercher la methode ´ est celle declar ´ ee´ pour a, c’est a` dire A.
    – etape ´ 2 : il n’y a qu’une methode ´ de nom m dans A. Elle a pour type A → void.
    – etape ´ 3 : le type fixe´ est A → void.
    – a` l’execution, ´ la recherche de la methode ´ m de type A → void se fait dans le type le plus petit
    ou type d’instance de a, c’est a` dire B. Il y a la` la methode ´ m de B qui a le bon type. C’est elle
    qui est execut ´ ee. ´
    Pour le deuxieme ` envoi de message, a.n(b) :
    – etape ´ 1 : la classe ou` chercher la methode ´ est celle declar ´ ee´ pour a, c’est a` dire A.
    – etape ´ 2 : il n’y a qu’une methode ´ de nom n dans A. Elle a pour type A → void.
    – etape ´ 3 : le type fixe´ est A → void.
    – a` l’execution, ´ la recherche de la methode ´ n de type A → void se fait dans le type le plus petit
    ou type d’instance de a, c’est a` dire B. La methode ´ n de B ne convient pas, car elle n’a pas le
    bon type. La methode ´ n de A convient. Elle a le bon type et elle est presente ´ dans la classe B
    par heritage. ´ C’est elle qui est choisie.
    Merci..

  3. #3
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par DLOYAS Voir le message
    question 1 : dans l'instruction A a = new B(); est ce cela veut dire qu'on ne crée dans a que la partie de B qui n'existe pas en A ?!
    Non, ça veux dire exactement ce qui est écrit: on crée un B et on stocke sa référence dans une variable appelée a.
    Citation Envoyé par DLOYAS Voir le message
    question 2 : A a = (B) b ;
    c'est quoi la différence entre cette écriture et celle-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    A a = new A();
    B b = new B();
    a=b;
    Dans le deuxième cas on a créé un A que l'on a jeté tout de suite, et qui ne sert à rien puisqu'il est remplacé dans la variable a par la référence au nouveau B() créé juste avant


    dans le cours le prof a écris que A a = (B) b n'est correcte que si la classe B est une sous-classe de A,(je comprends ça) mais il a ajouté que ( le type déclaré de b est une superclasse de B ) il est où le type déclaré de b dans l'instruction A a = (B) b ? (mes questions sont stupides? desolé mais je viens de commencer le cours)
    Il n'est pas dedans, il se situe avant, sous la forme, par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Object b; //le type déclaré est Object
    B b; // le type déclaré est B
    ou
    Tartempion b; // le type déclaré est Tartempion
    D'ailleurs ton prof omet un cas bien que franchement faut être con pour typecaster dans ce cas là car c'est inutile:
    le type déclaré de b est une superclasse ou une sous classe de B

    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
    25
     
    class A{
      void m(A a){
        System.out.println("m de A");
      }
      void n(A a){
        System.out.println("n de A");
      }
    }
     
     
    class B extends A{
      void m(A a){
        System.out.println("m de B");
      }
      void n(B b){
        System.out.println("n de B");
      }
      public static void main(String[] argv){
        A a = new B();
        B b = new B();
        a.m(b);
        a.n(b);
      }
    }
    qu'est ce qu'affichera l'exécution de la méthode main de B ?
    Le choix se fait en deux étapes. A la compilation on détermine les signatures de méthodes, à l'exécution on détermine la méthode réelle correspondant aux signature. La première étape utilise les types déclarés, la secondes les type actuels

    A est le type déclaré, il a deux méthode: m(A) et n(A), le code est donc traduit par le compilateur en un truc du genre


    a.m_A(b); //appeler m(A) sur l'instance a avec le paramètre l'instance b
    a.n_A(b);//appeler n(A) sur l'instance a avec le paramètre l'instance b


    a l'exécution, a référence une instance de type B. On cherche donc sur B une méthode m_A et une méthode n_A. m_A est bien redéfini dans B, mais n_A n'existe que dans le parent A

    pour dire autrement, dans B, ta méthode m est une redéfinition de la méthode m de A, car elle a les même paramètres, mais ta méthode n est une nouvelle méthode, distincte de celle présente dans A car les paramètres sont différents.

  4. #4
    Membre confirmé
    Homme Profil pro
    12
    Inscrit en
    Mai 2014
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : 12
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 67
    Par défaut
    Merci cher Ami,

    pour A a = (B) b on a declaré une reference de type B et on l' a stocké dans une réference a de type A ?
    pour
    @Ttchize_ : ( Non, ça veux dire exactement ce qui est écrit: on crée un B et on stocke sa référence dans une variable appelée a )

    une variable appelée a [ de type A ],c'est ça je que tu voulais dire bien sûr ... ?

    @Ttchize_ :
    ( D'ailleurs ton prof omet un cas bien que franchement faut être con pour typecaster dans ce cas là car c'est inutile )

    il a ajouté que ( le type déclaré de b est une superclasse de B ),je trouve ça un peu logique, je pense qu'il parlait de ce cas la :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Forme f = new Ce r c l e ( ) ;
    Ce r c l e c = ( Ce r c l e ) f ; // le type declaré de f est Forme, il est une superclasse de Cercle 
    Ca rr e r = ( Ca rr e ) f ;

    pourquoi la conversion
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Ca rr e r = ( Ca rr e ) f
    conversion provoque une erreur ?





    merci beaucoup pour ton explication

  5. #5
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par DLOYAS Voir le message
    Merci cher Ami,

    pour A a = (B) b on a declaré une reference de type B et on l' a stocké dans une réference a de type A ?
    Non, on a déclaré plus avant une variable (on ne déclare pas vraiment une référence, une référence c'est juste une valeur) appelée b de type que je ne connais pas puisque je n'ai pas le code qui va avec. On a déclaré aussi une variable a de type A. On prend la référence stockée dans b, on vérifie qu'elle est bien du type B et on copie cette référence dans a.


    Citation Envoyé par DLOYAS Voir le message
    une variable appelée a [ de type A ],c'est ça je que tu voulais dire bien sûr ... ?
    Oui la variable est déclaré de type A.


    @Ttchize_ :
    ( D'ailleurs ton prof omet un cas bien que franchement faut être con pour typecaster dans ce cas là car c'est inutile )

    il a ajouté que ( le type déclaré de b est une superclasse de B ),je trouve ça un peu logique, je pense qu'il parlait de ce cas la :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Forme f = new Ce r c l e ( ) ;
    Ce r c l e c = ( Ce r c l e ) f ; // le type declaré de f est Forme, il est une superclasse de Cercle 
    Ca rr e r = ( Ca rr e ) f ;
    Oui, je te te signale juste que ce code aussi est valide:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Cercle c = new Cercle ();
    Objet o = (Forme)c;
    Cercle n'est pas une superclasse de Forme, mais le typecasting reste valide, bien qu'inutile

    pourquoi la conversion
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Ca rr e r = ( Ca rr e ) f
    conversion provoque une erreur ?
    Il provoque une erreur à l'exécution. La compilation se passera sans problème, le type déclaré "Forme" est bien un supertype de Carre. Par contre, a l'exécution, la jvm va se retrouve avec f qui contient un Cercle, un Cercle ce n'est pas une Carre, il y a donc une erreur. Le typecasting ne sert qu'à indique au compilateur ce que tu t'attends à trouver comme objet. Il ne transforme pas l'objet. Un Cercle ne va pas magiquement devenir un Carre.

  6. #6
    Membre confirmé
    Homme Profil pro
    12
    Inscrit en
    Mai 2014
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : 12
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 67
    Par défaut
    je te remercie infiniment tchize_

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


    Juste une remarque complémentaire vis à vis du code initial de la classe B :

    • La méthode m(A) de B est bien une redéfinition de la méthode m(A) de A (ce qui fait que c'est bien la méthode du type réel qui est appelée).
    • Par contre la méthode n(B) de B n'est pas une redéfinition de la méthode n(B) de A puisque les paramètres diffèrent ! Il s'agit en fait d'une surcharge (même nom mais paramètres différents).


    On peut le voir en rajoutant l'annotation @Override sur ces méthodes : cela génèrera une erreur pour la méthode n(B)...


    Malgré leurs noms identiques, pour la JVM il n'y a aucun rapport entre n(A) et n(B).
    Elles pourraient très bien avoir des noms différents...



    a++

Discussions similaires

  1. DM Java liste, parcours, recherche
    Par kichnifou dans le forum Général Java
    Réponses: 2
    Dernier message: 17/10/2011, 13h15
  2. Réponses: 6
    Dernier message: 04/01/2011, 18h18
  3. JAVA : Marquer et rechercher code modifié
    Par ywan42 dans le forum Général Java
    Réponses: 10
    Dernier message: 26/08/2010, 15h04
  4. [JAVA & PL/SQL] Recherche d'informations
    Par ArCal dans le forum PL/SQL
    Réponses: 8
    Dernier message: 08/01/2008, 11h11
  5. [JAVA & PL/SQL] Recherche d'informations
    Par ArCal dans le forum SQL
    Réponses: 8
    Dernier message: 08/01/2008, 11h11

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