Quelle est la meilleure pratique et pourquoi : accéder aux variables de la classe de base par le biais d'un champ protégé ou d'un getter public sur le champ privé.
(Le getter sera quand même public)
Quelle est la meilleure pratique et pourquoi : accéder aux variables de la classe de base par le biais d'un champ protégé ou d'un getter public sur le champ privé.
(Le getter sera quand même public)
S'il y a de toute façon un getter public, pourquoi vouloir exposer le champ lui-même plus largement qu'il n'est absolument nécessaire ? Cela signifie qu'il est immédiatement accessible en écriture par les sous-classes (sauf s'il est final au départ).
Personnellement, je préfère que tous mes champs soient privés : cela permet une séparation plus nette entre l'API et l'implémentation. Je considère la relation entre une superclasse et une sous-classe comme similaire à celle d'un appelant et d'un appelé - les modifications de l'implémentation sous-jacente ne devraient pas briser les sous-classes, pas plus qu'elles ne devraient briser les appelants. Le nom d'un champ est un détail d'implémentation qui ne devrait pas avoir d'impact sur les autres classes.
Il est vrai que mon point de vue est parfois considéré comme un peu extrême...
Dans mon expérience, certes limitée, je n'ai pas trouvé de bonnes raisons d'utiliser des champs protégés, et cela semble toujours causer d'autres problèmes. Je suis d'accord pour dire qu'il est préférable de les rendre privés dans presque tous les cas.
Pourriez-vous fournir un exemple de travail/illustration pour ce scénario où les deux variables/méthodes de la superclasse sont utilisées dans la sous-classe ?
@Deepak : J'ai peur de ne pas avoir le temps de donner un exemple complet pour chaque réponse Java que je donne. Pourquoi n'essayez-vous pas vous-même, et si vous rencontrez des problèmes, posez une question ?
Vous devez toujours programmer en fonction de l'API publique d'une classe, c'est-à-dire utiliser les méthodes publiques.
La raison en est simple. Un jour, dans le futur, vous ou quelqu'un d'autre pourrait vouloir modifier l'implémentation. Cela devrait toujours être possible. Si vous vous appuyez sur une variable d'instance, vous vous limitez.
De plus, lors de l'accès à la variable, vous ne pouvez pas contrôler si cette variable est en lecture seule ni ajouter des contrôles lorsque cette variable est modifiée.
Si vous utilisez des setters/getters, vous pouvez toujours ajouter la validation, la vérification, etc. plus tard. Vous pouvez également fournir uniquement un getter pour rendre une variable en lecture seule.
Si quelqu'un expose une variable, ils doivent la considérer comme immuable, tout comme une méthode publique/protégée. Si quelqu'un expose un champ et le modifie ensuite, il est clair qu'il ne se soucie pas de briser les autres développeurs en premier lieu, et il est fort possible qu'il modifie également les méthodes :(
C'est vrai. C'est pourquoi j'ai ajouté autant de "devrait" à mon commentaire :) Mais la plupart du temps, il est plus facile de maintenir une méthode publique existante et de simplement ajouter une version surchargée/spéciale, c'est pourquoi je préfère les variables privées (sauf pour les constantes publiques statiques finales).
Voici quelques-unes des recommandations de Sun sur le contrôle de l'accès aux champs ici. Notez que le fait de rendre un champ protégé l'expose également au paquet, et pas seulement aux sous-classes. En général, comme indiqué dans le lien ci-dessus, les champs doivent être privés, sauf s'il existe une très bonne raison de ne pas le faire.
Effective Java 2nd Edition dit
Point 13 : minimiser l'accessibilité des classes et des membres
La règle de base est simple : rendre chaque classe ou membre aussi inaccessible que possible. possible. En d'autres termes, utilisez le niveau d'accès le plus bas possible, compatible avec le bon fonctionnement du logiciel que vous écrivez.
Ainsi, si vous n'êtes pas sûr de la raison pour laquelle vous avez besoin d'un membre de classe protégé (c'est-à-dire que vous n'avez pas besoin que le champ soit accessible aux sous-classes ou aux classes du même paquet), déclarez-le privé. Si vous souhaitez le définir depuis l'extérieur de la classe, créez un setter public.
Cependant, si votre membre est définitif, le fait de le protéger peut être acceptable dans certains cas (c'est-à-dire qu'il ne révèle pas d'informations sensibles).
Un problème de sécurité potentiel que je voudrais mentionner est que si vous avez un tableau déclaré protected final (même public final), la référence du tableau est finale (ne peut pas être modifiée), mais les objets contenus dans le tableau ne sont pas finaux (un intrus pourrait modifier le contenu du tableau).
Si vous connaissez le c++, vous savez probablement que
_
const int * someMember
est différent de
int * const someMember
_
Ce dernier est comme le tableau final en java.
La correction de la faille de sécurité susmentionnée consiste à renvoyer une copie profonde du tableau ou à le renvoyer en tant que liste en lecture seule.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
1 votes
Les champs protégés dans la classe de base sont mauvais .