有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

继承这种java接口策略合理吗?

我一直在考虑为我的代码实现某种策略

这是我的设置:

我有一个叫做“对象”的接口。 然后我有一个名为“实体”的接口,它扩展了“对象”。 从实体中涌现出无数的实现,比如“军队”、“城市”、“柠檬”等等

现在,我想把所有这些物体收集成某种形式的地图。然后从这个映射中,我想得到“Object”的具体实现

我想出的解决方案如下:

对象具有以下方法:

public Entity getEntity()

对象的所有实现都返回null,而实体返回自身

同样,在实体中,我会:

public Army getArmy()
public City getCity()

这样,我就可以简单地从映射中提取一个对象,并通过一系列空检查从中获取特定的类,如下所示

Object o = Objects.getObject(2dCoordinates);
Entity e = o.getEntity();
if (e != null){
Army a = e.getArmy();
if (a != null)
a.armySpecificMethod();
}

所有这些都没有使用“instanceof”和施法,这是我讨厌的

问题是这是否有一些不可预见的问题?我宁愿在重构我的代码之前向了解我的人学习,然后自己去发现


共 (2) 个答案

  1. # 1 楼答案

    你问你的策略是否有陷阱。我会说不,因为C#对其^{}关键字使用相同的策略。例如:e as Army如果e是-a Army,则返回e,否则返回null。它基本上是一个cast,而不是失败返回null

    然而,您不必使用接口实现此功能,您可以编写自己的as方法,例如:

    static <T> T as(Class<T> clazz, Object obj) {
        if (clazz.isInstance(obj)) {
            return (T) obj;
        }
        return null;
    }
    

    用法:

    Object o = Objects.getObject(2dCoordinates);
    Entity e = as(Entity.class, o);
    if (e != null) {
        Army a = as(Army.class, e);
        if (a != null)
        a.armySpecificMethod();
    }
    
  2. # 2 楼答案

    另一种方法是注册在特定事件中调用的回调/策略。诸如此类:

    public interface OnMapClicked<T> {
    
        void onItemSelected(T item);
    
    }
    

    你的GameMap(或其他)实现是:

    public GameMap {
    
        private final Map<Class<?>, OnMapClicked> listeners = new HashMap<>();
    
        public <T> void registerListener(Class<? extends T> type, OnMapClicked<T> listener) {
             listeners.put(type, listener);
        }
    
        //
    
        private void onMapClicked(Coordinates coordinates) {
            Object object = findObject(coordinates);
    
            listeners.get(object.getClass()).onItemSelected(object);
        }
    
    }
    

    这是一个非常粗糙的未经测试的实现,但希望您能理解。这里有一个非泛型实例的用法(在onMapClicked中),但它应该是安全的,因为我们正在检查registerListener中的输入类型