2011-08-18 18 views
7

Estoy leyendo Thinking In Java en este momento y me encontré con un pequeño problema. Estoy haciendo el ejercicio 12 del capítulo 8.Java inner class and inheritance

Cree una interfaz con al menos un método, en su propio paquete. Crea una clase en un> paquete separado. Agregue una clase interna protegida que implemente la interfaz. En un tercer paquete, herede de su clase y, dentro de un método, devuelva un objeto de la clase interna protegida, upcasting a la interfaz durante la devolución.

lo que he creado estos archivos .java:

A.java

package c08; 
    public interface A 
    { 
     void one(); 
    } 

Pr2.java

package c082; 
    import c08.*; 
    public class Pr2 
    { 
     protected class InPr2 implements A 
     { 
      public void one() {System.out.println("Pr2.InPr2.one");} 
      protected InPr2() {} 
     } 
    } 

Ex.java

package c083; 
    import c082.*; 
    import c08.*; 
    class Cl extends Pr2 
    { 
     A foo() 
     { 
      InPr2 bar=new InPr2(); 
      return bar; 
     } 
    } 

Y mi IDE NetBeans subraya

InPr2(); 

y dice que: InPr2() ha protegido el acceso en C082.Pr2.InPr2 y me pregunto por qué. Si no declarara explícitamente que el constructor en InPr2 debería estar protegido, solo sería accesible en el paquete C082, pero cuando herede la clase Pr2 no debería estar disponible en la clase Cl, porque InPr2 está protegido? Todo está bien cuando cambio de constructor a público.

+2

posible duplicado de [No se puede acceder a la clase interna protegida, mientras que hereda] (http://stackoverflow.com/questions/1487734/cant- access-protected-inner-class-while-inheriting) – Kal

Respuesta

2

Debería funcionar bien tal como lo tiene, excepto al cambiar protected InPr2() {} por public InPr2() { }. En otras palabras, "cualquiera puede crear una instancia de esta clase SI pueden ver la clase para empezar".

+0

Eso es cierto, pero en excersise dice que debería proteger esta clase interna, y me preguntaba por qué después de heredar y hacer que el constructor esté protegido no funciona. – Andrew

+0

Porque el acceso a la clase tiene un alcance de 'aquellos con acceso protegido a 'Pr2''. Esto incluye 'C1' porque extiende' Pr2'. El constructor dentro de 'InPr2', sin embargo, está disponible solo para' aquellos con acceso protegido a 'InPr2', que en este momento solo es' InPr2' y 'Pr2'. ¿Esto tiene sentido? El acceso para usar la clase y usar el constructor tiene un alcance diferente. – corsiKa

4

El constructor de InPr2 está protegido, lo que significa que sólo las clases que heredan de InPr2 (noPr2) pueden llamarlo. Las clases que heredan de Pr2 pueden ver la clase Pr2, pero no pueden llamar a sus miembros protegidos, como el constructor protegido.

+1

Tiene sentido, tenía la impresión de que si heredé Pr2 automáticamente debería tener acceso a la clase protegida. – Andrew

+0

@Andrew: Sí, así que creo que C1 debería poder ver la _clase_ 'InPr2', ya que' InPr2' es un miembro protegido de 'Pr2'. El constructor, sin embargo, no es miembro de 'Pr2'. – RustyTheBoyRobot

1

A pesar de que la clase InPr2 es accesible en Cl, su constructor no es. Un constructor protegido solo es accesible para subclases y clases en el mismo paquete.

0

Cambio:

Pr2.java

package c082; 
import c08.*; 
public class Pr2 
{ 
    protected class InPr2 implements A 
    { 
     public void one() {System.out.println("Pr2.InPr2.one");} 
     // This constructor was available only 
     // to a class inheriting form Pr2.InPr2 - protected InPr2() {} 
     public InPr2() {} 
    } 
} 

El constructor de Pr2.InPr2 era sólo disponible para una clase si se extendió Pr2.InPr2.

-1

no se puede proteger ninguna clase en Java.

+1

¿Puedes explicar un poco tu respuesta ...? – NREZ

0

Las variables, métodos y constructores de miembros protegidos no son accesibles fuera del paquete a menos que se hereden. Cuando intentamos crear un objeto de InPr2, el compilador mostrará un error ya que el constructor protegido no es accesible fuera del paquete. La creación de un objeto también depende del modificador de acceso del Constructor.

Usted puede hacer una cosa: InPr2 puede ser heredada dentro de la clase C.