2009-08-05 10 views
7

Powszechnym błędnym przekonaniem o poziomie dostępu w Javie, C#, C++ i PHP jest to, że dotyczy obiektów, a nie klas. Oznacza to, że (powiedzmy) obiekt klasy X nie może zobaczyć prywatnych członków X innych. W rzeczywistości, oczywiście, poziom dostępu jest oparty na klasach, a jeden obiekt X może bez trudu odnosić się do prywatnych członków innego.Czy istnieje język z poziomami dostępu opartymi na obiektach?

Czy istnieje język z poziomami dostępu opartymi na obiektach? Czy są one zamiast dostępu do klasy lub oprócz tego? Jaki wpływ ma ta funkcja na projekt programu?

+0

Mogłem dodać PHP do listy języków implementujących poziom dostępu oparty na klasach. –

Odpowiedz

6

Ruby ma poziom dostępu oparty na obiektach. Oto cytat z programowania Ruby:

Różnica między „chronione” i „prywatne” jest dość subtelny i jest inna niż w Ruby w większości popularnych języków oo. Jeśli metoda jest chroniona pod kątem , może być wywołana przez dowolną instancję klasy lub jego podklas . Jeśli metoda jest prywatny, może być wywołana tylko w kontekście obiektu wywołującego --- nigdy nie jest możliwy dostęp prywatnych metod innego obiektu bezpośrednio, nawet jeśli obiekt jest tej samej klasy jak gość.

A oto źródło: http://whytheluckystiff.net/ruby/pickaxe/html/tut_classes.html#S4

przykład różnica między Java i 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" 

Ruby

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

Czy możesz podać cytat? –

+0

Nadal go szukam. –

+0

"Prywatne" w tym sensie wydaje się bardziej prawdziwie modułowe. Mam nadzieję, że inne języki zaczną podobną funkcjonalność. – Imagist

-1

Możesz to zaimplementować w języku C#, stosując metodę zdolną do przechodzenia między stosami i sprawdzania, który obiekt jest obiektem wywołującym, i generowania wyjątku, jeśli nie jest to aktualna klasa. Nie wiem, dlaczego chciałbyś, ale myślałem, że go tam wyrzucę.

+0

Wyjaśnienie: należy to zrobić podczas kompilacji. Jest bezużyteczny w czasie wykonywania. – EFraim

+0

Czy to zrobiło? To jest poprawna odpowiedź ... –

+0

Nie, to perwersja. Nadmierne obciążenie środowiska wykonawczego i użycie całkowicie niepoprawnej metody. – EFraim

0

Głównym powodem, dla którego żaden język nie obsługuje tego na poziomie semantycznym, jest to, że różne potrzeby są zbyt różne, aby znaleźć wspólny mianownik, który jest wystarczająco duży dla takiej funkcji. Ukrywanie danych jest wystarczająco złe, a staje się gorsze, gdy potrzebujesz jeszcze drobniejszej kontroli.

Byłoby to korzystne dla takiego języka, na przykład można oznaczyć pewne dane jako prywatne dla każdego, ale obiekt, który je utworzył (hasła byłyby świetnym przykładem: nawet kod działający w tej samej aplikacji nie mógł ich odczytać).

Niestety, ta "ochrona" byłaby powierzchowna, ponieważ na poziomie asemblera ochrona nie istniałaby. Aby być wydajnym, sprzęt musiałby go obsługiwać. W tym przypadku prawdopodobnie na poziomie jednego bajtu w pamięci RAM. To sprawiłoby, że taka aplikacja byłaby wyjątkowo bezpieczna i boleśnie powolna.

W prawdziwym świecie znajdziesz to na TPM chip na swojej płycie głównej, a także w bardzo grubej formie z tabelami MMU procesora. Ale to na poziomie strony 4K, a nie na poziomie bajtów. Istnieją biblioteki do obsługi obu, ale nie liczy się jako "wsparcie językowe" IMO.

Java ma coś takiego w postaci Security API. Musisz opakować dany kod w opiekuna, który pyta bieżący numer SecuityManager, czy dostęp jest dozwolony, czy nie.

W języku Python można uzyskać coś podobnego w dekoratorach (dla metod i funkcji) lub implementując __setattr__ i __getattr__ dla dostępu w terenie.

+3

Twoja analiza jest w pewnym sensie ważna, ale wydajesz się mylące "enkapsulacja danych" z "bezpieczeństwem danych". Publiczne, chronione i prywatne modyfikatory w językach OOP nie mają na celu "zabezpieczenia" danych, lecz raczej enkapsulacji danych w klasie i "ochrony" przed zmianami dokonywanymi przez inne klasy. Modyfikatory nie mają na celu "ochrony" danych w sensie bezpieczeństwa informacji. – mipadi

+0

Jaki byłby sens takiej funkcji, gdyby nie bezpieczeństwo? W przypadku enkapsulacji danych wystarczy "prywatny", ponieważ zawsze można zawinąć pojedyncze pole w klasie, aby chronić dostęp do niego z innych instancji tej samej klasy. –

Powiązane problemy