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 :

Héritage de champs


Sujet :

avec Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 87
    Points
    87
    Par défaut Héritage de champs
    Bonjour,

    Peut-on redéfinir les champs par défaut de la classe-mère? Ma terminologie est peut-être incorrecte, voici un exemple; une classe représente les vertébrés avec ses caractéristiques très générales, une autre les mammifères.

    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
    public class test {
      public static void main (String argv[]) {
        Mammal chien = new Mammal("chien");
        System.out.println(chien);
      }
    }
     
    class Vertebrate {
      private String name;
      private boolean skeletton   = true;
      private String skeletton_type    = "osseux ou cartilagineux";
      private String reproduction = "indéfini";
      private String skin         = "indéfini";
      private String heat         = "indéfinie";
     
      public void setName (String name) {
        this.name = name;
      }
     
      public String toString () {
        String characteristics = new String();
        characteristics += "Nom         : " + name         + "\n";
        String squel = skeletton? "oui": "non";
        characteristics += "Squelette   : " + squel     + "\n";
        characteristics += "type        : " + skeletton_type     + "\n";
        characteristics += "Reproduction: " + reproduction + "\n";
        characteristics += "Tégument    : " + skin         + "\n";
        characteristics += "Température : " + heat               ;
        return characteristics;
      }
    }
     
    class Mammal extends Vertebrate {
      private String reproduction = "vivipare";
      private String skeletton_type    = "osseux";
      private String skin         = "pelage";
      private String heat         = "sang chaud";
     
      public Mammal (String name) {
        setName(name);
      }
    }
    Avec un appel à toString() sur un type Mammal, j'espérais obtenir les champs définis dans la classe Vertebrate et de Mammal selon qu'ils soient redéfinis ou non, mais non, j'obtiens tous ceux de la classe-mère.

    Comment adapter ce code ?



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ java test
    Nom         : chien
    Squelette   : oui
    type        : osseux ou cartilagineux
    Reproduction: indéfini
    Tégument    : indéfini
    Température : indéfinie

    Merci d'avance,

    Gauthier

  2. #2
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 442
    Points : 417
    Points
    417
    Par défaut
    Utilise des accesseurs (setteur en particulier)

  3. #3
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Citation Envoyé par gvdmoort Voir le message
    Peut-on redéfinir les champs par défaut de la classe-mère?
    Non, on ne peut redéfinir que des méthodes.

    Citation Envoyé par gvdmoort Voir le message
    Ma terminologie est peut-être incorrecte, voici un exemple; une classe représente les vertébrés avec ses caractéristiques très générales, une autre les mammifères.
    Tu as bien fait de donner un exemple, car en effet, "redéfinir" autre chose qu'une méthode, ça n'a pas de sens précis.

    Bref, on ne peut rien faire de ce genre. Déclarer des membres qui portent le même nom que des membres d'une classe mère, ça ne fait que masquer l'existence des membres de la classe mère aux yeux de la classe fille. Cela n'affecte pas les méthodes de la classe mère : elles ne peuvent pas voir ces nouveaux membres et pour elles, ils n'existent pas.

    Par ailleurs, ce qui est private est invisible aux classes filles : elles ne peuvent pas le lire, le modifier, savoir que ça existe, ou altérer son comportement d'une manière ou d'une autre. Si c'est private, ça ne concerne que la classe où c'est déclaré, les autres classes ne peuvent rien en faire. Les méthodes private ne peuvent pas être redéfinies.

    Citation Envoyé par gvdmoort Voir le message
    Comment adapter ce code ?
    À mon avis le plus simple est de définir des méthodes public getName(), getReproduction() etc, et d'utiliser ça. Les méthodes, ça peut se redéfinir.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 87
    Points
    87
    Par défaut Héritage, suite
    Merci pour vos réactions rapides, en particulier pour l'aspect "masquage".

    J'ai modifié le code de la façon suivante:

    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
    public class test {
      public static void main (String argv[]) {
        Mammal chien = new Mammal("chien");
        System.out.println(chien);
      }
    }
     
    class Vertebrate {
      private String name;
      private String level       =  "sous-embranchement";
      private String level_name  =  "vertébrés";
      private boolean skeletton   = true;
      private String skeletton_type    = "osseux ou cartilagineux";
      private String reproduction = "indéfini";
      private String skin         = "indéfini";
      private String heat         = "indéfinie";
     
      public void setName (String s) {
        this.name = s;
      }
      public void setSkelettonType (String s) {
        this.skeletton_type = s;
      }
      public void setReproduction (String s) {
        this.reproduction = s;
      }
      public void setSkin (String s) {
        this.skin = s;
      }
      public void setHeat (String s) {
        this.heat = s;
      }
     
      public String toString () {
        String characteristics = new String();
        characteristics += "Nom         : " + name         + "\n";
        String squel = skeletton? "oui": "non";
        characteristics += "Squelette   : " + squel     + "\n";
        characteristics += "type        : " + skeletton_type     + "\n";
        characteristics += "Reproduction: " + reproduction + "\n";
        characteristics += "Tégument    : " + skin         + "\n";
        characteristics += "Température : " + heat         + "\n";
        characteristics += level + "      : " + level_name + "\n";
        return characteristics;
      }
    }
     
    class Mammal extends Vertebrate {
      private String level       =  "Classe";
      private String level_name  =  "Mammifères";
     
      public Mammal (String name) {
        setName(name);
        setSkelettonType("osseux");
        setReproduction ("vivipare");
        setSkin         ("pelage");
        setHeat         ("sang chaud");
      }
     
      public String toString () {
        String s = super.toString();
        s += level + "      : " + level_name;
        return s;
      }
    }
    Et j'ai bien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Nom         : chien
    Squelette   : oui
    type        : osseux
    Reproduction: vivipare
    Tégument    : pelage
    Température : sang chaud
    sous-embranchement      : vertébrés
    Classe      : Mammifères
    À présent, j'ajoute un sous-niveau supplémentaire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Canine extends Mammal {
      private String level       =  "Famille";
      private String level_name  =  "Canidés";
     
      public Canine (String name) {
        setName(name);
      }
     
      public String toString () {
        String s = super.toString();
        s += level + "      : " + level_name;
        return s;
      }
    }
    mais j'ai une erreur à la compilation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Found 1 semantic error compiling "H:/tmp/test.java":
     
        71.   public Canine (String name) {
                                          ^
    *** Semantic Error: No applicable overload was found for a constructor with signature "Mammal()" in type "Mammal". 
    Perhaps you wanted the overloaded version "Mammal(java.lang.String name);" instead?
    et je ne comprends pas pourquoi il devrait y avoir un constructeur sans arguments dans la classe Mammal. Quand j'avais défini la classe Mammal, il n'y avait pas besoin d'un tel constructeur dans Vertebrate.

    Quelle solution ?

  5. #5
    Modérateur
    Avatar de Hizin
    Homme Profil pro
    Développeur mobile
    Inscrit en
    Février 2010
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur mobile

    Informations forums :
    Inscription : Février 2010
    Messages : 2 180
    Points : 5 072
    Points
    5 072
    Par défaut
    Quand tu construits une classe sans appel explicite envers un constructeur de la classe mère, il y en a appel implicite au constructeur "par défaut" (comprendre : "sans argument") de la classe mère.

    Ce constructeur est présent implicitement dans ta classe "Vertebrate". Il faut savoir qu'une classe sans constructeur explicitement écrit en possède un implicite sans argument et ne "faisant rien". Ne pas écrire de constructeur dans ta classe "Vertebrate" est équivalent a écrire un constructeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public Vertebrate()
    {
    }
    Il n'y a pas de constructeur sans argument dans ta classe "Mamal", c'est donc au développeur de dire explicitement quel constructeur celui-ci appel pour créer sa classe, Java ne pouvant plus le deviner.
    Ou sinon, de créer un constructeur sans argument dans la classe "Canine"

    L'idée est simple : pour construire une classe, il faut construire sa mère, et ainsi de suite.
    C'est Android, PAS Androïd, ou Androïde didiou !
    Le premier est un OS, le second est la mauvaise orthographe du troisième, un mot français désignant un robot à forme humaine.

    Membre du comité contre la phrase "ça marche PAS" en titre et/ou explication de problème.

    N'oubliez pas de consulter les FAQ Android et les cours et tutoriels Android

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    124
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2006
    Messages : 124
    Points : 87
    Points
    87
    Par défaut héritage et constructeurs
    Citation Envoyé par Hizin Voir le message
    Quand tu construits une classe sans appel explicite envers un constructeur de la classe mère, il y en a appel implicite au constructeur "par défaut" (comprendre : "sans argument") de la classe mère.

    Ce constructeur est présent implicitement dans ta classe "Vertebrate".
    En suivant tes explications, je ne comprends pas ce qui se passe; si je retire la classe Canine, et que je fais un appel de la forme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        Mammal chien = new Mammal();
    on est dans la situation où la classe fille (Mammal) n'a pas un tel constructeur, et devrait donc faire appel au constructeur implicite de la classe mère (Vertebrate). Or j'ai ce message:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    H:\tmp>d:\users\jikes\bin\jikes.exe test.java
     
    Found 1 semantic error compiling "H:/tmp/test.java":
     
         3.     Mammal chien = new Mammal();
                               ^----------^
    *** Semantic Error: No applicable overload was found for a constructor with signature "Mammal()" in type "Mammal". 
    Perhaps you wanted the overloaded version "Mammal(java.lang.String name);" instead?

  7. #7
    Modérateur
    Avatar de Hizin
    Homme Profil pro
    Développeur mobile
    Inscrit en
    Février 2010
    Messages
    2 180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur mobile

    Informations forums :
    Inscription : Février 2010
    Messages : 2 180
    Points : 5 072
    Points
    5 072
    Par défaut
    Non, c'est un autre problème que tu as là

    Je conviens que ce n'est pas clair dans mon message précédent, donc voici une reformulation :

    Quand une classe n'a aucun constructeur de déclaré, celle-ci s'en voit attribuer un sans argument et ne faisant rien implicitement.
    Quand une classe possède au moins un constructeur déclaré, le constructeur sans argument implicite n'existe plus. Si on désir un constructeur sans argument, il faut alors le déclarer soi-même.

    De plus, chaque constructeur appel implicitement ou explicitement un constructeur de sa classe mère.
    S'il n'y a aucun appel explicite, c'est le constructeur sans argument de la classe mère qui est appelée pour la construction.
    S'il y a un appel explicite, c'est le constructeur appelé qui est appelé (tourné comme ça, la phrase est un peu bêbête ).

    Dans ton cas, tu essayes de construire un objet "Mamal" en appelant le constructeur sans argument qui n'existe plus. L'erreur t'indique donc "Je ne trouve pas ce constructeur".

    Il faut bien comprendre que les seuls constructeurs que tu peux appeler sont uniquement ceux qui existent.
    Ici, "Mamal (String)" existe et appel implicitement "Vertebrate()" pour se construire.
    Par contre "Mamal()" n'existe pas, et ne remonte pas la chaîne de construction, mais résulte en une erreur.
    C'est Android, PAS Androïd, ou Androïde didiou !
    Le premier est un OS, le second est la mauvaise orthographe du troisième, un mot français désignant un robot à forme humaine.

    Membre du comité contre la phrase "ça marche PAS" en titre et/ou explication de problème.

    N'oubliez pas de consulter les FAQ Android et les cours et tutoriels Android

  8. #8
    Modérateur
    Avatar de Alkhan
    Homme Profil pro
    ingénieur full stack
    Inscrit en
    Octobre 2006
    Messages
    1 232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur full stack

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 232
    Points : 2 061
    Points
    2 061
    Par défaut
    bonjour

    Vu l'exemple que tu as donné tu devais avoir :
    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
    class Canine extends Mammal {
      private String level       =  "Famille";
      private String level_name  =  "Canidés";
     
      public Canine (String name) {
        super(name); // Le setName(name) étant fait par la classe Mammal
      }
     
      public String toString () {
        String s = super.toString();
        s += level + "      : " + level_name;
        return s;
      }
    }
    il est important de faire le super car cela va aussi initialiser les autres variables de Mammal !
    Il n'y a pas de problème, il n'y a que des solutions.
    Cependant, comme le disaient les shadoks, s'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
    Si toutefois le problème persiste, la seule solution restante est de changer le périphérique qui se trouve entre la chaise et l'écran

    Mes Articles : Mon premier article est sur le language D
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

Discussions similaires

  1. Héritage et champ statique
    Par Aedelon dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 10/08/2012, 14h36
  2. [1.x] Héritage et champs d'un formulaire
    Par bilbonec dans le forum Symfony
    Réponses: 5
    Dernier message: 18/11/2010, 20h20
  3. héritage et champs dupliqués
    Par *alexandre* dans le forum Hibernate
    Réponses: 0
    Dernier message: 06/10/2008, 17h53
  4. [héritage] Héritage et champs statiques.
    Par salome dans le forum Langage
    Réponses: 4
    Dernier message: 03/04/2005, 20h21
  5. [héritage] Héritage et champs statiques.
    Par salome dans le forum Langage
    Réponses: 2
    Dernier message: 02/04/2005, 00h11

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