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 :

débutant java Polymorphisme


Sujet :

Langage Java

  1. #1
    Membre régulier
    Inscrit en
    Mai 2006
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 161
    Points : 118
    Points
    118
    Par défaut débutant java Polymorphisme
    bonjour,

    je viens de tester ce code:
    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
    class A {
    	public void f(double x){
    	    System.out.println("A.f(double="+x+")");
    	  }
    }	
     
    class C extends A {
    	  public void f(long q){
    	    System.out.println("c.f(long="+q+")");
    	} 
     
    	}
     class Polym {
        public static void main(String args[]){
        	byte bb =1; long q=4; float x = 5.f;
        	A a = new A();
        	C c=new C(); c.f(bb);c.f(q);c.f(x);
        	a = c;       a.f(bb);a.f(q);a.f(x);
     
        }
    }
    résultats:
    c.f(long=1) // c'est évidant
    c.f(long=4) // c'est évidant
    A.f(double=5.0) // c'est évidant
    A.f(double=1.0)// pour quoi? c-à-d :pas évidant pour moi!!
    A.f(double=4.0) // pour quoi? c-à-d :pas évidant pour moi !!
    A.f(double=5.0) // pour quo? c-à-d : pas évidant pour moi!!


    d'avance merci.

  2. #2
    Expert éminent sénior
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

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

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Points : 21 324
    Points
    21 324
    Par défaut
    Citation Envoyé par Bba_M
    A.f(double=1.0)// pour quoi? c-à-d :pas évidant pour moi!!
    A.f(double=4.0) // pour quoi? c-à-d :pas évidant pour moi!!
    A.f(double=5.0) // pour quo? c-à-d : pas évidant pour moi!!
    Quand tu fais a = c, tu ne fais que copier la référence de c dans a, mais a ne devient pas de type C pour autant, il est donc tout à fait normal que ce soient toujours les méthodes de a qui soient appelées.

    Le fait de mettre la référence de c dans a, ne vas pas dire que a va employer les méthodes de c, il va juste prendre ses champs.

  3. #3
    Membre régulier
    Inscrit en
    Mai 2006
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 161
    Points : 118
    Points
    118
    Par défaut
    Citation Envoyé par wichtounet
    Quand tu fais a = c, tu ne fais que copier la référence de c dans a, mais a ne devient pas de type C pour autant, il est donc tout à fait normal que ce soient toujours les méthodes de a qui soient appelées.

    Le fait de mettre la référence de c dans a, ne vas pas dire que a va employer les méthodes de c, il va juste prendre ses champs.
    merci pour les réponses. j'ai éssayé ce code(pour comparer le résultat avec le précedant):

    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
    class A {
    public void affiche(){
    	System.out.print("je suis A ");
    }
    }
    class C extends A{
    	public void affiche(){
    		System.out.print("je suis C ");		
    	}
    }
     
    class Poly{
    	public static void main(String[]args){
    		A a = new A(); a.affiche();System.out.println();
    		C c = new C(); c.affiche();
    		a = c; a.affiche();
    	}
    }
    résultats:
    je suis A.
    je suis C je suis C. // ici c'est pas contradictoire avec le précedant?. normelment selon ce que vous aves dit : a= c; puis a.affiche() va appeler la méthode de "a" mais le résultat dit l'inverse c à d: a.affiche() a appelé la méthode de "c"( donc "a" a employé la méthode de "c".) n'est ce pas !.
    merci de m'expliquer ça. je ne comprend rien

  4. #4
    Expert éminent sénior
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Suisse

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

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Points : 21 324
    Points
    21 324
    Par défaut
    En fait, ce que j'ai dit est assez bête Je mélangeais tout...

    C'est pas vrai, il va quand même appeller la méthode de C si tu mets la référence de c dans a, ce qui est logique.

    Le problème avec ton premier exemple, vient du fait que les méthodes n'ont pas la même signature. Donc, quand tu fais a.uneMéthode(), il va appeller la meilleure méthode pour ce chiffre (dans ce cas avec long), mais dans le cas de c, il ne connait pas la méthode avec un long en paramètre, il ne connait que celle avec un double et va donc l'appeller.

  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,


    C'est une question interressante car il y a plusieurs concepts mis en oeuvre.

    Dans un premier temps il faut savoir que les types primaires sont convertit automatiquement vers un type plus grand lorsque cela s'avère neccessaire. Par exemple si une méthode attend un double, tu pourras lui passer un short, un int, un long ou un float sans que cela ne provoque d'erreur ou de warning : la valeur est automatiquement convertit en double. L'inverse n'est pas vrai car on pourrait alors avoir une perte de précision...

    Enfin les signatures des méthodes en Java sont définis par deux éléments :
    • son nom.
    • le nombre et le type de ses paramètres.
    Ainsi, dans ton premier exemple, tu as deux méthodes distinctes f(long) et f(double), même si elle ont le même nom. On parle alors de surcharge (overload en anglais).
    Donc d'après l'héritage, la classe A ne possède qu'une méthode f(double), alors que la classe C possède les méthodes f(long) et f(double) (qu'elle hérite directement de A).


    Pour comprendre le résultat que tu obtiens, il faut comprendre le principe le la compilation. Lorsque tu compiles ton code, le compilateur recherche la signature de méthode qui sera appellée en se basant sur le type déclaré de la variable (il y a un nom exact pour cela mais je ne m'en souviens plus ).

    Ainsi lorsques tu compile le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    C c=new C(); c.f(bb);c.f(q);c.f(x);
    Comme c est déclaré en tant que C, le compilateur a le choix d'utiliser f(long) ou f(double), ce qu'il fera selon le type du paramètre que tu lui passes...

    Mais lorsque tu compiles ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    A a = c;     a.f(bb);a.f(q);a.f(x);
    Comme a est déclaré en tant que A, le compilateur a un seul et unique choix : la méthode f(double) ! Donc il appelera forcément cette dernière et convertira automatiquement les types en double...

    Le compilateur ne se base en aucun cas sur le type réel de l'objet mais uniquement sur son type déclaré. En effet, il ne peut pas forcément connaitre le type réel de l'objet.






    Dans ton second exemple par contre, tu n'a qu'un seul et unique méthode affiche(), puisque son nom et ses "paramètres" sont identique. On parle ici de redéfinition de méthode par une classe fille (override en anglais).

    Donc ici dans tous les cas le compilateur va "appeller" la méthode affiche().


    La différence se situe alors à l'exécution. En java toutes les méthodes sont virtual par défaut. C'est à dire que la JVM recherchera la vrai méthode à appeller à l'exécution en cas de redéfinition. Ainsi lorsque la JVM exécute le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    C c = new C(); c.affiche();
    Le compilateur demande d'exécuter la méthode affiche() sur un objet du type C.
    A l'exécution la JVM vérifie le type exact (qui est bien C) et appelle la méthode affiche() de C --> "Je suis C".

    Mais lorsque tu exécutes ceci :
    Le compilateur demande d'exécuter la méthode affiche() sur un objet du type A.
    A l'exécution la JVM vérifie le type exact (qui est C et non A) et appelle la méthode affiche() de C --> "Je suis C".



    Je ne sais pas si je suis bien clair... n'hésites pas a demander des détails

    a++

  6. #6
    Membre éclairé
    Avatar de bbclone
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 537
    Points : 704
    Points
    704
    Par défaut
    > il y a un nom exact pour cela mais je ne m'en souviens plus

    early binding.

    un peu apres dans ta super lesson tu a parler de late binding mais tu n'a pas dit le nom non plus :-)

  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
    Citation Envoyé par bbclone
    > il y a un nom exact pour cela mais je ne m'en souviens plus

    early binding.

    un peu apres dans ta super lesson tu a parler de late binding mais tu n'a pas dit le nom non plus :-)

  8. #8
    Membre régulier
    Inscrit en
    Mai 2006
    Messages
    161
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 161
    Points : 118
    Points
    118
    Par défaut
    merci à vous et à tous. Excellent.
    mais il reste quelqs choses que j'ai pas encore compris l'écriture ci-dessus.
    le reste est trés claire et logique pour moi.
    en effet,

    la question que je me pose c'est pour quoi la JVM n'intrevient pas dans le premier exemple et vérifier le type exact??.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    A a = c;     a.f(bb);a.f(q);a.f(x);// premier Exemple
    et intervient dans le deuxiéme. Est ce que c'est un choix pour "SUN" ou autre chose??. et on peut dire la méme chose dans le deuxiéme exemple c-à-d: pour ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    A a = c;       a.affiche();//deuxième Exemple
    pour quoi on ne peut pas dire : Comme a est déclaré en tant que A, le compilateur appelera forcément la methode affiche() de a et non celle de c? .

  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
    Parce que les deux méthodes f() ne sont pas les mêmes, contrairement aux méthodes affiche() qui sont "les mêmes" puisqu'il y a une redéfinition de méthode...

    Si le compilateur code un appel à f(double), la JVM n'appellera pas f(long)...

    a++

Discussions similaires

  1. débutant JAVA+Eclipse
    Par ep31 dans le forum Eclipse Java
    Réponses: 8
    Dernier message: 12/12/2005, 14h27
  2. [Débutant][Java] Web Service
    Par ArseNic dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 14/11/2005, 11h09
  3. Réponses: 2
    Dernier message: 25/07/2004, 23h24
  4. [Débutant] java.lang.object
    Par bonnefr dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 27/05/2004, 14h54
  5. [débutante][java]connection internet PPC\PC de bureau
    Par Emma20 dans le forum Développement
    Réponses: 2
    Dernier message: 19/05/2004, 14h01

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