[Java] Les méthodes protégées ne peuvent pas toujours être appelées depuis une sous-classe

Aperçu

L'un des modificateurs d'accès de Java est protégé. Avez-vous déjà entendu parler de protected comme "accessible uniquement dans le même package et à partir de sous-classes"? Je vais vous dire que ce genre de compréhension peut conduire à des malentendus.

Je ne pense pas qu'il y ait de confusion particulière sur l'accès à partir du même package, donc je ne mentionnerai que l'accès à partir des sous-classes.

Public cible

Débutant Java

environnement

J'ai vérifié le fonctionnement avec Java11, mais je pense que le contenu n'est pas particulièrement différent même avec les anciennes versions.

Exemples qui ne fonctionnent pas

Étant donné qu'il est «accessible à partir des sous-classes», l'exemple de code ci-dessous semble fonctionner, mais il entraîne en fait une erreur de compilation. (Veuillez me pardonner pour le sens du nom ...)

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();  //Erreur: method()Est protégé par Super
    }
}

Il existe une classe Super qui a une méthode method () qualifiée avec protected et une classe Sub qui hérite de cette classe Super. La classe Super et la classe Sub sont dans des packages séparés, mais comme la classe Sub hérite de la classe Super (la classe Sub est une sous-classe de la classe Super), il est possible d'appeler la méthode method () à partir de la classe Sub. Il semble y avoir. Cependant, le code ci-dessus entraînera une erreur de compilation.

Des exemples qui fonctionnent

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();
    }
}

Cette fois, cela fonctionne, mais la classe Super et la relation entre la classe Super et la classe Sub n'ont pas changé, seulement la façon dont elles sont appelées depuis la classe Sub. Il y a (1) à (4), mais tous compilent et fonctionnent sans aucune erreur lors de l'exécution.

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

(1) crée explicitement une instance de la classe Sub et appelle la méthode () pour cette instance. J'ai eu une erreur de compilation avec une instance de Super class, mais il semble qu'il n'y ait pas de problème avec une instance de Sub class.

// (2)
this.method();

// (3)
method();

(2) est un appel avec ceci. Cela fonctionne également. (3) est sensiblement le même que (2), sauf que la description de ceci est omise. Comme cela pointe vers sa propre instance, il en va de même pour tous les points (1) à (3) dans le sens où il appelle method () de l'instance de la classe Sub.

// (4)
super.method();

(4) est légèrement différent de (1) à (3). (4) appelle super method (), qui fonctionne également. super fait référence à une instance de la superclasse (associée à elle-même). Lorsque j'ai explicitement créé une instance de la classe Super et appelé method () pour cette instance, une erreur de compilation s'est produite, mais si c'est super, il n'y a pas de problème. Je pensais qu'ils se comporteraient de la même manière car ce sont tous des instances de la classe Super, mais les résultats étaient un peu surprenants.

Résumé

Pour les méthodes protégées, la visibilité des sous-classes définies dans un autre package est la suivante.

--Dans une sous-classe, vous pouvez l'appeler à partir d'une instance de la sous-classe elle-même qui a été explicitement créée par new. --Peut être appelé à partir de cela dans la sous-classe. La même chose s'applique lors d'un appel sans la description de ce --Peut être appelé depuis super dans la sous-classe

Serpentin

Vous pouvez voir des méthodes qui semblent protégées et qualifiées avec l'intention de ne pouvoir être appelées qu'à partir du même package, mais dans ce cas, vous devez utiliser package private (pas de modificateur) au lieu de protected. Je n'utilise pas protégé personnellement. (Peut-être que vous ne comprenez pas comment l'utiliser ...)

Recommended Posts

[Java] Les méthodes protégées ne peuvent pas toujours être appelées depuis une sous-classe
La fonction modifiée de kotlin ne peut pas être appelée depuis java.
jsf.ajax.request: la méthode doit être appelée dans un formulaire
Java Stream ne peut pas être réutilisé.
Exécuter le fichier de commandes à partir de Java
Accéder à Teradata depuis une application Java
Java sera impliqué dès aujourd'hui
Impossible d'installer Java sur Ubuntu 13.04
Code Java qui ne peut pas être utilisé depuis Kotlin (pour les sessions d'étude en interne)