2016-05-18 22 views
5

Avendo queste classi:Matrice di oggetti della superclasse. Come gestirli come sottoclassi?

public abstract class Furniture 

public class Chair : Furniture 

public class Table : Furniture 

public class Kitchen 
{ 
ArrayList <Furniture> furnitures; 
//other code 
public void function() 
{ 
    Furniture furniture = furnitures.get(); 
    doSomethingInKitchen(furniture); 
} 


private void doSomethingInKitchen (Chair c); 
private void doSomethingInKitchen (Table t); 

} 

Sto cercando la migliore pratica che mi assicura di manipolare l'oggetto superclasse Mobili come una sottoclasse uno (sedia o un tavolo).

Ho provato con un cast semplice, ma quando chiamo la funzione funziona con l'oggetto mobili, non con il tavolo o la sedia uno.

Quello che ho cercato è qualcosa di simile:

for each Furniture in Array List 
if(furniture.get() istance of Table) 
{ 
currentFurniture = (Table) furniture.get(); 
} 

else if (furniture.get() istanceof Chair) 
{ 
currentFurniture = (Chair) furniture.get(); 
} 
doSomethingInKitchen(currentFurniture) 

Non so se il problema è che currentFurniture è dichiarato come

Furniture currentFurniture; 

E così non sarà riconosciuto come presidente o Tabella nonostante il casting o se il design stesso della soluzione è sbagliato.

+0

il polimorfismo funziona in base al tipo di oggetto ** su cui ** viene chiamato il metodo. Non sul tipo di argomento del metodo. Dovrebbe essere 'furniture.do SometomethingInTheKitchen()'. Aso, post vero codice Java, non pseudo-codice, quando si fa domande sugli errori in Java. –

+0

Solo un complemento di ciò che JBNizet ha dichiarato: Nel tuo esempio, supponi di "usare" il tuo oggetto. In questo modo potresti '(Kitchen Object) .furniture.get(). Use();' In questo modo, puoi codificare le classi superiori e inferiori, senza preoccuparti se il codice esiste. – Bonatti

risposta

3

Il cast viene perso non appena viene riassegnato alla variabile comune. È necessario gestire ogni tipo separatamente:

for (Furniture furniture : furnitures) { 
    if (furniture instanceof Table) { 
     doSomethingInKitchen((Table)furniture); 
    } else if (furniture instanceof Chair) { 
     doSomethingInKitchen((Chair)furniture); 
    } 
} 

Idealmente, però, si dovrebbe evitare di proiettare tutto e implementare la logica diversa della sottoclasse stesso. Per esempio:

abstract class Furniture { 
    abstract void doSomethingInKitchen(); 
} 

class Table extends Furniture { 
    @Override 
    void doSomethingInKitchen() { 
     // Table-specific logic 
    } 
} 

class Chair extends Furniture { 
    @Override 
    void doSomethingInKitchen() { 
     // Chair-specific logic 
    } 
} 

Ora nel tuo Kitchen basta fare

for (Furniture furniture : furnitures) { 
    furniture.doSomethingInKitchen(); 
} 
+0

Semplice e chiaro. Buona risposta! – EagleOne

+0

Si prega di notare che \t Ho scritto due funzione doSomethingInKitchen perché le sue istruzioni funzionano molto di più con i parametri di cucina che in quelli di (tabella/sedia). Modificato la domanda in base a questo commento perché penso che non fosse chiaro nella prima versione. – EagleOne

2

dal momento che si eredita Furniture Theres classe senza bisogno di implementare 2 methods per ogni chair e Table

private void doSomethingInKitchen (Chair c); 
private void doSomethingInKitchen (Table t); 

è possibile avere un singolo metodo come questo

private void doSomethingInKitchen (Furniture f); 

ed è possibile ottenereRid del casting in forloop e lasciare che il metodo esegua il casting.

private void doSomethingInKitchen (Furniture f){ 

    if(f instanceof Table){ 
    //code for the table 
    }else{ 
    //code for the chair 
    } 

} 
+0

Questa è una risposta valida, ma se stai già effettuando il refactoring, preferirei il polimorfismo. – shmosel

+0

Nonostante funzioni, non è considerato una buona pratica. Se si utilizza l'ereditarietà, perché non utilizzare il vero potenziale che sovrascrive i metodi sui bambini? – Kaostias

+0

volevo solo mostrarglielo, avere un metodo per ogni classe non è una buona pratica.anche se op ha 'metodi di sovrascrittura', dovrebbe in qualche modo' cast' l'oggetto' dato che sta 'iterando' gli' oggetti superclasse' altrimenti finirà per eseguire il metodo in 'super classe', – Priyamal

Problemi correlati