class Person
{
private BankAccount account;
Person(BankAccount account)
{
this.account = account;
}
public Person someMethod(Person person)
{
//Why accessing private field is possible?
BankAccount a = person.account;
}
}
Proszę zapomnij o projekcie. Wiem, że OOP określa, że obiekty prywatne są prywatne dla klasy. Moje pytanie brzmi: dlaczego OOP został zaprojektowany w taki sposób, że pola prywatne mają dostęp na poziomie klasy, a nie na poziomie obiektu ?
someMethod
jest ważny. Nic nie zwraca. To musi byćvoid
.Odpowiedzi:
Jestem też trochę ciekawa odpowiedzi.
Najbardziej satysfakcjonującą odpowiedzią, jaką znalazłem, jest Artemix w innym poście tutaj (zmieniam nazwę AClass na klasę Person): Dlaczego mają modyfikatory dostępu na poziomie klasy zamiast na poziomie obiektu?
EDYCJA: Prosimy o głosowanie na odpowiedź Artemixa. Po prostu go kopiuję i wklejam.
źródło
Person
w klasiePerson
nie musi znać implementacji całej klasy. Dobrą praktyką jest użycie akcesorium bez konieczności znajomości operacji wykonywanych przez akcesorium.equals(Object)
metodę w klasie Java, aby sprawdzić równośćPerson
obiektu z inną instancjąPerson
. Możesz chcieć umożliwić światu zewnętrznemu sprawdzanie, czy dwa wystąpienia są równe, ale możesz nie chcieć ujawniać wszystkich prywatnych pól klasy niezbędnych do sprawdzania równości światu zewnętrznemu za pomocą publicznych metod dostępu. Posiadanie dostępu doprivate
pól na poziomie klasy umożliwia implementację takiej metody bez wymuszonej konieczności implementacji takich metod publicznych.equals
).equals
można wykonać, wywołując prywatne metody dostępu .private
musi przyznać dostęp na poziomie klasy. Zgadzam się, że używanie akcesoriów jest ogólnie dobrym nawykiem, chociaż w tym przypadku jest to głównie kwestia kontekstu i osobistego stylu. Zwróć uwagę, że zarówno Joshua Bloch w efektywnej Javie (punkt 8), jak i Tal Cohen w tym artykule dr. Dobbsa mają bezpośredni dostęp do pól prywatnych w swoich listach kodu podczas omawiania sposobu implementacjiequals
.Zobacz specyfikację języka Java, Rozdział 6.6.1. Określanie dostępności
W Stanach
Kliknij powyższy link, aby uzyskać więcej informacji. Odpowiedź brzmi więc: ponieważ James Gosling i inni autorzy Javy zdecydowali, że tak będzie.
źródło
Dobre pytanie. Wydaje się, że modyfikator dostępu na poziomie obiektu jeszcze bardziej wymusiłby zasadę enkapsulacji.
Ale w rzeczywistości jest odwrotnie. Weźmy przykład. Załóżmy, że chcesz głęboko skopiować obiekt w konstruktorze, jeśli nie możesz uzyskać dostępu do prywatnych członków tego obiektu. Wtedy jedynym możliwym sposobem jest dodanie publicznych akcesorów do wszystkich członków prywatnych. W ten sposób obiekty będą widoczne dla wszystkich innych części systemu.
Zatem hermetyzacja nie oznacza zamknięcia się na całą resztę świata. Oznacza to wybiórcze podejście do tego, na kogo chcesz być otwarty.
źródło
o.deepCopy()
lub cokolwiek innego.To działa, ponieważ jesteś w
class Person
klasie - może zaglądać do własnego typu klasy. To naprawdę pomaga, gdy chcesz napisać konstruktor kopiujący, na przykład:class A { private: int x; int y; public: A(int a, int b) x(a), y(b) {} A(A a) { x = a.x; y = y.x; } };
Lub jeśli chcemy pisać
operator+
ioperator-
dla naszej dużej klasy liczbowej.źródło
Tylko moje 2 centy na pytanie, dlaczego semantyka prywatnej widoczności w Javie jest na poziomie klasy, a nie na poziomie obiektu.
Powiedziałbym, że wygoda wydaje się tutaj kluczowa. W rzeczywistości prywatna widoczność na poziomie obiektu zmuszałaby do ujawnienia metod innym klasom (np. W tym samym pakiecie) w scenariuszu przedstawionym w PO.
Prawdę mówiąc, nie byłem w stanie ani wymyślić, ani znaleźć przykładu pokazującego, że widoczność na poziomie prywatnej klasy (jak oferowana przez Javę) stwarza jakiekolwiek problemy w porównaniu z widocznością na poziomie prywatnym obiektu.
To powiedziawszy, języki programowania z bardziej szczegółowym systemem polityk widoczności mogą zapewnić widoczność obiektów na poziomie obiektu i na poziomie klasy.
Na przykład Eiffel oferuje selektywny eksport: możesz wyeksportować dowolny obiekt klasowy do dowolnej wybranej klasy, od {NONE} (obiekt-prywatny) do {DOWOLNY} (odpowiednik publicznego, a także domyślnego), do {PERSON} (klasa prywatna, zobacz przykład OP), do określonych grup klas {PERSON, BANK}.
Warto również zauważyć, że w Eiffel nie trzeba ustawiać atrybutu jako prywatnego i pisać metody pobierającej, aby uniemożliwić innym klasom przypisywanie do niego. Atrybuty publiczne w Eiffel są domyślnie dostępne w trybie tylko do odczytu, więc nie potrzebujesz funkcji pobierającej tylko do zwrócenia ich wartości.
Oczywiście nadal potrzebujesz ustawiacza, aby ustawić atrybut, ale możesz go ukryć, definiując go jako „przypisującego” dla tego atrybutu. Pozwala to, jeśli chcesz, na użycie wygodniejszego operatora przypisania zamiast wywołania ustawiającego.
źródło
Ponieważ
private
modyfikator dostępu sprawia, że jest widoczny tylko w klasie . Ta metoda jest nadal W klasie .źródło
private
pole jest dostępny w klasie / obiektu, w którym pole jest zadeklarowane. Jest prywatny dla innych klas / obiektów poza tą, w której się znajduje.źródło
Pierwszą rzeczą, którą musimy zrozumieć, jest to, że wszystko, co musimy zrobić, to przestrzegać zasad Ups, więc hermetyzacja polega na zawinięciu danych w pakiet (tj. Klasie), a następnie przedstawieniu wszystkich danych jako obiektu i łatwego dostępu. więc jeśli ustawimy pole jako nieprywatne, to dostęp do niego jest indywidualny. i to prowadzi do złego paratytu.
źródło
Dzięki koncepcji refleksji w Javie możliwa jest modyfikacja pól i metod prywatnych
Modificando metodos y campos privados con Refleccion en Java
źródło