我试图为转换器创建一个父类,避免重复代码,所以我开始做我在这里提供的java抽象类:
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
public abstract class AbstractUIConverter {
protected abstract <UIO, DTO> DTO toDto(final UIO input);
protected abstract <DTO, UIO> UIO toUIO(final DTO input);
protected <UIO, DTO> List<DTO> toDtoList(final List<UIO> inputList) {
return convertList(inputList, true);
}
protected <DTO, UIO> List<UIO> toUIOList(final List<DTO> inputList) {
return convertList(inputList, false);
}
private <I, O> List<O> convertList(final List<I> inputList, final boolean toDto) {
List<O> returnList;
if(CollectionUtils.isNotEmpty(inputList)) {
returnList = new ArrayList<O>(inputList.size());
O temp;
for (final I inputElem : inputList) {
if(toDto) {
temp = toDto(inputElem);
} else {
temp = toUIO(inputElem);
}
returnList.add(temp);
}
} else {
returnList = new ArrayList<O>(0);
}
return returnList;
}
}
问题出在子类化时。当我创建一个扩展此类的子类并替换方法签名中名为“input”的输入参数的类型以重写 toDto() 或 toUIO() 时,如下所示:
@Override
protected <UIO, DTO> DTO toDto(SomeTypeUIO input) {
出现一条消息:
The method toDto(SomeTypeUIO) of type SubclassConverter must override or implement a supertype method
如果我替换为第一种类型:
protected <SomeTypeUIO, DTO> DTO toDto(SomeTypeUIO input) {
出现此警告:
The type parameter SomeTypeUIO is hiding the type
这显然是我不想要的。
我尝试过参数化 AbstractUIConverter 但这更糟糕。我也尝试过在语法中弄乱“extends”。
我的目标是在子类中定义类型,因此转换列表的函数都在父类中完成。
我希望获得帮助和建议,或者一些用于在网络上查找的资源。
最佳答案
正确的方法是:
public abstract class AbstractUIConverter<UIO, DTO> {
protected abstract DTO toDto(final UIO input);
protected abstract UIO toUIO(final DTO input);
protected List<DTO> toDtoList(final List<UIO> inputList) {
return convertList(inputList, this::toDto);
}
protected List<UIO> toUIOList(final List<DTO> inputList) {
return convertList(inputList, this::toUIO);
}
private <I, O> List<O> convertList(final List<I> inputList, final Function<I, O> function) {
if(inputList.isEmpty()) {
return Collections.emptyList();
}
List<O> returnList = new ArrayList<>(inputList.size());
for(I input : inputList) {
returnList.add(function.apply(input));
}
return returnList;
}
}
<小时/>
您已经在方法调用中区分了如何转换数据。
public abstract class AbstractUIConverter<UIO, DTO> {
protected abstract DTO toDto(final UIO input);
protected abstract UIO toUIO(final DTO input);
protected List<DTO> toDtoList(final List<UIO> inputList) {
return convertList(inputList, new Function<UIO, DTO>() {
@Override
public DTO apply(UIO input) {
return AbstractUIConverter.this.toDto(input);
}
});
}
protected List<UIO> toUIOList(final List<DTO> inputList) {
return convertList(inputList, new Function<DTO, UIO>() {
@Override
public UIO apply(DTO input) {
return AbstractUIConverter.this.toUIO(input);
}
});
}
private <I, O> List<O> convertList(final List<I> inputList, final Function<I, O> function) {
if(inputList.isEmpty()) {
return Collections.emptyList();
}
List<O> returnList = new ArrayList<>(inputList.size());
for(I input : inputList) {
returnList.add(function.apply(input));
}
return returnList;
}
}
关于java - 泛型方法的子类实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45611127/