继承的枚举重新定义

时间:2012-10-06 09:51:04

标签: java enums

它比听起来更复杂,但我认为我不得不尝试类似的东西。我想创建一个带有枚举原型的抽象父类(我想声明枚举只有一个值,可能是默认的单元化值,并声明我将从子类中使用的几个方法),然后我想要扩展抽象父类以实际初始化相同的枚举(我知道这实际上隐藏了父枚举),以便kid类将在枚举中定义一组项目,但可能保留方法。

我对这个抽象级别知之甚少,所以我现在将描述我的问题的本质,以防有更实际的解决方案: 我有一堆文件,其中包含基于枚举实现大量命令的类。 (例如,class1实现Observer有一个更新方法,它使用基于枚举的开关来决定选择哪个命令,同样适用于其他类)我现在想要以一种我有一个精确的枚举变量的方式抽象整个事物所有类中的相同名称(例如CommandSet),以便我可以在父级内部使用通用方法,该方法将能够使用枚举的内部方法将帮助列表打印到我的系统。现在我知道我可以在每个类中重写完全相同的方法,但我想抽象它以便其他人可以继续扩展我正在制作的库!

希望我不会太困惑或太困惑,​​而且somone可以帮助我! :)

编辑:这是代码的概念(可能不对):

  public abstract class Commands{
    enum CommandSet{ 
        // empty command, placeholder
        null_command ("command name", "command description");
        // the Strings used for name and description
        private final String name;
        private final String description;
        // constructor 
        CommandSet(String name, String description){
            this.name=name;
            this.description=description;
        }
        // get parameters
        public String getName(){
            return name;
        }
        public String getDescription(){
            return description;
        }
    }
    public void showHelp(){
        for (CommandSet i : CommandSet.values()) {
            printf(i.getName(),":",i.getDescription());
        }
    }
}

public class StandardCommads extends Commands implements Observer{
    // I want to change the enum here, just changing the values so that null_command ("command name", "command description") will get removed and I will add a dozen other values, but keep the methods that the parent had
    // update inherited from Observer
    @Override
    public void update(Observable observable, Object object) {
        // I want the commands inside the switch cases defined inside this class's enum 
        switch(CommandSet.valueOf(String.valueOf(object)){
            case command1: doStuff1();break;
            case command2: doStuff2();break;
            ...
            case commandN: doStuffN();break;
        }
    // other methods
    void doStuff1(){
        ...
    }
    ...
    void doStuffN(){
        ...
    }
}

public class NonStandardCommads extends Commands implements Observer{
    // Another set of commands here for the enum keeping the same methods it had in the parent

    // update inherited from Observer
    @Override
    public void update(Observable observable, Object object) {
        // Other set of commands inside this class used in the switch statement
        switch(CommandSet.valueOf(String.valueOf(object)){
            case Zcommand1: doStuffz1();break;
            case Zcommand2: doStuffz2();break;
            ...
            case ZcommandN: doStuffzN();break;
        }
    // other methods
    void doStuffz1(){
        ...
    }
    ...
    void doStuffzN(){
        ...
    }
}

2 个答案:

答案 0 :(得分:3)

不可能:Java枚举既不能扩展另一个类,也不能自己扩展。

然而,他们可以实现接口。也许你可以利用它来发挥你的优势。


关于枚举的其他内容可能会对您有所帮助:枚举不是immutable。您可以更改枚举的字段值,但这会改变整个JVM的字段值。

另一种方法可能是将您的子类实例传递给枚举的方法,并让枚举使用您的子类作为call back,以便为枚举的其他用户从枚举中获取不同的功能。

答案 1 :(得分:1)

不,你不能这样做。

Java Enums很快耗尽了气体。当你想要在以后添加/扩展更多定义或实例化枚举实例时。 (例如,从数据库加载它们,在实例方法中配置它们,而不仅仅是静态配置它们。)

Java枚举中的行为/或逻辑也有限 - 您可以定义&设置属性,但只有静态初始化,逻辑似乎是基本的(你最终只是比较引用或序数,与其他定义的枚举常量)。

你能做什么:

可以使用整数代码实现祖先Command或AbstractCommand类,然后将其子类化以定义具体值/附加代码/加载或配置实例等。

为了进一步获益,您将获得高效的开关和放大器。发送(通过代码)以及定义更多细节/属性,根据需要实例化命令等的能力。

基本上,这是您在Java支持之前定义Enum的方式。虽然您可能将它们用作值对象,而不是严格静态。

我的专业知识:

我做了大量的编译器和类型系统工作,尝试了文件类型和相关数据/行为的枚举..探索了外部限制,并达到了明确的界限。

我也希望能够实例化&将新的UnknownFileType(“”)作为答案返回。枚举不能这样做。

示例:

(我们将通过String发送,而不是int - 因为您的代码似乎使用Java 7.这使命令解析更容易,而不需要语法“名称”和内部整数“代码”。)

public static class Command {
  protected String code;
  protected String desc;
  public String getCode() {return code;}
  public String getDesc() {return desc;}
  public Command (String code, String desc) {
    this.code = code;
    this.desc = desc;
  }
  public String toString() {return code;}
}

public class StandardCommands {
  public static Command READ = new Command("READ", "read a record");
  public static Command CREATE = new Command("WRITE", "create a record");
  public static Command EDIT = new Command("WRITE", "modify a record");
}
public class FurtherCommands extends StandardCommands {
  public static Command LIST = new Command("LIST", "list all records");
}

public class QueryCommands extends FurtherCommands {
  public static class QueryCmd extends Command {
    protected String search;
    public String getSearch() {return search;}
    // constructor..
  }
  public static QueryCmd QUERY_EXAMPLE = new QueryCmd("QUERY", "example", "query for specified string");


  public static QueryCmd createQuery (String search) {
    return new QueryCmd( "QUERY", search, "query for specified string");
  }
}