我可以在 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 做吗?

93256 次浏览

是的,你可以。它看起来像这样:

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

是的 Enum 是 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; }
}

但是对于一个真正的系统,我会把它变成一个 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也很重要。

你可以在 Java 语言规范中找到更多关于它的细节。

除了使用上述向枚举类型添加字段的技术之外,还可以使用纯方法和多态性。这是更多的“ 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 似乎允许这样做,并坚持在枚举元素中实现这些方法,但是没能正确地编译这些方法。所以看起来没有接口应该是可行的,但是可能还没有在编译器中实现。

我还有一个选择:

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上工作。