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 :

[Héritage] [Polymorphisme] Question de débutant ?


Sujet :

Langage Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 53
    Points : 46
    Points
    46
    Par défaut [Héritage] [Polymorphisme] Question de débutant ?
    Bonjour,
    J'ai une question stupide sur l'héritage et le polymorphisme. ça fait un bon moment que je fais du java mais là j'avoue que je ne comprends pas bien...

    Voici un petit 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
    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
     
    package test ;
     
    public class SurchargeTest {
     
    	public static void main(String[] args) {
    		new SurchargeTest().launchTest();
    	}
     
    	public void launchTest() {
    		A a[] = new A[2];
    		a[0] = new A1(5);
    		a[1] = new A2(6);
     
    		B b = new B1();
     
    System.out.println(b.transform(a[0], " test "));
    System.out.println(b.transform((A1) a[0], " test "));
    System.out.println(b.transform(a[1], " test "));
     
    }
     
    	abstract class A {
    		int value;
     
    		A(int initValue) {
    			value = initValue;
    		}
     
    		public String toString() {
    			return "" + value;
    		}
    	}
     
    	class A1 extends A {
    		A1(int initValue) {
    			super(initValue);
    		}
    	}
     
    	class A2 extends A {
    		A2(int initValue) {
    			super(initValue);
    		}
    	}
     
    	// class A3 A4 ...
     
    	abstract class B {
    		public abstract String transform(A a, Object c);
     
    		public String transform(A1 a, Object c) {
    			return "Cas special pour A1";
    		}
    	}
     
    	class B1 extends B {
    		public String transform(A a, Object c) {
    			return "T1 " + a.toString() + c.toString();
    		}
    	}
     
    	class B2 extends B {
    		public String transform(A a, Object c) {
    			return "T2 " + c.toString() + a.toString();
    		}
    	}
     
    	// class B3, B4 ...
     
    }
    Et voici ce qui apparaît à l'écran lors de son exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    T1 5 test 
    Cas special pour A1
    T1 6 test
    Ma question est simple, pourquoi lors du premier appel "b.transform(a[0], " test ")", le retour n'est pas "Cas spécial pour A1" comme pour l'appel b.transform((A1)a[0], " test ").

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 53
    Points : 46
    Points
    46
    Par défaut
    Une piste peut être : j'utilise ici à la fois le polymorphisme fort (héritage) et le polymorphisme faible (surcharge de signature).

    Citation Envoyé par TSnarfK

    abstract class B {
    public abstract String transform(A a, Object c);

    public String transform(A1 a, Object c) {
    return "Cas special pour A1";
    }
    }
    Si quelqu'un a une explication, je suis preneur.

  3. #3
    Membre confirmé Avatar de gronono
    Inscrit en
    Novembre 2003
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Novembre 2003
    Messages : 456
    Points : 482
    Points
    482
    Par défaut
    Bonjour,

    Lorsque tu fais A a1 = new A1() la variable a1 est du type A. Donc la méthode appelée est transform(A, Object).

    Par contre si tu déclares A1 a1 = new A1() la variable a1 est du type A1. Donc la méthode appelée est transform(A1, Object).

    Si si tu déclares A a1 = new A1() et que tu appelle transform par transform(a1, "test") alors tu force le type de a1 en A1.

    Dans le premier cas, la JVM considère que a1 est de type A
    Dans le second, de type A1 (il est déclaré explicitement)
    Dans le troisième de type A1 (c'est toi qui force)

    L'important est le type de la déclaration et non le type de l'instance.

    Il existe des exemples dans l'API standard:
    soit une ArrayList l.
    Si tu la déclare ArrayList l = new ArrayList(), tu peux utiliser la méthode add(int index, E element)
    Par contre si tu la déclare Collection l = new ArrayList(), tu ne peux utiliser la méthode add(int index, E element) .

    A+
    Gronono

  4. #4
    Membre éprouvé
    Profil pro
    Architecte technique
    Inscrit en
    Mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mars 2002
    Messages : 966
    Points : 1 085
    Points
    1 085
    Par défaut
    Juste pour préciser le vocabulaire, dans ton cas ce n'est pas de la surcharge de méthodes, c'est de la réécriture.

    La surcharge: c'est quand tu définis la même méthode avec une signature différente dans une classe fille ou dans la même classe.

    La réécriture: c'est quand tu redéfinis une méthode avec la même signature dans une classe fille.


    A+

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 53
    Points : 46
    Points
    46
    Par défaut
    Merci pour l'explication. Est-ce que cela veut dire que pour avoir le comportement que j'aurais souhaité, je suis obligé d'avoir une solution du type :
    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
     
    abstract class B {
    		public abstract String transform(A a, Object c);
     
    		public String specialCaseForA1(A a, Object c) {
    			return "Cas special pour A1";
    		}
    	}
     
    	class B1 extends B {
    		public String transform(A a, Object c) {
    			if (a instanceof A1)
    				return specialCaseForA1(a, c);
    			return "T1 " + a.toString() + c.toString();
    		}
    	}
     
    	class B2 extends B {
    		public String transform(A a, Object c) {
    			if (a instanceof A1)
    				return specialCaseForA1(a, c);
    			return "T2 " + c.toString() + a.toString();
    		}
    	}
    ce qui duplique le bout de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     if (a instanceof A1) return specialCaseForA1(a, c);
    pour chaque sous-classe B ?

    Y aurait-il une meilleur façon de faire les choses ? Est-ce un problème de conception à la base ?

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 53
    Points : 46
    Points
    46
    Par défaut
    Autant pour moi, pas besoin de dupliquer le code.
    Néanmoins, cette solution utilise toujours un "instanceof"...

    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
     
    abstract class B {
     
    		public String transform(A a, Object c){
    			if (a instanceof A){
    				return specialCaseForA1(a, c) ;
    			}			
    			return normalTransform(a,c) ;			
    		}
     
    		protected abstract String normalTransform(A a, Object c);
     
    		protected String specialCaseForA1(A a, Object c) {
    			return "Cas special pour A1";
    		}
    	}
     
    	class B1 extends B {
    		protected String normalTransform(A a, Object c) {
    			return "T1 " + a.toString() + c.toString();
    		}
    	}
     
    	class B2 extends B {
    		protected String normalTransform(A a, Object c) {
    			return "T2 " + c.toString() + a.toString();
    		}
    	}

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Points : 234
    Points
    234
    Par défaut
    Dans ton cas, tu aurais pu déclarer la méthode transform() dans la classe A, ce qui t'aurais permis de redéfinir son comportement pour A1.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 53
    Points : 46
    Points
    46
    Par défaut
    Oui, ce cas était simplifié pour la question. En fait dans le cas réel, j'ai besoin d'information contenue par les différents classes fils B1, B2, B3... pour faire la transformation en question (celle-ci étant donc fonction du type de A et fonction du type de B) d'où la présence de ces classes.

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Points : 234
    Points
    234
    Par défaut
    Je pense qu'il te faudrait quelque chose dans le genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public abstract class A {
         public String getRepresentation();
         public void setRepresentation(String s);
    }
     
    public class B {
         public A transformRepresentation(A a, C obj) {
              a.setRepresentation( a.getRepresentation() + obj.toString() );
              return a;
         }
    }

  10. #10
    Membre éprouvé
    Profil pro
    Architecte technique
    Inscrit en
    Mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mars 2002
    Messages : 966
    Points : 1 085
    Points
    1 085
    Par défaut
    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
     
    public interface A {
         public String getRepresentation();
         public void setRepresentation(String s);
    }
     
    public class B {
         public void transformRepresentation(C obj) {
              setRepresentation(getRepresentation() + obj.toString());
              return getRepresentation();
         }
    }
     
    public class B1 extends B implements A {
    [..]
    }
     
    public class B2 extends B implements A {
    [..]
    }

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

Discussions similaires

  1. [débutant] héritage, polymorphisme, etc !
    Par remsrock dans le forum C#
    Réponses: 4
    Dernier message: 31/10/2008, 13h33
  2. question de débutant sur les objets
    Par boucher_emilie dans le forum ASP
    Réponses: 3
    Dernier message: 06/08/2004, 11h51
  3. [MFC] Quelques questions de débutant...
    Par Sephi dans le forum MFC
    Réponses: 4
    Dernier message: 20/02/2004, 18h25
  4. Questions de débutant
    Par J-P-B dans le forum XMLRAD
    Réponses: 12
    Dernier message: 24/07/2003, 16h19
  5. [HyperFile] 2 questions de débutant
    Par khan dans le forum HyperFileSQL
    Réponses: 2
    Dernier message: 30/04/2002, 00h18

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