可以子类化枚举以强制编译器只接受某些枚举值吗?

时间:2016-01-09 01:01:42

标签: java javafx enums

JavaFX声明了枚举KeyCode,它枚举了公共键盘上每个键的代码。我目前正在声明一个只有给定一个修饰键才有意义的函数。它看起来像这样:

void doStuff(KeyCode c){
  if(!c.isModifierKey()) throw new IllegalArgumentException();
  ...
}

但我认为如果编译器可以为我做这个检查会更清晰。所以,如果我能以某种方式扩展' KeyCode到只包含修饰键的子集,我的代码会变得更清晰。有没有人知道如何做到这一点?

2 个答案:

答案 0 :(得分:1)

您不能在Java中继承enum

您需要定义自己的KeyCode枚举。但我怀疑你不会在这里获得太多清晰度。您可能希望将if命令封装到assert方法中,如下所示:

assertModifierKeyCode(KeyCode c) {
   if(!c.isModifierKey()) throw new IllegalArgumentException();
}

然后你的方法更简洁一些意思:

void doStuff(KeyCode c){
   assertModifierKeyCode(c);
    ...
}

当然,在调用doStuff之前,您可以自由检查键码约束,然后您可以使用ModifierCode枚举,将其误用为过滤器:

ModifierCode m = ModifierCode.fromKeyCode(c); // could throw Exception
doStuff( m );

...

void doStuff( ModifierCode m ) {
   switch ( m ) {
   case ...
}

要让KeyCode仍然可用,您构建ModifierCode并嵌入KeyCode

public enum ModifierCode {

   LSHIFT(KeyCode.LeftShift),
   RSHIFT(KeyCode.RightSHift)  // bear with me, I dont have KeyCode enum in memory
   ; 

   final private KeyCode keyCode;

   private ModifierCode(KeyCode c) {
       this.keyCode = c;
   }

   public KeyCode getKeyCode() {  // maybe asKeyCode() would also be a nifty name :-)
        return keyCode;
   }

   public static ModifierCode fromKeyCode(KeyCode c) {
       for(ModifierCode m : values() ) {
            if( m.keyCode == c ) {
                return m;
            }
       }
       throw IllegalArgumentException("No MOdifierCode with that KeyCode!");
   }
}

答案 1 :(得分:0)

我不认为这样的事情是可能的。我最接近的设计建议是确保枚举实现一个接口,然后将其拆分为两个枚举,一个带有修饰键的值,另一个没有。现有方法将采用接口,而不是枚举类。您应该尝试编程到接口而不是实现。

我的猜测是做运行时检查是最好的解决方案。