我可以在Java中为枚举添加一个函数吗?

时间:2010-03-16 18:32:30

标签: java function enums

我有一个枚举,看起来像

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做到吗?

4 个答案:

答案 0 :(得分:77)

是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也很重要。

答案 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或更高版本。