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 :

déclarer une classe comme étant une classe fille


Sujet :

Langage Java

  1. #1
    Membre averti
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2008
    Messages
    187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Octobre 2008
    Messages : 187
    Points : 448
    Points
    448
    Par défaut déclarer une classe comme étant une classe fille
    Bonjour,

    j'ai une question un peu particulière concernant le mécanisme d'héritage en Java.

    Je travaille actuellement sur l'interface graphique Swing, et j'ai besoin d'ajouter des comportements sur des composants. Pour faire ça, je déclare une classe fille d'un composant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public class MyButton extends JButton {
     public void nouvelleMethode() {..}
    }
    Jusque là tout va bien.

    Là où ça se corse, c'est que j'ai beaucoup de composants qui ont le même comportement (utilisent la même méthode nouvelleMethode), ce qui induis de la duplication de code...

    D'où ma question : Est-il possible, sans toucher au code de Swing, de déclarer une classe MaClasse, qui implémente la fonction nouvelleMethode, et qui soit père de la classe JComponent ? Cela me permettrait d'utiliser la méthode nouvelleMethode pour la plupart des composant, sans duplication de code...

    Si ce n'est pas possible (et je suppose que ça ne l'est pas), pourriez-vous m'indiquer un moyen élégant d'appliquer du comportement à tous les objets composants de Swing ?

    Merci d'avance.

  2. #2
    Membre habitué
    Homme Profil pro
    Inscrit en
    Juin 2009
    Messages
    112
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2009
    Messages : 112
    Points : 136
    Points
    136
    Par défaut
    Salut,

    Effectivement sans l'héritage multiple ça semble délicat.
    Peut être que tu peux t'en sortir en utilisant un visiteur. Au niveau ajout de fonctions il me semble que c'est le pattern le plus efficace
    "Je sais que je suis un geek depuis que j'utilise le timer de mIRC pour faire cuire des pâtes"

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    J'ai été confronté à un problème similaire. J'ai essayé plusieurs architectures, et celle que j'ai finalement adopté et qui me parait la plus propre est le Decorator.

    En clair, tu écris une classe qui hérite de JComponent et dans laquelle tu écris toutes les méthodes que tu veux factoriser.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public abstract class Decorator extends JComponent {
        public void methodeGenerale() {
        }
        public abstract JComponent getComponent();
    }
    Ensuite, tu fais hériter tes classes de composant de ton Decorator, et tu associes les sous-classes au composant Swing :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public class MonBouton extends Decorator {
        private JButton bouton;
     
        public void methodeSpecifique() {
        }
     
        @Override
        public JButton getComponent() {
            return bouton;
        }
    }

  4. #4
    Membre averti
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2008
    Messages
    187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Octobre 2008
    Messages : 187
    Points : 448
    Points
    448
    Par défaut
    Merci pour vos réponses rapides ...

    Le Décorator est certainement la meilleure solution, même si on est toujours obligé de déclarer des sous-classes pour tous les composants de Swing, ce qui n'est pas très souhaitable.

    J'ai peut-être trouvé une autre piste en m'inspirant du pattern du visiteur, mais là encore, je me heurte à un problème. Voilà l'idée que j'ai eu :

    On a une classe "Factory", qui définit la méthode "superMethode", avec des signatures différentes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Factory {
     
     public static void nouvelleMethode(JComponent o) {
      // ...
     }
     
     public static void nouvelleMethode(JButton o) {
      // ...
     }
     
     // ...
     
    }
    Pour utiliser la méthode superMethode sur un Composant c, il suffit d'appeler "Factory.nouvelleMethode(c)" (au lieu de "c.nouvelleMethode()" dans l'ancienne solution).

    L'idée de ce mécanisme est donc de définir un comportement de base dans la méthode qui prend en argument un JComponent, et de définir des comportements spécifiques au besoin grâce à la surcharge des méthodes.

    Problème : La fonction qui appelle nouvelleMethode ne connait pas à l'avance l'instance de l'objet c, seulement le type : Component; et puisque la résolution de l'appel des méthodes se fait en fonction du type de l'objet, c'est toujours la première méthode de Factory qui est appelée !

    Dans l'ancienne solution (celle où on faisait c.nouvelleMethode() ), ça marchait car la résolution de l'appel à la méthode se faisait en fonction de l'instance de l'objet...

    J'aimerais donc pouvoir différencier les instances du composant c, sans faire de gros switch case avec instanceOf...

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Il est vrai que le Decorator t'oblige à écrire autant de sous-classe que tu as de composants. Dans mon cas, cela ne posait pas de problème.

    Ton architecture basée sur un "Factory" n'est pas terrible, mais si tu y tiens vraiment, tu pourrais avoir quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public interface Visitor {
        public void visit(JComponent comp);
    }
    public class Factory {
        public void call(JComponent comp, Visitor v) {
            v.visit(comp);
        }
    }
    Dans ce cas, tu devras avoir autant de Visitor concret que de traitement spécifique.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Points : 402
    Points
    402
    Par défaut
    Je pense qu'il suffit d'utiliser l'héritage simple. Etend tes nouvelles classes de la classe qui implémente cette nouvelle méthode au lieu d'hériter de JComponent et autre..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class TaClass extends JComponent {
     protected void taNewMethod(...) {
        //...
     }
    }
     
    class NewClass extends TaClass /*JComponent*/ {
     //Nouvelles méthodes à implémenter
    }

  7. #7
    Membre averti
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2008
    Messages
    187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Octobre 2008
    Messages : 187
    Points : 448
    Points
    448
    Par défaut
    verbose << je ne comprend pas bien ta solution. Comment sélectionner le visiteur qui va effectuer le bon traitement sur le composant ? i.e. si on a un JComponent c, comment instancier le bon visitor v, si on ne connait pas l'instance de c à l'avance (à la compilation) ?

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Points : 48 807
    Points
    48 807
    Par défaut
    Si tu commençais par nous expliquer quel comportement tu tente d'ajouter sur tous les composant swing que tu utilise, on pourrait t'orienter. Par exemple si ce sont des comportements d'affichage, il te sera probablement plus facile de jouer avec les LookandFeel qui sont responsable du dessin des composant et qui sont centralisés.

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Citation Envoyé par dancingmad Voir le message
    verbose << je ne comprend pas bien ta solution. Comment sélectionner le visiteur qui va effectuer le bon traitement sur le composant ? i.e. si on a un JComponent c, comment instancier le bon visitor v, si on ne connait pas l'instance de c à l'avance (à la compilation) ?
    Si ton problème est d'associer un traitement à un type spécifique, je pense que le pattern Decorator est le mieux adapté.

    Si tu veux absolument adopter un "Factory", tu peux faire un truc dans ce genre :
    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
     
    public class Factory {
        private static Map<Class<?>,Visitor> mapper;
     
        static {
            mapper.put(VisitorA.class, new VisitorA());
            mapper.put(VisitorB.class, new VisitorB());
        }
     
        public static void call(JComponent comp) {
            Visitor v = mapper.get(comp.getClass());
            if (v != null) {
                v.visit(comp);
            }
        }
    }
    Mais très franchement, le Decorator est plus élégant.

  10. #10
    Membre averti
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Octobre 2008
    Messages
    187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo

    Informations forums :
    Inscription : Octobre 2008
    Messages : 187
    Points : 448
    Points
    448
    Par défaut
    Citation Envoyé par verbose Voir le message
    Mais très franchement, le Decorator est plus élégant.
    En effet, la solution avec la Factory est très peu élégente, et pas du tout orientée objet... Je vais donc utiliser le pattern Decorator.

    Merci pour vos réponses !

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

Discussions similaires

  1. Des classes comme réponse à une requête
    Par nissam1 dans le forum SPARQL
    Réponses: 4
    Dernier message: 11/04/2012, 22h45
  2. Réponses: 8
    Dernier message: 05/04/2011, 08h06
  3. Sauvegarde d'une sous classe en tant que classe parente
    Par Invité dans le forum Hibernate
    Réponses: 0
    Dernier message: 06/11/2009, 13h09
  4. Comment récupérer la classe window d'une application wpf depuis une application ext
    Par rsiwpf dans le forum Windows Presentation Foundation
    Réponses: 10
    Dernier message: 14/10/2008, 15h10
  5. copie d'une table Y d'une base A vers une table X d'une base
    Par moneyboss dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 30/08/2005, 21h24

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