różnica między modyfikatorami protected i package-private access w Javie? [duplikat]
To pytanie ma już odpowiedź tutaj:
- Jaka jest różnica między publicznym, chronionym, pakietem-prywatnym i prywatnym w Javie? 25 odpowiedzi
Widziałem różne artykuły na temat różnic między modyfikatorami protected i package private. Jedna rzecz znalazłem sprzeczne między tymi dwoma postami
-
Nie jest "package private" member access jest synonimem domyślnego (bez modyfikatora) dostępu?
W tym zaakceptowana odpowiedź mówi, że
Modyfikator protected określa, że członek może być dostępny tylko w jego własnym pakiecie (tak jak w pakiecie-private), a dodatkowo przez podklasę jego klasy w innym pakiecie.
-
Dlaczego modyfikator protected zachowuje się inaczej w podklasie Java?
W tym zaakceptowana odpowiedź mówi że
Aby zapewnić dostęp na poziomie chronionym, muszą być spełnione dwa warunki:
- klasy muszą być w tym samym pakiecie.
- musi istnieć związek dziedziczenia.
Jeśli to stwierdzenie jest poprawne, to dlaczego ten kod nie działa z following error message on my subclass Cat on line 17
The method testInstanceMethod() from the type Animal is not visible
Mój kod dla super i podklasy są poniżej.
package inheritance;
public class Animal {
public static void testClassMethod() {
System.out.println("The class" + " method in Animal.");
}
protected void testInstanceMethod() {
System.out.println("The instance " + " method in Animal.");
}
}
package testpackage;
import inheritance.Animal;
public class Cat extends Animal{
public static void testClassMethod() {
System.out.println("The class method" + " in Cat.");
}
public void testInstanceMethod() {
System.out.println("The instance method" + " in Cat.");
}
public static void main(String[] args) {
Cat myCat = new Cat();
Animal myAnimal = myCat;
myAnimal.testClassMethod();
myAnimal.testInstanceMethod();
}
}
Proszę wyjaśnić, dlaczego powyższy kod nie działa. To byłoby bardzo przydatne. Dzięki
3 answers
Pierwsza odpowiedź jest w zasadzie poprawna - protected
Członkowie mogą być dostępni przez
- klasy z tego samego pakietu
- podklasy klasy deklarującej z innych pakietów
Jest jednak mała sztuczka:
6.6.2 szczegóły dotyczące dostępu chronionego
Chroniony element lub konstruktor obiektu może być dostępny spoza pakietu, w którym jest zadeklarowany tylko przez kod odpowiedzialny za implementacja tego obiektu.
Oznacza to, że podklasa z innego pakietu nie może uzyskać dostępu do członków protected
arbitralnych instancji ich superklas, mogą uzyskać do nich dostęp tylko na instancjach własnego typu (gdzie type jest wyrażeniem typu compile-time, ponieważ jest to sprawdzenie w czasie kompilacji).
Na przykład (zakładając, że ten kod jest w Cat
):
Dog dog = new Dog();
Animal cat = new Cat();
dog.testInstanceMethod(); // Not allowed, because Cat should not be able to access protected members of Dog
cat.testInstanceMethod(); // Not allowed, because compiler doesn't know that runtime type of cat is Cat
((Cat) cat).testInstanceMethod(); // Allowed
Ma to sens, ponieważ dostęp do protected
członków Dog
przez Cat
może złamać niezmienniki Dog
, podczas gdy {[3] } może bezpiecznie uzyskać dostęp do swoich członków protected
, ponieważ wie, jak zapewnić własne niezmienniki.
Szczegółowe zasady:
6.6.2.1 dostęp do chronionego członka
Niech C będzie klasą, w której deklarowany jest chroniony element M. Dostęp jest dozwolony tylko w ciele podklasy S of C. Dodatkowo, jeśli Id oznacza pole instancji lub metodę instancji, to:
- Jeśli dostęp jest przez kwalifikowaną nazwę Q.Id, gdzie Q jest Nazwa wyrażenia, wtedy dostęp jest dozwolony wtedy i tylko wtedy, gdy typem wyrażenia Q Jest S lub podklasa S.
- jeśli dostęp jest wyrażeniem dostępu do pola E.Id, gdzie E jest wyrażeniem podstawowym, lub metodą wywołania wyrażenia E.Id ( ... ) .), gdzie E jest wyrażeniem podstawowym, wtedy dostęp jest dozwolony wtedy i tylko wtedy, gdy typem E jest S lub podklasa S.
6.6.2.2 kwalifikowany dostęp do chronionego konstruktora
Niech C będzie klasa, w której deklarowany jest chroniony konstruktor i niech s będzie najbardziej wewnętrzną klasą, w której deklaracji użycie chronionego konstruktora ma miejsce. Następnie:
- jeśli dostęp jest przez konstruktor superclass invocation super(. . .) lub przez wykwalifikowanego konstruktora superklasycznego wywołania postaci E. super(. . .), gdzie E jest wyrażeniem podstawowym, wtedy dostęp jest dozwolony.
- jeśli dostęp jest przez anonimowe wyrażenie tworzenia instancji klasy w postaci new C (. . .){...} lub przez kwalifikowane wyrażenie tworzenia instancji klasy w postaci E. new C(. . .){...}, gdzie E jest wyrażeniem podstawowym, wtedy dostęp jest dozwolony.
- W przeciwnym razie, jeśli dostęp jest przez proste wyrażenie tworzenia instancji klasy w postaci new C (. . .) lub przez kwalifikowane wyrażenie tworzenia instancji klasy w postaci E. new C(. . .), gdzie E jest wyrażeniem podstawowym, wtedy dostęp nie jest dozwolony. Do chronionego konstruktora można uzyskać dostęp za pomocą wyrażenia tworzenia instancji klasy (nie deklaruje anonimowej klasy) tylko z pakietu, w którym jest zdefiniowana.
Zobacz też:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-28 18:24:22
W protected access członkowie są dostępni w tym samym pakiecie, a dla dziedziczonego członka klasy w innym pakiecie również mogą być dostępni.
W pakiecie access można uzyskać dostęp do członków klas w tym samym pakiecie. Członkowie klasy w innych pakietach nie mogą być dostępni w pakiecie access.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-10 18:45:48
Stworzyłeś instancję kota i wrzuciłeś ją do super klasy, tj. typu zwierzęcia. Zgodnie z typem zwierzęcia jego testInstanceMethod jest widoczny w tym samym opakowaniu lub dowolnym podtypie. Jeśli nie wrzuciłeś do Animal wpisz kod zostanie skompilowany.
Hope that helps
./ Arun
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-28 18:28:00