如何编写可处理不同类型对象共享字段的通用函数?
解决方案
最稳妥且符合Java面向对象设计的方式是定义一个包含所有共同方法的接口,让所有有这些共同字段的类实现该接口,这样就能用接口作为参数编写通用函数,完全避免类型转换问题,后续新增类也只要实现接口就能复用。
步骤1:定义通用接口
先创建一个接口,把两个类共同字段对应的getter方法声明进去:
public interface Sport { String getCoach(); String getPlayer(); String getTeam(); String getTime(); // 后续新增共同字段时,直接在这里添加对应的getter方法 }
步骤2:让现有类实现接口
修改Soccer和Lacrosse类,实现Sport接口,返回各自类里的对应字段值:
public class Soccer implements Sport { private String Player; private int BallCnt; private String Team; private String Coach; private String Time; private String Shoes; // 构造器、其他字段的getter/setter省略 @Override public String getCoach() { return Coach; } @Override public String getPlayer() { return Player; } @Override public String getTeam() { return Team; } @Override public String getTime() { return Time; } } public class Lacrosse implements Sport { private String Player; private String Team; private String Rules; private String Coach; private String Time; // 构造器、其他字段的getter/setter省略 @Override public String getCoach() { return Coach; } @Override public String getPlayer() { return Player; } @Override public String getTeam() { return Team; } @Override public String getTime() { return Time; } }
步骤3:编写通用的getCommon函数
现在把函数参数类型改成Sport接口,不用再用Object,直接安全调用所有共同方法:
public Map<String, String> getCommon(Map<String, String> map, Sport sport) { map.put("coach", sport.getCoach()); map.put("player", sport.getPlayer()); map.put("team", sport.getTeam()); map.put("time", sport.getTime()); return map; }
备选方案:无法修改原有类时用反射
如果不能修改Soccer和Lacrosse的代码,可通过反射读取共同字段,但这种方式类型不安全、易出错,仅作为备选:
import java.lang.reflect.Field; import java.util.Map; public Map<String, String> getCommon(Map<String, String> map, Object obj) { String[] commonFields = {"Coach", "Player", "Team", "Time"}; for (String fieldName : commonFields) { try { Field field = obj.getClass().getDeclaredField(fieldName); field.setAccessible(true); map.put(fieldName.toLowerCase(), (String) field.get(obj)); } catch (NoSuchFieldException | IllegalAccessException e) { // 处理字段不存在或访问失败的情况 e.printStackTrace(); } } return map; }
注意事项
- 接口方式是类型安全的,编译器会检查所有实现类是否正确实现方法,后续新增类只要实现
Sport接口,就能直接传入getCommon函数。 - 反射方式无需修改原有类,但字段名拼写错误、类型变化都会导致运行时错误,维护成本高。
内容的提问来源于stack exchange,提问作者JustThatGuy93
相关产品推荐
相关产品推荐

