2015-04-29 16 views
5

Java 1.6. Ich habe eine Klasse um einige Methoden erweitert. Jetzt möchte ich die erweiterte Klasse anstelle der Basisklasse verwenden. Die Klassen, die die Basisklasse verwenden können, können die erweiterte Klasse jedoch nicht "erkennen". Was ist der (empfohlene) Fix?Verwenden Sie erweiterte Klasse anstelle der Basisklasse

Ich weiß, das wurde oft in verschiedenen Geschmacksrichtungen gefragt, aber ich kann es nicht bekommen!

Beispiel- Extend Klasse SAMRecord und verwenden SAMRecordExt Nachwort:

public class SAMRecordExt extends SAMRecord{ 

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

} 

Jetzt, während dies funktioniert:

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

Das gibt mir einen Kompilierungsfehler

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

Es überrascht nicht, diese funktioniert auch nicht (Laufzeitfehler):

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) 

Wie kann ich die erweiterte Klasse arbeiten, wo die Basisklasse funktioniert?

EDIT: Weitere Informationen über die Klassen, die ich verwende. sam Objekt stammt aus

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

Die vollständige Dokumentation ist https://samtools.github.io/htsjdk/javadoc/htsjdk/index.html

+0

Can Sie geben die Deklaration der Variablen "sam" in dem obigen Code an –

+0

Es scheint, dass diese Klasse mit der Superklasse verwendet werden sollte, was bedeutet: der Autor wusste von der Superklasse und benötigt die darin enthaltene Funktionalität. Nun, das Problem ist, wenn Sie versuchen, diese Umwandlung durchzuführen: Jede Instanz der Kindklasse ist eine Instanz der Superklasse, aber nicht jede Instanz der Superklasse ist eine Instanz der Kindklasse. – Stultuske

+0

Es scheint mir, dass Sie nicht den Code ausführen, von dem Sie glauben, dass er ausgeführt wird, oder eher, dass Sie den von Ihnen geposteten Code nicht kompilieren. Sie sollten keine Kompilierungsfehler erhalten, vorausgesetzt, SAMRecordExt erweitert SAMRecord gemäß dem von Ihnen geposteten Code. – EJP

Antwort

3

Das Problem ist:

sam.iterator().next() 

gibt ein SAMRecord Objekt

Welche

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

funktioniert nicht, da eine Superklasse keiner Unterklassenvariablen zugewiesen werden kann. Das allgemeine Problem ist, dass die Unterklasse spezifischer als die Superklasse ist. Deshalb können Sie einer Unterklassenvariablen kein Superklassenobjekt zuweisen, da die Superklasse nicht weiß, was die Unterklasse benötigt kennt.

Auf der anderen Seite kennt die Unterklasse die Details der Superklasse und einige weitere Details, was bedeutet, dass Sie in der Lage sind, einer Superklassenvariablen ein Unterklassenobjekt zuzuordnen.

Lösung für das Problem:(EDIT)

Normalerweise erweitern Sie die Klasse und sind in der Lage, die Iteratormethode außer Kraft zu setzen und einen gut ausgebauten Iterator vom Typ zurückkehren Sie mögen.

Aber das Problem, das ich hier sehe, ist, dass die Fabrik Ihre obj vom Typ SamReader erstellt, die Sie verwenden, um über den SamRecords iterieren

SO -> Sie müssen die Fabrik erstreckt sich eine andere Art von SamReader zurückzukehren und iterieren später über Ihrem gewünschten Datensatztypen, die

Quellcode der Factory-Klasse finden Sie unter:

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

+0

HALLO- Wenn Sie sagen, verwenden Sie den SAMRecord-Typ für die Variable, stört dies nicht den Punkt der Erweiterung der Klasse? – dariober

+0

Ja, ich würde es vorziehen, die Iterator-Methode zu überschreiben – Zelldon

+0

Danke! Über "überschreiben Sie die Iterator-Methode in der Sub-Klasse" jede Möglichkeit, Sie könnten eine Zusammenfassung des Codes zu verwenden? – dariober

Verwandte Themen