2013-04-17 15 views
5

Ho visto varianti di questa domanda ma nessuna di esse risolve veramente il mio problema.Come verificare se una classe estende un'altra

Diciamo che sto costruendo un esercito con le classi. Nella parte superiore della mia struttura di ereditarietà ho una classe astratta "Unità". Quindi una classe astratta "Flying", "Ground" e "Building" che estende l'unità. Quindi una classe di calcestruzzo "Helicopter" e "Jet" che estende Flying. Così come un concreto "Soldato" e "Serbatoio" classe che estende Terra. e infine un "HQ" e "Fornitura" che estende l'edificio.

Quanto segue è un metodo nella classe "Soldier":

public void attack(Unit enemy){ 
if(enemy.getSuperclass().equals(Flying)){ 
    System.out.print("Soldiers cant attack flying units"); 
} 
else{ 
    //Code to attack enemy here 
} 

voglio nemico essere qualsiasi forma di unità. Questo perché un soldato dovrebbe essere in grado di attaccare sia gli edifici che le altre unità terrestri, tuttavia non voglio che i soldati possano attaccare oggetti volanti.

Il problema evidente è che perché ho dichiarato nemico come Unità, non sa quale sottoclasse a cui appartiene, e quindi sta cercando di trovare una superclasse unità che non esiste.

Sono sicuro che potrei avere un getter per ogni unità che ha impostato manualmente quale tipo di unità è ... ma è più lavoro e non sembra efficiente.

+2

Wow, 5 risposte equivalenti pubblicate nello stesso intervallo di tempo di 10 secondi! –

+2

Si potrebbero anche utilizzare le interfacce, poiché l'ereditarietà delle classi potrebbe essere restrittiva per modellare tutto. Ma prima provare l'eredità va bene. –

+1

* instanceof * stupore! – NINCOMPOOP

risposta

11

Change

if(enemy.getSuperclass().equals(Flying)){ 

a

if(enemy instanceof Flying){ 

che verificherà se enemy è un'istanza di una qualsiasi delle classi che derivano da Flying, anziché controllare specificamente per la classe Flying (che sappiamo che enemy non sarà, come Flying è astratto).

instanceof è abbastanza comodo, ma ogni volta che lo uso (e talvolta lo faccio), faccio un passo indietro e guardo la mia struttura nella speranza che possa trovare il modo di refactoring per evitarlo (forse le cose che possono essere attaccate da i soldati hanno alcune caratteristiche comuni e potrebbero implementare una sottoclasse astratta Unit sottoclasse   — GroundBased o qualcosa di   — che è possibile utilizzare per l'argomento anziché Unit). Potrebbe non essere possibile in questo caso, ma vale la pena ricontrollare.

+0

Ripensare il design della classe è un buon consiglio. Un buon modo potrebbe anche essere quello di utilizzare un'interfaccia e implementare le parti comuni in un'unità di sottoclasse. Con un'interfaccia non devi preoccuparti che una classe derivi da una particolare implementazione di un'altra classe, ma puoi comunque assicurarti che il bevhiour sia lo stesso. – Devolus

+0

sì ma un'interfaccia non mi consente di creare metodi di cookie cutter da applicare alle classi concrete sotto di esso. Dovrei ricreare il metodo per ogni unità. A meno che non capisca le interfacce correttamente. – KroniK907

1
if (enemy instanceof Flying) 
    ... 
1

Hai provato:

if (enemy instanceof Flying) 
2

Prova utilizzando instanceof operatore.

if(enemy instanceof Flying){ 
     System.out.print("Soldiers cant attack flying units"); 
    } 
    else{ 
     attack(enemy); 
    } 
1

Penso che si sta cercando instanceofoperator.

L'operatore instanceof confronta un oggetto con un tipo specificato. Puoi usarlo per verificare se un oggetto è un'istanza di una classe, un'istanza di una sottoclasse o un'istanza di una classe che implementa un'interfaccia particolare.

Quindi è possibile aggiornare si funzione come segue:

if(enemy instanceof Flying){ 
    System.out.print("Soldiers cant attack flying units"); 
} 
else{ 
    attack(enemy); 
} 
1

Prova if(enemy instanceof Flying) {}

2

È possibile utilizzare instanceof per questo. Questo funziona anche per le interfacce.

Assicurarsi inoltre che la variabile non sia nulla quando si utilizza instanceof.

classe B estende Un

public class test 
    { 
    public static void main(String[] args) 
    { 
     A a = new B(); 
     B b = new B(); 
     if(a instanceof A) 
      System.out.println("B derived from A"); 
     if(b instanceof A) 
      System.out.println("B derived from A"); 
    } 
    } 
0

Questo è un odore di progettazione. Il requisito fondamentale è un lavoro per lo Visitor pattern ma dovresti anche cercare di usare il polimorfismo meglio di questo prima di arrivare anche al visitatore.

Problemi correlati