2009-08-05 19 views
7

Un error común sobre el nivel de acceso en Java, C#, C++ y PHP es que se aplica a objetos en lugar de clases. Es decir, que (digamos) un objeto de clase X no puede ver los miembros privados de otra X. De hecho, por supuesto, el nivel de acceso está basado en clases y un objeto X puede referirse sin esfuerzo a los miembros privados de otro.¿Hay un lenguaje con niveles de acceso basados ​​en objetos?

¿Existe un lenguaje con niveles de acceso basados ​​en objetos? ¿Son ellos en lugar de, o además del, acceso basado en la clase? ¿Qué impacto tiene esta característica en el diseño del programa?

+0

Me tomé la libertad de agregar PHP a la lista de idiomas que implementan el nivel de acceso basado en clases. –

Respuesta

6

Ruby tiene nivel de acceso basado en objetos. He aquí una cita de programación Ruby:

La diferencia entre "protegido" y "privado" es bastante sutil, y es diferente en Ruby que en la mayoría de los lenguajes orientados a objetos comunes . Si un método es protegido, puede ser llamado por cualquier instancia de la clase definitoria o sus subclases . Si un método es privado, es se puede llamar sólo dentro del contexto del objeto que llama --- nunca es posible acceder directamente a métodos privados de otro objeto, incluso si el objeto es de la misma clase que el llamador.

y aquí está la fuente: http://whytheluckystiff.net/ruby/pickaxe/html/tut_classes.html#S4

diferencia entre Java Ejemplo y Ruby

Java

public class Main { 
    public static void main(String[] args) { 
     Main.A a1 = new A(); 
     Main.A a2 = new A(); 

     System.out.println(a1.foo(a2)); 
    } 

    static class A 
    { 
     public String foo(A other_a) 
     { 
      return other_a.bar(); 
     } 

     private String bar() 
     { 
      return "bar is private"; 
     } 
    } 
} 

// Outputs 
// "bar is private" 

Rubí

class A 
    def foo other_a 
    other_a.bar 
    end 

    private 
    def bar 
    "bar is private" 
    end 
end 

a1 = A.new 
a2 = A.new 

puts a1.foo(a2) 

# outputs something like 
# in `foo': private method `bar' called for #<A:0x2ce9f44> (NoMethodError) 
+0

¿Puede proporcionar una citación? –

+0

Todavía lo estoy buscando. –

+0

"Privado" en este sentido parece más verdaderamente modular. Espero que otros idiomas tengan una funcionalidad similar. – Imagist

-1

Puede implementar esto en C# teniendo algún método capaz de recorrer la pila y verificar qué objeto es la persona que llama, y ​​lanzar una excepción si no es la clase actual. No sé por qué querrías, pero pensé que lo tiraría allí.

+0

Aclaración: esto debe hacerse en tiempo de compilación. Es inútil en tiempo de ejecución. – EFraim

+0

Wtf hizo esto obtener downvoted? Es una respuesta válida ... –

+0

No, es un pervertido. Incurriendo en tiempos de ejecución terribles, y usando un método absolutamente incorrecto. – EFraim

0

La razón principal por la cual ningún idioma tiene soporte para esto en el nivel semántico es que las diversas necesidades son demasiado diferentes para encontrar un denominador común que sea lo suficientemente grande para tal característica. La ocultación de datos ya es bastante mala, y solo empeora cuando se necesita un control aún más preciso.

Habría ventajas en dicho lenguaje, por ejemplo, podría marcar ciertos datos como privados para cualquier persona que no fuera el objeto que lo creó (las contraseñas serían un gran ejemplo: ni siquiera el código que se ejecuta en la misma aplicación podría leerlas))

Desafortunadamente, esta "protección" sería superficial ya que a nivel del ensamblador, la protección no existiría. Para ser eficiente, el hardware debería ser compatible. En este caso, probablemente en el nivel de un solo byte en la RAM. Eso haría que una aplicación así sea extremadamente segura y dolorosamente lenta.

En el mundo real, encontrará esto en el TPM chip en su placa base y, en una forma muy tosca, con las tablas MMU de la CPU. Pero eso está en un nivel de página 4K, no a nivel de byte. Hay bibliotecas para manejar ambas, pero eso no cuenta como IMO de "soporte de idiomas".

Java tiene algo como esto en forma de Security API. Debe envolver el código en cuestión en un guardián que le pregunte al actual SecuityManager si el acceso está permitido o no.

En Python, puede lograr algo similar con decoradores (para métodos y funciones) o implementando __setattr__ y __getattr__ para acceso de campo.

+3

Su análisis es válido en cierto sentido, pero parece confundir la "encapsulación de datos" con la "seguridad de los datos". Los modificadores públicos, protegidos y privados en los lenguajes de programación orientada a objetos (OOP) no están destinados a "proteger" los datos, sino más bien a encapsular datos en una clase y "protegerlos" de la alteración de otras clases. Los modificadores no están destinados a "proteger" los datos en el sentido de seguridad de la información. – mipadi

+0

¿Cuál sería el objetivo de tal característica si no es seguridad? Para la encapsulación de datos, "privado" es suficiente porque siempre puede envolver un único campo en una clase para proteger el acceso a ella de otras instancias de la misma clase. –

Cuestiones relacionadas