web-dev-qa-db-fra.com

Comprendre le modificateur protégé Java

J'ai une classe appelée A dans package1 et une autre classe appelée C dans package2. La classe C étend la classe A.

A a une variable d'instance qui est déclarée comme ceci:

protected int protectedInt = 1;

Voici le code de la classe A

package package1;

public class A {

    public int publicInt = 1;
    private int privateInt = 1;
    int defaultInt = 1;
    protected int protectedInt = 1;

}

Et voici le code de la classe C:

package package2;
import package1.A;

public class C extends A{

    public void go(){
        //remember the import statement
        A a = new A();
        System.out.println(a.publicInt);
        System.out.println(a.protectedInt);

    }
}

Eclipse souligne la dernière ligne de C.go () et dit que "A.protectedInt" n'est pas visible. Il semble que cela entre en conflit avec la définition du mot-clé "protected", donnée dans la documentation Oracle.

Le modificateur protected spécifie que le membre n'est accessible que dans son propre package (comme avec package-private) et, en outre, par une sous-classe de sa classe dans un autre package.

Que se passe t-il ici?

37
mahela007

Que se passe t-il ici?

Vous avez mal compris la signification de protected. Vous pouvez accéder aux membres protégés déclarés dans A à partir de C, mais uniquement pour les instances de C ou les sous-classes de C. Voir section 6.6.2 du JLS pour les détails de l'accès protégé. En particulier:

Soit C la classe dans laquelle un membre protégé est déclaré. L'accès n'est autorisé qu'à l'intérieur du corps d'une sous-classe S de C.

De plus, si Id désigne un champ ou une méthode d'instance, alors:

  • [...]

  • Si l'accès se fait par une expression d'accès au champ E.Id, où E est une expression principale, ou par une expression d'appel de méthode E.Id (...), Où E est une expression primaire, l'accès est autorisé si et seulement si le type de E est S ou une sous-classe de S .

(Je souligne.)

Donc ça le code serait bien:

C c = new C();
System.out.println(c.publicInt);
System.out.println(c.protectedInt);
39
Jon Skeet

Puisque C hérite de A, C peut directement utiliser la variable protected de A comme ci-dessous

public class C extends A{

    public void go(){

       System.out.println(protectedInt);

    }
}

Selon votre code, vous créez une instance de A et accédez à la variable protected via cette instance , ce qui viole Règle Java - ne variable protégée n'est pas visible en dehors du package

11
sanbhat
 public void go(){
        //remember the import statement
        A a = new A();
        System.out.println(a.publicInt);
        System.out.println(a.protectedInt);

    }

Lorsque vous faites A a = new A(); et a.protectedInt Vous essayez d'accéder au membre protégé de A qui est illégal selon les normes Java

Au lieu de cela, vous pouvez faire this.protectedInt Directement.

3
Abhishek Singh

Protégé signifie:

a) Ce membre sera accessible à toutes les classes d'un même package via la référence d'un objet.

b) Pour un paquet différent, cela ne sera accessible qu'à l'intérieur des sous-classes de A disons B et la référence utilisée peut être l'instance B ou n'importe quelle sous-classe de B.

Prenons un exemple:

Soit A la classe parente dans un paquet, disons com.ex1 Soit B, C des classes dans un package différent w.r.t à A disons com.ex2. Aussi, B extends A et C extends B. Nous verrons comment utiliser le champ protégé de A à l'intérieur de B (une sous-classe de A)

Code de A:

public class A {
    protected int a = 10;
}

Code de B:

public class B extends A {


    public void printUsingInheritance() {
        // Using this
        System.out.println(this.a);
    }


    public void printUsingInstantiation() {
        // Using instance of B
        B b = new B();
        System.out.println(b.a);

        // Using instance of C as C is subclass of B
        C c = new C();
        System.out.println(c.a);


        A a = new A();
        System.out.println(a.a); // Compilation error as A is not subclass of B
    }
}

Code de C:

public class C extends B {

}

Pour Statique protégé :

Les mêmes règles s'appliquent sauf qu'en b) maintenant il est accessible dans n'importe quelle sous-classe de A par la référence de classe de A. Référence

2
Number945

Dans le même package où le membre protégé est déclaré, l'accès est autorisé:

package package1;

public class C extends A{
    public void go(){
        A a = new A();
        System.out.println(a.protectedInt);  // got printed 
        C c = new C();
        System.out.println(c.protectedInt);  // got printed as well
    }
}

En dehors du package où le membre protégé est déclaré, l'accès est autorisé si et seulement si par un code responsable de l'implémentation de cet objet. Dans ce cas, C est responsable de l'implémentation de cet objet, afin qu'il puisse accéder au protégé.

package package2;

public class C extends A{
    public void go(){
        A a = new A();
        System.out.println(a.protectedInt);  // compiler complains  
        C c = new C();
        System.out.println(c.protectedInt);  // got printed
    }
} 
1
Ethan

Pas besoin d'instancier la classe de protection dans la classe Protection2. Vous pouvez appeler directement la variable protégée sans instancier la classe Protection. Parce que la classe Protection2 étend la classe de protection. Donc variable héritée automatiquement par la sous-classe.

Essayez avec le code ci-dessous:

public class Protection2 extends Protection{
Protection2()
{System.out.println("n_pro = " +n_pro);
}}
1
Sugumar