使用带有接口的抽象 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。
我知道有几个标题相似的主题,但实际上我的问题与其他主题略有不同。
我设计了这样一个解决方案,抽象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。