我有一个枚举,看起来像
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做到吗?
答案 0 :(得分:77)
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; }
}
但是在你的情况下,对于一个真正的系统,我会把它变成一个Enum,因为有一套固定的动物类型。
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
也很重要。
答案 1 :(得分:15)
是的,你可以。它看起来像这样:
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()
答案 2 :(得分:6)
我还有其他选择:
public enum Animal {
ELEPHANT {
@Override
boolean isMammal() {
return true;
};
@Override
boolean isReptile() {
return false;
}
},
SNAKE {
@Override
boolean isMammal() {
return false;
};
@Override
boolean isReptile() {
return true;
}
};
abstract boolean isMammal();
abstract boolean isReptile();
}
不需要外部接口,我很确定(没有测试)它也可以在Java7上使用。
答案 3 :(得分:1)
除了使用上面添加字段到枚举类型的技术之外,您还可以使用基于纯方法的方法和多态。这是更多" OOP风格"但我不会说它一定更好。
不幸的是,您需要定义一个接口:
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或更高版本。