[JAVA] Sous-classes d'une classe
Répondre à la discussion
Affichage des résultats 1 à 25 sur 25

[JAVA] Sous-classes d'une classe



  1. #1
    Aenonis

    Question [JAVA] Sous-classes d'une classe


    ------

    Bonjour,

    Je suis occupé à créer une petite application qui joue sur l'héritage et le polymorphisme.
    En fait, j'ai des classes et chacune des classes correspond à une fonctionnalité du programme.
    Chaque classe hérite d'une classe Token. Chaque classe est définie par un attribut de type String.
    Dans la classe Token, j'ai une fonction "getToken(String token)" qui renvoie la sous-classe correspondant au token passé en paramètre.

    En code, ça donne, par exemple:
    Code:
    public abstract class Token
    {
        protected final String token;
    
        protected Token(String token)
        {
            this.token=token;
        }
    
        public static Token getToken(String token)
        {
            switch (token)
            {
                case "+": return new Plus();
                case "-": return new Moins();
            }
            return null;
        }
    }
    
    public class Plus extends Token
    {
        public Plus()
        {
            super(classToken());
        }
    
        public static String classToken()
        {
            return "+";
        }
    }
    
    public class Moins extends Token
    {
        public Moins()
        {
            super(classToken());
        }
    
        public static String classToken()
        {
            return "-";
        }
    }
    J'aimerai dynamiser la fonction "getToken(String)".
    En effet, si j'ajoute une nouvelle classe par exemple "Fois" dont le code serait "*", je devrai modifier le code de la fonction en ajoutant un nouveau case au switch.
    Et je veux pousser le dynamisme à son paroxysme: en effet, je compte mettre la classe Token ainsi que les deux sous classes dans un JAR.
    Si un de mes utilisateurs veut créer ses propres tokens (par exemple le token "Sur" qui a le code "/"), il n'a qu'à hériter simplement de ma classe mère Token et de définir la fonction statique "classToken()" et mon propre code aura détecté sa classe (qui est dans un autre JAR évidemment).

    J'ai une idée du code que je vais écrire mais il ne me manque la fonction "Class<?>.getSubClasses()" .

    J'ai déjà regardé du coté de la réflection mais je ne sais pas comment parvenir à mes fins.

    Bien à vous,

    Aenonis

    -----

  2. #2
    Zartan

    Re : [JAVA] Sous-classes d'une classe

    C'est un problème intéressant et pas si difficile que ça à résoudre

    Il faut que les sous-classes soient responsables de leur détection. Par conséquent on les initialise et elles enregistrent une fonction booléenne qui renverra vrai si il s'agit bien du token en question. Ou alors une version plus simple consiste à enregistrer la chaîne de caractères qui correspond au token. Avec un tableau associatif à deux entrées String par exemple. La deuxième String étant le nom de la classe.

    Ensuite on remplace le switch par une boucle qui compare String token soit en utilisant les fonctions enregistrées ou bien les chaines. Pour initialiser l'objet on aura effectivement besoin de la réflection.

    En pratique il y a plusieurs façons de le faire. Attention aux risques de collision.

  3. #3
    Aenonis

    Question Re : [JAVA] Sous-classes d'une classe

    Merci de cette réponse explicite.

    C'est quoi une collision?

    Amicalement,

    Aenonis

  4. #4
    Zartan

    Re : [JAVA] Sous-classes d'une classe

    Une collision ce serait :

    Code:
    public class OperateurMoins extends Token // a-b
    {
        public OperateurMoins()
        {
            super(classToken());
        }
    
        public static String classToken()
        {
            return "-";
        }
    }
    public class SigneMoins extends Token // -a
    {
        public SigneMoins()
        {
            super(classToken());
        }
    
        public static String classToken()
        {
            return "-";
        }
    }
    Là c'est un cas simple, si ce sont des ensembles avec des valeurs communes ça peut être plus subtil et alors on a besoin d'un système de priorités.
    Dernière modification par Zartan ; 01/08/2012 à 20h00.

  5. A voir en vidéo sur Futura
  6. #5
    Aenonis

    Question Re : [JAVA] Sous-classes d'une classe

    Bonjour,

    Je viens de me replonger dans mon projet...

    J'ai implémenté une solution possible qui devrait marcher mais qui ne fonctionne pas.

    Voici le code que j'ai écrit:
    Code:
    public abstract class Token
    {
    	protected final String token;
    	private static final Map<String, Class> map=new LinkedHashMap<>();
    
    	protected Token(String token)
    	{
    		this.token=token;
    	}
    
    	protected static void register(String token, Class clazz)
    	{
    		//il faut gérer les collisions mais je ne sais pas comment...
    		map.put(token, clazz);
    	}
    	
    	protected static boolean isRegistered(String token)
    	{
    		return map.containsKey(token);
    	}
    	
    	public static Token getToken(String token)
    	{
    		for (String t : map.keySet())
    		{
    			if (t.equals(token))
    			{
    				return (Token)map.get(t).newInstance(); //j'ai enlevé le try-catch pour faciliter la lecture
    			}
    		}
    		return null;
    	}
    }
    
    public class Plus extends Token
    {
    	static
    	{
    		register(classToken(), Plus.class);		
    	}
    
    	public Plus()
    	{
    		super(classToken());
    	}
    
    	public static String classToken()
    	{
    		return "+";
    	}
    }
    
    public class Moins extends Token
    {
    	static
    	{
    		register(classToken(), Moins.class);		
    	}
    
    	public Moins()
    	{
    		super(classToken());
    	}
    
    	public static String classToken()
    	{
    		return "-";
    	}
    }
    Bon, normalement, le code fonctionne, je ne l'ai pas testé mais je sais que la logique est bonne.
    Le soucis, c'est que les blocs static (ceux qui enregistre les classes filles) ne sont pas appelés...
    J'ai cherché sur internet et j'ai vu que les blocs static sont appelés quand la classe est chargée. JAVA étant un "chargeur paresseux", il ne charge que les classes qu'il a besoin, cela explique qu'il n'appelle pas les blocs static.

    Il faut gérer les collisions.
    J'aimerai que le programme lance une exception lorsqu'il trouve une collision: en effet, je ne tolère aucune collision (le - unaire est géré autrement par un système de ma création), mais si je lance une exception dans la fonction register, l'exception devra obligatoirement être catchée dans le bloc static, ce qui ne m'arrange pas, vu que j'aimerai que l'exception soit gérée ailleurs (dans la fonction main par exemple).

    En vous remerciant,

    Aenonis

  7. #6
    Zartan

    Re : [JAVA] Sous-classes d'une classe

    Pourquoi avez-vous besoin d'instancier ces classes ? Est-ce que vous ne pourriez pas utiliser des singletons ?

    http://en.wikipedia.org/wiki/Singleton_pattern

    Il faudra quand même initialiser les classes que vous utilisez, c'est un principe qui n'est pas trop contraignant et qui a ses avantages.

    Pour les collisions votre fonction register doit vérifier que le token n'est pas déjà dans la hashmap avant l'ajout.

  8. #7
    Aenonis

    Re : [JAVA] Sous-classes d'une classe

    Je ne vois pas en quoi les singletons pourraient résoudre mon problème...

  9. #8
    Zartan

    Re : [JAVA] Sous-classes d'une classe

    C'est à vous de voir si vous avez besoin de les instancier ou non. Je ne peux pas répondre à votre place.

  10. #9
    Aenonis

    Re : [JAVA] Sous-classes d'une classe

    En effet, je ne dois pas les instancier, je peux avoir une référence sur la seule instance existante.

    Mais ça ne règle pas le soucis des blocs static qui ne se chargent pas.

  11. #10
    Zartan

    Re : [JAVA] Sous-classes d'une classe

    Et bien si vous relisez le wiki vous verrez que c'est expliqué dedans avec instance = new Singleton() ;

  12. #11
    Aenonis

    Re : [JAVA] Sous-classes d'une classe

    J'ai mis en oeuvre les 4 codes proposés sur le wiki, mais aucun ne fonctionne: les blocs static ne se chargent toujours pas.

  13. #12
    Zartan

    Re : [JAVA] Sous-classes d'une classe

    vous n'avez pas besoin de blocs statiques avec un singleton, vous initialisez vos données dans le constructeur, c'est d'ailleurs le but de la manip

  14. #13
    Aenonis

    Re : [JAVA] Sous-classes d'une classe

    le soucis, c'est que j'ai besoin des infos AVANT l'initialisation...

    dans le code suivant:
    Code:
    public static Token getToken(String token)
    	{
    		for (String t : map.keySet())
    		{
    			if (t.equals(token))
    			{
    				return (Token)map.get(t).newInstance(); //j'ai enlevé le try-catch pour faciliter la lecture
    			}
    		}
    		return null;
    	}
    le map ne contient rien... vu que les bloc static ne sont pas invoqués.
    que je remplace
    Code:
    return (Token)map.get(t).newInstance();
    par
    Code:
    return (Token)map.get(t).getMethod("jeveuxmoninstancesingleton").invoke();
    n'y changera strictement rien à la donne... vu la méthode jeveuxmoninstancesingleton() initialisera l'instance si pas initialisée...

    Au plaisir,

    Aenonis

  15. #14
    Zartan

    Re : [JAVA] Sous-classes d'une classe

    Bonsoir,je vous ai déjà dit que vous n'avez pas besoin de blocs static avec un singleton, mettez tout dans le constructeur.

  16. #15
    Zartan

    Re : [JAVA] Sous-classes d'une classe

    Citation Envoyé par Aenonis Voir le message
    que je remplace [CODE]return (Token)map.get(t).newInstance( );
    Remplacez newInstance() par getInstance()
    Relisez wikipedia :

    Code:
    public class Singleton {
        private static final Singleton instance = new Singleton();
     
        private Singleton() {}
     
        public static Singleton getInstance() {
            return instance;
        }
    }
    Votre classe est donc déjà initialisée.

  17. #16
    Zartan

    Re : [JAVA] Sous-classes d'une classe

    En effet, vous avez un problème d'initialisation, vous pouvez utiliser cette méthode pour pré-initialiser vos classes :


    http://docs.oracle.com/javase/1.4.2/...ang/Class.html

    forName(java.lang.String,%20bo olean,%20java.lang.ClassLoader )

    Comme elle prend le nom de la classe en paramètre vous pouvez déclarer celles que vous voulez utiliser dans un fichier.

  18. #17
    Aenonis

    Question Re : [JAVA] Sous-classes d'une classe

    J'ai réalisé le code suivant, en concordance avec Wikipédia...

    Code:
    public abstract class Token
    {
        protected final String token;
        private static final Map<String, Class> map=new LinkedHashMap<>();
    
        protected Token(String token)
        {
            this.token=token;
        }
    
        protected static void register(String token, Class clazz)
        {
            map.put(token, clazz);
        }
    
        protected static boolean isRegistered(String token)
        {
            return map.containsKey(token);
        }
    
        public static Token getToken(String token) throws InvalidTokenException
        {
            System.out.println(map.size()); //affiche 0
            for (String t : map.keySet())
            {
                if (t.equals(token))
                {
                    return (Token)map.get(t).getMethod("getInstance").invoke(null);
                }
            }
            return null;
    	}
    }
    
    public final class TokenAddition extends Token
    {
        private static final TokenAddition instance=new TokenAddition();
    
        public static TokenAddition getInstance()
        {
            return instance;
        }
    
        private TokenAddition()
        {
            super(classToken());
            register(classToken(), TokenAddition.class);
        }
    
        public static String classToken()
        {
            return "+";
        }
    }
    Vu que le ClassLoader ne charge pas la classe "TokenAddition" avant l'exécution du "Token.getToken()", la Map ne contient rien et me retourne null.
    Je savais bien que le fait d'avoir une classe singleton ne règlerait pas le problème... Vu que le soucis est que JAVA est Lazy...

    Au plaisir,

    Aenonis

  19. #18
    Aenonis

    Re : [JAVA] Sous-classes d'une classe

    Citation Envoyé par Zartan Voir le message
    En effet, vous avez un problème d'initialisation, vous pouvez utiliser cette méthode pour pré-initialiser vos classes :


    http://docs.oracle.com/javase/1.4.2/...ang/Class.html

    forName(java.lang.String,%20bo olean,%20java.lang.ClassLoader )

    Comme elle prend le nom de la classe en paramètre vous pouvez déclarer celles que vous voulez utiliser dans un fichier.
    Ouais, mais ça revient à charger toutes les classes dont j'ai besoin, ce qui revient au problème initial...

  20. #19
    Zartan

    Re : [JAVA] Sous-classes d'une classe

    Citation Envoyé par Aenonis Voir le message
    Ouais, mais ça revient à charger toutes les classes dont j'ai besoin, ce qui revient au problème initial...
    Pas exactement puisque vous pouvez trouver quelles sont les classes d'un paquetage en utilisant un code tel que celui-là : http://www.dzone.com/snippets/get-al...within-package

  21. #20
    Aenonis

    Thumbs up Re : [JAVA] Sous-classes d'une classe

    Tu sais quoi Zartan?

    Tu es merveilleux !

    ça fonctionne comme sur des roulettes !

    Tu m'as donné le code qu'il fallait.

    Le chargement des classes du package et de ses sous-packages est magique.

    Je te remercie !

    Aenonis

  22. #21
    Zartan

    Re : [JAVA] Sous-classes d'une classe

    Merci pour les compliments mais il ne faut pas se réjouir trop vite car les commentaires disent que ça pose problème avec les .jar et les zip et proposent des modifications

  23. #22
    Aenonis

    Re : [JAVA] Sous-classes d'une classe

    Quel genre de problèmes?

  24. #23
    Zartan

    Re : [JAVA] Sous-classes d'une classe

    C'est écrit dans les commentaires.

  25. #24
    Aenonis

    Re : [JAVA] Sous-classes d'une classe

    Ouais, mais l'anglais et moi, ça fait deux...

  26. #25
    Zartan

    Re : [JAVA] Sous-classes d'une classe

    Il faudra que vous fassiez un effort parce que ils proposent des solutions, et que je n'ai pas autant de temps à vous consacrer.

Discussions similaires

  1. Instancier une classe en Java
    Par narakphysics dans le forum Programmation et langages, Algorithmique
    Réponses: 1
    Dernier message: 21/04/2012, 18h26
  2. classe java
    Par littlegirl dans le forum Programmation et langages, Algorithmique
    Réponses: 1
    Dernier message: 01/05/2011, 13h21
  3. Instancier les classes en java
    Par invite2d9e7c03 dans le forum Logiciel - Software - Open Source
    Réponses: 0
    Dernier message: 26/03/2010, 10h52
  4. Affichage variable d'une classe java dans une page web
    Par invitee5fedd72 dans le forum Logiciel - Software - Open Source
    Réponses: 12
    Dernier message: 01/06/2009, 21h14
  5. matlab sous java
    Par ABN84 dans le forum Logiciel - Software - Open Source
    Réponses: 1
    Dernier message: 26/02/2007, 05h25