2009-05-22 11 views
7

Comencemos con otro comportamiento: incluso si declara un método/variable como privado, otra instancia de la misma clase puede acceder a él. Está bien, puedo vivir con eso. Yo llamo a estos class-private y no instance-private.En Java, ¿por qué un método de superclase no puede acceder a métodos/variables protegidos o privados desde una instancia de subclase?

Ahora la parte pregunta: Por ejemplo, en tiempo de ejecución Quiero ser capaz de verificar que todas las variables de cadena en this clase no son nulos, y si son nulos que se debe cambiar a la cadena "NULL".

Puedo ejecutar las variables usando la reflexión y obtener sus valores. Pero si amplío mi clase y agrego variables privadas o incluso protegidas, mi clase base no puede acceder a ellas. Tengo que setAccessible en las variables antes de poder usarlas.

Así que por favor explíqueme por qué la clase base (superclase) no puede acceder a variables privadas/protegidas desde su subclase. Es su subclase, así que no lo entiendo. ¿Cuál es la idea detrás de esto?

Sé que la superclase no debería conocer sus subclases, pero en mi ejemplo tiene sentido, ¿no?

¿Es porque no puedo o no debo restringir mis subclases de esta manera?


Actualización: Sobre la base de las respuestas, quiero saber también: ¿Por qué no se accede a variables privadas de otra instancia de la misma clase considerada una violación de la encapsulación?

+2

no, no tiene sentido. –

Respuesta

7

Es tan simple como una violación de la encapsulación. Otra clase no debería ser capaz de llegar a tu clase y estar jugando con cosas, incluso si generalizas esa clase. ¿Cómo sabe un Vehículo algo sobre un automóvil, por ejemplo? El objetivo de una clase base es proporcionar las subclases, pero al igual que un padre sobreprotector, lo que está sugiriendo sería demasiado.

+0

Entonces, ¿por qué acceder a las variables privadas de otra instancia desde la misma instancia de clase no se considera una violación de la encapsulación? Los automóviles deberían poder restringir los BMW para que solo tengan ruedas y no alas, porque si BMW tiene alas, no es un Auto (incluso si usa las alas "internamente") –

+1

Porque soy de la clase. No se puede hacer lo que se habla desde fuera de la clase, por lo tanto, la encapsulación es intachable. Desde dentro de la clase puede modificar miembros privados de otra instancia de la clase. ¿Cómo es eso una violación de algo? ¡Estoy en la clase! Puedo cambiar todo lo relacionado con la clase que quiero, entonces, ¿por qué no permitirlo? –

4

Todo se trata de herencia y encapsulación.

reglas de visibilidad de Java afirman que

  1. miembros privados sólo se puede acceder en la clase que los define
  2. miembros protegidos sólo pueden acceder en
    • la clase que los define
    • subclases de la clase que las define
    • otras clases en el mismo paquete que la clase que las define

Por supuesto, como usted menciona, en la reflexión puede cambiar las reglas (a menos que un SecurityManager lo prohíbe)

+1

O, sucintamente: Este comportamiento es por diseño ... –

+0

@Tetsujin: me acabas de hacer sonreír;) –

+0

¿Entonces por qué acceder a las variables privadas de otra instancia de la misma instancia de clase no se considera una violación de la encapsulación? –

0

tiendo a mirar más desde un punto de vista pragmático y realista:

public class Test1 { 
    private int a = 1; 

    public static void main(String s[]) { 
     System.out.println((new Test1()).a); 
     System.out.println((new Test1()).getA()); 
     System.out.println((new Test2()).getA()); 
    } 

    public int getA() { return a; } 
} 

class Test2 extends Test { 
    private int a = 2; 

    public int getA() { return a; } 
} 

Qué sintaxis propondrías Test1 para acceder al miembro privado a en Test2.Cuando se escribe Test1, es posible que Test2 ni siquiera exista.

Además, una clase base (superclase) no sabe cuándo se ha heredado de. Para permitir que una clase base sepa cuándo se ha heredado, debería poder modificar la clase base cuando hereda de ella. ¿Estás sugiriendo que de alguna manera debo modificar mi copia local de ArrayList cuando escribo:

class MyArrayList extends ArrayList 

y lo que sucede el día decido ejecutar el código en el ordenador, se puede conseguir mi copia modificada del ArrayList que sabe acerca MyArrayList, o modifico la copia en su computadora de alguna manera?

¿Podrían estos problemas ser superados de alguna manera? Ciertamente. ¿Hay algún valor para permitirlo? Ninguno que yo pueda ver

+0

En su ejemplo, la instancia de Test2 tendrá dos variables: Test1.a y Test2.a, cada una de ellas accesible solo desde su clase. Test1 puede cambiar el valor de Test1.a en la instancia de Test2, que el lenguaje considera correcto, pero no tendrá ningún efecto en Test2, incluso cuando Test1 "crea" que lo hace. Hay muchos ejemplos cuando la subclase rompe la compatibilidad cuando se usa como clase base. ¿Cómo es eso diferente de lo que estoy preguntando? –

+0

No estoy seguro de lo que estás tratando de decir. Regreso a mis preguntas originales: 1) ¿Qué tipo de sintaxis podría usar Test2 para acceder o actualizar miembros privados de su clase principal? 2) ¿Cómo sabe Test1 cómo exponer a sus miembros internos a una clase que quizás ni siquiera se haya escrito todavía? 3) ¿Cómo se propagan los cambios a la clase base que se ha modificado para proporcionar acceso a un niño heredado? 4) Lo más importante, ¿qué valor posible podría proporcionar esto a los programadores? –

+0

1) Test2 no puede acceder a miembros privados del padre (para eso sirve el modificador protegido). Pero Test1 puede acceder a miembros "desprotegidos" (no privados) de Test1. 2) protected lo hace 3) eso es lo mismo que cambiar las funciones protegidas o privadas en la clase base 4) escribiré otra pregunta solo para mostrar el problema exacto –

7

Para responder a su pregunta de actualización (ya que la pregunta original ya está bien respondida) el propósito de privado es ocultar los detalles de implementación para que esos detalles de implementación no se conviertan en dependencias. Esta es la esencia de la programación orientada a objetos: la encapsulación asegura que la complejidad se mantenga manejable al mantener diferentes partes aisladas en su propia área.

Como la clase conoce su propia implementación, la define, no se gana nada limitando el acceso a otras instancias, ya que la implementación de la clase declara todas las instancias privadas que ya está expuesta a todos estos detalles.

Ocultarlo en este caso de hecho aumentaría la complejidad, ya que tendría que agregar un nivel de acceso adicional para permitir la visibilidad a nivel de clase en lugar de la visibilidad del nivel de instancia sin realmente encapsular ninguna complejidad adicional.

Cuestiones relacionadas