Estaba pasando por esta pregunta ¿Hay alguna forma de anular las variables de clase en Java? El primer comentario con 36 votos a favor fue:
Si alguna vez ve un
protected static
, ejecute.
¿Alguien puede explicar por qué está protected static
mal visto?
final
. Un campo estático mutable compartido entre clases es definitivamente motivo de preocupación. Es probable que varias clases que actualizan un campo estático no sean confiables o fáciles de seguir, especialmente porque la presencia de cualquier campo o método protegido implica que la clase está destinada a ser extendida por clases en otros paquetes, posiblemente clases que no están bajo el control del autor de la clase que contiene el campo protegido.final
no significa que el campo sea inmutable. Siempre puede modificar elobject
referenciado por unafinal
variable de referencia.Respuestas:
Es más una cuestión de estilo que un problema directo. Sugiere que no ha pensado adecuadamente en lo que está sucediendo con la clase.
Pensar en qué
static
significa:Pensar en qué
protected
significa:Los dos significados no son exactamente excluyentes entre sí, pero están bastante cerca.
El único caso que puedo ver en el que podría usar los dos juntos es si tuviera una clase abstracta que fue diseñada para ser extendida y la clase extensible podría modificar el comportamiento usando constantes definidas en el original. Sin embargo, ese tipo de arreglo probablemente terminaría muy desordenado e indica una debilidad en el diseño de las clases.
En la mayoría de los casos, sería mejor tener las constantes como públicas, ya que eso solo hace que todo sea más limpio y permite a las personas que subclasifican más flexibilidad. Aparte de cualquier otra cosa, en muchos casos la composición es preferible a la herencia, mientras que las clases abstractas fuerzan la herencia.
Para ver un ejemplo de cómo esto podría romper las cosas y para ilustrar lo que quiero decir con la variable que no tiene una existencia independiente, pruebe este código de ejemplo:
Verás los resultados:
Pruébelo usted mismo en: https://ideone.com/KM8u8O
La clase
Test2
puede acceder al miembro estáticotest
desdeTest
sin necesidad de calificar el nombre, pero no hereda ni obtiene su propia copia. Está mirando exactamente el mismo objeto en la memoria.fuente
Rectangle
) para ajustar el ancho / alto para garantizar la igualdad (paraSquare
) producirá resultados no deseados si reemplaza cada supertipo con una instancia de su subtipo.Está mal visto porque es contradictorio.
Hacer una variable
protected
implica que se usará dentro del paquete o se heredará dentro de una subclase .Hacer la variable la
static
convierte en miembro de la clase, eliminando las intenciones de heredarla . Esto deja solo la intención de ser utilizado dentro de un paquete , y tenemospackage-private
para eso (sin modificador).La única situación para la que podría encontrar esto útil es si estuviera declarando una clase que debería usarse para iniciar la aplicación (como JavaFX
Application#launch
, y solo quisiera poder iniciar desde una subclase. Si lo hace, asegúrese de que el método también seafinal
para no permitir la ocultación . Pero esto no es "la norma", y probablemente se implementó para evitar agregar más complejidad al agregar una nueva forma de iniciar aplicaciones.Para ver los niveles de acceso de cada modificador, vea esto: Los tutoriales de Java: control del acceso a los miembros de una clase
fuente
static
eliminaría las intenciones de heredarlo. Debido a que mi subclase en otro paquete aún requiere que el campo de super seaprotected
para acceder, aunque seastatic
.package-private
no puedo ayudarprotected static
. Pero es un olor a código, de ahí la parte de " ejecución ". Los modificadores de acceso y la herencia son dos temas diferentes. Sí, no podrá acceder a un miembro estático de una superclase si lo fuerapackage-private
. Pero no debe confiar en la herencia para hacer referencia a losstatic
campos en primer lugar; es una señal de mal diseño. Notará que los intentos de anularstatic
métodos no dan resultados, lo que es una clara señal de que la herencia no se basa en clases. Si necesita acceso fuera de la clase o paquete, debería serpublic
private static
funciones útiles al principio, pero creo que alguien puede querer mejorar o personalizar mi clase y estas funciones útiles también pueden brindarles conveniencia.public
puede no ser apropiado ya que los métodos util no son para el usuario de las instancias de mi clase. ¿Podrías ayudarme a encontrar un buen diseño en lugar deprotected
? GraciasNo veo una razón en particular por la que esto deba estar mal visto. Siempre puede haber alternativas para lograr el mismo comportamiento, y dependerá de la arquitectura real si estas alternativas son "mejores" que un método estático protegido o no. Pero un ejemplo en el que un método estático protegido sería razonable, al menos, podría ser el siguiente:
(Editado para dividir en paquetes separados, para hacer el uso
protected
más claro)Derivado de eso:
Otra clase derivada:
El
protected static
modificador ciertamente se puede justificar aquí:static
, porque no dependen de variables de instancia. No están destinados a ser utilizados directamente como un método polimórfico, sino que son métodos de "utilidad" que ofrecen implementaciones predeterminadas. que son parte de un cálculo más complejo y sirven como "bloques de construcción" de la implementación real.public
, porque son un detalle de implementación. Y no pueden serprivate
porque deberían ser llamados por las clases extendidas. Tampoco pueden tener visibilidad "predeterminada", porque entonces no serán accesibles para las clases extendidas en otros paquetes.(EDITAR: Se podría suponer que el comentario original solo se refería a campos , y no a métodos ; entonces, sin embargo, era demasiado general)
fuente
protected final
(ya que no desea que se anulen), nostatic
. El hecho de que un método no utilice variables de instancia no significa que deba hacerlostatic
(aunque puede hacerlo ).final
, no solo deja en claro que el método no está destinado a ser anulado, sino que además le aclara al lector que el método no usa variables de instancia. En resumen: simplemente no hay razón para no hacerlo estático.protected
, no para mostrar la herencia, sino para mantenerlo en un solo paquete, no expuesto. Supongo que las interfaces selladas serían útiles de esta manera cuando lo hagan en Javaprotected
significa "Heredar clases (incluso en paquetes diferentes)" ...Los miembros estáticos no se heredan y los miembros protegidos solo son visibles para las subclases (y, por supuesto, la clase que los contiene), por lo que a
protected static
tiene la misma visibilidad questatic
, lo que sugiere un malentendido por parte del codificador.fuente
protected
no son lo mismo. Si solo dicestatic
, el campo solo es visible para las subclases del mismo paquete.protected static
permite el acceso dentro del paquete o desde una subclase . Hacer una variable estática elimina las intenciones de subclasificar, dejando que la única intención sea el acceso desde dentro del paquete.En realidad, no hay nada fundamentalmente malo en ello
protected static
. Si realmente desea una variable o método estático que sea visible para el paquete y todas las subclases de la clase declarante, entonces hágaloprotected static
.Algunas personas generalmente evitan el uso
protected
por varias razones y algunas personas piensan que lasstatic
variables no finales deben evitarse por todos los medios (personalmente simpatizo con esta última hasta cierto punto), por lo que supongo que la combinación deprotected
ystatic
debe quedar mal ^ 2 con las que pertenecen a ambos grupos.fuente
Protegido se usa para que pueda usarse en subclases. No hay lógica en definir una estática protegida cuando se usa en el contexto de clases concretas, ya que se puede acceder a la misma variable de forma estática, sin embargo, el compilador dará una advertencia para acceder a la variable estática de la superclase de forma estática.
fuente
Bueno, como la mayoría de la gente ha respondido:
protected
significa - ' paquete-privado + visibilidad a subclases - la propiedad / comportamiento es HEREDADA 'static
significa - ' lo opuesto a la instancia - es una propiedad / comportamiento de CLASE, es decir, NO ES HEREDADO 'Por tanto, son levemente contradictorios e incompatibles.
Sin embargo, recientemente se me ocurrió un caso de uso en el que podría tener sentido usar estos dos juntos. Imagine que desea crear una
abstract
clase que sea padre para tipos inmutables y que tenga un montón de propiedades que son comunes a los subtipos. Para implementar la inmutabilidad correctamente y mantener la legibilidad, uno podría decidir usar el patrón Builder .Y por qué
protected static
? Porque quiero un subtipo no abstractoAbstactType
que implemente su propio Builder no abstracto y esté ubicado afuerapackage X
para poder acceder y reutilizar elBaseBuilder
.Por supuesto que podemos hacer
BaseBuilder
público pero luego llegamos a otras declaraciones contradictorias:Entonces, en ambos casos con
protected static
ypublic
constructor de unabstract class
combinamos declaraciones contradictorias. Es una cuestión de preferencias personales.Sin embargo, sigo prefiriendo el
public
constructor de unabstract class
porqueprotected static
me parece más antinatural en un mundo OOD y OOP.fuente
No hay nada de malo en tener
protected static
. Una cosa que mucha gente está pasando por alto es que es posible que desee escribir casos de prueba para métodos estáticos que no desea exponer en circunstancias normales. He notado que esto es particularmente útil para escribir pruebas para métodos estáticos en clases de utilidad.fuente