Dlaczego nie możemy zdefiniować klasy jako protected
?
Wiem, że nie możemy, ale dlaczego? Powinien być jakiś konkretny powód.
Dlaczego nie możemy zdefiniować klasy jako protected
?
Wiem, że nie możemy, ale dlaczego? Powinien być jakiś konkretny powód.
Odpowiedzi:
Bo to nie ma sensu.
Chroniony element członkowski klasy (metoda lub zmienna) jest podobny do prywatnego pakietu (domyślna widoczność), z tym wyjątkiem, że można uzyskać do niego dostęp również z podklas.
Ponieważ w Javie nie ma pojęcia „podpakiet” lub „dziedziczenie pakietu”, zadeklarowanie klasy chronionej lub pakietu prywatnego byłoby tym samym.
Możesz jednak zadeklarować klasy zagnieżdżone i wewnętrzne jako chronione lub prywatne.
open
w Kotlinie, który pozwala na tworzenie podklas poza bieżącym pakietem (można sobie wyobrazić protected
w Javie, który temu zapobiega, z przeciwnym domyślnym).
Jak wiesz, domyślnym jest dostęp na poziomie pakietu, a chroniony jest dla poziomu pakietu plus klasy niebędące pakietami, ale rozszerza tę klasę (należy tu zauważyć, że możesz rozszerzyć klasę tylko wtedy, gdy jest widoczna!). Ujmijmy to w ten sposób:
Ponieważ nie ma możliwości ograniczenia podklasy tej klasy tylko przez kilka klas (nie możemy ograniczyć dziedziczenia klasy przez tylko kilka klas ze wszystkich dostępnych klas w pakiecie / poza pakietem), nie ma zastosowania specyfikatorów dostępu chronionego dla klas na najwyższym poziomie. Dlatego nie jest to dozwolone.
public class A
{
protected class B
{
}
}
@Nikita Rybak odpowiedź ma dobre strony, ale brak szczegółów, nie mogę po prostu zrozumieć pomysłu bez głębokiego przemyślenia, oto co myślałem, a teraz powinienem całkowicie zrozumieć powód.
Cztery modyfikatory dostępu, załóżmy, że pierwszy poziom jest publiczny, a czwarty poziom prywatny (na podstawie tej tabeli w kolejności). Pierwszą rzeczą, którą powinniśmy wiedzieć, jest to, dlaczego klasa nie może być zdefiniowana jako prywatna na najwyższym poziomie.
Więc jeśli "private class foo" (zdefiniowany prywatny element członkowski, tj. Sama klasa jest członkiem) zezwala, jaka jest zewnętrzna (zawierająca element)? Zakres pliku? Nie, zewnętrzny plik jest bezcelowy, ponieważ nawet wiele klas w jednym pliku zostanie skompilowanych w oddzielne pliki klas. Więc na zewnątrz jest pakiet . Ale domyślny modyfikator dostępu trzeciego poziomu już oznacza „prywatny pakiet ”. Zatem modyfikator dostępu prywatnego czwartego poziomu nie będzie używany / dozwolony.
Ale zagnieżdżona klasa prywatna jest dozwolona, ponieważ bezpośrednia zewnętrzna jest klasą, a nie pakietem, np . :
class PrivateNestedMain {
private static class Inner {
public static void main(String[] args) {
System.out.println("Hello from Inner!");
}
}
}
A co, jeśli zezwala na to „chroniona klasa foo”? chronioną cechą główną jest podklasa, więc zewnętrzna (pakiet) POWINNA (ze względu na up-to zakres, ale nadal jest opcjonalna) podać styl podklasy , tj. sub-pakietu, lub package A extends package B
, ale nic takiego nie wiemy. Tak więc chroniony nie może wykorzystać pełnego potencjału (główny zakres obejmuje podklasę) na najwyższym poziomie, którym jest pakiet zewnętrzny (tj. Nie ma takiego pakietu podrzędnego), ale chroniony może wykorzystać pełny potencjał w zagnieżdżonej klasie, której zewnętrzna jest klasa ( czyli może być podklasą) :
class ProtectedNestedMain {
protected static class Inner {
public static void main(String[] args) {
System.out.println("Hello from Inner!");
}
}
}
Zwróć uwagę, że powyższe „nie może wykorzystać pełnego potencjału”, ponieważ nie może dotrzeć do całej podklasy tylko dlatego, że nie ma zewnętrznej podklasy, co oznacza, że faktycznie można zezwolić na ochronę , jest to tylko kwestia wyboru, aby uniknąć powielania zadania pakietu -private, jeśli zewnętrzna nie może mieć podklasy , patrz poniżej.
Moje zagubienie jest spowodowane głównie przez słynną tabelę na https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html :
Jeśli dozwolony jest poziom 1 (publiczny) i 3 poziom (pakiet prywatny), to jak u licha poziom pośredni (chroniony) jest niedozwolony?
podklasa wsparcia publicznego, tak łatwa do wprowadzenia w błąd. Prawidłowy sposób odczytania tej tabeli to
publiczna podklasa wsparcia, jeśli zewnętrzna ma funkcję podklasy.
To samo mylące dotyczy pakiet-prywatny, pakiet-prywatny nie obsługuje podklasy ( N w komórce) nie oznacza, że pojęcie podklasy ma zastosowanie w zewnętrznym.
Oznacza to, że powinniśmy zignorować kolumnę Subclass, jeśli funkcja podklasy nie jest dostępna w zewnętrznym:
Jak widzimy teraz, zarówno chroniony, jak i prywatny pakiet są teraz na tym samym poziomie ( YYN ), koniec z nieporozumieniami co do tego, dlaczego poziom pośredni jest niedozwolony. Ogólnie rzecz biorąc, Java wybiera tylko pakiet prywatny, a nie chroniony, aby uniknąć nieporozumień ( to tylko kwestia wyboru , ale główną cechą chronioną jest podklasa, więc pakiet prywatny jest lepszy), w wyniku czego dozwolone są tylko 2 modyfikatory dostępu na najwyższym poziomie:
Na najwyższym poziomie - publiczny lub prywatny pakiet (bez jawnego modyfikatora).
Zdefiniowanie chronionego pola sprawia, że to pole jest dostępne zarówno wewnątrz pakietu, jak i poza pakietem tylko poprzez dziedziczenie (tylko w klasie potomnej).
Więc jeśli możemy uczynić klasę chronioną, możemy bardzo łatwo uzyskać do niej dostęp wewnątrz pakietu, ale aby uzyskać dostęp do tej klasy poza pakietem, najpierw musimy rozszerzyć tę jednostkę, w której ta klasa jest zdefiniowana, która jest jej pakietem.
A ponieważ pakietu nie można rozszerzyć (można go zaimportować), zdefiniowanie klasy chronionej ponownie sprawi, że pakiet będzie prywatny, co jest podobne do zdefiniowania go jako domyślnego, co już możemy zrobić. Dlatego nie ma żadnej korzyści z definiowania klasy prywatnej, a jedynie sprawi, że rzeczy będą niejasne.
Aby uzyskać więcej informacji, przeczytaj Dlaczego zewnętrzna klasa Java nie może być prywatna ani chroniona
Chroniony nie jest podobny do publicznego. Protected ma zarówno dostęp na poziomie pakietu, jak i można uzyskać do niego dostęp spoza pakietów tylko przez dziedziczenie. ma chronione metody, ale podklasy wywodzące się z tej klasy, tj. A nie może uzyskać dostępu do metod chronionych .. odwrotnie dzieje się z publicznymi ..
Przykład:
package 2;
class B
{
protected void method1()
{
}
}
package 1;
import 2.B;
class A extends B
{
//can access protected method
}
class C extends A
{
//can't access the protected method
}
zachowanie „protected” = zachowanie „default” + „użyj go w dowolnej podklasie w dowolnym pakiecie”.
W każdym razie mamy domyślny modyfikator dostępu dla klasy, jedyną zaletą, jaką możemy uzyskać z modyfikatora dostępu chronionego jest: - użycie go w dowolnym pakiecie poprzez podklasy. Ale w przypadku podklasy widoczność „chronionej” klasy nadrzędnej byłaby prywatna. Więc nie można uzyskać do niego dostępu. Zasadniczo, jeśli masz chronioną klasę najwyższego poziomu, żadna klasa zewnętrzna nie może uzyskać dostępu przez tworzenie podklas. Tak chroniony dla klasy na najwyższym poziomie jest bez znaczenia.
Chroniony : WIDOCZNY tylko na poziomie pakietu *.
klasa jest zdefiniowana jako chroniona ---> nie można jej rozszerzyć z zewnątrz pakietu (niewidoczne).
A jeśli nie można go rozszerzyć, nie ma sensu utrzymywać go jako chronionego , ponieważ wtedy stanie się domyślnym dostępem, który jest dozwolony.
To samo dotyczy prywatnych klas zdefiniowanych.
Uwaga: Klasy zagnieżdżone lub wewnętrzne można zdefiniować jako chronione lub prywatne .
* : Przeglądaj chronione słowo kluczowe, w tej odpowiedzi zawarłem.
Odpowiedź od @ Akash5288 nie miała dla mnie sensu:
Jeśli wszystkie klasy mogą tworzyć podklasy, będzie to podobne do specyfikatora dostępu publicznego.
Ponieważ nie ma możliwości ograniczenia podklasy tej klasy tylko przez kilka klas (nie możemy ograniczyć dziedziczenia klasy przez tylko kilka klas ze wszystkich dostępnych klas w pakiecie / poza pakietem), nie ma zastosowania specyfikatorów dostępu chronionego dla klas na najwyższym poziomie. Dlatego nie jest to dozwolone.
Możesz następnie zastosować tę samą logikę do chronionych metod i zmiennych, są one również „podobne do publicznych”. Wszystkie klasy poza pakietem mogą rozszerzać naszą klasę publiczną i używać jej chronionych metod. Dlaczego ograniczanie metod i zmiennych do klas rozszerzonych jest w porządku, ale ograniczanie całej klasy nie jest w porządku? „Podobny do publicznego” nie jest „taki sam jak publiczny”. Moja interpretacja jest taka, że dopuszczenie klasy chronionej jest w porządku, podobnie jak dopuszczenie metod chronionych.
Odpowiedź „nie możesz rozszerzyć klasy, do której nie masz dostępu / nie widzisz” jest bardziej logiczna.
To, co ma sens w przypadku tego pytania, to fakt, że JVM jest napisane w C (Sun JVM) i C ++ (Oracle JVM), więc podczas kompilacji utworzymy pliki .class z naszego pliku java i jeśli zadeklarujemy klasę ze słowem kluczowym Protected wtedy JVM nie uzyska do niego dostępu.
Odpowiedź, dlaczego chroniona klasa nie będzie dostępna dla JVM, jest taka, że ponieważ chronione pola są dostępne w ramach tego samego pakietu lub do innego pakietu tylko poprzez dziedziczenie, a JVM nie jest napisana w taki sposób, że będzie dziedziczyć klasę. Mam nadzieję, że to odpowiada na to pytanie :)
Podobnie zajęcia najwyższego poziomu nie mogą być prywatne. Wyjaśnienie jak poniżej:
A więc co się stanie, jeśli zdefiniujemy klasę private, która będzie dostępna tylko w ramach encji, w której jest zdefiniowana, która w naszym przypadku jest jej pakietem?
Tak więc zdefiniowanie prywatnego dostępu do klasy sprawi, że będzie ona dostępna w tym samym pakiecie, co domyślne słowo kluczowe już dla nas robi. Dlatego nie ma żadnej korzyści z definiowania klasy prywatnej, tylko sprawi, że rzeczy będą niejednoznaczne.
chroniony oznacza, że do członka można uzyskać dostęp przez dowolną klasę w tym samym pakiecie i przez podklasy, nawet jeśli znajdują się one w innych pakietach.
Przykład:
package a;
class parent{
protected void p();
}
package b;
import a.p;
class child extends parent{
//you can access method which is protected in the parent in the child
}
class another extends child {
//here you can not access the protected method
}
jeśli klasa zewnętrzna jest zadeklarowana przez protected, myślę, że chcesz, aby dostęp do tej klasy był możliwy tylko z tego samego pakietu i jego podklasy, ale z różnych pakietów. Jednak nie ma możliwości tworzenia podklas dla klasy chronionej, ponieważ kiedy piszesz „class Dog extends Animal”, z powodu chronionej „Animal” można uzyskać dostęp tylko przez jego podklasę, oczywiście „Dog” nie jest podklasą „Animal” .
Tak więc chroniona klasa zewnętrzna jest taka sama jak (domyślna) klasa zewnętrzna!