在返回类型中使用泛型时,我无法扩展父类 像下面的例子。
如您所知,如果没有泛型,下面的示例将正常编译,但它不是类型安全的,因为它的类型应该是Object。
我可以参考哪些明确的解决方案(或模式或建议,任何有用的东西!)?
class AbstractReader<T>{
public abstract T readNext();
}
class ByteArrayReader extends AbstractReader<byte[]>{
@Override
public byte[] readNext(){ /*...*/ }
}
class StringReader extends ByteArrayReader {
@Override
public String readNext() {
/* The return type is incompatible
with ByteArrayReader.readNext()! */
return new String(bytes);
}
}
答案 0 :(得分:3)
这里的问题是StringReader
扩展ByteArrayReader
没有意义。你将遗传与作文混为一谈。
当StringReader
继承自ByteArrayReader
时,您说它会履行一份合同,说明它的readNext
方法会返回byte[]
。
您真正想要做的是使用组合而不是继承:
class StringReader extends AbstractReader<String> {
private AbstractReader<byte[]> downstream;
public StringReader(AbstractReader<byte[]> downstream) {
this.downstream = downstream;
}
public String readNext() {
return new String(downstream.readNext());
}
}
此StringReader
符合AbstractReader<String>
合同,并按照下游AbstractReader<byte[]>
实施。请注意,它并未明确要求ByteArrayReader
- 任何旧的AbstractReader<byte[]>
都可以使用。
答案 1 :(得分:2)
您可以使用装饰器设计模式而不是继承:
class StringReader {
private ByteArrayReader bar;
public StringReader(ByteArrayReader bar) {
this.bar = bar
}
public String readNext() {
return new String(this.bar.readNext());
}
}
答案 2 :(得分:0)
你的问题试图告诉你的是,这不是对继承的好用。 StringReader绝对没有与ByteArrayReader的is-a关系。如果它们之间有一些共同的功能,那只是一个实现细节。任何这样的公共代码都应该被推送到AbstractReader,两者都应该直接扩展。然后抽象类正确地包含它的子类共有的代码,而StringReader和ByteArrayReader除了是同一个东西(可能是一个Reader)的实现之外是正确无关的。