2016-04-15 8 views
8
public class Test 
{ 
    static int i = 1; 

    static void m1() 
    { 
    } 
} 

class Test1 extends Test 
{ 
    int i = 1; //allowed 

    void m1()  // not allowed; Both are instance level, so why this difference? Both can be accessed with super keyword 
    { 
    } 
} 

Perché il metodo statico non può essere nascosto con la stessa firma, ma il campo statico può farlo? Entrambi sono a livello di istanza, quindi perché è consentito solo il campo statico?Assistenza di ereditarietà per nascondere il metodo e nascondere il campo

+1

[Here's non una risposta chiara, ma possibile indovinando che nasconde i metodi statici o vica versetto potrebbe portare a confusione] (http://stackoverflow.com/questions/14602220/why-doesnt-java-allow-hiding-static-methods-by-instance-methods) – SomeJavaGuy

risposta

8

m1() in classe Test è un metodo static, mentre m1() in Test1 è non statico. Ora immaginate se questo sarebbe stato permesso poi dell'attuazione verrebbe scelto da tempo di esecuzione quando si esegue sotto dichiarazione:

new Test1().m1(); 

Dal istanza della classe figlio (Test1 nel tuo caso) può accedere anche accedere metodo statico dalla classe genitore (da Test). Questo è il motivo per cui non è permesso.

Per voi prossima domanda perché variabile con lo stesso nome è consentito in Test1: variabile statica classe padre non si può accedere da un'istanza di classe del bambino. In altre parole lo stato statico della classe genitore è nascosto al bambino. Questo è

Test1.i; // compilation error, can't access parent's static variable 

comporterà un errore di compilazione. E se si tenta

new Test1().i; // will access Test1's i variable 

si punterà allo stato non genitore di classe figlio. Ecco perché la classe figlio può avere variabili con lo stesso nome.

Nota: Sei in Test era non statici, anche in quel caso Test1 può avere variabile con il nome i. In questo caso loin Test1 ombreggia lo i in Test.

EDIT

Da Shahaan Syed di comment:

new Test1().i; Perché questo è consentito è la mia preoccupazione

Per mettere confusione di Shahaan Syed In altre parole: Perché

  • in caso di variabili, classe figlia può avere una variabile non statico, mentre classe padre ha una variabile statica con lo stesso nome,
  • d'altra parte, la classe bambino non può avere un non-statica metodo quando la classe genitore ha un metodo statico con lo stesso nome?

Come Kevin Esche commented, penso anche che Java incasinato da qualche parte, consentendo l'accesso a static metodi della classe genitrice di istanza della classe figlio. Anche se non è una buona pratica e il compilatore genera anche un avvertimento.

Ecco un preventivo da (JLS §8.3):

A questo proposito, nascondere campi differisce da nascondere metodi (§8.4.8.3), poiché non v'è alcuna distinzione tra statico e non campi statici in campo nascosto mentre viene distinta una distinzione tra tra metodi statici e non statici in metodo nascosto.

Ma non ho trovato alcun ragionamento dietro questo in JLS.

Penso che invece di generare avviso ci dovrebbe essere stato errore di compilazione. Questo è l'accesso sia al campo static sia al metodo static della classe genitore dall'istanza della classe figlio, avrebbe dovuto essere un errore del compilatore. A questo riguardo le cose sarebbero state coerenti e facili da capire. Ma di nuovo è solo un mio pensiero.

Un'altra domanda interessante sulla stessa linea: Why isn't calling a static method by way of an instance an error for the Java compiler?

+4

Per aggiungere questa risposta, è molto probabile che ciò sia fatto per evitare confusione che ha la sua radice in una cattiva progettazione linguistica qui (essendo in grado di chiamare metodi statici su istanze di oggetti). – SomeJavaGuy

+0

@sudhir singh, ma lo stesso avrei detto per il nuovo Test1(). I; perché questo è permesso è il mio punto in questione. –

+2

@ShahaanSyed Perché a questo punto il linguaggio java è stato progettato male. Purtroppo questa è l'unica risposta plausibile qui. – SomeJavaGuy