Java子类转父类后仍显示子类字段,如何仅保留父类字段?
问题
我有DataRequest和DataWithIdRequest的类结构,DataWithIdRequest对象会传入控制器方法。我希望仅以父类DataRequest的形式将该对象传入其他类处理,但把DataWithIdRequest转成DataRequest后,子类的额外字段依然存在,该怎么实现只保留父类字段的需求?
代码示例如下:
public class DataRequest { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } public class DataWithIdRequest extends DataRequest { private Integer id; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } } // 控制器代码 public class SomeController { public void handleRequest(DataWithIdRequest request) { processData(request); } } // 领域类代码 public class DomainService { public Boolean processData(DataRequest request) { // 这里的request实际还是DataWithIdRequest实例,包含id字段 // 但我只想处理父类DataRequest的内容 } }
解决方案
1. 手动创建父类实例并复制字段
直接新建一个纯DataRequest实例,将原对象中属于父类的字段值复制过去,生成的新对象完全是父类类型,不包含子类额外字段:
// 控制器中处理 public class SomeController { private DomainService domainService; public void handleRequest(DataWithIdRequest request) { DataRequest pureDataRequest = new DataRequest(); pureDataRequest.setName(request.getName()); domainService.processData(pureDataRequest); } }
2. 在子类中添加转换方法
在DataWithIdRequest中封装转换逻辑,代码更整洁易维护:
// 在DataWithIdRequest中添加转换方法 public class DataWithIdRequest extends DataRequest { // 原有字段和方法... public DataRequest toPureDataRequest() { DataRequest request = new DataRequest(); request.setName(this.getName()); return request; } } // 控制器调用 public void handleRequest(DataWithIdRequest request) { domainService.processData(request.toPureDataRequest()); }
3. 使用Bean拷贝工具简化字段复制
如果字段较多,手动复制效率低,可以用Bean拷贝工具(如Spring的BeanUtils),仅拷贝父类声明的字段:
import org.springframework.beans.BeanUtils; public class SomeController { public void handleRequest(DataWithIdRequest request) { DataRequest pureDataRequest = new DataRequest(); // 排除子类独有的字段,仅拷贝父类字段 BeanUtils.copyProperties(request, pureDataRequest, "id"); domainService.processData(pureDataRequest); } }
4. 用组合替代继承(长期优化方案)
如果业务上需要明确区分“基础请求”和“带ID的请求”,可以重构类结构,用组合代替继承,从根源避免转型问题:
// 基础请求类 public class DataRequest { private String name; // getter、setter... } // 带ID的请求类,组合基础请求 public class DataWithIdRequest { private DataRequest dataRequest; private Integer id; // getter、setter... } // 控制器调用 public void handleRequest(DataWithIdRequest request) { domainService.processData(request.getDataRequest()); }
内容的提问来源于stack exchange,提问作者Mr Smith
相关产品推荐
相关产品推荐

