#java #inheritance #enums
#java #наследование #перечисления
Вопрос:
У меня есть строка (которая является сообщением), которую я получаю в качестве входных данных, и мне нужно выполнить одно из 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
}
возможно ли это сделать одним методом перечисления?
или я должен просто попытаться создать одно, и если я получу исключение, попробуйте другое и так далее?
Комментарии:
1. Можете ли вы описать, как ваше сообщение должно сравниваться с перечислениями?
2. Вам нужно предоставить больше информации о ваших ограничениях — почему у вас четыре разных перечисления? Требуется ли это где-либо еще в вашей программе? Каково желаемое поведение здесь? Вы просто вызываете метод для правильного перечисления и используете несколько перечислений вместо переопределения метода? Чего вы пытаетесь достичь в этой программе?
3. @Jeremy Heiler строка сообщения будет содержать от ОДНОГО до ДЕВЯТИ. @Mark Tozzi Каждое из перечислений означает, что сообщение должно быть отправлено в другую часть кода, и я не могу объединить их все в одно перечисление, потому что это остановило бы работу других частей. по аналогии, я могу получить любое число в строке, и мне нужно посмотреть, принадлежит ли оно к ЧЕТНОМУ или НЕЧЕТНОМУ перечислению.
Ответ №1:
Как отмечали другие, возможно, было бы лучше подумать, действительно ли вам нужны 4 разных перечисления.
Но если вы это сделаете, вы могли бы заставить их реализовать общий интерфейс. Затем вы можете сопоставить входные строки с соответствующим элементом enum и вызвать его метод для выполнения того, что вы хотите. Что-то вроде
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:
То, что вы действительно ищете, — это агрегирование других перечислений. Самый простой способ добиться этого — создать new enum
, который помещает все эти варианты в new 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;
}
}
Это более корректно объединит предыдущие перечисления в единую структуру данных.
Комментарии:
1. Идентификаторы в перечислении должны быть новыми именами. Им не разрешается быть ранее определенными константами из других перечислений, как в вашем примере.
2. @Avi, ты прав — слишком упростил проблему. Ждите продолжения кода.
Ответ №5:
Даже учитывая ваш нечетный / четный пример в комментариях, я не считаю, что несколько перечислений — это правильный путь. Я бы использовал что-то вроде (предупреждение, непроверено):
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()
для поиска элемента enum и 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);
}
Комментарии:
1. Вы могли бы, если хотите, поместить всю функциональность в сам класс enum; я опустил это для наглядности.
2. Эта функциональность поставляется в java enums «из коробки». Просто вызовите Type.valueOf(«ОДИН»)