【问题标题】:enum inheritance, or something similar枚举继承,或类似的东西
【发布时间】:2011-05-09 13:02:55
【问题描述】:

我有一个字符串(这是一条消息)作为输入,我需要根据字符串执行 4 种可能的事情之一 我知道有 eunm.valueOf() 选项,但我有 4 个不同的枚举,每个枚举都有很少的可能消息。

看起来像:

public enum first{ONE,TWO,THREE};
public enum second{FOUR,FIVE,SIX};
public enum third{SEVEN,EIGHT,NINE};

public void work(String message){
    //Here I want to compare message string to one of the 3 enums
}

是否可以在枚举的一种方法中做到这一点? 还是我应该尝试创建一个,如果我遇到异常尝试另一个等等?

【问题讨论】:

  • 你能描述一下你的消息应该如何与枚举进行比较吗?
  • 你需要提供更多关于你的约束的信息——为什么你有四个不同的枚举?您的程序中的其他地方是否需要这样做?这里期望的行为是什么?您是否只是在正确的枚举上调用方法并使用多个枚举而不是覆盖该方法?你想在这个项目中完成什么?
  • @Jeremy Heiler 消息字符串将包含 ONE 到 NINE。 @Mark Tozzi 每个枚举都意味着应该将消息发送到代码的不同部分,我不能将它们全部组合到一个枚举中,因为它会阻止其他部分工作。打个比方,我可以得到字符串中的任意数字,我要看看他是属于ODD枚举还是EVEN枚举。

标签: java inheritance enums


【解决方案1】:

正如其他人评论的那样,最好考虑一下您是否真的需要 4 个不同的枚举。

但如果你这样做,你可以让它们实现一个通用接口。然后您可以将输入字符串映射到适当的枚举成员,并调用其方法来完成您想要的。类似的东西

public interface SomeInterface {
  void doSomething();
};

public enum First implements SomeInterface {
  ONE,TWO,THREE;
  @Override
  public void doSomething() { ... }
};
...
Map<String, SomeInterface> myMap = new HashMap<String, SomeInterface>();
for (First item : First.values()) {
  myMap.put(item.toString(), item);
}
...

public void work(String message){
  SomeInterface obj = myMap.get(message);
  if (obj != null) {
    obj.doSomething();
  }
}

这假设您想要做的 4 件可能的事情对应于 4 个枚举。如果没有,您也可以为每个枚举成员单独覆盖该方法,例如

public enum First implements SomeInterface {
  ONE,
  TWO {
    @Override
    public void doSomething() { // do something specific to TWO }
  },
  THREE;
  @Override
  public void doSomething() { // general solution for all values of First }
};

【讨论】:

    【解决方案2】:

    Java 中的枚举是成熟的类。个别值甚至可以覆盖行为以满足他们的需要。它太酷了。您可以利用它来发挥自己的优势:

    public enum Value implements Worker
    {
        ONE,
        TWO,
        THREE
        {
            @Override
            public void doWork(String message)
            {
                // overrides behavior of base enum
            }
        },
        FOUR,
        /* ... */,
        NINE;
    
        private final String message;
    
        Value() { this(""); }
        Value(String message) { this.message = message; }
    
        public void doWork(String message)
        {
            if (this.message.equals(message))
            {
                /* ... */
            }
        }
    }
    
    public interface Worker
    {
        void doWork(String message);
    }
    

    【讨论】:

      【解决方案3】:

      您可以创建所有地图

       static final Map<String, Enum> enumMap = new LinkedHashMap<String, Enum>(){{
           for(First e: First.values()) put(e.name(), e);
           for(Second e: Second.values()) put(e.name(), e);
           for(Third e: Third.values()) put(e.name(), e);
       }};
      
       Enum e = enumMap.get(name);
      

      【讨论】:

        【解决方案4】:

        您真正要寻找的是其他枚举的聚合。最简单的方法是创建一个新的enum,将所有这些选择放在一个新的enum 中。大意是这样的:

        public enum Combination {
            NEWONE(first.ONE), NEWTWO(first.TWO), NEWTHREE(first.THREE),
            NEWFOUR(second.FOUR), NEWFIVE(second.FIVE), NEWSIX(second.SIX),
            NEWSEVEN(third.SEVEN), NEWEIGHT(third.EIGHT), NEWNINE(third.NINE);
        
            private String contents;
        
            public Combination(first f) {
                contents = f.toString();
            }
        
            public Combination(second s) {
                contents = s.toString();
            }
        
            public Combination(third t) {
                contents = t.toString();
            }
        
            public String toString() {
                return contents;
            }
        }
        

        这将更正确地将以前的枚举聚合到单个数据结构中。

        【讨论】:

        • 枚举中的标识符应该是新名称。不允许它们是以前定义的其他枚举中的常量,如您的示例所示。
        • @Avi,你是对的 - 过度简化了问题。等待更多代码。
        【解决方案5】:

        即使给出了 cmets 中的奇数/偶数示例,我也不认为使用多个枚举是要走的路。我会使用类似(警告,未经测试):

        public enum Numbers {
        ONE("first"), TWO("first"), THREE("first"), FOUR("second"), FIVE("second"), SIX("second"), SEVEN("third"), EIGHT("third"), NINE("third")
        
        private String type;
        
        Numbers(String t) { this.type = t; }
        String getType { return this.type; }
        }
        

        然后您可以使用valueOf() 查找枚举元素,并使用getType() 找出它属于您的三个类别中的哪一个。

        【讨论】:

          【解决方案6】:

          您的要求并不完全清楚,但也许您想定义字符串和常量之间的映射,如下所示:

          enum Type { FIRST, SECOND, THIRD };
          Map<String, Type> mapping = new HashSet<String, Type>(){{
              put("ONE", Type.FIRST);
              put("TWO", Type.FIRST);
              //...
              put("NINE", Type.THIRD);
          }};
          
          public Type getTypeFromString(String s) {
              return mapping.get(s);
          }
          

          【讨论】:

          • 如果需要,您可以将所有功能放入枚举类本身;为了清楚起见,我省略了这个。
          • 这个功能在 java 枚举中是开箱即用的。只需调用 Type.valueOf("ONE")
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-03-07
          • 2017-02-13
          • 1970-01-01
          • 1970-01-01
          • 2011-12-07
          • 2015-11-29
          • 2010-10-19
          相关资源
          最近更新 更多