[英]Java - Calling method from child of abstract class
给定以下抽象类:
public abstract class BaseVersionResponse<T extends BaseVO> {
public abstract void populate(T versionVO);
}
和以下子类:
public class VersionResponseV1 extends BaseVersionResponse<VersionVOV1>
{
protected String testFieldOne;
protected String testFieldTwo;
public String getTestFieldOne() {
return testFieldOne;
}
public void setTestFieldOne(String value) {
this.testFieldOne = value;
}
public String getTestFieldTwo() {
return testFieldTwo;
}
public void setTestFieldTwo(String value) {
this.testFieldTwo = value;
}
@Override
public void populate(VersionVOV1 versionVO) {
this.setTestFieldOne(versionVO.getFieldOne());
this.setTestFieldTwo(versionVO.getFieldTwo());
}
我希望通过调用方法执行以下操作:
public void getVersionInfo(String version) {
BaseVO versionVO = null;
BaseVersionResponse<? extends BaseVO> baseVersionResponse = null;
baseVersionResponse = createVersionResponse(version);
versionVO = createVersionVO(version);
baseVersionResponse.populate(versionVO);
}
其中createVersionResponse(...)
和createVersionVO(...)
如下所示:
public BaseVersionResponse<? extends BaseVO> createVersionResponse(String version) {
BaseVersionResponse<? extends BaseVO> specificVersionResponse = null;
if (version.equalsIgnoreCase("V1")) {
specificVersionResponse = new VersionResponseV1();
} else if (version.equalsIgnoreCase("V2"))
specificVersionResponse = new VersionResponseV2();
return specificVersionResponse;
}
public BaseVO createVersionVO(String version) {
BaseVO versionVO = null;
if (version.equalsIgnoreCase("V1")) {
versionVO = new VersionVOV1();
} else if (version.equalsIgnoreCase("V2"))
versionVO = new VersionVOV2();
return versionVO;
}
和VersionVOV1看起来像这样:
public class VersionVOV1 extends BaseVO {
private String fieldOne = null;
private String fieldTwo = null;
private String fieldThree = null;
public String getFieldOne() {
return fieldOne;
}
public void setFieldOne(String fieldOne) {
this.fieldOne = fieldOne;
}
public String getFieldTwo() {
return fieldTwo;
}
public void setFieldTwo(String fieldTwo) {
this.fieldTwo = fieldTwo;
}
public String getFieldThree() {
return fieldThree;
}
public void setFieldThree(String fieldThree) {
this.fieldThree = fieldThree;
}
}
当我尝试编译以下代码行时,就会出现我的问题:
baseVersionResponse.populate(versionVO);
在getVersionInfo(...)
。 我收到一条看起来像这样的消息:
类型BaseVersionResponse的方法populate(capture#3-of?)不适用于参数(BaseVO)
在上面的populate
方法上。
我的想法是(显然是不正确的),因为在代码的这一点上,baseVersionResponse实际上是一个特定的子实例,该类将确切知道要从该特定子类中调用哪个填充方法。
我在这里做错了什么? 如果这不是正确的方法,还有更好的方法吗?
感谢您的时间!
如果您只捕获类型(“ <?>”)的捕获,并且不选中它,它应该可以正常工作。 即使使用Object类型也可以进行编译。
但是,给定您的特定示例,您可能想要的是方法:
public BaseVersionResponse<?> createVersionResponse(String version)
变成:
public BaseVersionResponse<? extends BaseVO> createVersionResponse(String version)
然后,而不是使用
BaseVersionResponse<?>
采用
BaseVersionResponse<? extends BaseVO>
既然您知道返回类型将是实现接口/类的那些事情之一。
好的,我今天对此做了更好的了解。 问题在于,通配符虽然是正确的方法,但却使您无法执行以下操作:
BaseVO versionVO = createVersionVO(version);
因为populate
呼叫需要扩展 BaseVO,而不是不符合条件的实际BaseVO。 这意味着您不能直接传递那个versionVO变量。
因此,将类型检查保持在适当的位置,我认为这很好,因为您将始终需要实现,将上面的所有内容保持不变,然后将BaseVersionResponse
类更改为以下内容:
public abstract class BaseVersionResponse<T extends BaseVO> {
public T getVersion(BaseVO versionVO) {
try {
return (T) versionVO;
} catch (ClassCastException e) {
throw new IllegalArgumentException();
}
}
public abstract void populate(BaseVO versionVO);
}
因此,填充方法现在需要一个BaseVO,并且有一个新的getVersion方法可以为我们做一些明确的转换。 这应该没问题,因为我们知道工厂将始终提供正确的东西,但是如果另一个调用者不提供,则抛出IllegalArgumentException
。
现在,在您的响应类实现中,相应地更改populate方法:
public void populate(BaseVO version) {
VersionVOV1 versionVO = getVersion(version);
this.setTestFieldOne(versionVO.getFieldOne());
this.setTestFieldTwo(versionVO.getFieldTwo());
}
因此,我们将populate方法更改为采用BaseVO,而getVersion方法为我们进行了强制转换。 所有其他类型检查仍然适用,我们很好。
强制转换使它感觉不那么干净,但是对于您正在使用的工厂方法而言,它实际上是使类型声明和代码模式保持不变的唯一方法(我能想到)。
希望有帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.