La question est simple:
Comment declare vous vos variables d'instances?
(private or protected)
La question est simple:
Comment declare vous vos variables d'instances?
(private or protected)
Si grande est la faiblesse d'une âme, dont la raison est partie!
Ne jamais embrouiller ni abasourdir par une foule d'images le génie intérieur qui réside au fonde de sa poitrine,...
L'ambition est le rfuge de l'échec. "Oscar Wild"
Si la classe n'est pas vouée à etre étendue :
Tout en private sauf les constantes de classe ( public static final MA_CONSTANTE=...)
Si la classe est vouée à être étendue :
Tout en protected SAUF les variables gérées exclusivement par la classe courante.
Oui mais coment tu fais pour savoir si une classe va etre etendu ou pas. Comment tu sais si une variable vas etre exclusivement utilise dans une class?
Si grande est la faiblesse d'une âme, dont la raison est partie!
Ne jamais embrouiller ni abasourdir par une foule d'images le génie intérieur qui réside au fonde de sa poitrine,...
L'ambition est le rfuge de l'échec. "Oscar Wild"
Bah ça, c'est toi qui décide lors de la conception : la classe que tu es en train de concevoir devra-t-elle uniquement être utilisée telle-quelle, ou bien le développeur suivant aura-t-il le droit d'étendre ta classe ? ça relève du problème de conception là.Oui mais coment tu fais pour savoir si une classe va etre etendu ou pas
exemple assez courant :Comment tu sais si une variable vas etre exclusivement utilise dans une class
Ta classe possède une variable privée qui lui sert par exemple de limite :
private int limite;
Cette limite peut être initialisée par une valeur par défaut que les classes fille auront le droit d'étendre :
protected static int DEFAULT_LIMITE=100;
l'affectation de la variable limite se fait forcément par un setteur puisque des traitements dans ta classe en découlent :
public void setLimite(int l){
this.limite=l;
... // traitement interne à ta classe
}
Si tu avais mis la variable "limite" en protected, rien n'empêchait la classe fille de la modifier directement en omettant de faire les traitements internes.
Pour conclure, il me semble que tout cela concernce les règles de conception de la POO.
salut,
le private interdit tout accès aux attributs d'une classe depuis l'extérieur (notion d'encapsulation) mais elle crée un problème au niveau de l'héritage si tu déclare les attributs en private les classes héritants ne pourront pas accéder à ces attributs alors pour ne pas être obligés de les déclarer comme public pour les utiliser on a pensés à protected qui permet à ces classes d'accéder à ces attributs.
Personnellement je déclare exclusivement mes attributs de classes en protected, le private me semblant trop restrictif :
- Impossibilité d'y accéder depuis l'extérieur, quelle que soit la classe appelante (en revanche un attribut protected peut être modifié depuis une classe appartenant au même package),
- Pour pouvoir modifier ou accéder à un attribut, méthodes get/set systématiques (contraignat quand il y a une vingtaine d'attributs),
- Voir plus haut.
Les attributs déclarés en private peuvent être, selon certains, pour éviter au développeur suivant de faire n'importe quoi. Mais je considère que c'est au développeur suivant de savoir ce qu'il fait.
"Et tu comprendras pourquoi mon nom est l'Eternel, quand sur toi s'abattra la colère du Tout-puissant."
Là, je ne suis pas du tout d'accord :Envoyé par Rayndell
Quel est l'interet de déclarer un champ qu'on utilise exclusivemnt dans la classe courante comme protected ? aucun, et pire encore, c'est une source d'erreurs : les classes filles peuvent le changer par inadvertance (C'est parfaitemnt possible : à la longue, il y'aurait des collisions dans les noms de champs), et là, welcome to hell !
Pourquoi voudrais tu avoir des collisions de noms. Si tu veux utiliser une variable qui s'appèle comme celle definie dans la super classe alors c'est surement que c'est elle même que tu veux utilisé. Ou bien tu as un defaut de conception...Envoyé par djo.mos
Oui mais tu peux decider pour le present mais jamais pour l'avenir. Imagine un jour on embauche une autre personne. Elle ne seras pas forcement au courant de ton design original.Envoyé par iohack
Comment tu fais si un jour tu as une sous classe qui est obligé de faire un autre traitement?Envoyé par iohack
Si grande est la faiblesse d'une âme, dont la raison est partie!
Ne jamais embrouiller ni abasourdir par une foule d'images le génie intérieur qui réside au fonde de sa poitrine,...
L'ambition est le rfuge de l'échec. "Oscar Wild"
Non, ce que je voulais dire est que si un champ X est déclaré protected dans la classe A et qu'il est pourtant destiné à être utilisé uniquement dans A, alors il sera disponible quand même dans les sous classes de A, ce qui est risque d'erreurs.
Un exemple :
C'est un exemple bidon : La connerie dans b est que le programmeur a pensé qu'il affectait 0 à la vraible locale de la méthode qu'il a utilisé dans le for, pourtant, c'est le champ A.idx qui est mis à 0. A partir de là, Dieu seul sait ce qui peut se passer ...
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 public class A { protected int idx; : : } public class B extends A { public void uneGrosseConnerie(){ for(int idx=0;idx<10;i++){ : : } idx = 0;//voici la connerie : : } }
Si idx etait déclaré private, on aura eu une erreur de compilation au lieu d'un maudit bug !
Choisir le meme nom de variable de boucle que de variable d'instance est tres maladroit.Envoyé par djo.mos
Pour ma part se serais tres rare que j'utilise un nom de variable d'instance aussi court. idx. Je prefere largement index.
De plus si on a des bons outils de debug ce n'est pas difficile de corriger ce genre de bug.
Il est aussi rare de faire une l'erreur que tu as montrer. Ou alors tu n'as rien ecouté de ce que l'on t'as dis en cour et tu sais pas comment sont scopés les variables.
Si grande est la faiblesse d'une âme, dont la raison est partie!
Ne jamais embrouiller ni abasourdir par une foule d'images le génie intérieur qui réside au fonde de sa poitrine,...
L'ambition est le rfuge de l'échec. "Oscar Wild"
D'où l'importance de documenter son code (commentaires, diagramme des classes, etc).Envoyé par mathk
Personnellement je partage l'avis de iohack. C'est à toi de savoir (décider) si la classe peut-être étendue ou pas.
Si non déclarer la classe final, pas d'attribut protected.
Si oui, c'est à toi de considérer tous les problèmes qui peuvent en découler (même les plus impropables).
Je ne répondrai à aucune question technique par MP.
Pensez aux Tutoriels et aux FAQs avant de poster (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
Enfin, quand une solution a été trouvée à votre problème pensez au tag
Cours Dvp : http://ydisanto.developpez.com
Blog : http://yann-disanto.blogspot.com/
Page perso : http://yann-disanto.fr
Voici dans ce cas un exemple un peu équivalent à celui de djo.mos.
Supposons que j'écrive les classe A et B. La classe B aurait besoin d'utiliser la méthode check de A. Supposons que B puisse encore être dérivé pour d'autres classes à nous que je n'ai pas écrite, on interdirait donc pas check d'être redéfinie.
Supposons à présent qu'un autre programmeur, qui n'a uniquement la documentation des méthodes public (ce qui n'est pas forcement dénué de sens car on ne souhaite pas forcement que les gens connaissent notre implémentation) redéfinisse la méthode check :
Et on a une lançée d'exception.
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 /** * @(#)Test.java * * Test application * * @author * @version 1.00 2007/6/23 */ import java.util.List; import java.util.ArrayList; import java.lang.IllegalArgumentException; class A { protected boolean check(int i) { return(i>=0); } public A(int i) { if(!check(i)) throw new IllegalArgumentException(); } } class B extends A { public B() { super(3); } public int autremethode(int i) { if(check(i)) return i; else return -i; } } class C extends B { protected boolean check(int i) { return(i<0); } public C() { super(); } } public class Test { public static void main(String[] args) { B b = new C(); } }
Je ne répondrai à aucune question technique en privé
Oui mais l'utilisateur a eu besoin d'exprimer un autre implementation de check. C'est donc qu'il veux que i soit inferieur a zero. Si tu mets la method check private c'est pire qu'une exception car on peut meme pas exprimer d'autre besoins. Il faudra alors faire pleins de duplication de code.Envoyé par millie
Je ne doute pas qu'il ai des cas ou private est utilile. Mais franchement je pense que private est trops souvant utilise, cela au depend de la reutilisation.
Dans ton exemple il sufira de faire dans C
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 public C { super(-3); }Dans un monde ideal oui mais la programation c'est pas un truc de devinette. On jou pas au poker.Envoyé par le y@m's
Et puis les languages tell que Java sont si complexe que c'est encor plus difficile de tous prevoir.
Si grande est la faiblesse d'une âme, dont la raison est partie!
Ne jamais embrouiller ni abasourdir par une foule d'images le génie intérieur qui réside au fonde de sa poitrine,...
L'ambition est le rfuge de l'échec. "Oscar Wild"
Envoyé par mathk
Non, car j'ai supposé que la personne utilisant la bibliothèque contenant les classes A et B n'avaient aucune idée de l'implémentation de ces classes (donc qu'il ne savait pas que A avait une méthode protegée check).
Donc, qu'il définisse check dans C sans avoir du tout la connaissance que cette méthode existait dans A.
Ce qui n'est pas si anodin que ça je pense, car, quand on dispose d'une hiérarchie très compliqué dans une bibliothèque, l'utilisateur de celle ci ne va pas forcement aller chercher la documentation de toutes les classes de la hiérarchie (et surtout des membres protegés dont il se moque en règle général).
Cet exemple donne un exemple, où le développeur n'a pas de chance car il va interferer dans le fonctionnement de A sans le savoir (a priori).
Mais évidemment, si je développe les 3 classes, je saurais comment ça marche et je ne me ferais pas avoir dans la classe C.
Je ne répondrai à aucune question technique en privé
Salut,
Je vais ajouter mon grain de sel
Je suis tout à fait d'accord avec iohack et pas du tout avec mathk .
Il n'y a pas que la question des bugs. Le travail en équipe nécessite une "norme de codage", il nécessite également une bonne communication et la FORMATION des nouveaux (via une documentation de la norme de la boîte et dans l'idéal de code tutoriel à jour). Chaque développeur est néanmoins responsable du design de ses classes.
Nous mettons TOUTES nos variables de classes (côté model) en private. Nous utilisons un framework de binding (JGoodies Binding) et il FAUT toujours passer par les setters pour générer le comportement d'envoi des évènements de modification.
Côté Swing, celà dépend. Mais je sais par expérience, et surtout pour les débutants, qu'il est préférable d'avoir un maximum de restrictions (utiliser private et final autant que possible) sur les classes et éventuellement de "lever" certaines barrières par la suite que de tout permettre et se retrouver au final avec un code non maintenable.
C'est également plus facile de contrôler l'utilisation des classes maîtresses de l'application.
Selon moi et de façon plus générale, il serait préférable de ne JAMAIS ou presque avoir d'accès direct aux variables d'instance à partir d'autres classes mais d'avoir un mécanisme de getter/setter obligatoire car c'est comme ça qu'on a un contrôle maximal sur ce qui se passe et qu'on empêche une variable initialisée une fois pour toute d'être mise à null par un programmeur imprudent.
Je préfère prévoir l'utilisation qui sera faite de mes classes en ne permettant que ce que je souhaite permettre que de tout permettre et me voir assigner une liste de 100 bugs à cause d'un design permisif.Envoyé par mathk
++
Comment ça ? La réponse à ton problème n'est ni dans la faq, ni dans les tutos, ni dans sources ??? Etonnant...
De la bonne manière de poser une question (et de répondre).
Je ne fais pas de service par MP. Merci (...de lire les règles...).
Ma page dvp.com
Envoyé par millie
Si tu sous classe B c'est pour de bonne raison. Le minimum est de conaitre la super classe. Et si tes outils ne te permetent pas de lire facillement du code change les.
Redefinir check sans savoir quelle existe revien a faire en quelque sorte du sous-classage au lieu du sous-typage. Ce qui est du mauvais design.
Pour ma part je n'ai jamias eux ce genre de problemes.
Accéder a des variables par des mutateurs revient a avoir des variable public.Envoyé par natha
En quelque sorte.
Je serais interesse par des exemples concret ou vous utilise des variables privateEnvoyé par natha
Si grande est la faiblesse d'une âme, dont la raison est partie!
Ne jamais embrouiller ni abasourdir par une foule d'images le génie intérieur qui réside au fonde de sa poitrine,...
L'ambition est le rfuge de l'échec. "Oscar Wild"
En aucune sorte !Envoyé par mathk
Voici un exemple de classe métier nécessitant de n'avoir aucune variable statique car on souhaite toujours passer par les setters !
Et au niveau des getters différents de la variable public on peut imaginer ça :
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 public class Tutorial extends Model { // Names of the Bound Bean Properties ********************************************* public static final String PROPERTYNAME_NOM = "nom"; public static final String PROPERTYNAME_DESCRIPTION = "description"; public static final String PROPERTYNAME_GENTIL = "gentil"; public static final String PROPERTYNAME_DATE_JOUR = "dateJour"; public static final String PROPERTYNAME_NOMBRE1 = "nombre1"; public static final String PROPERTYNAME_NOMBRE2 = "nombre2"; public static final String PROPERTYNAME_CODE = "code"; // Instance Fields **************************************************************** private String m_nom; private String m_description; private boolean m_gentil; private Date m_dateJour; private int m_nombre1; private Integer m_nombre2; private TutorialCode m_code; /** * Default Constructor */ public Tutorial() { super(); } // Getters and setters ************************************************************ /** * @return Returns the nom. */ public String getNom() { return this.m_nom; } /** * @param nom The nom to set. */ public void setNom(String nom) { String oldValue = getNom(); this.m_nom = nom; firePropertyChange(PROPERTYNAME_NOM, oldValue, m_nom); } /** * @return Returns the description. */ public String getDescription() { return this.m_description; } /** * @param description The description to set. */ public void setDescription(String description) { String oldValue = getDescription(); this.m_description = description; firePropertyChange(PROPERTYNAME_DESCRIPTION, oldValue, m_description); } /** * @return Returns the gentil. */ public boolean isGentil() { return this.m_gentil; } /** * @param gentil The gentil to set. */ public void setGentil(boolean gentil) { boolean oldValue = isGentil(); this.m_gentil = gentil; firePropertyChange(PROPERTYNAME_GENTIL, oldValue, m_gentil); } /** * @return Returns the dateJour. */ public Date getDateJour() { return this.m_dateJour; } /** * @param dateJour The dateJour to set. */ public void setDateJour(Date dateJour) { Date oldValue = getDateJour(); this.m_dateJour = dateJour; firePropertyChange(PROPERTYNAME_DATE_JOUR, oldValue, m_dateJour); } /** * @return Returns the nombre1. */ public int getNombre1() { return this.m_nombre1; } /** * @param nombre1 The nombre1 to set. */ public void setNombre1(int nombre1) { int oldValue = getNombre1(); this.m_nombre1 = nombre1; firePropertyChange(PROPERTYNAME_NOMBRE1, oldValue, m_nombre1); } /** * @return Returns the nombre2. */ public Integer getNombre2() { return this.m_nombre2; } /** * @param nombre2 The nombre2 to set. */ public void setNombre2(Integer nombre2) { Integer oldValue = getNombre2(); this.m_nombre2 = nombre2; firePropertyChange(PROPERTYNAME_NOMBRE2, oldValue, m_nombre2); } /** * @return Returns the code. */ public TutorialCode getCode() { return this.m_code; } /** * @param code The code to set. */ public void setCode(TutorialCode code) { TutorialCode oldValue = getCode(); this.m_code = code; firePropertyChange(PROPERTYNAME_CODE, oldValue, m_code); } }
Ceci afin d'empêcher de pouvoir modifier la liste sans passer par le setList (ou d'autres méthodes à ajouter dans la classe qu'on pourrait appeler addItem ou removeItem).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 public static final String PROPERTYNAME_LIST = "list"; private List<String> m_list; public List<String> getList() { return m_list != null ? Collections.unmodifiableList(m_list) : null; } public void setList(List<String> list) { List<String> oldValue = getList(); this.m_list = list; firePropertyChange(PROPERTYNAME_LIST, oldValue, m_list); }
Voilà voilà, j'espère que c'est suffisant pour te faire comprendre l'utilité de private et le danger de tout mettre en protected ou public pour "se simplifier la vie" (pour moi c'est tout le contraire). Ceci n'est qu'un exemple parmi d'autres.
Comment ça ? La réponse à ton problème n'est ni dans la faq, ni dans les tutos, ni dans sources ??? Etonnant...
De la bonne manière de poser une question (et de répondre).
Je ne fais pas de service par MP. Merci (...de lire les règles...).
Ma page dvp.com
Qu'est ce que firePropertyChange est sense faire?Envoyé par natha
Pourquoi tu donne la possibiliter au setter de retourner null. Pourquoi ne renverais tu pas une liste vide.Envoyé par natha
Ca evite de faire des :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 if (list != null) ...Peut tu m'expliquer a quoi servent tes variables?Envoyé par natha
Si grande est la faiblesse d'une âme, dont la raison est partie!
Ne jamais embrouiller ni abasourdir par une foule d'images le génie intérieur qui réside au fonde de sa poitrine,...
L'ambition est le rfuge de l'échec. "Oscar Wild"
Envoyer un évènement indiquant que la propriété untel a été modifiée de oldValue vers une new value. Renseigne toi sur le binding.Qu'est ce que firePropertyChange est sense faire ?
C'était juste un exemple de code pour illustrer l'utilité du getter pour faire autre chose que ce que ferait une variable publique. Après null ou pas, c'est une question de contexte.Pourquoi tu donne la possibiliter au setter de retourner null. Pourquoi ne renverais tu pas une liste vide.
C'est du code tuto donc ça ne sert pas à grand chose ici. M'enfin sur le concept c'est un objet métier (partie Model en MVC). Ces variables décrivent mon objet, c'est tout... m'enfin je vais pas te faire un cours de conception objet.Peux tu m'expliquer a quoi servent tes variables ?
Comment ça ? La réponse à ton problème n'est ni dans la faq, ni dans les tutos, ni dans sources ??? Etonnant...
De la bonne manière de poser une question (et de répondre).
Je ne fais pas de service par MP. Merci (...de lire les règles...).
Ma page dvp.com
Sauf qu'avec null tu peux rien faire avec et tu auras surement des tests pour voir si ta variable est null ce qui est mocheEnvoyé par natha
Si grande est la faiblesse d'une âme, dont la raison est partie!
Ne jamais embrouiller ni abasourdir par une foule d'images le génie intérieur qui réside au fonde de sa poitrine,...
L'ambition est le rfuge de l'échec. "Oscar Wild"
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager