gpt4 book ai didi

Java - 从抽象类的子类调用方法

转载 作者:行者123 更新时间:2023-12-02 04:52:15 26 4
gpt4 key购买 nike

给定以下抽象类:

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(...)中。我收到一条消息,如下所示:

The method populate(capture#3-of ?) in the type BaseVersionResponse is not applicable for the arguments (BaseVO)

在上面的populate方法上。

我的想法是(这显然是不正确的),由于在代码中的此时,baseVersionResponse 实际上是一个特定的子实例,因此该类将确切地知道从该特定子类调用哪个填充方法。

我在这里做错了什么?如果这不是正确的方法,是否有更好的方法?

感谢您的宝贵时间!

最佳答案

好的,我今天仔细研究了这个。问题是通配符虽然是正确的方法,但会阻止您执行以下操作:

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);

}

因此,populate 方法现在采用 BaseVO,并且有一个新的 getVersion 方法可以为我们执行一些显式转换。这应该没问题,因为我们知道工厂总是会提供正确的东西,但如果另一个调用者不提供,则会抛出 IllegalArgumentException

现在,在您的响应类实现中,相应地更改填充方法:

public void populate(BaseVO version) {
VersionVOV1 versionVO = getVersion(version);
this.setTestFieldOne(versionVO.getFieldOne());
this.setTestFieldTwo(versionVO.getFieldTwo());
}

因此,我们更改了 populate 方法以采用 BaseVO,并且 getVersion 方法为我们进行转换。所有其他类型检查仍然适用,我们可以开始了。

转换让人感觉不那么干净,但对于您正在使用的工厂方法来说,这确实是(我能想到的)保持类型声明和代码模式所做出的保证完好无损的唯一方法。

希望有帮助!

关于Java - 从抽象类的子类调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29112714/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com