2009-08-28 11 views
12

Tengo dos preguntas sobre el códigoConfundir "reemplazar un método privado"

public class Override { 
    private void f() { 
     System.out.println("private f()"); 
    } 
    public static void main(String[] args) { 
     Override po = new Derived(); 
     po.f(); 
    } 
} 

class Derived extends Override { 
    public void f() { 
     System.out.println("public f()"); 
    } 
} 

/* 
* Output: private f() 
*/// :~ 

1) ¿Cómo es la función f es visible en la referencia de po de anulación;

2) ¿Por qué es la salida "f privada()"

+0

¿Pero cómo una referencia con un objeto de subclase puede llamar a un método privado de una súper clase? ¿Es esto un error? –

+0

No, esto no es un error, esto es exactamente como debería funcionar. – Jesper

+0

pero no está violando las reglas de herencia y vinculación tardía –

Respuesta

24
  1. main El método está dentro de la clase Override, por lo que por supuesto se puede ver a los miembros privados de la clase Override.

  2. Estás no método sobrescrito f en clase Derived, no hay polimorfismo. El tipo de la variable po es Override, por lo que tomará el método f de la clase Override.

Tenga en cuenta que el método f en clase Override no es visible en absoluto en la clase Derived. El método f en la clase Derived es un método diferente, que no tiene nada que ver con el método f en la superclase.

+0

Pero cuando la vinculación se realiza en tiempo de ejecución, entonces po tendrá el objeto de la clase Derivada, por lo que es capaz de llamar a un método privado de superclase. –

+3

En ninguna parte de su código hay una llamada a un método privado de una superclase. Cuando llama a po.f(), se llama a f de Override porque el tipo de po del tiempo de compilación es Override. Como no hay anulación, no hay enlace dinámico (no polimorfismo): Java no mira el tipo en tiempo de ejecución. – Jesper

2
Override po = new Derived(); 
po.f(); 

Usted está accediendo propio método de anulación incluso si el objeto se deriva porque según reglas de ámbito, los miembros privados de la clase se consideran en primer lugar, y como su escrito en el alcance de la anulación se hace referencia a la f privada, y dado que no se sobrescribe su clase privada en Clase derivada, solo prevalecerá si la firma del método es la misma.

Derived po = new Derived(); 
po.f(); 

THSI es el código correcto que la llamada de Derivado f

+0

La pregunta es sobre Java, no C#. 'virtual' no existe en Java. – Jesper

+0

Gracias por sus comentarios, arreglé el contestador también. –

0

La anulación de método tiene tres deben clase conditions.child tiene el mismo nombre y los parámetros y el valor devuelto como su súper class.But si tanto de el parámetro y el valor devuelto se varían, por lo que no es existir la anulación incluso si los dos son método método diferente bien como esto:!!!

public class Parent { 
      public int addV(int a,int b){ 
     int s; 
     s = a + b; 
     return s; 
    } 
} 

class Child extends Parent{ 
    public void addV(){ 
     //do...something 
    } 
} 

Eclipse no va a hablar de errores! porque el método addV en la clase Child es diferente con el método addV en la clase Parent. ¡Como tu instancia!

+0

Solo el nombre del método y la lista de argumentos deben ser exactamente iguales. El valor de devolución del hijo podría ser la subclase del valor de retorno del padre. Y hay dos reglas más que ha omitido. El método en el niño debe ser al menos tan accesible como el del padre. Y la subclase no puede arrojar una nueva excepción comprobada ni otras más amplias. – pkkoniec

Cuestiones relacionadas