You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 02:01:10