使用扩展类代替基类

5

Java 1.6. 我扩展了一个类以包含一些方法。现在我想使用扩展后的类来代替基础类。然而,能够使用基础类的类无法“识别”扩展后的类。有什么建议的解决方法吗?

我知道这个问题已经以不同的形式被问过很多次,但我还是弄不明白!

例如- 扩展类SAMRecord并在此之后使用SAMRecordExt

public class SAMRecordExt extends SAMRecord{

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

}

现在,虽然这个可以工作:
SAMRecord rec= sam.iterator().next();

这给了我一个编译错误。

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

毫不意外,这也不起作用(运行时错误):

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)

如何让扩展类能够像基类一样工作?
编辑:更多关于我使用的类的细节。sam对象来自
SamReaderFactory sf = SamReaderFactory.makeDefault();
SamReader sam= sf.open(new File(insam));

完整的文档请参见https://samtools.github.io/htsjdk/javadoc/htsjdk/index.html


你能否提供上述代码中变量"sam"的声明? - Akash Yadav
看起来那个类应该与超类一起使用,这意味着作者知道超类,并需要其中提供的功能。现在的问题是,当你尝试进行强制类型转换时:每个子类实例都是超类的实例,但并非每个超类实例都是子类的实例。 - Stultuske
在我看来,你好像没有运行你想要运行的代码,或者说你没有编译你发布的代码。根据你发布的代码,只要SAMRecordExt extends SAMRecord,就不应该出现任何编译错误。 - user207421
1个回答

3
问题是:
sam.iterator().next()

返回一个SAMRecord对象。

这意味着:

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

因为超类不能分配给子类变量,所以以下代码将不起作用。

一般问题在于子类比超类更具体,这就是为什么不能将超类对象分配给子类变量的原因,因为超类不知道子类需要知道的东西。

另一方面,子类知道超类的细节和更多细节,这意味着您可以将子类对象分配给超类变量。

解决方法:(编辑)

通常情况下,您会扩展类并能够覆盖迭代器方法并返回所需类型的良好构造迭代器。

但我在这里看到的问题是工厂创建了类型为SamReader的对象,您使用它来迭代SamRecords

因此 -> 您必须扩展工厂以返回其他类型的SamReader,并稍后迭代您希望的记录类型,请参见

Factory类的源代码:

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


你好- 当你说“在变量中使用SAMRecord类型”时,这不是抵消了扩展类的目的吗? - dariober
谢谢!关于“在子类中重写迭代器方法”,您能否发布一份使用代码的简介? - dariober
1
我看到的问题是工厂创建了类型为SamReder的对象,您使用它来迭代SamRecords -> 您必须扩展工厂以返回其他类型的SamReader,并稍后迭代其他记录类型,请参见https://github.com/samtools/htsjdk/blob/master/src/java/htsjdk/samtools/SamReaderFactory.java。 - Zelldon
1
谢谢,我会研究一下。所以问题和解决方案在SamReader中,而不是我的SAMRecordExt中。 - dariober
没错,我之前没有意识到这一点,因为我忽略了变量Sam的声明:SamReader sam = sf.open(new File(insam)); - Zelldon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接