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 :

Constructeur et Initialisation


Sujet :

Langage Java

  1. #1
    Membre expérimenté Avatar de dazz_x
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 269
    Par défaut Constructeur et Initialisation
    Bonjour à tous et à toutes, ô valeureux combattants du NullPointerException !

    Une question existentielle me taraude depuis 15 min, et c'est pourquoi je m'apprête à m'adresser à vous.
    Bon, il s'agit ici de constructeur

    J'ai une classe que l'on va appeller ... Claudia (ben oui, pourquoi MaClasse ou Test ...). Cette Classe hérite d'une classe abstraite TopModel dans laquelle est défini un constructeur qui est sensé ne servir a rien sinon initialiser des champs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    PaireDeJambes mesJambes;
    public TopModel(){
     mes Jambes=new PaireDeJambes(1.00f);
    }
    Lorsque je crée une Claudia, je fais new Claudia(1.18) et ça m'appelle le constructeur de Claudia suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public Claudia(float longueur){
    mesJambes=new PaireDeJambes(longueur);
    }
    Il me semblait que tout constructeur dérivé prenait en totalité la charge de la construction de l'objet. Donc j'en déduisais que mon appel au constructeur de Claudia ne créait qu'une seule instance de PaireDeJambes...
    Or en profilant la chose avec TPTP, quelle n'est pas ma surprise en découvrant non pas UNE mais DEUX instances de PaireDeJambes !!!!
    Je debugge un coup, et je me rends compte que le new Claudia(1.18) appelle un new TopModel() et crée donc une instance de PaireDeJambes et puis ensuite appelle le constructeur de Claudia et crée une deuxième instance....
    Ma question est : Auriez vous une explication à cela ?

    Merci d'avance
    (en même temps, ma femme m'a fait le même coup à la deuxième échographie, je ne m'attendais qu'à une instance de et j'en ai eu deux )

  2. #2
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Par défaut
    Dans un constructeur l'appel à un constructeur parent est obligatoire (et doit aussi être la première instruction dudit constructeur). Par commodité, le fait de ne pas mettre d'appel a un constructeur parent est équivalent à appelé le constructeur par défaut de la classe parente.

    Je sais pas si je suis clair
    en fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public Claudia(float longueur){
         mesJambes = new PaireDeJambes(longueur);
    }
    est équivalent à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public Claudia(float longueur){
         super();
         mesJambes = new PaireDeJambes(longueur);
    }
    Pour vérifier, supprime le constructeur par défaut de la classe TopModel (tu rajoute un paramètre bidon) et tu compile :
    le compilateur geulera comme quoi il y a une erreur dans le constructeur de Claudia parce qu'il trouve pas le constructeur par défaut de TopModel (ce qui montre bien qu'il y fait appel ).

    Pour résumer si tu ne fait pas d'appel explicite vers un constructeur parent il y en a un implicite vers le constructeur paremt par défaut.
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  3. #3
    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
    Citation Envoyé par dazz_x
    Je debugge un coup, et je me rends compte que le new Claudia(1.18) appelle un new TopModel() et crée donc une instance de PaireDeJambes et puis ensuite appelle le constructeur de Claudia et crée une deuxième instance....
    Ma question est : Auriez vous une explication à cela ?
    C'est normal : lorsque tu crées un nouvel objet, le constructeur de l'objet parent est toujours appellé, même si tu ne le précises pas explicitement.

    En fait le code de ton constructeur de Claudia est équivalent à celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public Claudia(float longueur){
        super();
        mesJambes=new PaireDeJambes(longueur);
    }
    Donc avant d'exécuter le code du constructeur de Claudia, tu exécutes le constructeur par défaut de TopModel...

    Ce mécanisme est obligatoire car lorsque tu écris une classe fille, tu ne connais pas forcément l'implémentation exacte de la classe parente. Donc c'est le constructeur de la classe parent qui s'occupe de la son initialisation. De plus ta classe Claudia ne peut pas initialiser les éventuelles objets private de la classe TopModel !

    Pour faire plus propre il faudrait utiliszer deux constructeurs dans la classe TopModel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class TopModel {
        PaireDeJambes mesJambes;
     
        public TopModel(){
            this(new PaireDeJambes(1.00f));
        }
     
        public TopModel(PaireDeJambes jambes){
            mesJambes = jambes;
        }
    }
    Et utiliser le bon constructeur parent dans Claudia :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public Claudia(float longueur){
        super(new PaireDeJambes(longueur));
    }

    Citation Envoyé par dazz_x
    Merci d'avance
    (en même temps, ma femme m'a fait le même coup à la deuxième échographie, je ne m'attendais qu'à une instance de et j'en ai eu deux )
    Il faut faire un System.gc() pour forcer le garbage collector a libérer les instances en trop
    Ok je sors

    a++

    [edit] grilled

  4. #4
    Membre expérimenté Avatar de dazz_x
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Mars 2006
    Messages : 269
    Par défaut
    Bon, ben merci à tous les deux...
    Je me doutais bien de l'affaire, mais je me suis laissé emporté par une phrase du bouquin de Delannoy "Programmer en Java" (très bon par ailleurs) qui dit que le constructeur de l'objet qui hérite de la classe de base doit s'occuper de l'entièreté de la construction de l'objet .... d'où j'en avais déduis
    pas d'appel implicite au constructeur par défaut
    Mais bon

  5. #5
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Par défaut
    N'oublie pas le tag
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 27/10/2013, 16h09
  2. [Débutant] Problème : definition d'un constructeur d'initialisation
    Par IssamSoft dans le forum C#
    Réponses: 3
    Dernier message: 28/03/2012, 09h02
  3. Attributs, constructeurs et initialisation
    Par Targan dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 26/11/2010, 15h31
  4. Constructeur Font initialisation
    Par schneidb dans le forum Langage
    Réponses: 2
    Dernier message: 27/03/2007, 15h22
  5. Constructeur avec initialisation
    Par bahaaldine dans le forum C++
    Réponses: 9
    Dernier message: 17/11/2006, 13h01

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