Java中如何避免在多个类中重复声明工具函数?
最佳实践方案
针对你的场景,推荐两种符合需求的实现方式,优先选择第一种静态工具类方案:
方案1:提取静态工具类(推荐)
将GameMap中操作char[][]的工具逻辑抽离到独立的静态工具类,所有操作以目标数组作为参数传入。这样既可以复用代码,又不需要依赖继承,同时类内部能直接访问自身的私有数组。
代码示例
静态工具类(封装复用逻辑)
public class MapUtils { // 私有构造,禁止实例化工具类 private MapUtils() {} public static void setCharAt(char[][] map, int x, int y, char c) { // 可添加边界校验等通用逻辑 if (x >= 0 && x < map.length && y >= 0 && y < map[0].length) { map[x][y] = c; } } public static char getCharAt(char[][] map, int x, int y) { if (x >= 0 && x < map.length && y >= 0 && y < map[0].length) { return map[x][y]; } return '\0'; // 或根据需求抛出异常 } // 可添加其他工具函数,如clearMap、fillArea等 }
改造GameMap类
public class GameMap { private char[][] map; public GameMap(int width, int height) { this.map = new char[width][height]; } // 委托调用工具类方法,对外保持原有调用方式 public void setCharAt(int x, int y, char c) { MapUtils.setCharAt(this.map, x, y, c); } public char getCharAt(int x, int y) { return MapUtils.getCharAt(this.map, x, y); } // 类内直接访问私有map数组 public void initDefaultMap() { this.map[0][0] = 'S'; // 直接操作数组 } }
BotPlayer类实现
// BotPlayer已继承其他类,无需再继承GameMap public class BotPlayer extends SomeParentClass { private char[][] memorizedMap; public BotPlayer(int width, int height) { this.memorizedMap = new char[width][height]; } // 复用工具类逻辑,自定义对外方法名 public void setMemorizedChar(int x, int y, char c) { MapUtils.setCharAt(this.memorizedMap, x, y, c); } public char getMemorizedChar(int x, int y) { return MapUtils.getCharAt(this.memorizedMap, x, y); } // 类内直接访问私有memorizedMap数组 public void refreshMemory() { this.memorizedMap[1][1] = 'E'; // 直接操作数组 } }
方案优势
- 完全消除代码重复,所有map操作逻辑统一维护
- 不依赖继承,解决BotPlayer无法多继承的问题
- 类内部可直接访问自身私有数组,满足需求
- 工具类职责单一,易于测试和扩展
方案2:组合+委托(适合带状态的工具逻辑)
如果你的map操作需要维护状态(比如记录操作次数、历史变更),可以将操作逻辑封装成带状态的类,通过组合的方式让GameMap和BotPlayer持有该类实例,实现委托调用。
代码示例
操作逻辑类
public class MapOperations { private char[][] targetMap; public MapOperations(char[][] targetMap) { this.targetMap = targetMap; } public void setCharAt(int x, int y, char c) { if (x >= 0 && x < targetMap.length && y >= 0 && y < targetMap[0].length) { targetMap[x][y] = c; } } public char getCharAt(int x, int y) { if (x >= 0 && x < targetMap.length && y >= 0 && y < targetMap[0].length) { return targetMap[x][y]; } return '\0'; } // 可添加状态相关方法,如getOperationCount() }
GameMap类改造
public class GameMap { private char[][] map; private MapOperations operations; public GameMap(int width, int height) { this.map = new char[width][height]; this.operations = new MapOperations(this.map); } public void setCharAt(int x, int y, char c) { operations.setCharAt(x, y, c); } // 类内直接访问map数组 public void resetMap() { for (int i = 0; i < map.length; i++) { Arrays.fill(map[i], '\0'); } } }
BotPlayer类实现
public class BotPlayer extends SomeParentClass { private char[][] memorizedMap; private MapOperations memoryOperations; public BotPlayer(int width, int height) { this.memorizedMap = new char[width][height]; this.memoryOperations = new MapOperations(this.memorizedMap); } public void setMemorizedChar(int x, int y, char c) { memoryOperations.setCharAt(x, y, c); } // 类内直接访问memorizedMap数组 public void clearMemory() { Arrays.fill(this.memorizedMap[0], '\0'); } }
方案优势
- 支持维护操作状态,扩展性更强
- 同样无需继承,符合多继承限制
- 类内部仍可直接访问私有数组
内容的提问来源于stack exchange,提问作者mathsymaths
相关产品推荐
相关产品推荐

