使用带有接口的抽象 class 的设计问题

Design problems of using abstract class with an interface

我知道有几个标题相似的主题,但实际上我的问题与其他主题略有不同。

我设计了这样一个解决方案,抽象class实现和接口,在构造函数中调用接口的默认方法来初始化映射。

这是我的界面:

   public interface ICalculator{

        int VALUE_OF_X= 10;
        int VALUE_OF_Y= 50;
        int VALUE_OF_Z = 70;


        Map<String, Integer> CHAR_VAL_MAP = new HashMap<String, Integer>(7);

        default void initValueMap(){
            CHAR_VAL_MAP.put("X", VALUE_OF_X);
            CHAR_VAL_MAP.put("Y", VALUE_OF_Y);
            CHAR_VAL_MAP.put("Z", VALUE_OF_Z);
        }

        public int calculate(final String inStr);
}

并创建了一个摘要class:

 public abstract  class AbstractCalculator implements ICalculator{

    protected AbstractCalculator(){

        initValueMap();
    }
}

我的想法是确保 initValueMap 方法被抽象隐式调用 class。

而扩展抽象class的concreateclass是:

public class MyCalculator extends AbstractCalculator{

    public int calculate(final String romanNumberStr){
        // some logic code
    }
}

我基本上有两个问题:

1) 是否存在设计问题或OOP概念的错误使用? 2) 在 C++ 中。使用 const 作为参数是良好的编程行为。但是在java字里,就不是那么常见了。方法参数中使用final不好吗?

你把事情复杂化了。 Java 9 向集合实用程序 class 添加了一些不错的 of() 方法。您可以使用它们来创建一个充满值的映射,而无需调用额外的 init 方法。然后将该地图实例传递给 new HashMap() 以将该数据放入可修改的地图实例中。对于较旧的 java,您始终可以编写一个方法来创建 returns 预填充地图。无需像您一样进行创建和填充(在单独的代码段中)。

郑重声明:您了解接口的所有字段默认情况下都是静态的,因此在使用它们的所有代码之间共享?!

关于final,const与C++有不少不同。 final 参数给你的唯一一件事就是检查以防止你无意中写入参数。拥有它可能很有用,但大多数人根本不使用它,因为它们增加的收益很少,但会使代码更难阅读。

有几种方法可以确保仅在地图完全初始化后才调用 calculate。一种方式是直接在接口中声明和初始化:

public interface ICalculator {

    int VALUE_OF_X = 10;
    int VALUE_OF_Y = 50;
    int VALUE_OF_Z = 70;

    Map<String, Integer> CHAR_VAL_MAP = initValueMap();

    static Map<String, Integer> initValueMap() {

        Map<String, Integer> map = new HashMap<String, Integer>(7);
        map.put("X", VALUE_OF_X);
        map.put("Y", VALUE_OF_Y);
        map.put("Z", VALUE_OF_Z);

        return map;
    }

    public int calculate(final String inStr);
}

这可能是首选,因为 static 数据在声明的地方被静态初始化(尽管我们大多数人并不特别喜欢用这种代码填充接口)。

如果你想在抽象class中调用这段初始化代码,你仍然可以使用一个static块:

public abstract class AbstractCalculator implements ICalculator {
    static {
        ICalculator.initValueMap();
    }
}

但最简单的方法可能是按照 GhostCat 的回答中的建议使用 Map.of,除非您的 Java 运行时早于 9。