2009-05-24 12 views
39

¿Cuál es la razón por la que en Java, un miembro con un modificador "protegido" no solo puede acceder a la misma clase y subclases, sino también a todos en el mismo paquete?¿Por qué el modificador "protegido" en Java permite el acceso a otras clases en el mismo paquete?

Me pregunto acerca de las razones de diseño, el lenguaje no aplicaciones reales (por ejemplo, pruebas)

+10

+1 Francamente, también quiero saber por qué. Siempre me pareció una de las decisiones de diseño más estúpidas de Java. – cletus

+1

@cletus: Por lo tanto, lo pienso más, así que más llegué a la conclusión de que "paquete privado" era la idea no bien pensada. Para el "paquete privado" para el trabajo real y ofrecer cualquier tipo de protección real, los paquetes deberían compilarse dentro de una sola unidad de compilación. Y uno no debería ser capaz de mejorarlos más tarde. – Martin

Respuesta

22

Este diseño se basa en la idea de que el paquete es la unidad apropiada, mantenido y publicado por un equipo consistente internamente; las relaciones de herencia tienen mucho menos que ver con quién está manteniendo y liberando qué cuándo.

+1

Gracias por la respuesta. Por supuesto, no funciona, ya que nadie le impide distribuir un paquete en varios contenedores, y con él en varios equipos. Así que es otra buena idea no completamente pensada. Algo de lo que Java está lleno. – Martin

7

Básicamente tiene que ver con la vista de un paquete como una unidad api controlada (de ahí la recomendación de comenzar su paquete con su nombre de dominio - unicidad global garantizada), por lo que la visibilidad crece desde privado -> paquete-privado -> protegido -> público. Si la protección no fuera un aumento sobre el paquete privado, sino un tipo diferente de visibilidad, debería haber alguna manera de combinar los dos tipos de visibilidad cuando sea necesario.

+0

Pero nadie le impide agregar una nueva clase a un paquete que ya está saliendo. Entonces, "paquete privado" y con eso "protegido" es solo una recomendación para los programadores. Ambos no ofrecen ninguna protección real contra los programadores maliciosos/desesperados que desean/necesitan llamar al método. - "protegido" como en C++ al menos forzaría el uso de una subclase, pero en Java ni siquiera necesitas hacer eso. – Martin

1

Dado niveles progresivos de acceso, privado, paquete, protegido y público, sería innecesariamente limitante si se protegiera entonces el paquete ya que eso me obligaría a permitir acceso a subclases para otorgar a otros miembros del mismo paquete. Sin embargo, intuitivamente, debería ser que otras clases en el mismo paquete son más confiables que otras clases "por ahí". De modo que está protegido entre el paquete y el público, ya que permite una exposición más amplia de acceso.

Creo que la razón básica se basa en la intuición de que hay un nivel básico de "confianza" entre las clases en el mismo paquete; razonablemente puede esperar que hagan lo correcto entre ellos, en la mayoría de los casos, el paquete será responsabilidad de un solo ingeniero o equipo, por lo que debe haber una armonía de diseño consistente.

+0

Esa es la teoría. Pero en la práctica, esto solo sería cierto cuando un paquete debería compilarse en una única unidad de compilación y no podría mejorarse fuera. Pero ese no es el caso y, por lo tanto, con la ayuda de una delgada clase de delegados, cualquier método de "paquete privado" puede hacerse público. Una pista para el programador pero no una verdadera protección. – Martin

+0

@martin: solo si publica el paquete sin sellarlo, qué capacidad aborda este problema en particular. –

+0

"sellado del paquete": nunca lo escuché, pero parece interesante. ** ¡Cuéntame más! ** (unas palabras para ayudarme a buscar los detalles en Google es suficiente) – Martin

20

Los modificadores están bien descritos at http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html. A partir de ahí vemos esta figura.

Modifier  Class  Package Subclass World 
public   Y   Y   Y   Y 
protected  Y   Y   Y   N 
no modifier  Y   Y   N   N 
private   Y   N   N   N 

De esto el motivo de la decisión de diseño es obvio: es tener una buena matriz simétrica.

+4

Sería simétrico de todos modos ... –

+0

Gracias por esta tabla. – Marin

+0

@Michael Myers: Bueno, no, no sería simétrico de todos modos. Es simétrico por una razón. – Glenn

13

En Java 1.0 había un quinto modificador de acceso: private protected. Esto fue protected sin el acceso predeterminado. Aparentemente, nunca funcionó correctamente y se eliminó en 1.1. Por lo tanto, parece que el protected se define de la forma en que el orden total parece ser espurio. El modificador de acceso module en Java 7 tiene algunas preguntas de diseño en esta área.

Dado que se pensó que sería una buena idea que el modificador de acceso predeterminado para los miembros fuera "paquete privado", parece razonable que protected debería tener al menos este nivel de acceso. Por mi dinero, protected no paga en absoluto en el idioma.

+0

Nunca había oído hablar de eso, pero ingresé a Java en 1.1 ... ¡Gracias! – Uri

+0

Y como nadie te impide agregar más clases a un paquete en un archivo jar diferente, "paquete privado" tampoco es tan privado. Tal como están las cosas: cualquier cosa que no sea privada o pública es más o menos una pista para el programador pero no una protección real. – Martin

0

Java sigue sus principios de diseño en sí mismo. ¿Qué sucede cuando intentas reducir/reducir el alcance del método público en una subclase? uno obtiene un error. Java niveles modificadores de alcance siguen: < privada (por defecto) < protegida < pública

Toda clase de paquete se supone que es amigable, ya que trabajan juntos. Para que un miembro esté disponible en el paquete, se define en el alcance predeterminado.

Una subclase puede residir fuera del paquete, siguiendo los niveles de alcance otra vez: privado < (predeterminado) < protegido < público - No podemos reducir el alcance. Protegido es un ámbito más amplio que el predeterminado, por lo que Java no contradice sus propias directrices. Por lo tanto, un miembro protegido estará disponible en el alcance predeterminado. También: clase < paquete < Proyecto.

No limite los modificadores a solo la visibilidad, pero la herencia, la estructura también están en funcionamiento al mismo tiempo y añádalos a la imagen también. Si esto fuera cierto: privado < protegido < (predeterminado) < público. entonces todas las subclases tendrían que residir en el mismo paquete, entonces, por qué necesita heredar, puede acceder a todo, ya que el ámbito predeterminado está disponible en el nivel de paquete. El alcance predeterminado habría perdido su valor, al igual que la herencia.

Cuestiones relacionadas