J'étais en train de passer en revue cette question. Existe-t-il un moyen de remplacer les variables de classe en Java? Le premier commentaire avec 36 votes positifs était:
Si jamais vous voyez un
protected static
, courez.
Quelqu'un peut-il expliquer pourquoi un est protected static
mal vu?
final
. Un champ statique mutable partagé entre les classes est certainement un sujet de préoccupation. Plusieurs classes mettant à jour un champ statique ne seront probablement pas fiables ou faciles à suivre, d'autant plus que la présence de tout champ ou méthode protégé implique que la classe est censée être étendue par des classes dans d'autres packages, éventuellement des classes non sous le contrôle du auteur de la classe contenant le champ protégé.final
ne signifie pas que le champ est immuable. Vous pouvez toujours modifier leobject
référencé par unefinal
variable de référence.Réponses:
C'est plus un problème stylistique qu'un problème direct. Cela suggère que vous n'avez pas bien réfléchi à ce qui se passe avec la classe.
Pensez à ce que
static
signifie:Pensez à ce que
protected
signifie:Les deux significations ne sont pas exactement mutuellement exclusives, mais elles sont assez proches.
Le seul cas que je peux voir où vous pourriez utiliser les deux ensemble est si vous aviez une classe abstraite qui a été conçue pour être étendue et que la classe d'extension pourrait alors modifier le comportement en utilisant les constantes définies dans l'original. Ce genre d'arrangement finirait probablement par être très compliqué et indique une faiblesse dans la conception des classes.
Dans la plupart des cas, il serait préférable que les constantes soient publiques, car cela rend tout plus propre et permet aux personnes de sous-classer plus de flexibilité. Indépendamment de toute autre chose, dans de nombreux cas, la composition est préférable à l'héritage, tandis que les classes abstraites forcent l'héritage.
Pour voir un exemple de la façon dont cela pourrait casser les choses et pour illustrer ce que je veux dire par la variable n'ayant pas d'existence indépendante, essayez cet exemple de code:
Vous verrez les résultats:
Essayez-le vous-même sur: https://ideone.com/KM8u8O
La classe
Test2
peut accéder au membre statique àtest
partir deTest
sans avoir besoin de qualifier le nom - mais elle n'hérite ni n'obtient sa propre copie. Il regarde exactement le même objet en mémoire.la source
Rectangle
) pour ajuster la largeur / hauteur pour garantir l'égalité produira (pourSquare
) des résultats indésirables si vous remplaciez chaque supertype par une instance de son sous-type.C'est mal vu parce que c'est contradictoire.
La création d'une variable
protected
implique qu'elle sera utilisée dans le package ou qu'elle sera héritée dans une sous-classe .Faire de la variable en
static
fait un membre de la classe, éliminant les intentions d'en hériter . Cela ne laisse que l'intention d'être utilisé dans un package , et nous avonspackage-private
pour cela (pas de modificateur).La seule situation pour laquelle je pourrais trouver cela utile est si vous déclariez une classe qui devrait être utilisée pour lancer l'application (comme celle de JavaFX
Application#launch
, et que vous vouliez uniquement pouvoir lancer à partir d'une sous-classe. Si vous le faites, assurez-vous que la méthode est égalementfinal
à disallow cacher . Mais ce n'est pas « la norme », et a probablement été mis en œuvre pour empêcher l' ajout d'une plus grande complexité en ajoutant une nouvelle façon de lancer des applications.Pour voir les niveaux d'accès de chaque modificateur, voir ceci: Les didacticiels Java - Contrôle de l'accès aux membres d'une classe
la source
static
éliminer les intentions d'en hériter. Parce que ma sous-classe dans un autre package nécessite toujours le champ de super pour êtreprotected
accessible, même si c'eststatic
.package-private
ne peut pas aiderprotected static
. Mais c'est une odeur de code, d'où la partie " run ". Les modificateurs d'accès et l'héritage sont deux sujets différents. Oui, vous ne pourrez pas accéder à un membre statique d'une super classe si c'était le caspackage-private
. Mais vous ne devez pas vous fier à l'héritage pour référencer lesstatic
champs en premier lieu; c'est un signe de mauvaise conception. Vous remarquerez que les tentatives de substitution destatic
méthodes ne donnent aucun résultat, ce qui est un signe clair que l'héritage n'est pas basé sur une classe. Si vous avez besoin d'un accès en dehors de la classe ou du package, il devrait êtrepublic
private static
fonctions util au début, mais je pense que quelqu'un voudra peut-être améliorer ou personnaliser à partir de ma classe et ces fonctions util peuvent également leur être utiles.public
peut ne pas convenir car les méthodes util ne sont pas destinées à l'utilisateur des instances de ma classe. Pourriez-vous m'aider à trouver un bon design au lieu deprotected
? MerciJe ne vois pas de raison particulière pour laquelle cela devrait être mal vu. Il peut toujours y avoir des alternatives pour obtenir le même comportement, et cela dépendra de l'architecture réelle si ces alternatives sont "meilleures" qu'une méthode statique protégée ou non. Mais un exemple où une méthode statique protégée serait raisonnable, au moins, pourrait être le suivant:
(Modifié pour être divisé en packages séparés, pour rendre l'utilisation de
protected
plus claire)Dérivé de cela:
Une autre classe dérivée:
Le
protected static
modificateur peut certainement être justifié ici:static
, car elles ne dépendent pas des variables d'instance. Ils ne sont pas destinés à être utilisés directement comme une méthode polymorphe, mais sont plutôt des méthodes «utilitaires» qui offrent des implémentations par défaut qui font partie d'un calcul plus complexe et servent de «blocs de construction» de l'implémentation réelle.public
, car elles sont un détail d'implémentation. Et ils ne peuvent pas l'êtreprivate
car ils devraient être appelés par les classes étendues. Ils ne peuvent pas non plus avoir de visibilité "par défaut", car ils ne seront alors pas accessibles pour les classes d'extension dans d'autres packages.(EDIT: on pourrait supposer que le commentaire original ne faisait référence qu'à des champs , et non à des méthodes - alors, cependant, c'était trop général)
la source
protected final
(puisque vous ne voulez pas qu'elles soient remplacées), passtatic
. Le fait qu'une méthode n'utilise pas de variables d'instance ne signifie pas qu'elle devrait l'êtrestatic
(bien qu'elle le puisse ).final
, il ne fait pas seulement clair que la méthode ne vise pas à être surchargée, il en plus clairement au lecteur que la méthode n'utilise pas les variables d'instance. Si succinctement: il n'y a tout simplement aucune raison de ne pas le rendre statique.protected
, non pas pour montrer l'héritage, mais pour le garder sous un seul paquet - non exposé. Je suppose que les interfaces scellées deviendraient utiles de cette manière lorsqu'elles le seront en javaprotected
signifie "Hériter des classes (même dans des packages différents)" ...Les membres statiques ne sont pas hérités, et les membres protégés ne sont visibles que par les sous-classes (et bien sûr la classe contenant), donc a
protected static
a la même visibilité questatic
, suggérant un malentendu de la part du codeur.la source
protected
ne sont pas les mêmes. Si vous dites simplementstatic
, le champ n'est visible que pour les sous-classes du même package.protected static
permet l'accès au sein du package ou à partir d'une sous-classe . Rendre une variable statique supprime les intentions de sous-classification, laissant la seule intention étant l'accès depuis l'intérieur du package.En fait, il n'y a rien de fondamentalement mal avec
protected static
. Si vous voulez vraiment une variable statique ou une méthode visible pour le package et toutes les sous-classes de la classe déclarante, allez-y et créez-laprotected static
.Certaines personnes évitent généralement d'utiliser
protected
pour diverses raisons et certaines personnes pensent que lesstatic
variables non finales devraient être évitées par tous les moyens (je sympathise personnellement avec ces dernières dans une certaine mesure), donc je suppose que la combinaison deprotected
etstatic
doit paraître mauvaise ^ 2 à ceux qui appartiennent aux deux groupes.la source
Protected est utilisé pour pouvoir être utilisé dans les sous-classes. Il n'y a pas de logique dans la définition d'une statique protégée lors de l'utilisation dans le contexte de classes concrètes car vous pouvez accéder à la même variable de manière statique.Cependant, le complicateur donnera un avertissement pour accéder à la variable statique de la super classe de manière statique.
la source
Eh bien, comme la plupart des gens ont répondu:
protected
signifie - ' package-private + visibilité aux sous-classes - la propriété / le comportement est HÉRITÉ 'static
signifie - ' l'opposé de l'instance - c'est une propriété / un comportement de CLASSE, c'est-à-dire qu'elle n'est PAS HÉRITÉE 'Par conséquent, ils sont légèrement contradictoires et incompatibles.
Cependant, récemment, je suis venu à un cas d'utilisation où il pourrait être judicieux d'utiliser ces deux ensemble. Imaginez que vous vouliez créer une
abstract
classe qui est un parent pour les types immuables et qui a un tas de propriétés qui sont communes aux sous-types. Pour implémenter correctement l' immuabilité et conserver la lisibilité, vous pouvez décider d'utiliser le modèle Builder .Et pourquoi
protected static
? Parce que je veux un sous-type non abstraitAbstactType
qui implémente son propre constructeur non abstrait et est situé à l'extérieurpackage X
pour pouvoir accéder et réutiliser leBaseBuilder
.Bien sûr, nous pouvons rendre le
BaseBuilder
public mais ensuite nous arrivons à une autre déclaration contradictoire:Donc, dans les deux cas avec
protected static
etpublic
constructeur d'un,abstract class
nous combinons des déclarations contradictoires. C'est une question de préférences personnelles.Cependant, je préfère toujours le
public
constructeur d'unabstract class
car celaprotected static
me semble plus artificiel dans un monde OOD et OOP!la source
Il n'y a rien de mal à avoir
protected static
. Une chose que beaucoup de gens oublient est que vous voudrez peut-être écrire des cas de test pour des méthodes statiques que vous ne voulez pas exposer dans des circonstances normales. J'ai remarqué que cela est particulièrement utile pour écrire des tests de méthode statique dans des classes utilitaires.la source