2015-04-29 18 views
5

Java 1.6. Ho esteso una classe per includere alcuni metodi. Ora vorrei usare la classe estesa al posto della classe base. Tuttavia, le classi che potrebbero utilizzare la classe base non possono "riconoscere" la classe estesa. Qual è la correzione (raccomandata)?Utilizzare la classe estesa al posto della classe base

So che questo è stato chiesto molte volte in sapori diversi, ma non riesco a farlo!

Esempio- Estendere classe SAMRecord e utilizzare SAMRecordExt afterwords:

public class SAMRecordExt extends SAMRecord{ 

    public SAMRecordExt(SAMFileHeader header) { 
     super(header); 
    }  

} 

Ora, mentre questo funziona:

SAMRecord rec= sam.iterator().next(); 

Questo mi dà un errore di compilazione

SAMRecordExt recext= sam.iterator().next(); 
>>> Type mismatch: cannot convert from SAMRecord to SAMRecordExt 

Non sorprende, questo non funziona neanche (errore di runtime):

SAMRecordExt recext= (SAMRecordExt) sam.iterator().next(); 
>>> Exception in thread "main" java.lang.ClassCastException: htsjdk.samtools.SAMRecord cannot be cast to markDupsByStartEnd.SAMRecordExt 
at markDupsByStartEnd.Main.main(Main.java:96) 

Come posso fare funzionare la classe estesa dove ha funzionato la classe base?

MODIFICA: Ulteriori dettagli sulle classi che sto utilizzando. sam oggetto proviene da

SamReaderFactory sf = SamReaderFactory.makeDefault(); 
SamReader sam= sf.open(new File(insam)); 

documentazione completa è https://samtools.github.io/htsjdk/javadoc/htsjdk/index.html

+0

Can tu fornisci la dichiarazione della variabile "sam" nel codice sopra riportato –

+0

Sembra che quella classe fosse pensata per essere usata con la super classe, il che significa: l'autore sapeva della super classe e aveva bisogno della funzionalità fornita in questo. Ora, il problema è che quando provi a fare quel cast: ogni istanza della classe child è un'istanza della super-classe, ma non tutte le istanze della super-classe sono un'istanza della classe child. – Stultuske

+0

Mi sembra che tu non stia eseguendo il codice che pensi di essere in esecuzione, o piuttosto che non stia compilando il codice che hai postato. Non dovresti ricevere alcun errore di compilazione fornito 'SAMRecordExt estende SAMRecord' secondo il codice che hai postato. – EJP

risposta

3

Il problema è:

sam.iterator().next() 

restituisce un oggetto SAMRecord

Il che significa

SAMRecordExt recext= sam.iterator().next(); 

non funziona perché una super classe non può essere assegnata a una variabile di sottoclasse.

Il problema generale è che la sottoclasse è più specifica della super classe ecco perché non è possibile assegnare un oggetto super-classe a una variabile subClass perché la super classe non conosce le cose che la sottoclasse ha bisogno di conoscere.

D'altra parte la sottoclasse conosce i dettagli della super classe e alcuni dettagli in più che significa che è possibile assegnare un oggetto sub-classe a una variabile super-classe.

soluzione per il problema:(EDIT)

Normalmente si estende la classe e sono in grado di eseguire l'override del metodo iteratore e restituire un iteratore ben costruito del tipo che si desidera.

Ma il problema che vedo qui è che la fabbrica crea il tuo obj di tipo SamReader che si utilizza per scorrere i SamRecords

SO -> è necessario estende la fabbrica per riportare altro tipo di SamReader e iterare in seguito sopra i vostri tipi di record voluto vedere il codice sorgente

della classe di fabbrica:

https://github.com/samtools/htsjdk/blob/master/src/java/htsjdk/samtools/SamReaderFactory.java

+0

HI- Quando dici "usa il tipo SAMRecord per la variabile", questo non risolve il problema di estendere la classe? – dariober

+0

sì, preferirei sovrascrivere il metodo iteratore – Zelldon

+0

Grazie! Informazioni su "sovrascrivere il metodo iteratore nella sottoclasse" ogni possibilità di pubblicare una sinossi del codice da utilizzare? – dariober