privados - publico privado protegido java
Qué diferencia hay entre los modificadores de acceso protegidos y los paquetes privados en Java? (3)
Esta pregunta ya tiene una respuesta aquí:
He visto varios artículos sobre las diferencias entre los modificadores privados protegidos y de paquete. Una cosa que encontré contradictoria entre estas dos publicaciones.
¿El acceso "privado al paquete" no es sinónimo del acceso predeterminado (sin modificador)?
En esto la respuesta aceptada dice que
El modificador protegido especifica que solo se puede acceder al miembro dentro de su propio paquete (como con el paquete privado) y, además, mediante una subclase de su clase en otro paquete.
¿Por qué el modificador protegido se comporta de manera diferente aquí en la subclase Java?
En esto la respuesta aceptada dice que
Para satisfacer el nivel de acceso protegido se deben cumplir dos condiciones:
- Las clases deben estar en el mismo paquete.
- Debe haber una relación de herencia.
¿No son contradictorios? de mi comprensión de otros artículos, la primera publicación da la respuesta correcta que protege == paquete-privado + subclase en otro paquete.
Si esta declaración es correcta, entonces por qué este código falla con el siguiente mensaje de error en mi subclase Cat en la línea 17
The method testInstanceMethod() from the type Animal is not visible
mi código para super y subclase están abajo.
package inheritance;
public class Animal {
public static void testClassMethod() {
System.out.println("The class" + " method in Animal.");
}
protected void testInstanceMethod() {
System.out.println("The instance " + " method in Animal.");
}
}
package testpackage;
import inheritance.Animal;
public class Cat extends Animal{
public static void testClassMethod() {
System.out.println("The class method" + " in Cat.");
}
public void testInstanceMethod() {
System.out.println("The instance method" + " in Cat.");
}
public static void main(String[] args) {
Cat myCat = new Cat();
Animal myAnimal = myCat;
myAnimal.testClassMethod();
myAnimal.testInstanceMethod();
}
}
Por favor aclarar por qué el código anterior falla. Eso sería muy útil. Gracias
En el acceso protegido, se puede acceder a los miembros en el mismo paquete y también se puede acceder a los miembros de la clase heredados en otro paquete.
En el acceso al paquete se puede acceder a los miembros de las clases en el mismo paquete. No se puede acceder a los miembros de la clase en otros paquetes en el acceso al paquete.
Ha creado una instancia de Cat y la ha convertido en su tipo de superclase, es decir, tipo de animal. Según el tipo de animal, su testInstanceMethod es visible en el mismo paquete o en cualquier subtipo. Si no lanzaste al tipo Animal, el código se compilará.
Espero que ayude
./Arun
La primera respuesta es básicamente correcta: se puede acceder a los miembros protected
por
- clases del mismo paquete
- subclases de la clase declarante de otros paquetes
Sin embargo, hay un pequeño truco:
6.6.2 Detalles sobre acceso protegido
Se puede acceder a un miembro o constructor protegido de un objeto desde fuera del paquete en el que se declara solo por el código que es responsable de la implementación de ese objeto.
Significa que la subclase de otro paquete no puede acceder a miembros protected
de instancias arbitrarias de sus superclases, solo puede acceder a ellos en instancias de su propio tipo (donde tipo es un tipo de expresión en tiempo de compilación, ya que es un control en tiempo de compilación).
Por ejemplo (suponiendo que este código está en Cat
):
Dog dog = new Dog();
Animal cat = new Cat();
dog.testInstanceMethod(); // Not allowed, because Cat should not be able to access protected members of Dog
cat.testInstanceMethod(); // Not allowed, because compiler doesn''t know that runtime type of cat is Cat
((Cat) cat).testInstanceMethod(); // Allowed
Tiene sentido, porque el acceso de protected
miembros protected
de Dog
by Cat
puede romper invariantes de Dog
, mientras que Cat
puede acceder a sus propios miembros protected
forma segura, porque sabe cómo garantizar sus propios invariantes.
Reglas detalladas:
6.6.2.1 Acceso a un miembro protegido
Sea C la clase en la que se declara un miembro protegido m. El acceso está permitido solo dentro del cuerpo de una subclase S de C. Además, si Id denota un campo de instancia o método de instancia, entonces:
- Si el acceso es por un nombre calificado Q.Id, donde Q es un nombre de expresión, entonces el acceso está permitido si y solo si el tipo de la expresión Q es S o una subclase de S.
- Si el acceso es mediante una expresión de acceso de 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 solo si el tipo de E es S o una subclase de S.
6.6.2.2 Acceso calificado a un constructor protegido
Sea C la clase en la que se declara un constructor protegido y S sea la clase más interna en cuya declaración se produce el uso del constructor protegido. Entonces:
- Si el acceso es mediante una invocación del constructor de superclase super (...) o mediante una invocación del constructor de superclase calificado de la forma E.super (...), donde E es una expresión primaria, entonces se permite el acceso.
- Si el acceso es mediante una expresión de creación de instancia de clase anónima de la forma nueva C (...) {...} o mediante una expresión de creación de instancia de clase calificada de la forma E.new C (...) {... }, donde E es una expresión primaria, entonces se permite el acceso.
- De lo contrario, si el acceso es mediante una expresión de creación de instancia de clase simple de la forma nueva C (...) o mediante una expresión de creación de instancia de clase calificada de la forma E.new C (...), donde E es una expresión principal , entonces el acceso no está permitido. Se puede acceder a un constructor protegido mediante una expresión de creación de instancia de clase (que no declara una clase anónima) solo desde el paquete en el que está definido.
Ver también: