Partage
  • Partager sur Facebook
  • Partager sur Twitter

Quelques questions

généricité et réflexibilité

Sujet résolu
    22 février 2009 à 16:29:10

    1)La réflexibilité : j'ai fait des manipulations sur le code de cisboy pour pouvoir invoquer des autres méthodes de la classe Paire, mais, j'ai du récupérer trois objets de type classe pour pouvoir récupérer les méthodes de la classe Paire sinon ça na marche pas.

    Donc j'ai fait comme ceci :
    //On va chercher la méthode toString, elle n'a aucun paramètre
    Method m = cl.getMethod("toString", null);
    //On va rechercher la méthode setValeur1, elle a un paramètre.
    Class c2 = Class.forName (nom);
    Method m2 = c2.getMethod("setValeur1", String.class);
    //On va rechercher la méthode getValeur1, elle n'a aucun paramètre.
    Class c3 = Class.forName (nom);
    Method m3 = c3.getMethod ("getValeur1", null);

    Et j'aimerais savoir pourquoi suis je obligé de récupérer chaque dois un objet de type Class différents pour que ça marche, est ce un bug ou est ce normal et si oui pourqoi ?

    2)La généricité : j'ai essayer de faire une liste dans laquelle on peut ajouter des éléments d'un classe mais aussi de ces sous classes.
    J'ai fait une classe Point et une classe Circle qui en hérite.
    Mais j'ai un problème avec la méthode add il me mets en compilation qu'il ne la trouves pas :
    listePC.add (new Point (7, 4));
    listePC.add (new Circle (7, 8, 4));


    J'aimerais savoir pourquoi.

    Erf et pourquoi il me poste 3*le sujet, y'a moyen de les supprimer ?
    • Partager sur Facebook
    • Partager sur Twitter
      22 février 2009 à 19:14:47

      donne un code complet et l'erreur de compilation exacte
      • Partager sur Facebook
      • Partager sur Twitter
        22 février 2009 à 20:47:56

        Alors voici les classes que j'ai créés d'abord la classe Point :

        public class Point implements Comparable<Point>
        {
            // instance variables - replace the example below with your own
            private int x, y;
            /**
             * Constructor for objects of class Point
             */
            public Point()
            {
                y = 0;
                x = 0;
            }
            public Point (int x, int y) {
                this.x = x;
                this.y = y;        
            }
        
            /**
             * An example of a method - replace this comment with your own
             * 
             * @param  y   a sample parameter for a method
             * @return     the sum of x and y 
             */
            public void move (int nvX, int nvY) {
                x = nvX;
                y = nvY;
            }
            public int getX () {
                return x;
            }
            public int getY () {
                return y;
            }
            public String toString () {
                return "Le point se trouve en ("+x+";"+y+")";
            }
            public boolean equals (Point p2) {
                return x == p2.x && y == p2.y;
            }
            public void setX (int x) {
                this.x = x;
            }
            public void setY (int y) {
                this.y = y;
            }
            public Point getPoint () {
                return this;
            } 
            public int compareTo (Point p) {
                return (x + y) - (p.x + p.y);
                    
            }
        }
        


        Ensuite la classe Circle qui en hérite :
        /**
         * Write a description of class Circle here.
         * 
         * @author (your name) 
         * @version (a version number or a date)
         */
        public class Circle extends Point 
        {
            // instance variables - replace the example below with your own
           
            private int rayon;
            /**
             * Constructor for objects of class Circle
             */
            public Circle()
            {
                super (0, 0);
                rayon = 0;
            }
            public Circle(int rayon) 
            {        
                this.rayon = rayon;
            }
            public Circle (int x, int y, int rayon) {
                super (x, y);
                this.rayon = rayon;
            }       
        
            /**
             * An example of a method - replace this comment with your own
             * 
             * @param  y   a sample parameter for a method
             * @return     the sum of x and y 
             */
            public void changeRayon (int nvR)
                
            {
                rayon = nvR;
            }
            public void move (int nvX, int nvY) {
                super.setX (nvX);
                super.setY (nvY);        
            }
            public int getRayon () {
                return rayon;
            }
            public String toString ()  {
                return "La longeur du rayon du cercle est : "+rayon+"\n"
                +"Le centre : "+super.toString();
            }  
            public Point getCentre () {
                return super.getPoint ();
            }
            public boolean equals (Circle c2) {
                   return (super.equals (c2.getCentre())) && (rayon == c2.rayon);
            }
            public void tourner () {
                System.out.println("Je tourne!");
            }
        }
        

        Jusque là ça va, le problème est avec ma classe Test :
        import java.util.ArrayList;
        import java.util.Collection;
        public class Test {
        
        	/**
        	 * @param args
        	 */
        	public static void main(String[] args) {
        		
        		    ArrayList<? extends Point> listePC = new ArrayList();
        		    listePC.add (new Point (7, 4));
        		    listePC.add (new Circle (7, 8, 4));
        		    System.out.println(listePC.get(0));
        	}
        
        }
        

        Il me souligne toujours add en rouge, et il me mets comme erreur ceci :

        Exception in thread "main" java.lang.Error: Unresolved compilation problems:
        The method add(capture#1-of ? extends Point) in the type ArrayList<capture#1-of ? extends Point> is not applicable for the arguments (Point)
        The method add(capture#2-of ? extends Point) in the type ArrayList<capture#2-of ? extends Point> is not applicable for the arguments (Circle)
        at Test.main(Test.java:11)


        Et je n'arrive pas à corriger cette erreur.

        Et pour l'autre avec la réflexibilité, voilà le code complet :
        La classe Paire :
        /**
         * Write a description of class Paire here.
         * 
         * @author (your name) 
         * @version (a version number or a date)
         */
        public class Paire
        {
             private String valeur1, valeur2;
                
                public Paire(){
                        this.valeur1 = null;
                        this.valeur2 = null;
                        System.out.println("Instanciation ! !");
                }
                
                public Paire(String val1, String val2){
                        this.valeur1 = val1;
                        this.valeur2 = val2;
                        
                        System.out.println("Instanciation avec des paramètres ! !");
                        
                }
                
                public String toString(){
                        return  "Je suis un objet qui a pour valeur : " + this.valeur1 + " - " + this.valeur2;
                }
         
                public String getValeur1() {
                        return valeur1;
                }
         
                public void setValeur1(String valeur1) {
                        this.valeur1 = valeur1;
                }
         
                public String getValeur2() {
                        return valeur2;
                }
         
                public void setValeur2(String valeur2) {
                        this.valeur2 = valeur2;
                }
        }
        

        Et ma classe Test :

        import java.lang.reflect.Constructor;
        import java.lang.reflect.InvocationTargetException;
        import java.lang.reflect.Method;
        import java.lang.reflect.Type;
        import java.lang.reflect.Array;
         
        public class Test {
         
                public static void main(String[] args) {                
                        
                        String nom = Paire.class.getName();
                        
                        
                                try {
                                        //On crée un objet Class
                                        Class cl = Class.forName(nom);
                                        //Nouvelle instance de la classe Paire
                                        Object o = cl.newInstance();
                                        
                                        //On crée les paramètres du constructeur
                                        Class[] types = new Class[]{String.class, String.class};
                                        //On récupère le constructeur avec les deux paramètres
                                        Constructor ct = cl.getConstructor(types);                      
                                        //On instancie l'objet avec le constructeur surchargé !
                                        Object o2 = ct.newInstance(new String[]{"valeur 1 ", "valeur 2"});
                                        //Instanciation dynamique d'un tableau.
                                        Object tableau = Array.newInstance (Object.class, 2);
                                        //Place le premier objet dans le tableau.
                                        Array.set (tableau, 0, o);
                                        //Place le second objet dans le tableaux
                                        Array.set (tableau, 1, o2);
                                        //On va chercher la méthode toString, elle n'a aucun paramètre
                                        Method m = cl.getMethod("toString", null);
                                        //On va rechercher la méthode setValeur1, elle a un paramètre.
                                        Class c2 = Class.forName (nom);
                                        Method m2 = c2.getMethod("setValeur1", String.class);
                                        //On va rechercher la méthode getValeur1, elle n'a aucun paramètre.
                                        Class c3 = Class.forName (nom);
                                        Method m3 = c3.getMethod ("getValeur1", null);
                                        
                                        //La méthode invoke exécute la méthode sur l'objet passé en paramètre,
                                        // Si pas de paramètre, null en deuxième paramètre de la méthode invoke !
                                        
                                        System.out.println("---------------------------------------------");
                                        //On invoque toString sur o2.
                                        System.out.println("Méthode " + m.getName() + " sur o2: " + m.invoke(o2, null));
                                        //On invoque toString sur o.
                                        System.out.println("Méthode " + m.getName() + " sur o: " + m.invoke(o, null)); 
                                        //On invoque setValeur1 sur o
                                        System.out.println("Méthode " + m2.getName() + "sur o : " );
                                        m2.invoke(o, "Valeur 1");
                                        //On invoque la méthode getValeur1 sur o.
                                        System.out.println("Méthode " + m3.getName() + "sur o : " + m3.invoke (o, null));
                                        //On affiche le première objet du tableau : 
                                        System.out.println(Array.get(tableau, 0));
                                } catch (SecurityException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                } catch (IllegalArgumentException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                } catch (ClassNotFoundException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                } catch (InstantiationException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                } catch (IllegalAccessException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                } catch (NoSuchMethodException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                } catch (InvocationTargetException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }                    
                        
                }
        }
        


        Je ne comprends pas pourquoi il faut créer trois objets de type Class pour récupérer les méthodes.
        Si je fais comme ça, ça ne marche pas :
        import java.lang.reflect.Constructor;
        import java.lang.reflect.InvocationTargetException;
        import java.lang.reflect.Method;
        import java.lang.reflect.Type;
        import java.lang.reflect.Array;
         
        public class Test {
         
                public static void main(String[] args) {                
                        
                        String nom = Paire.class.getName();
                        
                        
                                try {
                                        //On crée un objet Class
                                        Class cl = Class.forName(nom);
                                        //Nouvelle instance de la classe Paire
                                        Object o = cl.newInstance();
                                        
                                        //On crée les paramètres du constructeur
                                        Class[] types = new Class[]{String.class, String.class};
                                        //On récupère le constructeur avec les deux paramètres
                                        Constructor ct = cl.getConstructor(types);                      
                                        //On instancie l'objet avec le constructeur surchargé !
                                        Object o2 = ct.newInstance(new String[]{"valeur 1 ", "valeur 2"});
                                        //Instanciation dynamique d'un tableau.
                                        Object tableau = Array.newInstance (Object.class, 2);
                                        //Place le premier objet dans le tableau.
                                        Array.set (tableau, 0, o);
                                        //Place le second objet dans le tableaux
                                        Array.set (tableau, 1, o2);
                                        //On va chercher la méthode toString, elle n'a aucun paramètre
                                        Method m = cl.getMethod("toString", null);
                                        //On va rechercher la méthode setValeur1, elle a un paramètre.
                                       
                                        Method m2 = c1.getMethod("setValeur1", String.class);
                                        //On va rechercher la méthode getValeur1, elle n'a aucun paramètre.
                                       
                                        Method m3 = c1.getMethod ("getValeur1", null);
                                        
                                        //La méthode invoke exécute la méthode sur l'objet passé en paramètre,
                                        // Si pas de paramètre, null en deuxième paramètre de la méthode invoke !
                                        
                                        System.out.println("---------------------------------------------");
                                        //On invoque toString sur o2.
                                        System.out.println("Méthode " + m.getName() + " sur o2: " + m.invoke(o2, null));
                                        //On invoque toString sur o.
                                        System.out.println("Méthode " + m.getName() + " sur o: " + m.invoke(o, null)); 
                                        //On invoque setValeur1 sur o
                                        System.out.println("Méthode " + m2.getName() + "sur o : " );
                                        m2.invoke(o, "Valeur 1");
                                        //On invoque la méthode getValeur1 sur o.
                                        System.out.println("Méthode " + m3.getName() + "sur o : " + m3.invoke (o, null));
                                        //On affiche le première objet du tableau : 
                                        System.out.println(Array.get(tableau, 0));
                                } catch (SecurityException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                } catch (IllegalArgumentException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                } catch (ClassNotFoundException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                } catch (InstantiationException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                } catch (IllegalAccessException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                } catch (NoSuchMethodException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                } catch (InvocationTargetException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }                    
                        
                }
        }
        


        Il m'affiche ceci comme erreur :

        Exception in thread "main" java.lang.Error: Unresolved compilation problems:
        c1 cannot be resolved
        c1 cannot be resolved

        at Test.main(Test.java:37)


        Voila

        • Partager sur Facebook
        • Partager sur Twitter
          23 février 2009 à 9:26:27

          Oula c'est un peu fouillis tout ça ...
          Pourquoi tu as 2 programme ? Est-ce 2 problème différents ? (si oui alors 2 topic)

          Essaye de nous dire aussi ce que doit faire ton programme, car nous le donner comme ça sans nous dire un peu a quoi ça correspond ni ce que tu veux faire avec ... ça devient tout de suite plus dure pour t'aider.
          • Partager sur Facebook
          • Partager sur Twitter
            23 février 2009 à 9:30:11

            En ce qui concerne la généricité, j'ai trouvé une alternative pour initialiser la l'ArrayList à partir d'un tableau.

            import java.util.ArrayList;
            import java.util.Arrays;
            import java.util.Collection;
            public class Test {
            
            	/**
            	 * @param args
            	 */
            	public static void main(String[] args) {
            		    Point[] pts = new Point[] {new Point(2, 3), new Point(5, 7),
            		    new Circle(5, 4, 8), new Circle(6, 9, 5)};
            		    ArrayList<? extends Point> listePC = new ArrayList(Arrays.asList(pts));
            		    for (Point p : listePC)
            		    	System.out.println(p);
            	}
            
            }
            


            Mais bon le problème reste surtout si je veux ajouter des éléments après dans la liste.

            La méthode add marche bien quand la liste n'accepte qu'un seul type d'élément, mais quand il s'agit de deux.

            Enfin c'est durement parce le prototype de la méthode add est celui-ci :

            boolean add(E e)

            et qu'il n'y a pas de méthodes :
            boolean add (? extends E)

            Enfin soit sans doute y-a-il une bonne raison à cela, je pense que ce problème n'est pas ré solvable car il faudrait pouvoir modifier le code de la classe ArrayList, et on n'y a pas accès.

            Mais je vais laisser le sujet ouvert au cas ou.

            Et pour ma question sur la réflexibilité, je pense que c'est normal, mais je n'arrive pas à comprendre pourquoi il ne reconnais plus c1 lorsque j'utilise un getMethod dessus.
            • Partager sur Facebook
            • Partager sur Twitter
              23 février 2009 à 9:43:46

              Citation : Lolilolight

              Il m'affiche ceci comme erreur :

              Exception in thread "main" java.lang.Error: Unresolved compilation problems:
              c1 cannot be resolved
              c1 cannot be resolved

              at Test.main(Test.java:37)


              Tu mélange c1 (le chiffre un) et cl (la lettre L) dans ton programme.

              Je regarde ton premier programme, celui avec ton problème d'arrayList, c'est bien ca ?
              • Partager sur Facebook
              • Partager sur Twitter
                23 février 2009 à 13:53:42

                Ha bah oui tiens, j'ai confondu le l avec le 1. (Purée ils se ressemblent comme 2 goutes d'eau)

                Purée, je l'avais même pas remarquer, ça devient grave, bon bah ça m'en fait déjà un de résolu.

                Pour le deuxième programme en fait, donc sur la généricité, le but du programme est de faire en sorte d'avoir une liste dans laquelle je peux ajouter des cercles et des points.
                J'ai donc fait une classe Point, et Circle qui hérite de Point, et la classe Test qui contient la liste.

                Lorsque j'initialise la liste à l'aide d'un tableau, pas de problème. Le problème est lorsque je veux rajouter des éléments dedans après.

                import java.util.ArrayList;
                import java.util.Arrays;
                import java.util.Collection;
                public class Test {
                
                	/**
                	 * @param args
                	 */
                	public static void main(String[] args) {
                		    Point[] pts = new Point[] {new Point(2, 3), new Point(5, 7),
                		    new Circle(5, 4, 8), new Circle(6, 9, 5)};
                		    ArrayList<? extends Point> listePC = new ArrayList(Arrays.asList(pts));
                		    for (Point p : listePC)
                		    	System.out.println(p);
                		    listePC.add(new Point(5, 6));
                	}
                
                }
                


                Il me mets cette erreur ci, effectivement il n'y a pas la méthode attendue dans la classe ArrayList.


                Exception in thread "main" java.lang.Error: Unresolved compilation problem:
                The method add(capture#2-of ? extends Point) in the type ArrayList<capture#2-of ? extends Point> is not applicable for the arguments (Point)

                at Test.main(Test.java:15)


                Je voulais juste savoir si il n'y a pas moyen de résoudre ce problème.





                • Partager sur Facebook
                • Partager sur Twitter
                  23 février 2009 à 14:03:53

                  Je ne suis pas sur du tout, mais est-ce qu'en mettant "<? extends Point>" ton ArrayList ne pourrait pas prendre QUE des classes héritant de point. Donc tu ne pourrait pas ajouter de point car elle n'hérite pas d'elle même ?

                  Je pense que ton application devrait marcher si tu met uniquement "ArrayList<Point>".
                  • Partager sur Facebook
                  • Partager sur Twitter
                    23 février 2009 à 14:12:13

                    Ha bah oui, en effet, si je fais comme tu me l'a dis elle accepte des points, et des cercles.

                    Je dois avoir mal compris le tutoriel de cisboy alors, c'est juste ArrayList<Circle> qui n'hérite pas de ArrayList<Point> et donc on ne pet pas écrire listePoint = listeCercle, mais rien n'empêche de faire comme ceci :
                    import java.util.ArrayList;
                    import java.util.Arrays;
                    import java.util.Collection;
                    public class Test {
                    
                    	/**
                    	 * @param args
                    	 */
                    	public static void main(String[] args) {
                    			
                    		    Point[] pts = new Point[] {new Point(2, 3), new Point(5, 7),
                    		    new Circle(5, 4, 8), new Circle(6, 9, 5)};
                    		    ArrayList<Point> listePC = new ArrayList(Arrays.asList(pts));
                    		    for (Point p : listePC)
                    		    	System.out.println(p);
                    		    listePC.add(new Point(5, 6));
                    		    listePC.add(new Circle (2, 3, 4));		    
                    	}
                    
                    }
                    


                    Hors je pensais que l'on ne pouvait pas.
                    Merci de m'avoir aidé, le sujet est enfin résolu.
                    (Assez compliqué à comprendre quand même la généricité et l'héritage)

                    • Partager sur Facebook
                    • Partager sur Twitter
                      23 février 2009 à 18:39:01

                      Au passage, une toute petite chose : peut-on dire qu'un cercle est un point et qu'un point est un cercle ? Non donc je pense que l'héritage n'a pas sa place ici.

                      Enfin tes problèmes sont résolus, bon courage pour la suite :)
                      • Partager sur Facebook
                      • Partager sur Twitter
                        23 février 2009 à 19:08:52

                        L'héritage dis, un cercle est un point, fin, moi j'ai utilisé l'héritage pour avoir plus facile, je dirai même un cercle est une infinité de points.^^

                        Mais bon je n'ai gardé que le centre car je n'ai besoin que de lui comme information.
                        Et l'héritage ne dis pas un Point est un Cercle, la relation n'est valable que dans un seul sens.

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Quelques questions

                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                        • Editeur
                        • Markdown