2011-04-12 15 views
13

Test.javaSustitución de métodos protegidos en Java

package a; 
import b.B; 
public class Test { 
    public static void main(String[] v) { 
     new A().test(); 
     new B().test(); 
    } 
} 

A.java:

package a; 
public class A { 
    protected void test() { } 
} 

B.java:

package b; 
public class B extends a.A { 
    protected void test() { } 
} 

¿Por qué new B().test() dará un error? ¿Eso no rompe las reglas de visibilidad?

B.test() es invisible en Test porque están en diferentes paquetes, y sin embargo, se niega a llamar a la test() en B 's superclase que es visible.

Se agradecerían los enlaces a la parte apropiada de JLS.

+1

"dará un error" .. ¿Puede ser más específico? – Jeremy

+2

@Kevin pregunta por qué no puede llamar a un método al que tiene acceso el súper método de. – corsiKa

+1

@Jeremy: se niega a compilar: "a/Test.java: 10: test() tiene acceso protegido en b.B" – CromTheDestroyer

Respuesta

12

Aquí tienes JLS en protected palabra clave: JLS protected description y JLS protected example.

Básicamente un modificador protected significa que se puede acceder campo/método/... 1) en una subclase de la clase dada y 2) de las clases en el mismo paquete.

Por 2) new A().test() obras. Pero new B().test() no funciona, porque la clase B está en un paquete diferente.

7

Así no es como funciona la herencia en Java.

Si se anula un método y el método reemplazado no está visible, es un error en tiempo de compilación intentar llamarlo.

Parece que espera que Java vuelva automáticamente al método en la superclase, pero eso no sucede.

Voy a tratar de excavar el JLS más tarde sobre por qué esto no se hace ...

7

El problema es que en tiempo de compilación le está diciendo a Java que desea tener acceso a un miembro protegido de una clase cuando no tienes ese acceso.

Si lo hizo en su lugar;

A a = new B(); 
    a.test(); 

entonces sería trabajar y el método reemplazado porque se ejecutará en tiempo de compilación de Java comprueba que tienes acceso a A. En tiempo de ejecución del objeto proporcionado tiene el método apropiado por lo que el método de prueba B() ejecuta. La vinculación dinámica o la vinculación tardía es la clave.

0

Sí, se puede anular el método protegido.

class A{ 
protected void f(){ 
SOP("A"); 
}} 
class B extends A{ 
protected void f(){ 
SOP("B"); 
} 
public static void main(String...args) 
{ 
B b=new B(); 
b.f(); 
} 
} 

Salida: B

Cuestiones relacionadas