[英]Java documentation practice for overriding methods whose return type is subclass of overridden method's return type
[英]How to return a subclass of parameterized return type whose parametric type is a subclass of the return type's parametric type?
标题听起来有点复杂,但事实上问题很简单。 我有以下方法:
AbstractClassA<AbstractClassB> myMethod() {...}
我想像这样调用它:
ClassAImpl<ClassBImpl> result = myMethod();
问题是,无论我尝试什么,我最终都得到了未经检查的强制警告或编译器错误。
这样做的正确方法是什么?
这完全取决于。 最简单的答案是,您只需要将myMethod
的结果转换为与结果相同的类型。 假设我们从问题中取出所有泛型,如下所示:
public class Demo {
private abstract class AbstractClassA {}
private class ClassAImpl extends AbstractClassA {}
private abstract class AbstractClassB {}
private class ClassBImpl extends AbstractClassB {}
Demo() {
ClassAImpl result = myMethod();
}
public AbstractClassA myMethod() {
return new ClassAImpl();
}
public static void main(String[] args) {
new Demo();
}
}
对myMethod
的调用仍然是编译器错误,因为类型不匹配。 考虑这一点的一个好方法是想象你对myMethod
体内的代码一无所知。 你怎么知道它返回ClassAImpl
而不是AbstractClassA
其他子类型? 所以为了使它工作,你需要像这样调用myMethod
:
ClassAImpl result = (ClassAImpl)myMethod()
至于泛型位,您可能希望您的方法签名类似于:
public AbstractClassA<? extends AbstractClassB> myMethod()
但也许想要这样的东西:
public AbstractClassA<ClassBImpl> myMethod()
甚至:
public ClassAImpl<ClassBImpl> myMethod()
除了最后一个之外的所有都需要一些显式的铸造。
为什么你到底会这样做呢? 你的设计是错误的,或者你遗漏了一些重要的信息。 如果myMethod
与尝试调用位于同一个类中,那么调用者可以了解有关如何实现该方法的信息,则应创建一个返回更具体类型的私有myMethodAux
。 但是,您可能仍会遇到方差问题,因为ClassAImpl<ClassBImpl>
不是AbstractClassA<AbstractClassB>
的子类。 它是AbstractClassA<? extends AbstractClassB>
的子类AbstractClassA<? extends AbstractClassB>
AbstractClassA<? extends AbstractClassB>
。
您上面的评论似乎表明您不了解Java中子类型关系的这种差异限制。
如果没有显式类型转换,则无法将超类型指定为子类型。
在向下投射之前使用instanceof
运算符。
尝试Class#isInstance()
abstract class AbstractClassA<T extends AbstractClassB> {}
abstract class AbstractClassB {}
class ClassAImpl<T extends AbstractClassB> extends AbstractClassA<T> {}
class ClassBImpl extends AbstractClassB {}
...
public static AbstractClassA<? extends AbstractClassB> myMethod() {
return new ClassAImpl<ClassBImpl>();
}
...
AbstractClassA<? extends AbstractClassB> returnValue=myMethod();
if(returnValue.getClass().isInstance(new ClassAImpl<ClassBImpl>())){
ClassAImpl<ClassBImpl> result=(ClassAImpl<ClassBImpl>)returnValue;
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.