通过接口使用抽象类的设计问题

时间:2019-03-16 12:58:04

标签: java oop polymorphism abstract-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);
}

并创建了一个抽象类:

 public abstract  class AbstractCalculator implements ICalculator{

    protected AbstractCalculator(){

        initValueMap();
    }
}

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

扩展抽象类的concreate类是:

public class MyCalculator extends AbstractCalculator{

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

我基本上有两个问题:

1)是否存在任何设计问题或OOP概念的错误使用? 2)在C ++中。使用const作为参数是良好的编程行为。但是用java来说,它不是那么普遍。在方法参数中使用final是否不好?

2 个答案:

答案 0 :(得分:3)

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

记录一下:您了解接口的所有字段默认情况下都是静态的,因此使用它们的所有代码之间都可以共享吗?

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

答案 1 :(得分:0)

有几种方法可以确保仅在映射完全初始化之后才调用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数据是在声明的地方静态初始化的(尽管我们大多数人并不特别喜欢用这种代码填充接口)。

如果要在抽象类中调用此初始化代码,仍然可以使用static块:

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

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