Java中使用基类作为请求入参出现方法重写错误如何解决
问题根因
Java方法覆写要求参数类型完全匹配,当前抽象父类AbstractDataExporter的getEntities方法固定入参为基类ExportRequest,子类尝试用子类MenuExportRequest作为入参属于参数窄化,不符合覆写规则,因此抛出编译错误。
修复方案
给抽象类新增Request类型的泛型约束即可,修改代码如下:
1. 重构抽象类定义
新增第二个泛型参数R,限定必须是ExportRequest的子类,调整getEntities方法的入参类型为泛型R:
public abstract class AbstractDataExporter<T, R extends ExportRequest> implements DataExporter { @Override public MultipartFile export(ExportRequest request) throws IOException { // 类型强转,由于子类已指定具体R类型,调用方传参也为对应子类请求,转换安全 final Iterable<T> entities = getEntities((R) request); // 省略其他代码 } protected abstract Iterable<T> getEntities(R request); }
2. 调整实现类继承逻辑
继承抽象类时指定具体的Request子类为MenuExportRequest,此时子类的getEntities方法即可正常覆写:
public class MenuExporter extends AbstractDataExporter<MenuDTO, MenuExportRequest> { @Override protected Iterable<MenuDTO> getEntities(MenuExportRequest request){ UUID menuUuid = request.getMenuUuid(); // 省略其他代码 } }
可选优化(类型安全校验)
如果需要避免误传其他类型的请求导致强转异常,可以在抽象类的export方法中增加类型校验,规避泛型擦除带来的类型转换风险:
@Override public MultipartFile export(ExportRequest request) throws IOException { // 校验请求类型是否匹配 if (!getRequestClass().isInstance(request)) { throw new IllegalArgumentException("请求类型不匹配,期望类型:" + getRequestClass().getName()); } final Iterable<T> entities = getEntities((R) request); // 省略其他代码 } // 新增抽象方法,子类返回对应Request的Class类型 protected abstract Class<R> getRequestClass();
对应MenuExporter新增实现即可:
@Override protected Class<MenuExportRequest> getRequestClass() { return MenuExportRequest.class; }
内容的提问来源于stack exchange,提问作者user17188729
相关产品推荐
相关产品推荐

