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

Java Discussion :

"overridable method called in constructor" : où est le problème ?


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    lvr
    lvr est déconnecté
    Membre éclairé Avatar de lvr
    Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Avril 2006
    Messages
    919
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2006
    Messages : 919
    Par défaut "overridable method called in constructor" : où est le problème ?
    Bonjour,

    NetBeans me met un wanring chaque fois que j'utilise une méthode non finale dans un constructeur.
    Où est le problème ?
    Au contraire, je trouve ça très pratique.
    Cela permet à des sous-classes de s'initier de manière customisée.

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par lvr Voir le message
    Cela permet à des sous-classes de s'initier de manière customisée.
    ... Et cela avant que le constructeur de leur classe mère se soit terminé, ce qui est contraire à l'encapsulation et donc un appel aux bugs.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    lvr
    lvr est déconnecté
    Membre éclairé Avatar de lvr
    Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Avril 2006
    Messages
    919
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2006
    Messages : 919
    Par défaut
    Citation Envoyé par thelvin Voir le message
    ... Et cela avant que le constructeur de leur classe mère se soit terminé, ce qui est contraire à l'encapsulation et donc un appel aux bugs.
    C'est quoi la solution ?

    Exemple, j'ai une application Swing dont son initialisation j'ai écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class A extends JFrame {
      final JPanel;
      public A() {
        JPanel panel=createPanel();
        }
     
      JPanel createPanel() {
        return new PanelX();
        }
      }
    Je veux une version spéciale de cette application dans laquelle j'aurai un panneau légèrement revu.
    Je crée donc donc une sous classe de mon
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class B extends A {
      public B() {
        super()
        }
     
      @Overide
      JPanel createPanel() {
        return new PanelY();
        }
      }
    Une solution avec des factory serait-elle mieux ? Sauf que cela ne fonctionne pas avec les attributs "final"

  4. #4
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par lvr Voir le message
    C'est quoi la solution ?
    Celle qui fait le taf'.

    Dans ton exemple, il y a le simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class A extends JFrame {
      final JPanel;
     
      protected A(Jpanel panel) {
        this.panel = panel;
      }
     
      public A() {
        this(new PanelX());
      }
     
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class B extends A {
      public B() {
        super(new PanelY());
      }
    }
    Citation Envoyé par lvr Voir le message
    Une solution avec des factory serait-elle mieux ?
    Ça peut dans des cas plus compliqués.

    Citation Envoyé par lvr Voir le message
    Sauf que cela ne fonctionne pas avec les attributs "final"
    Pas plus que d'habitude.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    Deja, commencons par le probleme. Le cas suivant, par exemple, ne marcherait pas :
    Citation Envoyé par lvr Voir le message
    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
    class A extends JFrame {
      final JPanel;
      public A() {
        JPanel panel=createPanel();
        }
     
      JPanel createPanel() {
        return new PanelX();
        }
      }
     
    class B extends A {
      JPanel monPan = new PanelB();
      public B() {
        super()
        }
     
      @Overide
      JPanel createPanel() {
        return monPanel;
        }
      }
    Ca ne saute pas aux yeux mais le probleme, c'est que les variables de classes de B sont initialisées apres celles de A. Donc au moment de l'appel de createPanel dans le constructeur du pere de B, monPanel sera null. Dans ce cas, ca va générer une NullPointerException donc c'est facilement compréhensible mais dans le cas d'une modification de variable utilisée par le pere ou quelque chose de plus complexe, ca risque d'etre moins trivial a debugger.

    Citation Envoyé par lvr Voir le message
    Une solution avec des factory serait-elle mieux ? Sauf que cela ne fonctionne pas avec les attributs "final"
    L'attribut n'a pas besoin d'etre "final" dans le cas d'une factory. Si l'objectif de dériver la classe est seulement de creer des panels différents, oui, ca peut etre une solution. Pour un probleme qui ressemble, j'avais choisi la solution d'avoir un constructeur tres simple mais d'imposer l'appel à une fonction "build" qui fait en gros ce que fait ton constructeur. Ca donne quelque chose comme ca :

    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
    class A extends JFrame {
      final JPanel;
      public A() {
        }
     
      public void build() {
        JPanel panel=createPanel();
      }
     
      JPanel createPanel() {
        return new PanelX();
        }
      }
     
    class B extends A {
      JPanel monPan = new PanelB();
      public B() {
        super()
        }
     
      @Overide
      JPanel createPanel() {
        return monPanel;
        }
      }
    Et la, ca marche.

  6. #6
    lvr
    lvr est déconnecté
    Membre éclairé Avatar de lvr
    Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Avril 2006
    Messages
    919
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Responsable de projet fonctionnel
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2006
    Messages : 919
    Par défaut
    Je vois où le problème... Je crois que je vais abandonner cette mauvaise "bonne" pratique... Reste à voir comment au cas par cas.

    J'hésitais aussi aux méthodes de type "build()". Mais ça rend plus compliqué le travail avec des GUI builder comme celui de Netbeans...
    Quant aux paramètres, ça marche s'il y en a 1 ou 2 après ça devient compliqué...

    Merci pour les pistes.

  7. #7
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par lvr Voir le message
    Quant aux paramètres, ça marche s'il y en a 1 ou 2 après ça devient compliqué...
    Un paramètre, qui est une classe qui contient les autres paramètres.

    Si nécessaire, ce paramètre peut carrément être une factory ou un builder.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. Réponses: 3
    Dernier message: 15/10/2009, 19h03
  2. Pb retour methode call.invoke
    Par tigerpob79 dans le forum Services Web
    Réponses: 2
    Dernier message: 06/11/2008, 17h21
  3. héritage et override methodes sous .NET
    Par julien.63 dans le forum ASP.NET
    Réponses: 15
    Dernier message: 15/10/2008, 15h47
  4. Réponses: 4
    Dernier message: 17/05/2007, 16h47

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