Dlaczego w Javie nie ma modyfikatora dostępu „tylko podklasy”?

17

W Javie dostępne są cztery modyfikatory dostępu do metod:

public - każda klasa może korzystać z tej metody.

protected - klasy w tym samym pakiecie i podklasy w dowolnym pakiecie mogą korzystać z tej metody.

private - tylko ta klasa może korzystać z tej metody.

no modifier („pakiet prywatny”) - tylko klasy w tym samym pakiecie mogą korzystać z tej metody.

Często zdarza się, że chcę mieć użyteczne metody w nadklasie, z których mogą korzystać wszystkie podklasy. Ale dostęp do tej metody nie miałby sensu dla innych klas iw pewnym sensie spowodowałoby to przerwanie enkapsulacji.

Muszę więc zadeklarować te użyteczne metody w nadklasie publiclub protected, co wystawia je wszystkim pozostałym klasom przynajmniej w pakiecie. Mimo że są przeznaczone wyłącznie do wykorzystania przez podklasy.

Czy istnieje powód, dla którego nie ma subclasses-onlymodyfikatora dostępu w Javie? Wydaje mi się to bardzo dziwne. Czy coś brakuje?

Również subclasses-onlymodyfikator dostępu byłby przydatny, gdy chcesz wystawiać zmienne tylko na podklasy. Co mi się często zdarza.

Aviv Cohn
źródło

Odpowiedzi:

10

Ponieważ można emulować modyfikator tylko podklas, używając chronionego modyfikatora i wymuszając, że tylko klasa nadrzędna i jej podklasy znajdują się w tym samym pakiecie.

To rzeczywiście dobra praktyka, ponieważ pakiety nie tylko pomagają organizować duże projekty pod względem spójności, ale pokazują również, że klasy w tym samym pakiecie mogą mieć pewien poziom sprzężenia.

Tércio de Almeida
źródło
15
„i wymuszanie, że tylko klasa nadrzędna i jej podklasy znajdują się w tym samym pakiecie” - A jak by to zrobić ?!
JimmyB
1
I wtedy nie możesz użyć modyfikatora dostępu dostępnego tylko w pakiecie. Potrzebujesz głupiej ilości paczek. To nie jest praktyczne rozwiązanie.
user253751
13

Java pierwotnie miała taki modyfikator. Został napisany, private protectedale usunięty w Javie 1.0.

Zakładam, że było to wezwanie do oceny, że dodatkowa złożoność nie była warta kosztów.

Każda funkcja językowa ma swój koszt: ucząc ją nowych programistów; w dokumentacji; implementując go w kompilatorze, JVM i narzędziach programistycznych; w uzasadnieniu poprawności programu; w ograniczaniu przyszłej ewolucji języka; i więcej. Funkcje językowe współdziałają ze sobą, potencjalnie z interakcjami N 2 .

Jaki procent programistów Java przeczytał specyfikację języka Java i specyfikację VM? Założę się, że to niewielki procent, który przemawia za jeszcze prostszym językiem ze względu na zrozumiałość i inżynierię produktów, od których możemy polegać

Zaleta tej private protectedfunkcji była niewielka, ponieważ pakiet jest główną jednostką modułowości.

Jerry101
źródło
1
więc była wersja Java przed 1.0?
Mark Yisri
1
@ MarkYisri Java opublikował publiczne wersje alfa i beta w 1995 roku i napisano przeciwko nim sporo kodu.
David Moles,
4

Kontrola dostępu może być wymyślona w wyniku relacji z wyimaginowanym programistą, który pracuje z twoją klasą nad metodami klasowymi i ich właściwościami ...

TY: Powiedz, że chcesz zrobić x, wywołujesz metodę doX .. DEV: Powiedz mi więcej ... jakie są argumenty?

To jest publiczne ...

TY: Wewnątrz doX dzwonię ... DEV: Zaraz, za dużo informacji, nie obchodzi mnie to. Chcę tylko wiedzieć, jak go używać. Powiedz mi coś innego.

To jest prywatne ...

TY: Podczas subklasy mam doX i doY wywołuję doI, co robi ... DEV: Tak, podklasę, powiedz mi więcej ...

To jest chronione ...

TY: Wyjeżdżam na wakacje za godzinę, nie będzie mnie przez następne 6 miesięcy. Szef mówi, że ten szczeniak jest twój! PA. DEV: Czekaj, jeszcze nie idź, powiedz mi wszystko ...

To jest pakiet.

TY: Metoda DOItWhen jest wywoływana tylko przez tę klasę i nie zmieniła się od dziesięciu lat. To ... DEV: Zaraz, do 50 minut. Następna nieruchomość i mów szybciej.

To jest chronione prywatnie ...

jmoreno
źródło
3

To już istnieje. Jest chroniony

Masz kontrolę nad tym, jakie klasy istnieją w pakiecie. Jeśli w pakiecie nie ma innej klasy, a dana zmienna lub metoda jest chroniona, jest to „tylko podklasa”.

To powiedziawszy, po raz kolejny masz kontrolę nad tym, jakie klasy istnieją w pakiecie. Możesz po prostu nie używać chronionych metod lub zmiennych.


źródło
3
Czy oprócz niektórych zarezerwowanych pakietów systemowych nie mogę dodać klasy do żadnego pakietu, nawet do jednego z nich, do którego nie mam zamiaru dodawać klas?
David Moles,
@David IIRC tak, ale nie pozwoli ci uzyskać dostępu do pól pakietu z innego pliku JAR, więc nawet jeśli umieścisz go w tym samym pakiecie, jeśli jest on w innym pliku JAR, nie będziesz mieć do niego dostępu. Jeśli jednak masz na myśli ten sam plik JAR, to tak, możesz uzyskać do niego dostęp, ale jeśli możesz modyfikować dany plik JAR, równie łatwo możesz zmienić modyfikator dostępu.
Pokechu22,
1
@ Pokechu22 Myślę, że musisz potwierdzić pieczęć JAR, aby uzyskać tę ochronę, ale dobra uwaga.
David Moles