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

Entrée/Sortie Java Discussion :

Demande d'explications sur le choix de la meilleure (et unique) méthode


Sujet :

Entrée/Sortie Java

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Consultant Formateur Mainframe
    Inscrit en
    Septembre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Consultant Formateur Mainframe
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2012
    Messages : 15
    Points : 39
    Points
    39
    Par défaut Demande d'explications sur le choix de la meilleure (et unique) méthode
    Bonjour,

    Voici un exercice tiré du livre "Exercices en Java" de Claude Delannoy (Editions Eyrolles) et pour ceux qui ont le livre, il s'agit de l'exercice n°66 "dérivations successives et surdéfinition".

    ... (je cite le livre)

    Quels résultats fournit le programme 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
    26
    27
    class A
    { public void f(double x) { System.out.print ("A.f(double=" + x +")" ; } }
    class B extends A {}
    class C extends A
    { public void f(long q)  { System.out.print ("C.f(long="   + q + ") " ; } }
    class D extends C
    {public void f(int n){System.out.print("D.f(int="+n+")");} }
    class E extends B {}
    class F extends C
    { public void f(float x){ System.out.print("F.f(float="+x+")");}
       public void f(int n){ System.out.print("F.f(int="+n+")");} }
     
    public class Surdf {
     
    	/**
             * @param args
             */
    	public static void main(String[] args) {
    		byte bb=1; short p=2; int n=3; long q=4; float x=5.f; double y=6.;
    		A a = new A(); a.f(bb); a.f(x); 							System.out.println();
    		B b = new B(); b.f(bb); a.f(x); 							System.out.println();
    		C c = new C(); c.f(bb); c.f(q); c.f(x); 					System.out.println();
    		D d = new D(); d.f(bb); c.f(q); c.f(y); 					System.out.println();
    		E e = new E(); e.f(bb); e.f(q); e.f(y); 					System.out.println();
    		F f = new F(); f.f(bb); f.f(n); f.f(x); f.f(y); f.f(p);		System.out.println();
    	}
    }
    le résultat obtenu est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    A.f(double=1.0)A.f(double=5.0)
    A.f(double=1.0)A.f(double=5.0)
    C.f(long=1)C.f(long=4)A.f(double=5.0)
    D.f(int=1)C.f(long=4)A.f(double=6.0)
    A.f(double=1.0)A.f(double=4.0)A.f(double=6.0)
    F.f(int=1)F.f(int=3)F.f(float=5.0)A.f(double=6.0)F.f(int=2)
    l'Auteur précise : ...

    Ici, on fait intervenir à la fois la redéfinition d’une méthode et sa surdéfinition. Pour résoudre un appel de la forme o.f(v) (o étant un objet et v une expression), on recherche toutes les méthodes acceptables, à la fois dans la classe de o et dans toutes ses ascendantes. On utilise ensuite les règles habituelles de recherche de la meilleure (et unique) méthode. En définitive, le programme fournit les résultats suivants (notez que certaines conversions peuvent apparaître) :

    ... (fin de citation du livre)

    Qui pourrait expliquer (simplement :-) les critères qui ont déterminé le choix de la meilleure méthode pour chaque ligne de code ?

    Sans en être sur, je suppose qu'il doit s’agir d'un problème d'affectation sans perte d'information ... mais je n'ai trouvé aucun tutoriel ou article sur ce sujet précis ou j'ai mal cherché ;-).

    Merci pour vos commentaires et explications.

    Cordialement.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Le choix se fait sur la base du type connu (le type de la "variable") de ce qui est passé en paramètre (dans le cas de type primitif, c'est simple, c'est le type ; pour des classes, c'est la classe la plus proche, du plus bas au plus haut dans la hiérarchie).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int ii=0;
    double dd=0d;
    long ll=0L;
    D d = new D();
    d.f(ii); // appel D.f(int)
    d.f(dd); // appel D.f(double), soit A.f(double)
    d.f(ll); // appel D.f(long), soit C.f(double)
    Le sujet est abordé plus en détail dans cette récente discussion. Et en quelque sorte ici aussi (c'est le corrollaire).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre chevronné
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Points : 1 993
    Points
    1 993
    Par défaut
    Citation Envoyé par Demi Humain Voir le message
    Quels résultats fournit le programme suivant :
    Ca ne compile pas !

    Parce que :
    - on ne peut avoir qu'une seule définition de classe dans un seul et même fichier (sinon, il faudrait sortir toutes les classes A B C D E F...)
    - il manque des parenthèses fermantes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class A
    { public void f(double x) { System.out.print ("A.f(double=" + x +")" ; } } // <-- là
    class B extends A {}
    class C extends A
    { public void f(long q)  { System.out.print ("C.f(long="   + q + ") " ; } }// <-- et là
    Sans en être sur, je suppose qu'il doit s’agir d'un problème d'affectation sans perte d'information ...
    C'est exactement ça ! Et de concordance du plus proche type SUPERIEUR s'il n'y a pas de correspondance exacte

    Ici, on fait intervenir à la fois la redéfinition d’une méthode et sa surdéfinition.
    Marrant comme moi j'ai appris les termes de surcharge (overload : avoir une méthode qui a le même nom mais pas les mêmes paramètres) et de redéfinition (override : créer une signature de méthode dans une classe fille qui soit exactement la même que celle de la classe mère).
    Ca fait deux mots bien distincts en français, donc plus faciles à appréhender. Parce que le terme de surdéfinition, je...


    Ensuite, c'est parfaitement illisible, donc je comprends que ça n'aide pas à la compréhension !
    Reformatons cette horreur et faisons en sorte que tout tienne correctement dans le même fichier

    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
    public class Surfd {
     
    	public static void main(String[] args) {
    		byte bb = 1;
    		short p = 2;
    		int n = 3;
    		long q = 4;
    		float x = 5.f;
    		double y = 6.;
     
    		A a = new A();
    		a.f(bb);
    		a.f(x);		
    		System.out.println();
     
    		B b = new B();
    		b.f(bb);
    		a.f(x);
    		System.out.println();
     
    		C c = new C();
    		c.f(bb);
    		c.f(q);
    		c.f(x);		
    		System.out.println();
     
    		D d = new D();
    		d.f(bb);
    		c.f(q);
    		c.f(y);
    		System.out.println();
     
    		E e = new E();
    		e.f(bb);
    		e.f(q);
    		e.f(y);
    		System.out.println();
     
    		F f = new F();
    		f.f(bb);
    		f.f(n);
    		f.f(x);
    		f.f(y);
    		f.f(p);
    		System.out.println();
    	}
     
    	static class A {
    		public void f(double x) {
    			System.out.print("A.f(double=" + x + ")");
    		}
    	}
     
    	static class B extends A {
    	}
     
    	static class C extends A {
    		public void f(long q) {
    			System.out.print("C.f(long=" + q + ") ");
    		}
    	}
     
    	static class D extends C {
    		public void f(int n) {
    			System.out.print("D.f(int=" + n + ")");
    		}
    	}
     
    	static class E extends B {
    	}
     
    	static class F extends C {
    		public void f(float x) {
    			System.out.print("F.f(float=" + x + ")");
    		}
     
    		public void f(int n) {
    			System.out.print("F.f(int=" + n + ")");
    		}
    	}
    }
    Haaa, on respire...

    Bon, reprenons ligne par ligne pour bien comprendre ce qui se passe, et ajoutons des commentaires
    A a = new A(); c'est la classe mère ! Une seule méthode f(double)
    a.f(bb); on lui passe une valeur byte, ça lui va, un double peut contenir la valeur d'un byte --> ca affiche A.f(double=1)
    a.f(x); on lui passe une valeur float, ça lui va, un double peut contenir la valeur d'un float--> ca affiche A.f(double=5)

    Ensuite, B, qui par définition est une classe fille de A, qui n'a pas de méthodes. Elle hérite des méthodes et propriétés de A.
    Le résultat sera donc le même que les deux lignes précédentes

    Vient alors C, qui est une classe fille de A et qui possède une méthode f(int). C hérite des méthodes de A, et f(long) n'a pas la même signature que f(float), on a donc une extension de méthode. C se retrouve alors avec deux méthodes accessibles : f(float) et f(long).
    c.f(bb); ici, on commence les trucs drôles, à savoir la correspondance de type. Il n'y a pas de méthode dans C qui prenne un byte. Mais il y a un ordre de préférence s'il n'y a pas de type qui correspond. Dans le cas présent, on voit que le type byte passe de préférence dans une déclaration long (dans la classe C) plutôt qu'une déclaration double.
    c.f(q); ici on a un long, on passe donc bien dans la méthode de C directement (concordance de type exacte)
    c.f(x); ici on a un float. Nombre a virgule, donc ça ne peut pas tenir dans un long -> on passe dans le double, donc la méthode de A

    La classe D est une classe fille de C. Elle hérite de toutes ses méthodes, et rajoute une nouvelle signature f(int).
    D a donc trois méthodes visibles : f(double), f(long) et f(int)
    d.f(bb); on passe un byte à une classe qui possède une méthode qui accepte trois types. Le type le plus proche de byte, c'est int, du coup on passe dans D
    c.f(q); et là on on revient sur une instance de C... auquel on passe un long... ben donc c.f(long)...
    c.f(y);et encore une instance de C avec une variable double... ben donc c.f(double)...
    Pour les deux cas précédents, le résultat aurait été le même avec d.f(q) et d.f(y)

    E étend B... B ne définissait aucune méthode supplémentaires par rapport à A, et E ne définit rien du tout non plus... Du coup tout appel sera rigoureusement identique à un appel de la classe A.

    F étend C, qui étend A, et F définir deux méthodes : f(float) et f(int)
    C définissait f(long)
    A définit f(double)
    F a donc comme méthodes accessibles
    f(float) (venant de F)
    f(int) (venant de F)
    f(long) (venant de C)
    f(double) (venant de A)

    Et ici, on peut dire, qu'à AUCUN MOMENT on n'a de redéfinition de méthode ! Une redéfinition , ça aurait été de définir une méthode f(double) dans F.
    f.f(bb); on passe un byte, ca colle avec int -> F.f(int)
    f.f(n); on passe un int, ça colle avec F.f(int)
    f.f(x); on passe un float, ça colle avec F.f(float)
    f.f(y); on passe un double --> A.f(double)
    f.f(p); on passe un short... Ben int correspond bien -> F.f(int)


    Voilà, donc en fait, je trouve l'exemple et l'exercice très mauvais pour essayer de comprendre ce qui se passe.

    Le mieux pour comprendre, c'est de voir par type dans quoi on peut ranger la variable. On la range toujours dans le plus petit type qui correspond à la définition.
    Imaginons que tu ajoutes dans F les méthodes suivants :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public void f(short n) {
    			System.out.print("F.f(short=" + n + ")");
    		}
    		public void f(double n) {
    			System.out.print("F.f(double=" + n + ")");
    		}
    Quel sera le résultat?


    F.f(short=1)
    F.f(int=3)
    F.f(float=5.0)
    F.f(double=6.0)
    F.f(short=2)
    On passera à chaque fois dans les méthodes de F qui correspondent à chaque fois parfaitement au type passé en paramètre
    Je ne suis pas mort, j'ai du travail !

  4. #4
    Membre chevronné
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Points : 1 855
    Points
    1 855
    Par défaut
    Citation Envoyé par eulbobo Voir le message
    Marrant comme moi j'ai appris les termes de surcharge (overload : avoir une méthode qui a le même nom mais pas les mêmes paramètres) et de redéfinition (override : créer une signature de méthode dans une classe fille qui soit exactement la même que celle de la classe mère).
    Ca fait deux mots bien distincts en français, donc plus faciles à appréhender. Parce que le terme de surdéfinition, je...
    effectivement la terminologie laisse parfois à désirer sur certains documents en français (les barbarismes et les approximations abondent!)
    j'utilise specialisation pour overriding, mais redéfinition me convient.

    et si on proposait sur notre site préféré une page de terminologie?
    (bon je reconnais être un extrémiste du français et proposer des traductions pour tout , mais je sais me limiter -et manger des bifsteques comme tout le monde-)
    J'ai des principes: je peux toujours trouver une bonne raison pour les contredire .... mais j'ai des principes!
    (mon excellent bouquin sur Java : https://eska-publishing.com/fr/livre...822407076.html)

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Consultant Formateur Mainframe
    Inscrit en
    Septembre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Consultant Formateur Mainframe
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2012
    Messages : 15
    Points : 39
    Points
    39
    Par défaut les classes Java dans un fichier zip
    Bonjour,

    Merci pour les réponses, désolé pour les erreurs et voici l'exercice en fichier joint exercice_66.zip exporté sous Eclipse (donc qui fonctionne :-).

    Je me permets de rappeler les définitions suivantes pour aider à la compréhension du terme "du plus proche type SUPERIEUR" pour les débutants qui liront ce post.

    Types primitifs de Java Type Description (tiré du livre les cahiers du programmeur Java 1.4 et 5.0 de Emmanuel Puybaret (Editions eyrolles) un peu vieux mais encore vrai, je pense :-)

    byte : entier signé sur 8 bits (valeurs de – 128 à 127)
    short : entier signé sur 16 bits (valeurs de – 32 768 à 32 767)
    int : entier signé sur 32 bits (valeurs de – 2 147 483 648 à 2 147483 647)
    long : entier signé sur 64 bits (valeurs de – 9 223 372036 854 775808 à 9 223 372 036 854 775 807)
    float : décimal à virgule flottante sur 32 bits (valeurs de ± 10-45 à ± 1038 environ)
    double : décimal à virgule flottante sur 64 bits (valeurs de ± 10-323 à ±10308 environ)
    char : code Unicode sur 16 bits (peut être utilisé aussi comme entier non signé)
    valeur booléenne (vrai ou fausse)


    Cordialement

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

Discussions similaires

  1. [Choix] Demande d'informations sur le choix d'un CMS
    Par Maxoo dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 6
    Dernier message: 04/06/2007, 15h18
  2. Réponses: 4
    Dernier message: 09/10/2006, 22h12
  3. Réponses: 3
    Dernier message: 27/09/2006, 13h11
  4. [C#] demande d'explication sur un sample msdn
    Par legillou dans le forum Windows Forms
    Réponses: 2
    Dernier message: 27/06/2006, 17h01
  5. [final]demande d'explication sur ce mot-clé
    Par Invité dans le forum Langage
    Réponses: 10
    Dernier message: 18/04/2006, 11h32

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