Partage
  • Partager sur Facebook
  • Partager sur Twitter

Main : protected accessible ?

Sujet résolu
    10 mai 2008 à 18:34:45

    Bonjour,

    En suivant le cours sur java, une question m'est venue à l'issue du chapitre "Classes Abstraites".

    J'ai fait tout le chapitre, et je me suis rendu compte d'une incohérence vis à vis de ce qui nous a été appris.
    Pour tester tout ce qui a été construit dans ce chapitre, on nous propose de faire cela (on a alors le projet avec les Classes main, Animal, Canin...):

    Loup dodge = new Loup(20, "Gris bleuté");
            dodge.boire();
            dodge.manger();
            dodge.bouger();
            dodge.crier();
            System.out.println(dodge.toString());
    

    Ne faites pas attention, j'ai remplacer 1 par dodge pour le nom.

    On obtient bien le résultat indiqué dans le cours.

    Dès lors j'ai ajouté (juste par curiosité, pour tester)
    dodge.couleur = "jaune";
            System.out.println(dodge.toString());
    


    Et là, problème, ma variable "couleur" a bien été changée ! o_O
    Or si on prend l'ensemble du code comme il est fait, je trouve cela bizarre. En effet aucun Accesseur n'a été mis dans une seule des classes. Et d'après le cours, une variable protected ne peut être modifiée en dehors de sa classe mère ou filles que via les accesseurs.

    Je ne comprends pas alors, pourquoi "couleur" qui est en protected, a pût être changée en dehors de la classe mère et ses filles (car le main n'est pas une classe fille de Animal).

    Quelqu'un peut-il m'expliquer comment j'ai pu changer une variable protected sans accesseur directement dans le main ?
    • Partager sur Facebook
    • Partager sur Twitter
      10 mai 2008 à 18:40:08

      Salut,

      Si mes souvenirs sont bons (je n'ai pas appris le Java par le tuto du sdz) l'attribut protected est accessible (méthode ou variable) par la même classe, une classe fille et par une classe du même package.

      N'ayant pas ton code source complet il est difficile de te répondre plus.
      • Partager sur Facebook
      • Partager sur Twitter
        10 mai 2008 à 18:51:19

        Salut,

        Voici le projet complet contenant tout le code. Je précise que concernant les animaux, comme il s'agit à chaque fois d'une même manipulation, je n'ai complété les classes que pour les animaux Loup et Chien (les autres n'ont pas de constructeurs si ce n'est celui qu'attribuera la JVM).
        (9 Ko)

        http://www.stephen.123.fr/telecharger/Animal.zip

        Une classe de même package peut donc accéder à une 'protected' ?
        Comment protéger une variable en empêchant une modification directe en dehors de la classe dès lors ?

        Car si on met 'private', les classes filles ne peuvent héritées de ces variables.

        EDIT : Il s'agit de mon code. Mais si ma vérification est bonne, je n'ai pas fait d'erreur par rapport au modèle.
        • Partager sur Facebook
        • Partager sur Twitter
          10 mai 2008 à 19:01:05

          voila un petit récapitulatif :

          -public: acces possible de partout

          -néant(droit de paquetage): acces possible depuis toutes les classes du meme paquetage(quel que soit le droit d'acces de la classe qui est au minimum celui du paquetage)

          -protected:acces possible depuis toutes les classes du même paquetage ou depuis les classes dérivées

          -private:acces restreint à la classe ou est faite la déclaration

          Voila en esperant avoir répondu à ta question ;)
          • Partager sur Facebook
          • Partager sur Twitter
            10 mai 2008 à 22:40:44

            Citation : Steph0

            Comment protéger une variable en empêchant une modification directe en dehors de la classe dès lors ?


            Private.
            Car protected permet à toutes les classes du même package d'y avoir accès.
            Et rien ne permet pas l'héritage.
            • Partager sur Facebook
            • Partager sur Twitter
              10 mai 2008 à 23:19:18

              Salut,

              Merci à vous deux ! Vous m'avez bien éclairé !

              En fait, j'avais les idées confuses entre private et protected surtout et cela m'a permis d'être au point dessus. En plus j'ai appris un nouveau type d'accès (néant). :)

              Par contre, concernant mon exemple (Animal). J'essaye de faire en sorte que poids et couleur ne soient modifiables que par les classes héritant de la superclasse Animal (en bref, toutes les classes sauf le main).
              Mais en mettant private aux variables et en ajoutant les accesseurs, cela me provoque des erreurs dans les classes héritées.

              Ne peut-on pas en Java restreindre l'accès à certaines variables juste à la classe contenant les variables et les classes héritant de la variable ?
              • Partager sur Facebook
              • Partager sur Twitter
                10 mai 2008 à 23:32:52

                Salut ,

                A ma connaissance on ne peut pas faire cela,mais en mettant private et en utilisant des accesseurs cela devrait bien fonctionner.
                • Partager sur Facebook
                • Partager sur Twitter
                  11 mai 2008 à 0:08:57

                  Salut,

                  Justement non. Malgré l'héritage, et les accesserus, celle qui hérite ne peut modifier la variable de la superclasse.

                  Bon après est-ce que c'est utile. C'est surtout parce qu'il parait qu'il ne vaut mieux pas que les variables soit directement modifiable à partir du main.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    11 mai 2008 à 0:14:27

                    L'encapsulation est une règle d'or en programmation.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      11 mai 2008 à 0:42:27

                      Je suis débutant en programmation. D'après Wikipédia, l'encapsulation consiste à ne proposer que des méthodes pour modifier les objets.

                      Mais dans mon cas, on a ici justement une faute d'encapsulation non ? Car couleur et poids sont directement modifiables si les variables sont en protected et en private impossible de faire en sort que les héritées puissent modifier mais pas le main (qui n'est pas marqué comme héritant).

                      EDIT : Hmm une idée ! Pur respecter la règle ne conviendrait-il pas de mettre dans un package mes superclasses et classes, et dans un autre les classes exécutant (Main) ? Car du coup protected empêcherait la modification d'un package à l'autre.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        11 mai 2008 à 0:54:11

                        Citation : Steph0

                        EDIT : Hmm une idée ! Pur respecter la règle ne conviendrait-il pas de mettre dans un package mes superclasses et classes, et dans un autre les classes exécutant (Main) ? Car du coup protected empêcherait la modification d'un package à l'autre.


                        Idée intéressante... Tu est sur la bonne voie.
                        Après quand on parle d'encapsulation, c'est surtout pour la sécurité des données. Faudrait pas qu'on puisse modifier un élément qui sert au fonctionnement de la classe comme un compteur par exemple. D'où l'intérêt des variables private. Après, protected fera le reste pour l'héritage.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          11 mai 2008 à 1:06:11

                          Salut,

                          Merci Vince33 pour tout tes conseils. :)
                          • Partager sur Facebook
                          • Partager sur Twitter
                            11 mai 2008 à 2:32:23

                            Vous avez l'air experts en sécurité... Je dirai rien.
                            T'as une classe mère avec ses variables. Tu déclares toujours ces variables de classe en private (ou éventuellement public mais à la seule condition qu'elles soient aussi static et final, des constantes quoi, pas de pb ac ça...)
                            pour accéder à ces variables, tu crée des setters et des getters (public) dans ta classe mère.
                            Quand ta classe fille héritera de la classe mère, la classe fille aura accès aux méthodes super.getters et super.setters puisque publics, mais pas aux variables elles-mêmes donc dans la pratique tu auras à remplacer chaque appel explicite de ta variable par l'appel indirect via un accesseur.
                            Sinon protected ? Ben j'en ai jamais eu vraiment l'usage, c'est assez particulier et à mon sens ça ressemble un peu à du bricolage. Éventuellement ça peut être pas mal pour des variables statiques, si on a plusieurs classes qui forment un ensemble cohérent dans un même package, mais mieux vaut s'en passer...
                            Je pense que tu adoptes une mauvaise approche en cloisonant tes classes comme tu le décris, juste pour satisfaire la règle du "protected" ...
                            • Partager sur Facebook
                            • Partager sur Twitter
                              11 mai 2008 à 11:31:41

                              Salut,

                              Pour ma part j'avoue ne pas être expert en sécurité.
                              Cependant si j'utilisais le protected c'est parce qu'il en était ainsi dans l'exemple. Mais c'est vrai que ça gène pour ce qui est de l'encapsulation si je reste avec le main dans le même package.

                              Ainsi j'ai mis toutes mes variables en private, mis les accesseurs (nous sommes ici dans la superclasse Animal) et j'ai appelé avec ceci :

                              // Dans la classe Loup héritant de la superclasse Animal
                              public Loup(double poids, String couleur){
                                          super.setCouleur(couleur);
                                  }
                              


                              pour effectuer un changement.

                              L'approche est-elle meilleur ainsi ? Je pense que cela suit ce que rom1dep préconise.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                11 mai 2008 à 13:49:40

                                Citation : rom1dep

                                Tu déclares toujours ces variables de classe en private (ou éventuellement public mais à la seule condition qu'elles soient aussi static et final, des constantes quoi, pas de pb ac ça...)


                                Dans ces conditions d'héritages de ces variables private ne se fait pas. Ce qui peut poser problème dans certains cas.

                                Citation : rom1dep


                                Vous avez l'air experts en sécurité... Je dirai rien.


                                Je dois le prendre comment ça ? o_O
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  11 mai 2008 à 15:47:36

                                  Citation : Vince33


                                  Citation : rom1dep

                                  Vous avez l'air experts en sécurité... Je dirai rien.


                                  Je dois le prendre comment ça ? o_O


                                  Je sais pas, tu te sens visé ?

                                  Citation : Vince33


                                  Citation : rom1dep

                                  Tu déclares toujours ces variables de classe en private (ou éventuellement public mais à la seule condition qu'elles soient aussi static et final, des constantes quoi, pas de pb ac ça...)


                                  Dans ces conditions d'héritages de ces variables private ne se fait pas. Ce qui peut poser problème dans certains cas.


                                  aucun problème :

                                  package app;
                                  
                                  public class Mere {
                                  	private int maVariable = 1;
                                  
                                  	public void setMaVariable(int newValue) {
                                  		maVariable = newValue;
                                  	}
                                  	
                                  	public int getMaVariabe(){
                                  		return this.maVariable;
                                  	}
                                  }
                                  


                                  package app;
                                  
                                  public class Fille extends Mere {
                                  
                                  	public Fille(){
                                  		super.maVariable=12;//erreur, maVariable non accessible
                                  		
                                  		System.out.println(super.getMaVariabe());//sort 1
                                  		super.setMaVariable(12);
                                  		System.out.println(super.getMaVariabe());//sort 12
                                  	}
                                  	
                                  	public static void main(String[]args){
                                  		new Fille();
                                  	}
                                  }
                                  

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    11 mai 2008 à 15:51:18

                                    Dans ces conditions ok.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      12 mai 2008 à 11:34:36

                                      Salut,

                                      J'en profite pour dire que c'est ce que j'ai fait. J'en conclu que c'est la bonne manière de faire (si vous êtes tous les deux d'accord). :)

                                      super.setMaVariable(12);
                                      • Partager sur Facebook
                                      • Partager sur Twitter

                                      Main : protected accessible ?

                                      × 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