Poniżej znajduje się pseudo kod, próbowałem go w Javie i PHP i oba działały:
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();
Dlaczego możesz to zrobić w paradygmacie OOP i jaki jest z tego pożytek?
equals
że trzeba sprawdzić prywatne pola innej instancji. (Publikowanie jako komentarz, ponieważ jest krótki, i nic o OOP-ności tego podejścia)this
, więc jedynymi obiektami własnej klasy, do których mogą się dostać, są te, które sami tworzą (lub które są przekazywane jako parametr). Więc jeśli uważasz to za naruszenie enkapsulacji lub dziury w zabezpieczeniach, to nie jest tak, jakby było bardzo duże i może nie być warte zatkania.Odpowiedzi:
W Javie zmienne prywatne są widoczne dla całej klasy. Można do nich uzyskać dostęp za pomocą metod statycznych i innych instancji tej samej klasy.
Jest to na przykład przydatne w metodach fabrycznych . Metoda fabryczna zwykle dokonuje inicjalizacji obiektu, który jest tak złożony, że nie chcesz pozostawiać go kodowi aplikacji. Aby dokonać inicjalizacji, metoda fabryczna często potrzebuje dostępu do wewnętrznych elementów klasy, których nie chcesz ujawniać. Możliwość bezpośredniego dostępu do zmiennych prywatnych znacznie ułatwia życie.
Jednak jeśli chcesz ukryć szczegóły implementacji klasy nawet przed metodami statycznymi lub przed innymi instancjami tej klasy, możesz zastosować wzorzec danych klasy prywatnej . Umieść wszystkie prywatne zmienne klasy w prywatnej klasie wewnętrznej i deleguj dowolne moduły pobierające lub ustawiające do modułów pobierających i ustawiających tej klasy wewnętrznej.
Inną opcją jest zdefiniowanie interfejsu dla klasy, który deklaruje wszystkie publiczne metody klasy, a następnie odwołuje się tylko do klasy w ramach tego interfejsu, o ile to możliwe. Odwołanie do typu interfejsu nie może być użyte do bezpośredniego dostępu do wszystkiego, co nie zostało zadeklarowane w interfejsie, bez względu na to, gdzie (z wyjątkiem oczywiście refleksji). Gdy używasz zorientowanego obiektowo języka programowania, który nie ma interfejsów (na przykład C ++), można je symulować za pomocą abstrakcyjnej klasy podstawowej, która jest dziedziczona przez rzeczywistą klasę.
źródło
Niektóre języki i środowiska wykonawcze (np. Java, .NET) przyjmują założenie, że każdemu, kto kompiluje kod dla określonej klasy, można ufać, że nie użyje żadnych prywatnych członków żadnej instancji tej klasy w sposób, który byłby szkodliwy dla jego poprawności operacja. Inne języki i frameworki są pod tym względem bardziej restrykcyjne i nie pozwalają na dostęp do prywatnych członków instancji, z wyjątkiem kodu działającego w tej instancji . Oba projekty mają zalety i wady.
Największą zaletą zezwalania każdemu kodowi w klasie na dostęp do prywatnych członków dowolnej instancji jest to, że istnieją przypadki, w których ten poziom dostępu jest odpowiedni, a
private
praca w ten sposób eliminuje potrzebę posiadania innego kwalifikatora dostępu do tego celu lub inaczej zmusi kod do ujawnienia członków w szerszym zakresie niż byłoby to idealne.Zaletą uniemożliwienia takiego dostępu (jak miało to miejsce w przypadku modelu Microsoft Common Object Model (COM)) jest to, że pozwala on kodowi zewnętrznemu traktować klasy jako interfejsy. Jeśli grupa
ImmutableMatrix
zawiera prywatne lub chronionedouble[][]
pole oporowe i jeśli kod w klasie bada tablicę podkładową innych przypadkach, to nie jest możliwe określenie klasy nie tablicy oparciem (na przykładZeroMatrix
,IdentityMatrix
), który może wykorzystać kod zewnętrzny w iImmutable2dMatrix
bez konieczności uwzględnienia przez tę klasę pola zaplecza. Jeśli nic wewnątrz nieImmutable2dMatrix
korzysta z prywatnych członków żadnej instancji innej niżthis
, wówczas można by zmienić nazwę klasy naImmutableArrayBackedMatrix
i zdefiniować nowąImmutableMatrix
klasę abstrakcyjną, która mogłaby mieć,ImmutableArrayBackedMatrix
podobnie jak wyżej wymienione klasy nieobsługiwane przez tablice, jako podtypy.Zauważ, że takiemu refaktoryzacji nie można zapobiec, jeśli język „zezwoli”
ImmutableMatrix
na sprawdzenie tablicythis
pomocniczej dla instancji innych niż , chyba że język skorzystałby z tej możliwości i faktycznie zbadał instancje zewnętrzne. Podstawowym efektem ograniczenia użycia takiego języka jest to, że kompilator natychmiast skrzęczy przy każdej próbie napisania kodu, który nie byłby podatny na takie refaktoryzowanie.źródło
Java nie jest językiem zorientowanym obiektowo, ale językiem opartym na klasach - klasa określa dostęp do operacji i zachowania, a nie instancję.
Więc nie bądź zbyt zaskoczony, że pozwala ci robić rzeczy, które nie są ściśle obiektowe.
Ponieważ metoda ma ten sam zakres klasy co instancja, ma pełny dostęp do prywatnych członków. Podobne reguły dotyczą instancji klas wewnętrznych uzyskujących dostęp do danych z instancji klas zewnętrznych - instancja klasy wewnętrznej może uzyskiwać dostęp do prywatnych członków klasy zewnętrznej.
Jest to dziedziczone z C ++, gdzie jest przydatne do tworzenia konstruktorów kopiowania i przenoszenia. Jest także przydatny do porównywania lub łączenia dwóch obiektów, których wartość zależy od elementów, które nie są publicznie dostępne w efektywny sposób (na przykład moduł pobierający tablicę w Javie powinien skopiować tablicę, aby kod klienta nie mógł jej zmodyfikować, zmieniając wewnętrzny stan obiektu, ale konieczność kopiowania tablic w celu porównania równości obiektów nie jest skuteczna)
źródło