1

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

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

希望我不会太困惑或太困惑,​​有人可以帮助我!:)

编辑:这是代码的一个想法(可能不正确):

  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(){
        ...
    }
}
4

2 回答 2

3

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

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


枚举还有一些其他的东西可以帮助你:枚举不是不可变的。您可以更改枚举的字段值,但这会为整个 JVM 更改它们。

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

于 2012-10-06T10:23:00.077 回答
2

不,你不能那样做。

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

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

你可以做什么:

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

为了获得更多好处,您可以获得高效的切换和调度(通过代码)以及定义更多细节/属性、根据需要实例化命令等的能力。

本质上,这就是在 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");
  }
}
于 2012-10-06T10:49:24.587 回答