Zum Inhalt springen

Problem mit Java - Zugriffmodifikator protected


kurtchen

Empfohlene Beiträge

Hallo liebe Forumsteilnehmer,

ich hatte ja schon mal gepostet, dass ich zur Zeit versuche, mir ein paar Java-Kenntnisse anzueignen, um vor dem Studium schon mal ein bisschen in den Stoff reinzuschnuppern. Aktuell beschäftige ich mich mit Vererbung. Und da habe ich jetzt ein Verständnisproblem. Vielleicht gibt es ja im Forum Studenten der Informatik (oder auch Absolventen), die mir da weiterhelfen können.

Bislang kannte ich die Zugriffsmodifikatoren "private" und "public". Nun habe ich neu "protected" kennengelernt. Ich habe das so verstanden, dass eine Methode, die als "protected" ausgezeichnet ist, von allen Subklassen einer Klasse aufgerufen werden kann, aber von anderen Klassen nicht. Ich habe dann verschiedene Beispiele durchprobiert, wo ich Methoden einer Klasse, die vormals "private" waren als "protected" ausgezeichnet habe. Und tatsächlich, ich konnte sie von Subklassen aus aufrufen. So weit so gut.

Nun wollte ich einmal ausprobieren, wie der Aufruf von einer anderen Klasse aus scheitert, hauptsächlich weil ich mal sehen wollte, was dann für eine Fehlermeldung ausgegeben wird. Und ob das schon beim Compilieren oder erst zur Laufzeit geschieht. Ich habe eine Klasse "Protected" geschrieben, mit einer Methode mit der Signatur "protected void meldungAusgeben()". Die Methode tut nichts weiter als per System.out.println() den String "I am protected." auf der Konsole auszugeben. Dann habe ich eine zweite Klasse "ProtectedTest" geschrieben. Die tut nichts weiter als in ihrer main-Methode die Methode "meldungAusgeben()" aus "Protected" aufzurufen. Zu meiner Überraschung klappt das tadellos und die Meldung wird auf der Konsole ausgegeben. Aber sollte so ein Aufruf nicht scheitern? (Man beachte: "ProtectedTest" ist keine Subklasse von "Protected".) Was ist dann überhaupt der Unterschied zwischen "public" und "protected"? Anscheinend habe ich grundsätzlich falsch verstanden, was der Zugriffsmodifikator "protected" macht. In welchen Fällen verhindert er denn nun den Zugriff?

Habe mich auch schon per Google umgeschaut, aber es immer wieder so verstanden, dass der Modifikator "protected" Subklassen den Zugriff ermöglicht und anderen Klassen nicht. Wo liegt mein Fehler?

Ich hoffe auf erhellende Hinweise.

Viele Grüße

Kurtchen

Link zu diesem Kommentar
Auf anderen Seiten teilen

Anzeige: (wird für registrierte Benutzer ausgeblendet)

Es kommt hier darauf an, in welchem Package die Klassen sich befinden. Wenn Du nichts weiter definiert hast (mit einem expliziten package Statement am Anfang der Datei), dann befinden sich die Klassen im Standard (default) Paket. Und aus Klassen im gleichen Paket heraus sind alle Methoden sichtbar, die nicht als private deklariert sind, d.h. public, protected oder ohne expliziten Zugriffsmodifizierer (default).

Siehe z.B. http://openbook.rheinwerk-verlag.de/javainsel/javainsel_05_002.html#dodtpfb5f7361-adc5-4f6d-bb52-c834da20b996

Link zu diesem Kommentar
Auf anderen Seiten teilen

Aha. Packages waren in meinem Buch noch nicht Thema. Der Link sieht interessant aus. Also ist es wohl so, dass meine beiden Klassen im gleichen Package liegen und deshalb alles public ist, was nicht als private deklariert wurde.

Dann muss ich mich jetzt wohl erst mal damit beschäftigen, was genau Packages sind.

Das scheint echt ein Problem mit OOP zu sein, dass man doch viele Konzepte kennen muss. Was lernt man in welcher Reihenfolge? Aber immerhin scheine ich in diesem Anlauf ganz gut voran zu kommen.

Vielen Dank, lippi.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Interessantes Thema!

Ich bin ja seit eh und je .NET-Entwickler und habe null Erfahrung mit Java. Und z. B. in C# gibt es einen Unterschied zwischen "protected" und "protected internal". Ist die Funktion nur protected, dann ist sie wirklich nur für die abgeleiteten Klassen sichtbar. Bei protected internal ist die Methode auch innerhalb der Assembly (also bei Java dann das Package) sichtbar. Gibt es solch eine Unterscheidung bei Java gar nicht? Was mache ich, wenn ich wirklich nur Subklassen die Methode zur Verfügung stellen möchte? Muss ich dann zwangsläufig diese Klassen in ein separates Package packen?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Die Frage von kawoosh ist klar formuliert. Eine Antwort würde mich auch interessieren. In meinem Lehrbuch heißt es dazu wörtlich: "Datenfelder und Methoden mit der Zugriffsstufe protected können innerhalb der Klasse selbst und von allen Subklassen benutzt werden, aber nicht von anderen Klassen." Hier folgt eine Fußnote: "In Java ist diese Regel nicht so eindeutig, wie hier beschrieben, da Java eine weitere Sichtbarkeitsstufe kennt, die Paketstufe genannt wird, aber nicht mit einem bestimmten Schlüsselwort verbunden ist. Wir werden hierauf nicht näher eingehen und Sie sollten im Allgemeinen davon ausgehen, dass die Zugriffsstufe protected der besonderen Beziehung zwischen Superklasse und Subklasse vorbehalten ist."

So ganz verstehe ich noch nicht, was damit gemeint ist. Ich werde jedenfalls jetzt erst mal die vorgeschlagenen Übungen zur Vererbung machen, um ein Gefühl für die Sache zu bekommen. Und hoffe, dass ich dann weiterführende Erklärungen verstehe. Die ja vielleicht auch von Forumsteilnehmern kommen können.

Es macht mir jedenfalls Spaß, objektorientierte Programmierung zu lernen. Ich habe mich schon lange gefragt, was es mit der Vererbung auf sich hat. Das klang so biologisch. Die Sache wird Schritt für Schritt klarer. Diese kleinen Erfolge motivieren mich. Ich entdecke ein Stück weit den Spaß wieder, den ich damals zu Schulzeiten an Pascal hatte. Mann, ist das lange her!

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also es gibt in Java vier Zugriffs-Modifier, nämlich public, private, protected und default. Letzterer wird durch kein Schlüsselwort gekennzeichnet, ist aber ein eigener Modifier, kein Kurzwort für einen anderen. Was die machen, wird Tabellenartig z. B. hier: https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html gezeigt. Das ist eindeutig, und ich verstehe nicht, warum Dein Lehrbuch hier ein Geheimnis macht. Einen Modifier, der nur in der Klasse und für Subklassen gilt, gibt es (wie aus der Tabelle ersichtlich) nicht. Nun werden sich gewissen Leute bestätigt sehen wie toll .NET ist und wie mies Java, aber es gibt bei den vier "Kategorien" Class, Package, Subclass, World ein Dutzend mögliche Kombinationen. Java hat dafür nur vier Modifier. Da sind eben nicht alle Kombinationen realisiert. Ehrlich gesagt habe ich noch nie was vermisst, und sollte man ernsthaft alle Möglichkeiten anbieten? Aber jedenfalls ist es alles eindeutig und klar definiert.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke stefhk3, für die Information. Das habe ich verstanden.

Mir geht es im Moment auch gar nicht darum, welche Programmiersprache die tollste ist. Ich versuche, Java zu lernen, weil ich gerne verstehen möchte, was objektorientierte Programmierung ist. Das scheint momentan das verbreitetste Paradigma zu sein, also möchte ich einmal grundsätzlich verstehen, was es damit auf sich hat. Ich nehme an, wenn man die Konzepte verstanden hat, ist es mit wesentlich geringerem Aufwand machbar, auch andere objektorientierte Sprache zu lernen. Gerade C# soll ja Java recht ähnlich sein.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja, das ist auch so. Ich empfinde C# eigentlich als einen Java-Clone (das gilt für die Sprache wie für das Konzept von Bytecode, VM usw.). Die Unterschiede sind eigentlich Details. C++ z. B. ist deutlich anders (wenn auch objektorientiert, man kann da schon was lernen, aber als Java-Programmierer kann man sich nach kurzer Lektüre zu den Unterschieden hinsetzen und programmieren, das geht in C++ eher nicht, insbesondere wenn man kein C kann).

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich wollte keinen Glaubenskrieg zwischen den Programmiersprachen auslösen, dafür habe ich von Java einfach zu wenig Ahnung. Mich interessiert eher das Doing in Java, wenn es keine Unterscheidung zwischen protected und protected internal gibt.

Was muss ich konkret machen, wenn eine Funktion wirklich nur für die erbenden Klassen sichtbar sein soll? Muss ich dann ein spezielles Package aufmachen? Oder hilft man sich mit Kommentaren, die darauf hinweisen, dass nur innerhalb einer Vererbungshierarchie die Funktion genutzt werden darf?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich weiß nicht, was sich die Java-Leute so gedacht haben, aber ich habe den Modifkator noch nicht vermisst. Letztlich sind all diese Sachen eh nur Hilfmittel, wirklich "geheim" ist da nicht, wenn jemand will, kommt er immer ran. Und insofern kann man ja die Dinger protected machen und wenn man wirklich eine Library oder so ausliefert, hat man eh ein eigenes Package. Dann haben dritte, die in anderen Packages arbeiten, ja erst mal keinen Zugriff. Aber ich muss zugeben, dass es mir als Problem noch nicht aufgefallen ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.




×
  • Neu erstellen...