2012-01-27 10 views
6

ho ottenuto questo errore di compilazione:non può ridurre la visibilità del metodo di metodo ereditato dal genitore

You cannot reduce the visibility of a inherited method.

ho il seguente codice

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");   
    } 
} 

Qui classe genitore ha func() metodo che è pubblico e sovrascritto dal sottoclasse TestClass che è privato. Ora il compilatore lancia l'errore che non riesco a ridurre la visibilità. Per dire tecnicamente, ogni volta che creo un oggetto di tipo assegnando al tipo oggetto genitore, poiché il metodo func() viene sovrascritto, funcClass di testClass verrà chiamato sempre, quindi perché dovremmo occuparci della visibilità? qual è la ragione di questo errore? Qualcuno può spiegarmi chiaramente?

risposta

20

È perché la sottoclasse ha la visibilità di private per il metodo void func(), ma la superclasse ha visibilità public.

Se il codice è stato permesso di compilare, che sarebbe esploso in fase di esecuzione, se avete fatto queste cose:

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

di "fissare" questo, fare della sottoclasse func metodo public:

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


E si prega di utilizzare convenzioni di denominazione standard; in questo caso "classi dovrebbero iniziare con una lettera maiuscola" - cioè Parent non parent

+0

Grazie Bohemain. Ho capito il motivo. Grazie per aver sottolineato gli standard di denominazione. – Mojoy

+0

Ciao .. Questo mi fa pensare perché non posso modificare il modificatore in classe figlio per un metodo che è pubblico in super-classe? Dal momento che è possibile accedere al modificatore protetto all'interno del pacchetto e dei sottotipi di qualsiasi pacchetto !! – Mojoy

+0

I metodi 'protected' non sono visibili ad altre classi arbitrarie, ma il metodo' public' del super è, quindi si applica lo stesso ragionamento. * Qualsiasi * riduzione della visibilità è un errore. – Bohemian

11

Da 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.

Dopo tutto, ci si aspetterebbe solo un metodo private per essere chiamato da codice all'interno la stessa classe - se finiva per essere chiamata a causa dell'override di un metodo pubblico, sarebbe piuttosto confuso.

2

Se ci pensate, non essendo in grado di fare questo ha senso ..

Il motivo è che si potrebbe passare l'oggetto figlio intorno come se fosse il genitore uno (ad esempio è possibile utilizzare il tipo di genitore come il tipo di riferimento a un'istanza TestClass).

ad es.

parent p = new TestClass(); 

C'è forse qualche codice che usa altrove parent tipi e chiama quel metodo:

esempio

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

Se tu fossi in grado di ridurre la visibilità del metodo quindi chiamando aMethod(p) avrebbe dovuto gettare un qualche tipo di eccezione di runtime - non permettere questo assicura questo non è richiesto.

Problemi correlati