[Java] Geschützte Methoden können nicht immer innerhalb einer Unterklasse aufgerufen werden

Überblick

Einer der Java-Zugriffsmodifikatoren ist geschützt. Haben Sie jemals von geschützt als "nur innerhalb desselben Pakets und von Unterklassen zugänglich" gehört? Ich werde Ihnen sagen, dass diese Art von Verständnis zu Missverständnissen führen kann.

Ich glaube nicht, dass es eine besondere Verwirrung über den Zugriff innerhalb desselben Pakets gibt, daher werde ich nur den Zugriff von Unterklassen erwähnen.

Zielgruppe

Java Anfänger

Umgebung

Ich habe den Vorgang mit Java11 überprüft, aber ich denke, dass der Inhalt auch bei älteren Versionen nicht besonders unterschiedlich ist.

Beispiele, die nicht funktionieren

Mit dem Verständnis, dass es "von Unterklassen aus zugänglich" ist, scheint der folgende Beispielcode zu funktionieren, führt jedoch tatsächlich zu einem Kompilierungsfehler. (Bitte vergib mir den Namenssinn ...)

package test.sp;

public class Super {
    protected void method() {
        System.out.println("Super#method() called.");
    }
}
package test.sub;
import test.sp.Super;

public class Sub extends Super {
    public static void main(String[] args) {
        Sub sub = new Sub();
        sub.run();
    }

    private void run() {
        Super sp = new Super();
        sp.method();  //Error: method()Ist durch Super geschützt
    }
}

Es gibt eine Super-Klasse mit einer protected method () -Methode und eine Sub-Klasse, die von dieser Super-Klasse erbt. Die Super-Klasse und die Sub-Klasse befinden sich in separaten Paketen. Da die Sub-Klasse jedoch von der Super-Klasse erbt (die Sub-Klasse ist eine Unterklasse der Super-Klasse), kann die method () -Methode von der Sub-Klasse aufgerufen werden. Es scheint zu geben. Der obige Code führt jedoch zu einem Kompilierungsfehler.

Beispiele, die funktionieren

package test.sp;

public class Super {
    protected void method() {
        System.out.println("Super#method() called.");
    }
}
package test.sub;
import test.sp.Super;

public class Sub extends Super {
    public static void main(String[] args) {
        Sub sub = new Sub();
        sub.run();
    }

    private void run() {
        // (1)
        Sub sub = new Sub();
        sub.method();

        // (2)
        this.method();

        // (3)
        method();

        // (4)
        super.method();
    }
}

Diesmal funktioniert es, aber die Super-Klasse und die Beziehung zwischen der Super-Klasse und der Sub-Klasse haben sich nicht geändert, nur die Art und Weise, wie sie von der Sub-Klasse aufgerufen werden. Es gibt (1) bis (4), aber alle kompilieren und arbeiten zur Laufzeit fehlerfrei.

// (1)
Sub sub = new Sub();
sub.method();

(1) Erstellt explizit eine Instanz der Unterklasse und ruft die Methode () für diese Instanz auf. Ich habe einen Kompilierungsfehler mit einer Instanz der Super-Klasse erhalten, aber es scheint, dass es kein Problem mit einer Instanz der Sub-Klasse gibt.

// (2)
this.method();

// (3)
method();

(2) ist ein Anruf damit. Das funktioniert auch. (3) ist im Wesentlichen dasselbe wie (2), außer dass die Beschreibung davon weggelassen wird. Da dies auf eine eigene Instanz verweist, ist es für alle (1) bis (3) in dem Sinne gleich, dass es method () der Subklasseninstanz aufruft.

// (4)
super.method();

(4) unterscheidet sich geringfügig von (1) bis (3). (4) ruft super method () auf, was auch funktioniert. super bezieht sich auf eine Instanz der Oberklasse (mit sich selbst verbunden). Als ich explizit eine Instanz der Super-Klasse erstellt und method () für diese Instanz aufgerufen habe, ist ein Kompilierungsfehler aufgetreten, aber wenn es super ist, gibt es kein Problem. Ich dachte, dass sie sich gleich verhalten würden, weil sie alle Instanzen der Superklasse sind, aber die Ergebnisse waren etwas überraschend.

Zusammenfassung

Für geschützte Methoden ist die Sichtbarkeit von Unterklassen, die in einem anderen Paket definiert sind, wie folgt.

Serpentin

Möglicherweise werden Methoden angezeigt, die geschützt zu sein scheinen, um sie nur innerhalb desselben Pakets aufrufbar zu machen. In diesem Fall sollten Sie jedoch das Paket private (kein Modifikator) anstelle von protected verwenden. Ich benutze nicht persönlich geschützt. (Vielleicht verstehst du nicht, wie man es benutzt ...)

Recommended Posts

[Java] Geschützte Methoden können nicht immer innerhalb einer Unterklasse aufgerufen werden
Die geänderte Funktion von kotlin kann nicht von Java aus aufgerufen werden.
jsf.ajax.request: Die Methode muss innerhalb eines Formulars aufgerufen werden
Java Stream kann nicht wiederverwendet werden.
Führen Sie eine Batchdatei von Java aus
Greifen Sie über eine Java-Anwendung auf Teradata zu
Java soll ab heute dabei sein
Java kann unter Ubuntu 13.04 nicht installiert werden
Java-Code, der nicht von Kotlin verwendet werden kann (für interne Lernsitzungen)