Protected-Verhalten.

  • Hallo ich hab gerade ein kleines Problem in Java. Ich habe versucht zwischen 2 Klassen eine Abstrakte Klasse in der Hierachie einzufügen. Ich hab das Problem mal mit Dummy Klassen nachgestellt:

    davon erbt B

    Code
    package pack2;
    
    
    import pack1.A;
    
    
    public abstract class B extends A {
    
    
    }

    und zu guter letzt erbt hiervon C

    soweit funktioniert das ganze, wenn ich allerdings den Parameter Typen von C auf B ändere, was mehr oder minder der Sinn des ganzen war:

    unterwellt er mir im if das var.i mit der Meldung das i nicht visible sei.
    Nur das verstehe ich nicht, sowohl B und C erben von A was man ja auch daran sieht das this.i immer geht. Warum gehts aber mit var.i nicht?

    Einmal editiert, zuletzt von LordNecro (29. April 2010 um 11:53)

  • Wenn ich in einer Datei folgenden Code schreibe, funktioniert alles wie erwartet:

    Kann deinen Fehler also nicht ganz nachvollziehen. Nachdem aber jetzt dein Beispiel schon einen Fehler zu haben scheint, könnte es ja vielleicht auch in anderen Aspekten vom Original abweichen - vielleicht in etwas, das du als unwichtig übersiehst. Zeig mal den Original-Code her, dann lässt sich das Problem vielleicht erkennen.

  • Kann deinen Fehler also nicht ganz nachvollziehen. Nachdem aber jetzt dein Beispiel schon einen Fehler zu haben scheint, könnte es ja vielleicht auch in anderen Aspekten vom Original abweichen - vielleicht in etwas, das du als unwichtig übersiehst. Zeig mal den Original-Code her, dann lässt sich das Problem vielleicht erkennen.



    Du musst in der Parameterliste von doSomething den Typen von var auf B ändern, dann solltest den Fehler haben den ich nicht verstehe.

  • Wenn ich in einer Datei folgenden Code schreibe

    ... dann liegt alles in demselben Package. In LordNecros Beispiel ist aber A in pack1 und B und C sind in pack2.

    Hab mir jetzt schnell in der Java Language Specification die Regelungen zu "protected" angesehen, wirklich schlau werd ich daraus allerdings nicht.

  • Du musst in der Parameterliste von doSomething den Typen von var auf B ändern, dann solltest den Fehler haben den ich nicht verstehe.

    Habe ich jetzt gemacht, ändert nichts.

    ... dann liegt alles in demselben Package. In LordNecros Beispiel ist aber A in pack1 und B und C sind in pack2.

    Tut es. Die packages hat er ja als "Typo" bezeichnet, ich habe ihn so verstanden, dass doch alle Klassen im gleichen Paket liegen.

    Das Problem taucht auch nur auf, wenn man die Klassen in verschiedenen packages platziert. Das liegt daran, dass "protected" bedeutet, dass das Feld nur zu Subklassen im eigenen package hin sichtbar ist, nicht allgemein zu jeder erbenden Klasse hin.

    "protected" Felder sind zur Subklasse hin sichtbar, jedoch nur, wenn sie im gleichen package liegt. Wenn man packages als Module betrachtet, das nur über (public-)Schnittstellen kommunizieren sollte, dann ist das Verhalten durchaus sinnvoll.

  • Das Problem taucht auch nur auf, wenn man die Klassen in verschiedenen packages platziert. Das liegt daran, dass "protected" bedeutet, dass das Feld nur zu Subklassen im eigenen package hin sichtbar ist, nicht allgemein zu jeder erbenden Klasse hin.


    A liegt in package1, B und C liegen im package2. Dieser Aussage oben muss ich leider wiedersprechen. Wäre i nur im aktuellen Package sichtbar würden die geerbten Klassen ausserhalb des package1( also im package2) gar keinen member i haben. Den haben sie aber, wie man durch this.i ganz leicht erkennen kann.

  • Ich habe das Problem mittlerweile in nem Dokument von Java gefunden.
    http://java.sun.com/docs/books/jls…/names.doc.html

    Hier unter 6.6.7. Neues Problem an dem ganzen: Die Begründung ist für mich absolut nicht logisch, vieleicht kann mir das jemand irgendwie anschaulich machen.

    Die Quintessenz scheint zu sein, das der Parameter von der aufrufenden Klasse erben muss bzw die aufrufende Klasse ist.
    Und da B nicht von C erbt sondern umgekehrt gehts nicht.

    EDIT: ne das kanns auch nicht sein sonst ginge im 6.6.7 Bsp Wrap

    2 Mal editiert, zuletzt von LordNecro (29. April 2010 um 13:34)

  • Das Verhalten der Vererbungen und Rechte ist in Java tatsächlich recht kompliziert und unüberschaubar. Ich habe das Gefühl, dass ein Großteil der Komplexität daher kommt, dass die Sichtbarkeit bzw. Nicht-Sichtbarkeit im Gegensatz zu C++ auch auf Binary-Ebene greifen muss. In C++ kann man ja locker mal in einem Headerfile etwas von private auf public umstellen und damit eine Object-Datei compilieren, die auf das private Feld zugreift; das ganze linkt man dann mit dem restlichen, normal compilierten Code zusammen und hat damit die Zugriffskontrolle ausgehebelt. In Java geht das einfach nicht.

  • Das Verhalten der Vererbungen und Rechte ist in Java tatsächlich recht kompliziert und unüberschaubar.

    Die zahlreichen Belege dafür wären mir unbekannt. Hättest du Beispiele? Das von LordNecro beschriebene Problem ist noch das komplexeste, das ich bisher gesehen habe.

    Zitat

    In C++ kann man ja locker mal in einem Headerfile etwas von private auf public umstellen und damit eine Object-Datei compilieren, die auf das private Feld zugreift;

    An den Regeln selbst scheint das ja nichts zu ändern - und ob das ein Vorteil ist, sei dahingestellt: Wenn Sichtbarkeiten sich derart leicht umgehen lassen, dann ist es nicht weit her mit der Sicherheit.

  • Die zahlreichen Belege dafür wären mir unbekannt. Hättest du Beispiele? Das von LordNecro beschriebene Problem ist noch das komplexeste, das ich bisher gesehen habe.


    Also ich hab mir jetzt auch mal das Kapitel aus der langspec durchgelesen, und es klingt tatsächlich alles recht naheliegend und unkompliziert. Nachdem ich mit Java aber typischerweise eher auf der Bytecode-Ebene zu tun hatte, weiß ich von dort, dass es schon einige Überraschungen im Zusammenhang mit protected gibt, z.B. http://dow.ngra.de/2008/11/03/when-protected-isnt-protected/

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!