2009-08-05 11 views
7

Un comune equivoco sul livello di accesso in Java, C#, C++ e PHP è che si applica agli oggetti piuttosto che alle classi. Cioè, che (diciamo) un oggetto della classe X non può vedere i membri privati ​​di un'altra X. In effetti, ovviamente, il livello di accesso è basato sulla classe e un oggetto X può facilmente riferirsi ai membri privati ​​di un altro.Esiste una lingua con livelli di accesso basati su oggetti?

Esiste una lingua con livelli di accesso basati su oggetti? Sono invece o in aggiunta all'accesso basato su classi? Che impatto ha questa caratteristica sulla progettazione del programma?

+0

Mi sono preso la libertà di aggiungere PHP all'elenco di lingue che implementano il livello di accesso basato su classi. –

risposta

6

Ruby ha un livello di accesso basato su oggetti. Ecco una citazione di programmazione Ruby:

La differenza tra "protetta" e "privato" è abbastanza sottile, e è diverso in Ruby che nella maggior parte dei linguaggi OO comuni. Se un metodo è protetto da , può essere chiamato da qualsiasi istanza della classe di definizione o dalle sue sottoclassi . Se un metodo è privata, può essere chiamato solo nel contesto dell'oggetto chiamante --- non è mai possibile accedere direttamente metodi privati ​​di un altro oggetto, anche se l'oggetto è della stessa classe come il chiamante.

Ed ecco la fonte: http://whytheluckystiff.net/ruby/pickaxe/html/tut_classes.html#S4

differenza Esempio tra Java e 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" 

Rubino

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

Potete fornire una citazione? –

+0

Sto ancora cercando. –

+0

"Privato" in questo senso sembra più veramente modulare. Spero che altre lingue acquisiscano funzionalità simili. – Imagist

-1

È possibile implementare questo in C# con un metodo in grado di camminare nello stack e controllare quale oggetto è il chiamante e generare un'eccezione se non è la classe corrente. Non so perché vorresti, ma pensavo di buttarlo là fuori.

+0

Precisazione: questa cosa dovrebbe essere fatta in fase di compilazione. È inutile in fase di esecuzione. – EFraim

+0

Wtf è stato downvoted per? È una risposta valida ... –

+0

No, è una perversione. Incremento del sovraccarico di runtime e utilizzo di metodi assolutamente scorretti. – EFraim

0

Il motivo principale per cui nessuna lingua supporta questo livello a livello semantico è che le varie esigenze sono troppo diverse per trovare un denominatore comune che sia abbastanza grande per tale funzione. Il nascondiglio dei dati è già abbastanza grave, e diventa solo peggiore quando hai bisogno di un controllo ancora più preciso.

Ci sarebbero dei vantaggi in un tale linguaggio, ad esempio, potresti contrassegnare certi dati come privati ​​per chiunque tranne l'oggetto che li ha creati (le password sarebbero un ottimo esempio: nemmeno il codice in esecuzione nella stessa applicazione potrebbe leggerle).

Sfortunatamente, questa "protezione" sarebbe superficiale poiché a livello di assemblatore, la protezione non esisterebbe. Per essere efficiente, l'hardware dovrebbe supportarlo. In questo caso, probabilmente a livello di un singolo byte nella RAM. Ciò renderebbe tale applicazione estremamente sicura e dolorosamente lenta.

Nel mondo reale, questo lo trovate nello TPM chip sulla scheda madre e, in una forma molto approssimativa, con le tabelle MMU della CPU. Ma questo è a un livello di pagina 4K, non a livello di byte. Ci sono librerie per gestire entrambi, ma ciò non conta come "supporto per la lingua" IMO.

Java ha qualcosa del genere in forma di Security API. È necessario avvolgere il codice in questione in un tutore che chiede l'attuale SecuityManager se l'accesso è consentito o meno.

In Python, è possibile ottenere qualcosa di simile con i decoratori (per metodi e funzioni) o implementando __setattr__ e __getattr__ per l'accesso al campo.

+3

L'analisi è valida in un certo senso, ma sembra che tu stia confondendo "l'incapsulamento dei dati" con "sicurezza dei dati". I modificatori pubblici, protetti e privati ​​nei linguaggi OOP non intendono "proteggere" i dati, ma piuttosto incapsulare i dati in una classe e "proteggerli" dalle alterazioni di altre classi. I modificatori non sono pensati per "proteggere" i dati nel senso della sicurezza delle informazioni. – mipadi

+0

Quale sarebbe il punto di tale funzionalità se non la sicurezza? Per l'incapsulamento dei dati, "privato" è sufficiente perché puoi sempre racchiudere un singolo campo in una classe per proteggere l'accesso ad esso da altre istanze della stessa classe. –

Problemi correlati