Могу ли я добавить функцию в перечисления в Java?
у меня есть перечисление, которое выглядит как
public enum Animal {
ELEPHANT,
GIRAFFE,
TURTLE,
SNAKE,
FROG
}
и я хочу сделать что-то вроде
Animal frog = Animal.FROG;
Animal snake = Animal.SNAKE;
boolean isFrogAmphibian = frog.isAmphibian(); //true
boolean isSnakeAmphibian = snake.isAmphibian(); //false
boolean isFrogReptile = frog.isReptile(); //false
boolean isSnakeReptile = snake.isReptile(); //true
boolean isFrogMammal = frog.isMammal(); //false
boolean isSnakeMammal = snake.isMammal(); //false
я упростил пример для дидактических целей, но это было бы действительно полезно для меня в моей реальной жизни пример. Могу ли я сделать это на Java?
3 ответа:
Да перечисление-это класс в Java:
public enum Animal { ELEPHANT(true), GIRAFFE(true), TURTLE(false), SNAKE(false), FROG(false); private final boolean mammal; private Animal(final boolean mammal) { this.mammal = mammal; } public boolean isMammal() { return this.mammal; } }
но в вашем случае для реальной системы я бы сделал это перечисление, так как есть фиксированный набор типов животных.
public enum Type { AMPHIBIAN, MAMMAL, REPTILE, BIRD } public enum Animal { ELEPHANT(Type.MAMMAL), GIRAFFE(Type.MAMMAL), TURTLE(Type.REPTILE), SNAKE(Type.REPTILE), FROG(Type.AMPHIBIAN); private final Type type; private Animal(final Type type) { this.type = type; } public boolean isMammal() { return this.type == Type.MAMMAL; } public boolean isAmphibian() { return this.type == Type.AMPHIBIAN; } public boolean isReptile() { return this.type == Type.REPTILE; } // etc... }
также обратите внимание, что важно сделать любую переменную экземпляра
final
Как хорошо.
да, можно. Это будет выглядеть так:
public enum Animal { ELEPHANT(false), GIRAFFE(false), TURTLE(false), SNAKE(false), FROG(true); private final boolean isAmphibian; Animal(boolean isAmphibian) { this.isAmphibian = isAmphibian; } public boolean isAmphibian() { return this.isAmphibian; } }
тогда вы бы назвали это так:
Animal.ELEPHANT.isAmphibian()
а также используя методы выше, которые добавляют поле к перечисленному типу, вы также можете использовать чистый метод, основанный на подходе и полиморфизме. Это больше "ООП стиль", но я бы не сказал, что это обязательно лучше.
к сожалению, вам нужно определить интерфейс:
public interface AnimalTraits { default boolean isAmphibian() { return false; }; default boolean isReptile() { return false; }; default boolean isMammal() { return false; }; }
но тогда вы можете реализовать интерфейс в каждом из ваших элементов перечисления:
public enum Animal implements AnimalTraits { ELEPHANT { @Override public boolean isMammal() { return true; } }, GIRAFFE { @Override public boolean isMammal() { return true; } }, TURTLE { @Override public boolean isReptile() { return true; } }, SNAKE { @Override public boolean isReptile() { return true; } }, FROG { @Override public boolean isAmphibian() { return true; } } }
обратите внимание, что я использую реализаций по умолчанию в интерфейсе, чтобы сократить объем вводимого текста, вам необходимо в перечислимом.
Что касается необходимости интерфейса: я попытался добавить методы в интерфейс в качестве абстрактных методов в верхней части перечисления, и Eclipse, казалось, позволял это и настаивал на реализациях в элементах перечисления, но затем не смог их правильно скомпилировать. Таким образом, похоже, что это должно быть возможно без интерфейса, но, возможно, это еще не реализовано в компиляторе.
Примечание: требуется Java 8 или выше.