El siguiente es un pseudocódigo, lo probé en Java y PHP y ambos funcionaron:
class Test {
private int a = 5;
public static function do_test(){
var t = new Test();
t.a = 1;
print t.a // 1
}
}
Test::do_test();
¿Por qué puedes hacer esto en el paradigma OOP y de qué sirve?
equals
que tiene que verificar los campos privados de otra instancia. (Publicación como comentario, ya que es breve, y nada sobre la OOP-ness de este enfoque)this
, por lo que los únicos objetos de su propia clase a los que pueden acceder son los que crean ellos mismos (o que se pasan como un parámetro). Entonces, si considera que esto es una violación de la encapsulación o un agujero de seguridad, no es que sea muy grande, y puede que no valga la pena taparlo.Respuestas:
En Java, las variables privadas son visibles para toda la clase. Se puede acceder desde métodos estáticos y desde otras instancias de la misma clase.
Esto es, por ejemplo, útil en los métodos de fábrica . Un método de fábrica generalmente inicializa un objeto que es tan complejo que no desea dejarlo en el código de la aplicación. Para realizar la inicialización, el método de fábrica a menudo necesita acceso a los elementos internos de clase que no desea exponer. Ser capaz de acceder a las variables privadas directamente hace que su vida sea mucho más fácil.
Sin embargo, cuando desea ocultar los detalles de implementación de una clase incluso de métodos estáticos o de otras instancias de esa clase, puede seguir el patrón de datos de la clase privada . Coloque todas las variables privadas de una clase en una clase interna privada y delegue cualquier getters o setters a getters y setters de esa clase interna.
Otra opción es definir una interfaz para la clase que declare todos los métodos públicos de la clase y luego solo haga referencia a la clase bajo esa interfaz siempre que sea posible. Una referencia al tipo de interfaz no se puede utilizar para acceder directamente a nada no declarado en la interfaz, sin importar dónde (excepto con reflexión, por supuesto). Cuando utiliza un lenguaje de programación orientado a objetos que no tiene interfaces (como C ++, por ejemplo), se pueden simular con una clase base abstracta que la clase real hereda.
fuente
Algunos lenguajes y frameworks de tiempo de ejecución (por ejemplo, Java, .NET) suponen que cualquier persona que esté compilando el código para una clase en particular puede confiar en que no usará ningún miembro privado de ninguna instancia de esa clase de manera que sea perjudicial para su correcto operación. Otros lenguajes y marcos son más restrictivos en ese sentido, y no permiten el acceso a miembros privados de una instancia, excepto por el código que se ejecuta en esa instancia . Ambos diseños tienen ventajas y desventajas.
La mayor ventaja de permitir que cualquier código dentro de una clase acceda a miembros privados de cualquier instancia es que hay casos en los que ese nivel de acceso es apropiado, y tener
private
trabajo de esa manera elimina la necesidad de tener un calificador de acceso diferente disponible para ese propósito o de lo contrario, forzará el código para exponer a los miembros de manera más amplia de lo que sería ideal.Una ventaja de no permitir dicho acceso (como fue el caso en el Modelo de objetos comunes de Microsoft (COM)) es que permite que el código externo trate las clases como interfaces. Si una clase
ImmutableMatrix
contiene undouble[][]
campo de respaldo privado o protegido , y si el código dentro de la clase examina la matriz de respaldo de otras instancias, entonces no será posible definir una clase sin respaldo de matriz (por ejemploZeroMatrix
,IdentityMatrix
) que el código externo podría usar como anImmutable2dMatrix
, sin que esa clase tenga que incluir el campo de respaldo. Si nada en el interiorImmutable2dMatrix
utiliza miembros privados de cualquier otra instancia que no seathis
, entonces sería posible cambiar el nombre de la claseImmutableArrayBackedMatrix
y definir una nuevaImmutableMatrix
clase abstracta que podría tenerImmutableArrayBackedMatrix
como subtipos las clases no respaldadas por matriz mencionadas anteriormente.Tenga en cuenta que dicha refactorización no se evitaría si el lenguaje "permitiera"
ImmutableMatrix
examinar la matriz de respaldo para instancias distintasthis
, a menos que el lenguaje aprovechara esa capacidad y realmente examinara instancias externas. El efecto principal de tener un lenguaje que restringe dicho uso es que hará que el compilador grazne inmediatamente en cualquier intento de escribir código que no sea susceptible de tal refactorización.fuente
Java no es estrictamente un lenguaje orientado a objetos, sino un lenguaje basado en clases : la clase determina las operaciones y el acceso al comportamiento en lugar de la instancia.
Así que no se sorprenda demasiado de que le permita hacer cosas que no estén estrictamente orientadas a objetos.
Dado que el método está en el mismo ámbito de clase que la instancia, tiene acceso completo a miembros privados. Reglas similares gobiernan instancias de clases internas que acceden a datos de instancias de clases externas: una instancia de una clase interna puede acceder a miembros privados de la clase externa.
Esto se hereda de C ++, donde es útil para crear constructores de copiar y mover. También es útil para comparar o combinar dos objetos en los que su valor depende de miembros a los que no se puede acceder públicamente de manera eficiente (por ejemplo, el captador de una matriz en Java debe copiar la matriz para que el código del cliente no pueda modificarla, cambiando el estado interno del objeto, pero tener que copiar matrices para comparar la igualdad de objetos no es eficiente)
fuente