Hilfe, um das Problem mit der geschützten Methode zu verstehen

9

Ich lese Sybex Complete Java 2 Certification Studienführer April 2005 (ISBN0782144195). Dieses Buch ist für Java-Entwickler gedacht, die eine Java-Zertifizierung bestehen möchten.

Nach einem Kapitel über Zugriffsmodifikatoren (zusammen mit anderen Modifikatoren) habe ich die folgende Frage (# 17) gefunden:

  

Wahr oder falsch: Wenn sich die Klasse Y ausdehnt   Klasse X, die beiden Klassen sind in   verschiedene Pakete und Klasse X hat eine   geschützte Methode namens abby ()   Jede Instanz von Y kann das Abby () aufrufen   Methode einer anderen Instanz von Y.

Diese Frage hat mich ein wenig verwirrt.

Soweit ich weiß, können Sie die geschützte Methode für jede Variable derselben Klasse (oder Unterklassen) aufrufen. Sie können es nicht auf Variablen aufrufen, die höher in der Hierarchie sind als Sie (z. B. implementierte Schnittstellen).

Sie können beispielsweise kein Objekt klonen, nur weil Sie es erben.

Aber die Fragen sagen nichts über den Variablentyp, nur über den Instanztyp.

Ich war ein wenig verwirrt und antwortete "wahr".

Die Antwort im Buch ist

  

Falsch. Ein Objekt, das eine geschützte Methode von einer Oberklasse in einem anderen Paket erbt, kann diese Methode für sich selbst, aber nicht für andere Instanzen derselben Klasse aufrufen.

Hier ist nichts über den Variablentyp, nur über den Instanztyp.

Das ist sehr seltsam, ich verstehe es nicht.

Kann jemand erklären, was hier vor sich geht?

    
zeroed 11.02.2010, 13:13
quelle

6 Antworten

2
  

Wahr oder falsch: Wenn die Klasse Y die Klasse X erweitert, befinden sich die beiden Klassen in unterschiedlichen Paketen und die Klasse X hat eine geschützte Methode namens abby (). Dann kann jede Instanz von Y die abby () -Methode einer anderen Instanz aufrufen von Y.

     

"Falsch. Ein Objekt, das eine geschützte Methode von einer Oberklasse in einem anderen Paket erbt, kann diese Methode für sich selbst, aber nicht für andere Instanzen derselben Klasse aufrufen."

Lassen Sie uns das niederschreiben, wie BalusC did, und füge zu Y eine Methode hinzu, die abby () von jeder anderen Instanz von Y aufruft:

%Vor%

Es ist möglich, dass Y die abby () - Methode einer beliebigen Instanz von Y aufruft, auf die es eine Referenz hat. Die Antwort im Buch ist also offensichtlich falsch. Java verfügt nicht über instanzspezifische Bereiche (im Gegensatz zu Scala mit einem instance-privaten Bereich).

Wenn wir versuchen, barmherzig zu sein, bedeutet vielleicht die Frage, indem wir " any andere Instanz von Y" sagen, dass sie auf die Methode von zugreifen kann, die zufällig in Erinnerung ist - was nicht möglich ist, weil Java keinen direkten Speicherzugriff hat. Aber in diesem Fall ist die Frage so schlecht formuliert, dass Sie sogar antworten könnten: "Falsch. Sie können Methoden nicht auf Instanzen aufrufen, die sich auf einer anderen JVM befinden, oder Instanzen, die Garbage Collected gesammelt haben, oder Instanzen auf einer JVM, die gestorben ist vor einem Jahr usw. "

    
Esko Luontola 11.02.2010, 13:59
quelle
1

Aus Die Java-Sprachspezifikation :

6.6.2.1 Zugriff auf ein geschütztes Mitglied

Sei C die Klasse, in der ein geschütztes Member m deklariert ist. Zugriff ist nur innerhalb des Körpers einer Unterklasse S von C erlaubt. Wenn Id ein Instanzfeld oder eine Instanzmethode bezeichnet, dann gilt:

  • Wenn der Zugriff über einen qualifizierten Namen Q.Id erfolgt, wobei Q ein ExpressionName ist, ist der Zugriff nur zulässig, wenn der Typ des Ausdrucks Q S oder eine Unterklasse von S ist.
  • Wenn der Zugriff durch einen Feldzugriffsausdruck E.Id, wobei E ein primärer Ausdruck ist, oder durch einen Methodenaufrufausdruck E.Id (...), wobei E ein primärer Ausdruck ist, dann ist der Zugriff zulässig wenn und nur wenn der Typ von E S ist oder eine Unterklasse von S.

So ist das geschützte Mitglied in allen Instanzen von S zugänglich, und die Antwort in Ihrem Buch ist einfach falsch.

    
starblue 11.02.2010 19:37
quelle
0

Diese Frage scheint schlecht formuliert zu sein - und fragt nach einem sehr seltenen Randfall (von dem ich nicht einmal sicher bin, dass er im SCJP-Test behandelt wird). Die Art, wie es formuliert ist, macht deine Antwort richtig und die gegebene Antwort falsch. Ein ähnliches Konstrukt zu codieren und es leicht auszuführen beweist das ...

%Vor%     
Nate 11.02.2010 13:36
quelle
0

Weil der Variablentyp hier irrelevant ist, bis er im Kontext der Frage "vernünftig" ist. Da die Methode abby() zu X gehört (und Y erbt sie), spielt es keine Rolle, mit welchem ​​Typ die Variable referenzierende Instanz von Y deklariert wird: sie kann entweder X oder Y sein. Be abby() zugänglich, wir könnten es durch beide Variablen nennen:

%Vor%     
Rorick 11.02.2010 13:36
quelle
0
  

Wahr oder falsch: Wenn die Klasse Y die Klasse X erweitert, befinden sich die beiden Klassen in unterschiedlichen Paketen, und die Klasse X hat eine geschützte Methode namens abby (). Dann kann jede Instanz von Y die abby () -Methode einer anderen Instanz aufrufen von Y.

Lass es uns zeigen.

Klasse X:

%Vor%

Klasse Y:

%Vor%

Testfall:

%Vor%

Lies nun die Frage erneut: Kann y1 call abby() auf y2 , y3 usw.? Ruft% ce_de% auf abby() auch die von y1 , y2 usw.?

Bei zukünftigen Fragen versuchen Sie, Stift und Papier zu greifen und die Fragen wörtlich zu interpretieren. Es gibt ziemlich viele Löcher in solchen Fragen.

    
BalusC 11.02.2010 13:27
quelle
0

Ich bin mir fast sicher, dass die Frage bedeutete:

"Jede Instanz von Y kann die abbey () -Methode einer anderen Instanz von X " aufrufen (nicht Y).

In diesem Fall wird es tatsächlich fehlschlagen. Um das Beispiel von einer anderen Antwort oben zu leihen, das folgende:

%Vor%

wird nicht kompiliert.

Die Java-Sprachspezifikation erklärt warum hier: Ссылка

  

6.6.2.1 Zugang zu einem geschützten Mitglied

     

Sei C die Klasse, in der a   Geschütztes Mitglied m ist deklariert. Zugriff   ist nur innerhalb des Körpers eines erlaubt   Unterklasse S von C. Zusätzlich, wenn Id   bezeichnet ein Instanzfeld oder eine Instanz   Methode, dann: Wenn der Zugriff von a ist   qualifizierter Name Q.Id, wobei Q ein ist   ExpressionName, dann ist der Zugriff   zulässig, wenn und nur wenn der Typ von   der Ausdruck Q ist S oder eine Unterklasse von   S. Wenn der Zugriff über einen Feldzugriff erfolgt   Ausdruck E.Id, wobei E eine Primäre ist   Ausdruck oder durch einen Methodenaufruf   Ausdruck E.Id (...), wobei E ein ist   Primärer Ausdruck, dann ist der Zugriff   nur dann erlaubt, wenn der Typ von E   ist S oder eine Unterklasse von S. (Hervorhebung von mir).

    
Dean Povey 09.03.2010 03:34
quelle