我有
interface Module {
List<String> parse();
}
接口有几种实现,在应用程序中我希望有HashSet<Module>
,确保每个模块只有一个实例。为此,我需要为每个班级提供适当的hashCode
。 hashCode
的正确实现将为一个模块类的各种实例返回相同的常量,但对于不同的模块则返回不同的实例。
要创建一个漂亮的设计解决方案,我想从模块的名称计算hashCode,如:
public int hashCode() {
return ConcreteModule.class.getName().hashCode();
}
但是这个代码对于接口的每个实现都是一样的...我的想法是创建一个实现哈希码的抽象模块,但是有可能达到扩展这个抽象类的类的名称吗? 像:
public abstract class AbstractModule implements Module {
public int hashCode() {
// get the class name of class extending the abstract module
// and return hashcode of its string name
}
}
然后
public class ConcreteModule extends AbstractModule implements Module {
// implementation of parse() no need to create hashcode for each module
}
您是否建议为每个模块创建hashCodes,或者是否可以创建我正在尝试的内容?欢迎提出任何建议或建议。提前致谢
答案 0 :(得分:2)
经过一番思考,你想要做的就是关掉课堂上的地图,而不是实例....
HashMap<Class<? extends Module>, <Module>> mymap = .....
然后,每个类类型只有一个值。你可以用:
mymap.put(module.class(), module);
答案 1 :(得分:1)
怎么样:
return getClass().getName().hashCode();
虽然,您可以轻松使用:
return getClass().hashCode();
答案 2 :(得分:1)
您可以像下面这样简单地实现它:
@Override
public final int hashCode() {
return this.getClass().getName().hashCode();
}
@Override
public final boolean equals(Object other) {
if (other == this) {
return true;
}
if (other == null) {
return false;
}
return other.getClass().equals(this.getClass());
}
但我不确定这是最好的主意。此外,您不能保证接口的所有实现都扩展您的抽象类。
您可以简单地维护Map<Class<? extends Module>, Module>
。每个模块实现都会将自己添加到您的注册表中,如果模块的类已经在地图中,您只需拒绝或忽略新的模块实例。