Pregunta

Acabo de recibir un error extraño que implica un modificador protegido.

Tengo el siguiente código:

package p1;

public class C1 {
    protected void doIt() {}
}


package p2;

public class C2 extends p1.C1 {
    private C1 c1_instance;
    public void doItAgain() {
        c1_instance.doIt(); // wtf!!!!
    }
}

Entiendo error, afirmando que doIt() ¡Tiene acceso protegido y no se puede acceder! Pero estoy en la subcase y tengo y tengo acceso a doIt() método.

¿No es un error?

¿Fue útil?

Solución

También tuve la impresión de lo que protected significaba "accesible desde el mismo paquete o desde una subclase" pero el Especificación del idioma Java Por supuesto, es más preciso, y explica que en una subclase S de C, "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 expresión Q es s o una subclase de S. "

Entonces solo puedes acceder a un protected Método de la superclase a través de una referencia a la subclase desde la que está llamando, como este:

public class C2 extends C1 {
    private C2 c2_other_instance;
    public void doItAgain() {
        c2_other_instance.doIt();
    }
}

Si explica por qué desea acceder a una instancia de la superclase desde una instancia diferente de la subclase, entonces alguien podría sugerir un mejor diseño. De lo contrario, tendrá que hacer el método public O ponga las clases en el mismo paquete.

Otros consejos

En Java, no puedes llamar protected métodos En un caso diferente de la clase base, incluso desde dentro de una subclase:

public class C2 extends p1.C1 {
    private C1 c1_instance;
    public void doItAgain() {
        doIt();             // fine
        c1_instance.doIt(); // disallowed
    }
}

La única excepción es cuando tanto la clase base como la subclase están en el mismo paquete.

Para citar el Tutorial de Java OO:

los protected El modificador especifica que el miembro solo se puede acceder dentro de su propio paquete (como con el paquete-privado) y, además, por una subclase de su clase en otro paquete.

Protegido es equivalente al acceso a nivel de paquete; No puede acceder al método si está en un paquete diferente.

Debería poder llamar doit () directamente sin pasar por el objeto C1_instance, sin embargo, ya que C2 es una subclase.

De http://download.oracle.com/javase/tutorial/java/javaoo/accesscontrol.html

"El modificador protegido especifica que solo se puede acceder al miembro dentro de su propio paquete (como con el paquete-privado) y, además, por una subclase de su clase en otro paquete".

C2 puede ser una subcase de C1, pero esto no significa que pueda acceder a esos métodos en una instancia diferente, es decir, C1_instance puede no ser una instancia de C2. Podría acceder a él si estuviera en el mismo paquete.

No, protected Asegura el acceso en el mismo paquete y en las clases descendientes. No está en el mismo paquete ni está accediendo directamente a una clase descendiente. C2 es un descendiente pero c1_instance no lo es.

Si su método se declara protegido, puede acceder a esto dentro de esta clase, con el paquete y dentro de la subclase.

Ahora, aquí está la pregunta, ¿por qué hay un error a pesar de acceder a este miembro protegido desde su subclase? La respuesta es acceder al método protegido desde una subclase que su subclase debe usar el método directamente desde la subclase directa. Aquí la subclase directa es C2 pero la instancia C1_Instance no lo es. Puede usar este método directamente (doit () en lugar de c1_instance.doit ())

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top