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

  1. #1
    lvr
    lvr est déconnecté
    Membre extrêmement actif Avatar de lvr
    Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Avril 2006
    Messages
    909
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 909
    Points : 1 360
    Points
    1 360
    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 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 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 extrêmement actif Avatar de lvr
    Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Avril 2006
    Messages
    909
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 909
    Points : 1 360
    Points
    1 360
    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 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 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 chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    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 extrêmement actif Avatar de lvr
    Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Avril 2006
    Messages
    909
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 909
    Points : 1 360
    Points
    1 360
    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 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 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

  8. #8
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Personellement, dans les applications plus complexes, quand ça s'y prête, j'utilise cette solution

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    @Configurable
    public class X {
          @PostConstruct
          protected void init(){
          }
    }
    Mais ça ne marche que si on a intégré spring à l'application

  9. #9
    lvr
    lvr est déconnecté
    Membre extrêmement actif Avatar de lvr
    Profil pro
    Responsable de projet fonctionnel
    Inscrit en
    Avril 2006
    Messages
    909
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2006
    Messages : 909
    Points : 1 360
    Points
    1 360
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Mais ça ne marche que si on a intégré spring à l'application
    Ce serait beau. Mais je ne connais Spring que de nom... A investiguer pour la prochaine application.

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