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 :

Ajouter une méthode à une classe existante, sans héritage


Sujet :

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 Ajouter une méthode à une classe existante, sans héritage
    Bonjour à tous,

    Je pense avoir compris comment créer une sous-classe qui hérite (avec "extends") des méthode de sa classe-mère, mais je ne comprends pas comment enrichir une classe existante, sans modifier celle-ci, et sans créer de sous-classe.

    Exemple, j'aimerais disposer d'une méthode qui me dit si une chaîne est un anagramme, je voudrais donc compléter la classe String par:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public boolean isAnagram () {
      // ...
    }
    de façon à pouvoir utiliser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    String s1 = new String("kayak");
    if (s1.isAnagram()) {
      // ...
    }
    Apparemment, si je crée un fichier String.java pour y déclarer cette méthode, plus aucune autre méthode de la classe n'est reconnue.

    Comment faire ?

    Merci d'avance,

    G.

  2. #2
    Membre du Club
    Inscrit en
    Janvier 2008
    Messages
    74
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 74
    Points : 68
    Points
    68
    Par défaut
    Ca doit pas être possible de modifier un .class (ici String.class), et vu que tu n'a pas accès au String.java originel, c'est raté.

    Donc, à priori, héritage comme solution...

  3. #3
    Modérateur

    Avatar de Robin56
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juin 2009
    Messages
    5 297
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Juin 2009
    Messages : 5 297
    Points : 13 670
    Points
    13 670
    Par défaut
    L'héritage est justement fais pour ça car là tu ne veux plus utiliser la classe String de base mais une classe custom. Tu peux faire une classe à côté sinon qui prend en paramètre un String tout simplement si la solution de la sous-classe ne te plait pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    String s = "toto";
    boolean b = StringUtilitaire.anagramme(s);
    Responsable Java de Developpez.com (Twitter et Facebook)
    Besoin d'un article/tutoriel/cours sur Java, consulter la page cours
    N'hésitez pas à consulter la FAQ Java et à poser vos questions sur les forums d'entraide Java
    --------
    Architecte Solution
    LinkedIn : https://www.linkedin.com/in/nicolascaudard/

  4. #4
    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
    on ne peux pas faire de sous classe de String, String est final.

  5. #5
    Modérateur

    Avatar de Robin56
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juin 2009
    Messages
    5 297
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Juin 2009
    Messages : 5 297
    Points : 13 670
    Points
    13 670
    Par défaut
    Donc il ne te reste que la solution de la classe utilitaire.
    Responsable Java de Developpez.com (Twitter et Facebook)
    Besoin d'un article/tutoriel/cours sur Java, consulter la page cours
    N'hésitez pas à consulter la FAQ Java et à poser vos questions sur les forums d'entraide Java
    --------
    Architecte Solution
    LinkedIn : https://www.linkedin.com/in/nicolascaudard/

  6. #6
    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
    Tout d'abord, il faut voir une classe ou une interface comme un contrat. C'est à dire que toute classe qui herite d'une autre classe ou qui implemente une interface devra definir les methodes de celles-ci.
    Par exemple, si je prends une instance de object ou d'un de ses descendants, je suis sur d'avoir une méthode toString().

    Pour ajouter une methode à une classe existante, il faut faire une sous classe. Par exemple, si Fils herite de Pere, Fils possedera toutes les fonctions de Pere plus celles qu'elle définira elle meme. Ainsi, Fils pourra etre utilisé partout ou Pere etait utilisé. En revanche, Pere ne pourra pas etre utilisé la ou Fils est utilisé.

    Pour répondre à la question de base, il est possible d'ajouter une methode à une classe existante. Pour ca, tu peux regarder du coté de la programmation orientée Aspect.
    Mais dans ton cas, il faut passer comme ca a été indiqué par une classe utilitaire.

  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
    Pour résumer :

    Citation Envoyé par gvdmoort Voir le message
    mais je ne comprends pas comment enrichir une classe existante, sans modifier celle-ci, et sans créer de sous-classe.
    Normal que tu ne voies pas comment faire ça en Java, c'est impossible.
    Et il est rare que ce soit gênant. Des solutions très raisonnables ont été proposées ici.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Tu peux aussi utiliser le pattern decorator, il me semble (à vérifier) :
    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
     
     
    public class MyString {
     
    	private String str;
     
    	public MyString(String str) {
    		this.str = str;
    	}
     
    	public int length() {
    		return str.length();
    	}
     
    	public String substring(int index) {
    		return str.substring(index);
    	}
     
    	public static void main(String[] args) {
    		MyString str = new MyString("chaine");
    		System.out.println(str.length());
    	}
     
    }
    Ta classe encapsule un objet de type string.
    Tu redéfinis toutes les méthodes de la classe String, mais qui font simplement appel à l'implémentation de ton objet String, comme pour length dans l'exemple.
    Puis tu rajoutes les méthodes propres à ton implémentation.
    C'est fastidieux puisque String a beaucoup de méthodes mais ça peut être parfois intéressant.

  9. #9
    Membre actif

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    171
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 171
    Points : 218
    Points
    218
    Par défaut
    Bonjour,

    Juste pour compléter le message de fr1man, le pattern Decorator nécessite que la classe décoratrice hérite d'une base commune à la class décorée.
    Et ce afin que la classe décoratrice puisse être utilisé partout une un object décoré est attendu.

    Donc ça donnerait :

    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
    public class MyString extends String {
     
    	private String str;
     
    	public MyString(String str) {
    		this.str = str;
    	}
     
    	public int length() {
    		return str.length();
    	}
     
    	public String substring(int index) {
    		return str.substring(index);
    	}
     
            
            public boolean isAnagram () {
            // Calcul avec str
            }
    	
            public static void main(String[] args) {
    		MyString str = new MyString("chaine");
    		
                   System.out.println(str.isAnagram());
    	}
     
    }

    Quoiqu'il en soit le pattern Décorator est une solution élégante dans le cas évoqué dans ce topic.

  10. #10
    Membre régulier

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2011
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2011
    Messages : 37
    Points : 89
    Points
    89
    Par défaut
    Je me permet d'ouvrir une petite parenthèse : il est tout à fait possible d'ajouter des méthodes à une classe sans héritage en utilisant des APIs "sauvages" permettant de manipuler le bytecode.

    Avec Javassist :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ClassPool pool=ClassPool.getDefault();
    Loader cl=new Loader(pool);
    CtClass ct=pool.makeClass("myClass");
    String myMethod = "public void myMethod() { System.out.println(\"youpi\"); }";
    ct.addMethod(CtNewMethod.make(myMethod, ct));
    ct.writeFile();
    Bon ça fait longtemps que je n'ai pas touché à Javassist, mais ça a une tête du genre et, en tous cas, ça permet de faire entre autres ce genre de choses...

  11. #11
    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
    Pour rappel, on parle là d'un problème de débutant par rapport au language, donc les modifications sauvage d'une classe de java.lang on oublie, et l'orienté aspect aussi. C'est sortir les cuirassé pour souffler une mouche morte!

    Donc, non, en java, on n'ajoute pas une méthode à une classe existante, on utilise l'héritage pour ça. Et non, ce n'est donc pas applicable à String puisque cette classe est final.

  12. #12
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2008
    Messages
    1 190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 190
    Points : 2 657
    Points
    2 657
    Par défaut
    Il est clair que le problème ici est un problème de compréhension par l'auteur. Et de tels bidouillages sont franchement à bannir.

  13. #13
    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
    Citation Envoyé par aurelman Voir le message
    Juste pour compléter le message de fr1man, le pattern Decorator nécessite que la classe décoratrice hérite d'une base commune à la class décorée.
    Et ce afin que la classe décoratrice puisse être utilisé partout une un object décoré est attendu.
    Sauf que String est final donc c'est pas possible


    Citation Envoyé par tchize_ Voir le message
    Pour rappel, on parle là d'un problème de débutant par rapport au language, donc les modifications sauvage d'une classe de java.lang on oublie, et l'orienté aspect aussi. C'est sortir les cuirassé pour souffler une mouche morte!
    Oui mais ca n'empeche pas de parler de techniques qui permettraient de faire ca. Peut etre que certains qui vont tomber sur ce topic à travers un moteur de recherche seront contents de trouver une réponse. Mais sur le fond, je suis d'accord pour dire que ce ne sont pas les techniques à utiliser pour le probleme dont on parle (mais les solutions ont deja été données des le début...)

  14. #14
    Membre actif

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    171
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 171
    Points : 218
    Points
    218
    Par défaut
    Citation Envoyé par hwoarang Voir le message
    Sauf que String est final donc c'est pas possible
    Ben oui c'est vrai ça ! au temps pour moi )

    Donc pas d'héritage de String.

    Donc soit une classe Utilitaire avec une méthode prenant une String en parametre et retournant un booleen. La méthode triviale

    Une classe wrapper, un peu sur le model du Décorator mais sans l'héritage... ou au pire un Décorator avec héritage de l'interface CharSequence pour garder un peu de souplesse (mais est-ce vraiment utile vu le besoin initial ...)

  15. #15
    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
    j'avoue qu'en bientot 8 ans d'usage professionnel de java, je n'ai jamais eu besoin d'ajouter une méthode dans String

  16. #16
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2008
    Messages
    1 190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 190
    Points : 2 657
    Points
    2 657
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    j'avoue qu'en bientot 8 ans d'usage professionnel de java, je n'ai jamais eu besoin d'ajouter une méthode dans String
    T'es pas joueur c'est pour ça

  17. #17
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Points : 1 475
    Points
    1 475
    Par défaut
    Pour ce qui est de modifier la classe String par des moyens détournés, il me semble que de toutes façons les JVM standard sont, pour des raison de sécurité, protégées contre les redéfinition du contenu de java.lang, donc sauf à modifier le JRE (du genre patcher la bilbiothèque de base qui contient java.lang), on ne peut pas "bidouiller" String.

  18. #18
    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
    avec aop et compagnie, tu ne sait rien faire, que ce soit dans java.lang ou autre chose, si t'es dans un environnement avec un securitymanager (applet, webstart, certains serveurs J2EE)

  19. #19
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Juin 2012
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Surcharge ou ajout de méthode à la création de l'instance
    La discussion est terminée depuis longtemps mais je me permets un petit ajout pour les suivants.

    Il me semble qu'il est possible de surcharger ou d'ajouter une méthode à une classe, mais seulement à la création de l'objet. Les modifications de la classe n'atteignent donc que l'instance créée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    String string = new String(){
        public boolean isAnagram(){
            boolean answer;
            // Your code...
            //
            return answer;
        }
    };
    Ce procédé est plus courant pour les Listener lorsqu'on veut modifié la réaction d'une instance à un clique de souris ou autre.

  20. #20
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Points : 1 475
    Points
    1 475
    Par défaut
    Raté!
    En fait ce qu'on fait ici est de créer à la volée une classe anonyme dérivée de la classe de base, et en même temps une instance de cette classe.
    Ca revient donc à la première option évoquée plus haut: créer une classe dérivée. String étant une classe final, non-dérivable, ça ne marchera pas dans ce cas.

    Par ailleurs (oui je sais, cette réflexion vient bien tard...), en terme de conception, il me semble qu'une anagramme n'est PAS une String...c'est une relation entre deux String.
    à savoir: une chaîne de caractère n'est pas une anagramme dans l'absolu, elle est une anagramme D'UNE AUTRE chaîne de caractère.

    ex: si on compare "étant" et "tanté", on peut conclure que l'un est l'anagramme de l'autre.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Ajout de méthodes à une classe
    Par jacksparo4 dans le forum Langage
    Réponses: 18
    Dernier message: 14/05/2015, 09h09
  2. Ajouter des méthodes à une classe annotée
    Par ThomasEscolan dans le forum Langage
    Réponses: 2
    Dernier message: 04/09/2012, 17h29
  3. Héritage d'une méthode de classe.
    Par alainbb dans le forum Langage
    Réponses: 7
    Dernier message: 09/03/2011, 17h12
  4. comment ajouter des méthodes à une classe lors Runtime?
    Par revever dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 31/03/2008, 13h53
  5. [C#] Ajout d'une méthode à la classe DropDownList
    Par Scorff dans le forum ASP.NET
    Réponses: 2
    Dernier message: 30/08/2005, 14h23

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