2012-10-12 77 views
5

Tengo algunas dudas con respecto al identificador protegido. En el primer capítulo de Sun Certified Java Programmer Study Guide por K.Sierra encontré la siguiente información:Comportamiento del miembro protegido una vez que se heredó.

"Una vez que la subclase-fuera del paquete hereda el miembro protegido, ese miembro (heredado por la subclase) se convierte en privado para cualquier código fuera de la subclase, con la excepción de las subclases de la subclase ".

He proporcionado un código de muestra que refleja la declaración anterior y es absolutamente claro para mí.

// Parent class 
package package1; 

import package2.Child; 
public class Parent { 

    protected int i = 5; 

} 

// Child class 
package package2; 

import package1.Parent; 

public class Child extends Parent { 

    // variable 'i' inherited 

} 


package package2; 

public class Neighbour { 

    public void protectedTesting(){ 
     Child child = new Child(); 
     System.out.println(child.i); // no access 
    } 
} 

Empecé a experimentar e hice un pequeño cambio: moví al vecino al paquete1. Y hay un acceso a la variable "i" que es un poco sorprendente para mí, ya que no es conforme a la declaración "se convierte en privado a cualquier código fuera de la subclase" clase

Vecino después del cambio:

package package1; 

import package2.Child; 

public class Neighbour { 

    public void protectedTesting(){ 
     Child child = new Child(); 
     System.out.println(child.i); // access! 
    } 
} 

Por favor, aclaremelo. Gracias.

Respuesta

5

En resumen, protected es paquete privado y visible para las subclases. Incluso el JLS es vago en este (JLS §6.6.2):

Un protected miembro o constructor de un objeto se puede acceder desde el exterior del paquete en el que se declara únicamente por el código que se encarga de la aplicación de dicho objeto.

Especifica que, fuera del paquete, solo las subclases pueden acceder a miembros protegidos. Esto implica que también puede acceder a la variable dentro del paquete. Es una redacción pobre, pero es cierto que los miembros protegidos tienen visibilidad a nivel de paquete , así como visibilidad de nivel de subclase.

Consulte también:

+0

Respuesta detallada y explicativa. – MrKiller21

1

La verdad no está en "Guía de Estudio de Certificado en Plataforma Java Programmer", pero en el Java Language Specification

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 código que es responsable de la implementación de ese objeto.

+0

Es cierto que el SCJPSG no es definitivo. Sin embargo, eso no lo hace incorrecto. Ver la respuesta de Nandkumar Tekale. –

+0

"Una vez que la subclase-fuera del paquete hereda el miembro protegido, ese miembro (heredado por la subclase) se convierte en privado PARA CUALQUIER CÓDIGO fuera de la subclase" - Personalmente, me parece incorrecto y engañoso. – MrKiller21

3

Y hay un acceso a la variable "i" que es un poco sorprendente para mí, ya que no está de acuerdo con la declaración "se convierte en privada para cualquier código fuera de la subclase"

-> Pero ha movido clase Neighbour en el paquete package1 que es cierto de acuerdo a "Protected members can be accessed by classes in same package"

"Una vez que la subclase-fuera-del-paquete hereda el miembro protegido, ese miembro (como heredado por la subclase) se convierte en privado para cualquier código fuera de la subclase, con la excepción de las subclases de la subclase ".

-> Dentro del paquete todavía está protegido y no es privado para todas las clases dentro del paquete.

+1

+1 - para explicar por qué el comportamiento observado por el OP es en realidad * consistente * con el libro de K. Sierra. –

1

protected visibilidad incluye visibilidad del nivel del paquete. Herencia le permite tratar su objeto Child como una instancia de Parent. Como el miembro i de Parent está declarado en el mismo paquete, se puede acceder desde Neighbour.

package package1; 

import package2.Child; 

public class Neighbour { 

    public void protectedTesting() { 
     Parent neighboured = new Child(); 
     System.out.println(neighboured.i); // access 
    } 
} 
Cuestiones relacionadas