如何从抽象类扩展枚举类?

Zim*_*bim 36 java

有这样的事情:

public enum Token
{
     FOO("foo", "f"),
     QUIT("quit", "q"),
     UNKNOWN("", "");
     ...

     public parse(String s) {
         for (Token token : values()) {
              ...
              return token;
         }
         return UNKNOWN;
     }
}
Run Code Online (Sandbox Code Playgroud)

抽象类:

abstract class Base 
{
    private boolean run;

    Base() {
        run = true;

        while (run) {
             inp = getInput();
             act(inp);
        }
    }

    public boolean act(String s) {
        boolean OK = true;
        switch (Token.parse(inp)) { /* Enum */
             case FOO:
                    do_foo();
                    break;
             case QUIT:
                    run = false;
                    break;
             case UNKNOWN:
                    print "Unknown" + inp;
                    OK = false;
                    break;
             }
         }
         return OK;
    }
}
Run Code Online (Sandbox Code Playgroud)

而扩展器:

class Major extends Base
{

}
Run Code Online (Sandbox Code Playgroud)

我想要的是扩展act,如果super不处理它然后尝试处理它Major.例如add PRINT_STAT("print-statistics", "ps")- 但同时让Base类处理默认值QUIT.

这是一个完全错误的方法吗?

到目前为止我所做的是添加一个接口通常:

public interface BaseFace
{
      public boolean act_other(String inp);
}
Run Code Online (Sandbox Code Playgroud)

在课堂上Base implements BaseFace:

      case UNKNOWN:
          OK = act_other(inp);
Run Code Online (Sandbox Code Playgroud)

在课堂上Major:

  public boolean act_other(String inp) { 
       if (inp.equals("blah")) {
            do_blah();
            return true; 
       }
       return false;
  }
Run Code Online (Sandbox Code Playgroud)

这看起来像一个可用的设计?

而且,主要问题:

是否有延长一些好的方法Token类,这样我可以使用相同的开关办法,Major作为Base?我想知道的是,如果有一个更好的设计,第二个,如果我必须为一个新的令牌类Major或如果我以某种方式可以扩展或以其他方式重新使用现有的.


编辑:概念点是Base我可以轻松地在不同的项目中重复使用的类处理各种类型的输入.

And*_*mas 47

所有enums隐瞒扩展Enum.在Java中,类最多可以扩展一个其他类.

但是,您可以让您的枚举类实现一个接口.

这个关于枚举类型的Java教程:

注意:所有枚举都隐式扩展java.lang.Enum.因为类只能扩展一个父类(请参阅声明类),所以Java语言不支持多重继承状态(请参阅状态,实现和类型的多重继承),因此枚举不能扩展任何其他内容.

编辑Java 8:

从Java 8开始,接口可以包含默认方法.这允许您在接口中包含方法实现(但不包括状态).虽然此功能的主要目的是允许公共接口的演变,但您可以使用它来继承定义多个枚举类之间的公共行为的自定义方法.

但是,这可能很脆弱.如果稍后将具有相同签名的方法添加到java.lang.Enum类,它将覆盖您的默认方法.(当在类的超类和接口中定义方法时,类实现总是获胜.)

例如:

interface IFoo {
    public default String name() {
        return "foo";
    }
}

enum MyEnum implements IFoo {
    A, B, C
}

System.out.println( MyEnum.A.name() );  // Prints "A", not "foo" - superclass Enum wins
Run Code Online (Sandbox Code Playgroud)

  • 完成教程的有用链接:http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9 (3认同)

Pra*_*nde 5

您的问题似乎是命令模式的不错选择

最好将枚举用作支持的操作的逻辑组。IMO,只有一个枚举将所有受支持的操作分组,这将提高代码的可读性。考虑到这一点,令牌枚举应包含所有受支持的操作类型

enum Token
{
   FOO("foo", "do_foo"),
   QUIT("quit", "do_quit"),
   PRINT_STATS("print", "do_print_stats"),
   UNKNOWN("unknown", "unknown")
   .....   

}
Run Code Online (Sandbox Code Playgroud)

考虑创建一个接口Actor,该接口定义一个方法,例如act,如下所示:

public interface Actor
{
   public void act();
}
Run Code Online (Sandbox Code Playgroud)

与其让单个类做同样的事情,还不如让每个受支持的命令拥有一个类,例如

public class FooActor implements Actor
{
    public void act()
    {
        do_foo(); //call some method like do_foo
    }
}

public class PrintActor implements Actor
{
    public void act()
    {
        print_stats(); //call some print stats
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,将有一个驱动程序代码,将要执行的动作作为输入,初始化适当的Actor并通过调用act()方法执行该动作。

public class Driver
{
   public static void main(String[] args)
   {
      String command; // will hold the input string from the user.

      //fetch input from the user and store it in command

      Token token = Token.parse(command);

      switch(token)
      {
         case FOO:
                   new FooActor().act();
                   break;

         case PRINT_STATS:
                   new PrintActor().act();
                   break;
          .... 

      }


   }
}
Run Code Online (Sandbox Code Playgroud)

这样的设计将确保您可以轻松添加新命令,并且代码保持模块化。

  • 您可以向枚举添加一个act方法,而不是switch(token),只需调用token.act();即可。 (2认同)