¿Por qué no hay un modificador de acceso 'solo subclases' en Java?

16

En Java, hay cuatro modificadores de acceso disponibles para los métodos:

public - Cualquier clase puede usar este método.

protected - las clases en el mismo paquete y las subclases en cualquier paquete pueden usar este método.

private - Solo esta clase puede usar este método.

no modifier ("paquete privado"): solo las clases del mismo paquete pueden utilizar este método.

Lo que sucede a menudo es que quiero tener métodos útiles en una superclase, que todas las subclases puedan usar. Pero no tendría sentido para otras clases acceder a este método, y en cierto sentido rompería la encapsulación.

Así que tengo que declarar estos métodos útiles en la superclase publico protected, que los expone a todas las demás clases al menos en el paquete. Aunque solo están destinados a ser utilizados por las subclases.

¿Hay alguna razón por la cual no hay un subclasses-onlymodificador de acceso en Java? Me parece muy extraño. ¿Me estoy perdiendo de algo?

Además, un subclasses-onlymodificador de acceso también sería útil para cuando desee exponer variables solo a subclases. Lo que a mí me pasa mucho.

Aviv Cohn
fuente

Respuestas:

10

Porque puede emular el modificador de solo subclases utilizando el modificador protegido y haciendo cumplir que solo la clase primaria y sus subclases estén en el mismo paquete.

De hecho, es una buena práctica, porque los paquetes no solo ayudan a organizar grandes proyectos en términos de cohesión, sino que también muestran que las clases en el mismo paquete pueden tener algún nivel de acoplamiento.

Tércio de Almeida
fuente
15
"y hacer cumplir que solo la clase padre y sus subclases están en el mismo paquete" - Ahora, ¿cómo se puede hacer eso?
JimmyB
1
Y luego no puede usar el modificador de acceso de solo paquete. Y necesitas una cantidad tonta de paquetes. Esta no es una solución práctica.
user253751
13

Java originalmente tenía un modificador de este tipo. Fue escrito private protectedpero eliminado en Java 1.0.

Supongo que fue una decisión de juicio que la complejidad adicional no valía la pena.

Cada característica del lenguaje tiene un costo: en enseñarla a nuevos programadores; en la documentación; al implementarlo en el compilador, JVM y herramientas de desarrollo; en razonamiento sobre la corrección del programa; en restringir la futura evolución del lenguaje; y más. Las características del lenguaje interactúan entre sí, potencialmente con interacciones N 2 .

¿Qué porcentaje de programadores de Java ha leído las especificaciones del lenguaje Java y las especificaciones de VM? Apuesto a que es un pequeño porcentaje, que defiende un lenguaje aún más simple en aras de la comprensibilidad y los productos de ingeniería en los que podemos confiar

El beneficio de la private protectedcaracterística fue pequeño ya que el paquete es la unidad principal de modularidad.

Jerry101
fuente
1
Entonces, ¿había una versión de Java anterior a la 1.0?
Mark Yisri
1
@MarkYisri Java tuvo versiones públicas alfa y beta en 1995, y se escribió un poco de código en su contra.
David Moles
4

El control de acceso puede considerarse como el resultado de una cobertura con un desarrollador imaginario que está trabajando con su clase sobre los métodos y propiedades de la clase ...

USTED: Diga que quiere hacer x, llama al método doX ... DEV: Dime más ... ¿cuáles son los argumentos?

Esto es público ...

USTED: Dentro de doX llamo ... DEV: Whoa, demasiada información, no me importa eso. Solo quiero saber cómo usarlo. Dime algo más.

Esto es privado ...

USTED: Al subclasificar, tengo doX y doY call doIt lo que hace ... DEV: Sí, voy a subclasificar, cuéntame más ...

Esto está protegido ...

USTED: Me voy de vacaciones en una hora, me iré por los próximos 6 meses. ¡El jefe dice que este cachorro es tuyo! Adiós. DEV: Espera, no te vayas, dime todo ...

Este es el paquete.

USTED: El método doItWhen solo lo llama esta clase y no ha cambiado en diez años. Es ... DEV: Whoa, tenemos 50 minutos. Siguiente propiedad, y habla más rápido.

Esto está protegido privado ...

jmoreno
fuente
3

Esto ya existe. Está protegido

Usted tiene control sobre qué clases existen dentro del paquete. Si no hay otra clase en el paquete y una variable o método dado está protegido, es 'solo subclases'.

Dicho esto, una vez más, tienes control sobre qué clases existen dentro del paquete. Puede elegir simplemente no utilizar los métodos o variables protegidos.


fuente
3
Además de ciertos paquetes de sistema reservados, ¿no puedo agregar una clase a cualquier paquete, incluso uno de los suyos al que no tiene intención de agregar clases?
David Moles
@David IIRC sí, pero no le permitirá acceder a los campos del paquete desde otro JAR, por lo que incluso si lo coloca en el mismo paquete, si está en otro JAR no podrá acceder a él. Sin embargo, si se refiere al mismo JAR, entonces sí, puede acceder a él, pero si puede modificar el JAR en cuestión, podría cambiar fácilmente el modificador de acceso.
Pokechu22
1
@ Pokechu22 Creo que tienes que sellar afirmativamente el JAR para obtener esa protección, pero buen punto.
David Moles