2012-01-27 13 views
6

Tengo este error del compilador:No se puede reducir la visibilidad del método método heredado del padre

You cannot reduce the visibility of a inherited method.

tengo el siguiente código

class Parent {  
    public void func() { 
     System.out.println("in Parent"); 
    } 
} 

public class TestClass extends Parent {  
    public static void main(String args[]) { 
     parent obj=new TestClass(); 
     obj.addTest(); 
    } 

    private void func() { 
     System.out.println("in child");   
    } 
} 

Aquí clase padre tiene func() método que es público y anulado por el subclase TestClass que es privada. Ahora el compilador arroja el error de que no puedo reducir la visibilidad. Para decir técnicamente, cada vez que creo un objeto de TestClass asignando al objeto padre de tipo, ya que el método func() está anulado, el func() de TestClass se va a llamar siempre, entonces ¿por qué deberíamos cuidar la visibilidad? ¿Cuál es la razón detrás de este error? ¿Puede alguien explicarme claramente?

Respuesta

20

Es porque la subclase tiene visibilidad de private para el método void func(), pero la superclase tiene visibilidad public.

Si el código se le permitió compilar, que explotaría en tiempo de ejecución si se hizo esto:

parent p = new TestClass(); 
p.func(); // boom - func is public in parent, but TestClass's impl is private, so no access would be allowed 

para "arreglar" esto, hacer de la subclase func método public:

public class TestClass extends parent { 
    ... 
    public void func() { // give it public visibility 
     System.out.println("in child");   
    } 
} 


Y utilice las convenciones de nomenclatura estándar; en este caso "clases deben comenzar con una letra mayúscula" - es decir, no Parentparent

+0

Gracias Bohemain. Tengo el motivo. Gracias por señalar los estándares de nombres. – Mojoy

+0

Hola ... Esto me hace pensar ¿por qué no puedo tener el modificador protegido en clase para un método que es público en superclase? ¡Como se puede acceder al modificador protegido dentro del paquete y subtipos de cualquier paquete! – Mojoy

+0

los métodos 'protected' no son visibles para otras clases arbitrarias, pero el método' public' de super es así que se aplica el mismo razonamiento. * Cualquier * reducción en la visibilidad es un error. – Bohemian

11

De section 8.4.8.3 of the Java Language specification:

The access modifier (§6.6) of an overriding or hiding method must provide at least as much access as the overridden or hidden method, or a compile-time error occurs. In more detail:

  • If the overridden or hidden method is public, then the overriding or hiding method must be public; otherwise, a compile-time error occurs.
  • If the overridden or hidden method is protected, then the overriding or hiding method must be protected or public; otherwise, a compile-time error occurs.
  • If the overridden or hidden method has default (package) access, then the overriding or hiding method must not be private; otherwise, a compile-time error occurs.

Note that a private method cannot be hidden or overridden in the technical sense of those terms. This means that a subclass can declare a method with the same signature as a private method in one of its superclasses, and there is no requirement that the return type or throws clause of such a method bear any relationship to those of the private method in the superclass.

Después de todo, sólo se esperaría un método private a ser llamado por código dentro de la misma clase: si terminara siendo llamado debido a la anulación de un método público, eso sería bastante confuso.

2

Si se piensa en ello, al no ser capaz de hacer esto tiene sentido ..

La razón es que usted podría pasar el objeto infantil en todo como si fuera el padre uno (es decir, se puede utilizar el tipo de matriz como el tipo de referencia a una instancia de TestClass).

p. Ej.

parent p = new TestClass(); 

Hay tal vez algo de código en otro lugar que utiliza parent tipos y llama a este método:

por ejemplo,

public static void aMethod(parent aParent){ 
    p.func(); 
} 

Si fueron capaces de reducir la visibilidad del sistema, a continuación, llamar aMethod(p) tendría que tirar algún tipo de excepción en tiempo de ejecución - no permitir que esto asegura que esto no es necesario.

Cuestiones relacionadas