我正在尝试为我的程序设置一个多态的ExportRule系统,但是在弄清楚如何从配置文件构造所需的ExportRule时遇到麻烦,该配置文件通过String在文件的顶部定义了ExportRule。
我一直想做这样的事情:
private ExportRule loadExportRule(String fileName) throws IOException, InvalidConfigurationException, FileNotFoundException{
if(fileName == null) {
throw new NullPointerException("fileName cannot be null!");
}
YamlConfiguration exportRuleConfig = new YamlConfiguration();
exportRuleConfig.load(getFilePath(fileName));
return ExportRules.fromString(exportRuleConfig.getString("exportRule")).fromYamlConfiguration(exportRuleConfig);
}
其中ExportRules是将字符串映射到实际.class(扩展ExportRule)的枚举,然后将调用静态fromFileConfiguration()工厂方法以从文件生成ExportRule,如下所示:
exportRule: nameOfExportRule
//all the configurationstuff for the rule
我遇到的问题是如何实际调用fromFileConfiguration()方法,因为它是静态方法,因此Java不允许我通过ExportRule接口保证它的存在
是否有一种干净的方法来实现这样的目标,还是我必须在枚举中为每个ExportRule做某种switch语句?
编辑:
谢谢glee8e!
这是我的枚举:
public enum ExportRules {
COMMENT_CONCAT("CommentConcat") {
@Override
public ExportRule fromFileConfiguration(FileConfiguration fileConfiguration) throws InvalidConfigurationException {
return CommentConcat.fromFileConfiguration(fileConfiguration);
}
};
private String name;
ExportRules(String name) {
this.name = name;
}
public abstract ExportRule fromFileConfiguration(FileConfiguration fileConfiguration) throws InvalidConfigurationException;
public String getName() {
return name;
}
public static ExportRules fromString(String str) {
for(ExportRules rule : ExportRules.values()) {
if(str.equalsIgnoreCase(rule.getName())) return rule;
}
return null;
}
}
最佳答案
多态不是用于静态对象,而是用于实例方法,至少在Java中是如此。将您的fromFileConfiguration
设为抽象实例方法,并将其实现为单个常量:
public enum ExportRules {
A_RULE {
@Override public ExportRule fromFileConfiguration(YamlConfiguration c) {...}
},
//...
public abstract ExportRule fromFileConfiguration(YamlConfiguration c);
}
请记住,java枚举也是普通的类。他们可以实现接口,具有抽象方法等。但是,您不能拥有非
Enum
超类和非私有构造函数。附注:对于Java8,由于该枚举只有一个抽象方法,因此您可以使用
Function
而不是创建许多子类,如下所示:public enum ExportRules {
A_RULE((c) -> {//...}),
//...
private final Function<YamlConfiguration, ExportRule> func;
private ExportRules( Function<YamlConfiguration, ExportRule> fun) {
func = fun;
}
public ExportRule fromFileConfiguration(YamlConfiguration c) {
return func.apply(c);
}
}
这不是经典的多态性,但可以完成工作并减少产生的废品。