2015-11-02 8 views
5
class A {int x = 5;} 
class B extends A {int x = 10;} 
class D { 
    public static void main(String[] args){ 
     A b0 = new B(); 
     System.out.print(b0.x); 
    } 
} 

Mi chiedo il motivo per cui questo codice stampa 5 invece di 10.statico Instance Ricerca variabile Java

Se io invece scrivo quanto segue, convertendo le variabili x ai metodi, funziona più come mi aspetto, e stampa 10, poiché in fase di compilazione ha semplicemente controllato se il tipo statico di b0, A, ha un metodo x, e quindi in fase di esecuzione, usa il tipo dinamico di b0, B, per eseguire x.

class A {int x() {return 5;}} 
class B extends A {int x() {return 10;}} 
class D { 
    public static void main(String[] args){ 
     A b0 = new B(); 
     System.out.print(b0.x()); 
    } 
} 

mia teoria è che le variabili di istanza sono guardato fino staticamente a differenza di metodi, ma non sono sicuro sul perché sarebbe.

Grazie!

risposta

4

Nel B il campo x da A è ombreggiato (nascosto) non escluso. Per rispondere "perché questo sarebbe" riferimenti ai documenti here e here. Il compilatore sceglierà una delle 2 istanze di x in base al tipo dell'oggetto contenente. E b0 è di tipo A

A b0 = new B(); 

Quando si definisce metodi (getter) d'altra parte questi metodi possono sovrascrivere con la stessa firma nella classe padre. Un'altra brutta sorpresa è che un campo nella classe genitore è ombreggiato anche se è un tipo diverso.

L'ombreggiamento dei membri è considerato una cattiva pratica in quanto tende a confondere gli sviluppatori.

4

Poiché si sta accedendo alla variabile x dalla classe A, poiché b0 è definito come A. Si chiama nascondere una variabile, e non come si potrebbe sospettare sovrascrivere una variabile, cosa che non è possibile in java. Otterrai il risultato previsto se accederai a x da b0 utilizzando un TypeCast.

A b0 = new B(); 
System.out.print(((B)b0).x); 

Utilizzando un typecast si sarebbe accedendo alla variabile x dalla classe B ora.

per ulteriori informazioni si può leggere attraverso JLS 8.3

3

campi statiche non vengono ereditate, che non hanno la precedenza a vicenda, si ombra l'un l'altro. Quando si accede direttamente al campo statico con lo stesso nome nel proprio caso, il campo della superclasse nasconde l'altro campo e si hanno due Xe int, ma quella della superclasse non è nascosta e viene selezionata. Ancora meglio, quando chiamate un'altra istanza dello stesso metodo e accedete allo stesso campo statico, è quando le cose diventano molto strane. I campi statici vengono sommati e si può finire con X 5 + 5 = 10.

D'altra parte, se si eredita il campo non statico dalla superclasse, non c'è alcun problema che abbia un valore diverso in sub- classe, perché la sottoclasse può sovrascrivere il super membro non statico.

Le variabili statiche e l'ereditarietà sono cattive, rompono il polimorfismo dove meno te lo aspetti. (In realtà, se capisci i concetti della tua lingua, te lo aspetti, ma altre persone potrebbero non farlo)