2012-02-23 11 views
33

Ho 3 classi:Se si sovrascrive un campo in una sottoclasse di una classe, la sottoclasse ha due campi con lo stesso nome (e tipo diverso)?

public class Alpha { 
    public Number number; 
} 

public class Beta extends Alpha { 
    public String number; 
} 

public class Gama extends Beta { 
    public int number; 
} 

Perché il seguente codice compilare? E perché il test passa senza errori di runtime?

@Test 
public void test() { 
    final Beta a = new Gama(); 
    a.number = "its a string"; 
    ((Alpha) a).number = 13; 
    ((Gama) a).number = 42; 

    assertEquals("its a string", a.number); 
    assertEquals(13, ((Alpha) a).number); 
    assertEquals(42, ((Gama) a).number); 
} 
+2

E? funziona così Se è necessario eseguire l'override, è necessario utilizzare i metodi setter/getter. Il campo pubblico è quasi sempre una pessima idea. – kan

risposta

45

Le variabili membro non possono essere sovrascritte come metodi. Le variabili number nelle classi Beta e Gama sono nascondono (non sovrascrivendo) la variabile membro number della superclasse.

Mediante il casting è possibile accedere al membro nascosto nella superclasse.

36

campi non può essere ignorata ; non sono accessibili in modo polimorfico in primo luogo - stai solo dichiarando un nuovo campo in ogni caso.

Compilare perché in ogni caso il tipo di espressione in fase di compilazione è sufficiente per determinare quale campo definito number.

Nella programmazione del mondo reale, si potrebbe evitare questo in due modi:

  • buon senso: i campi shadowing rende il codice più difficile da leggere, quindi basta non farlo
  • Visibilità: se rendi privati ​​tutti i tuoi campi, le sottoclassi non li sapranno comunque