Comprender el modificador protegido de Java
Tengo una clase llamada A en el paquete1 y otra clase llamada C en el paquete2. La clase C amplía la clase A.
A tiene una variable de instancia que se declara así:
protected int protectedInt = 1;
Aquí está el código para la clase A.
package package1;
public class A {
public int publicInt = 1;
private int privateInt = 1;
int defaultInt = 1;
protected int protectedInt = 1;
}
Y aquí está el código para la clase 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 subraya la última línea C.go()
y dice que "A.protectedInt" no está visible. Parece que esto entra en conflicto con la definición de la palabra clave "protegida", dado que la documentación de Oracle dice:
El modificador protected especifica que solo se puede acceder al miembro dentro de su propio paquete (como con paquete privado) y, además, mediante una subclase de su clase en otro paquete.
¿Que está pasando aqui?
¿Que está pasando aqui?
Has entendido mal el significado de protected
. Puede acceder a los miembros protegidos declarados desde A
dentro de C
, pero solo para instancias C
o subclases de C
. Consulte la sección 6.6.2 de JLS para obtener detalles sobre el acceso protegido. En particular:
Sea C la clase en la que se declara un miembro protegido. El acceso sólo está permitido dentro del cuerpo de una subclase S de C.
Además, si Id denota un campo de instancia o un método de instancia, entonces:
[...]
Si el acceso se realiza mediante una expresión de acceso al campo E.Id, donde E es una expresión primaria, o mediante una expresión de invocación de método E.Id(. . .), donde E es una expresión primaria, entonces el acceso está permitido si y sólo si el tipo de E es S o una subclase de S .
(El énfasis es mío).
Entonces este código estaría bien:
C c = new C();
System.out.println(c.publicInt);
System.out.println(c.protectedInt);
Dado que C
se hereda A
, C
puede usar directamente la protected
variable como se A
muestra a continuación
public class C extends A{
public void go(){
System.out.println(protectedInt);
}
}
Según su código, está creando una instancia A
y accediendo a protected
la variable a través de esa instancia , lo que viola la regla de Java: una variable protegida no es visible fuera del paquete
Protegido significa:
a) Este miembro será accesible para todas las clases en el mismo paquete a través de la referencia de un objeto.
b) Para paquetes diferentes, esto será accesible sólo dentro de las subclases de A, digamos B, y la referencia utilizada puede ser una instancia de B o de cualquier subclase de B.
Tomemos un ejemplo:
Sea A una clase principal en algún paquete, por ejemplo com.ex1
.
Sean B y C clases en diferentes paquetes relacionados con A, digamos com.ex2
. Además, B extends A
y C extends B
.
Veremos cómo podemos usar campos protegidos de A dentro de B (una subclase de A).
El código A:
public class A {
protected int a = 10;
}
El código 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 a 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 a subclass of B
}
}
código C:
public class C extends B {
}
Para estática protegida :
Se aplican las mismas reglas excepto que en b) ahora es accesible en cualquier subclase de A mediante la referencia de clase de A. Referencia