枚举继承,或类似的东西

7

我有一个字符串(一条消息),作为输入,根据这个字符串需要执行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
2
你需要提供更多关于约束条件的信息 - 为什么你有四个不同的枚举?这在程序的其他地方是否需要?这里的期望行为是什么?你只是在正确的枚举上调用方法并使用多个枚举而不是重写该方法吗?你在这个程序中想要实现什么? - Mark Tozzi
@Jeremy Heiler 消息字符串将包含数字1到9。@Mark Tozzi 每个枚举值都意味着该消息应发送到代码的不同部分,我无法将它们全部组合成单个枚举值,因为这会导致其他部分停止工作。打个比方,我可以得到字符串中的任何数字,并且必须确定它属于ODD枚举还是EVEN枚举。 - Benny
6个回答

6

正如其他人所评论的那样,你最好考虑一下是否真的需要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();
  }
}

假设你想要做的四件事情对应于四个枚举值。如果不是这样,你可以为每个枚举成员单独覆盖该方法,例如:

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 }
};

1

你真正需要的是其他枚举类型的聚合。最简单的方法是创建一个新的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
@Avi,你说得对 - 简化了问题。请稍等,更多代码即将到来。 - Bob Cross

1
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);
}

1

你可以创建一个包含它们所有的 Map

 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);

0

即使在评论中给出了您的奇偶示例,我认为多个枚举不是解决此问题的方法。我会使用类似以下代码的东西(注意,未经测试):

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() 查找它属于哪个类别中的三个类别之一。


-1

目前并不完全清楚您的问题,但或许您想要定义字符串和常量之间的映射,示例如下:

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);
}

如果你愿意的话,你可以把所有功能都放到枚举类本身中;但出于清晰起见,我省略了这一点。 - Avi
这个功能在Java枚举中自带。只需调用Type.valueOf("ONE")即可。 - finalman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接