Sostituzione per l'istanza di Java?

10

Quindi sono abbastanza nuovo nella programmazione nel mondo reale (al di fuori dei progetti accademici) e ho trovato molti post che dicono che l'utilizzo di instanceof è una cosa negativa da usare per determinare quale classe è un oggetto specifico.

La mia situazione è che ho tre classi, una classe di prodotti di base, una che estende quella e un'altra che la estende. Questi sono tutti memorizzati nella stessa tabella in un database e ho del codice che deve usare i metodi su ognuno per estrarre i dati da essi.

Qual è la migliore pratica per aggirare questo modo di farlo? Ho letto alcune cose sul polimorfismo ma non riesco a trovare alcun esempio che risolva il problema che ho. Tutti di solito sovrascrivono un metodo che per me non funzionerà in quanto ho bisogno di estrarre cose diverse dai diversi oggetti.

C'è un modo migliore per farlo o sono bloccato con instanceof o qualche tipo di riflessione per ottenere i campi specifici per gli oggetti?

    
posta Thomas Mitchell 18.01.2013 - 16:52
fonte

4 risposte

15

La ragione per cui instanceof è scoraggiata è che non è OOP.

Non ci dovrebbe essere alcun motivo per il chiamante / utente di un oggetto per sapere quale classe concreta è un'istanza di oltre il quale digitare la variabile che è dichiarata come.

Se hai bisogno di un comportamento diverso nelle sottoclassi, aggiungi un metodo e implementalo in modo diverso.

    
risposta data 18.01.2013 - 17:04
fonte
8

instanceof non è necessariamente una cosa negativa, tuttavia è qualcosa che si dovrebbe guardare.

Un esempio di dove funziona correttamente è in un posto dove si ottiene una raccolta del tipo base e si desidera solo quelli di un sottotipo. Ottenere gli indirizzi di rete da NetworkInterface.getNetworkInterfaces() restituisce gli oggetti NetworkInterface che hanno una collezione di oggetti InetAddress, alcuni dei quali sono Inet4Address e alcuni sono Inet6Address. Se si vuole filtrare la collezione per oggetti Inet4Address, è necessario usare instanceof.

Nella situazione descritta nel post originale, esiste una classe Base, qualcosa che estende quella classe base e qualcosa che estende la classe estesa. Anche se non completamente informativo, sembra che abbia le basi di un design non proprio ideale.

Quando si restituisce una classe base a meno che non ci siano buone ragioni per la sua progettazione in questo modo (compatibilità a ritroso tra le specifiche di una versione precedente) non si dovrebbe cercare di dare un'occhiata ai tipi sottostanti. Se ti viene restituito un Set, sai che stai ricevendo un set. Consente allo sviluppatore di cambiare in seguito la propria mente per restituire un tipo più specifico (SortedSet) o modificare il tipo sottostante (da HashSet a TreeSet) senza interrompere nulla.

Riconsiderare la progettazione di come gli oggetti sono strutturati e controllati per vedere se è possibile creare un modello di classe migliore che non richiede una distinzione di tipi.

    
risposta data 18.01.2013 - 17:30
fonte
1

Puoi usare il metodo getClass ().

Sei sicuro di aver bisogno di tre classi diverse? Forse una classe con un interruttore interno funzionerà meglio?

    
risposta data 18.01.2013 - 16:59
fonte
1

Tipicamente quando mi scopro di voler sapere il tipo di qualcosa significa che ho implementato la mia struttura di oggetto in modo errato. La maggior parte di queste volte si tratta di violare LSP .

Ci sono volte però dove vorrei avere un modo per fare l'invio dinamico e salvare una tonnellata di codice della piastra della caldaia e la mia struttura a prova di futuro. C # fornisce la parola chiave dinamica nelle nuove versioni del framework ma, per quanto ne so, Java non ha ancora qualcosa di simile.

Detto questo, l'instanceof è generalmente migliore rispetto al confronto delle classi poiché supporterà l'ereditarietà in modo appropriato. Puoi anche utilizzare metodi come isAssignableFrom e altri dall'API reflexion. Se vuoi implementare qualcosa come la spedizione dinamica, puoi farlo tramite l'API di reflection ma attenzione, sarà lento. Usare con cautela, idealmente dovresti correggere la struttura dell'oggetto e il design della tua app, se possibile.

Spero che questo aiuti

    
risposta data 18.01.2013 - 17:26
fonte

Leggi altre domande sui tag