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

Sam*_*ijo 60 java enums function

我有一个枚举,看起来像

public enum Animal {
  ELEPHANT,
  GIRAFFE,
  TURTLE,
  SNAKE,
  FROG
}
Run Code Online (Sandbox Code Playgroud)

我想做点什么

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
Run Code Online (Sandbox Code Playgroud)

我简化了教学目的的例子,但这对我的真实例子非常有用.我可以用Java做吗?

小智 80

是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; }
}
Run Code Online (Sandbox Code Playgroud)

但在你的情况下,对于一个真正的系统,我会把它作为一个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...
}
Run Code Online (Sandbox Code Playgroud)

另请注意,创建任何实例变量也很重要final.

  • 显式总是优于隐式 (2认同)

dan*_*ben 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;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后你会称之为:

Animal.ELEPHANT.isAmphibian()

  • 不是"应该是私人的",但必须是私人的. (5认同)
  • 这很奇怪 - http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html上的Planet示例不使用构造函数上的private修饰符.你确定吗? (2认同)
  • 不需要.他们隐含地已经是私人的.列无论如何都是不可实现的. (2认同)

Ema*_*rsa 11

我还有一个选择:

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();
}
Run Code Online (Sandbox Code Playgroud)

不需要外部接口,我很确定(没有测试)它也适用于 Java7。

  • 这是最完整的答案!+1 (2认同)

rgh*_*ome 6

除了使用上述向枚举类型添加字段的技术外,您还可以使用基于纯方法的方法和多态性。这更像是“OOP 风格”,但我不会说它一定更好。

不幸的是,您可能(请参阅下面的评论)需要定义一个接口:

public interface AnimalTraits {
    default boolean isAmphibian()   { return false; };
    default boolean isReptile()     { return false; };
    default boolean isMammal()      { return false; };
}
Run Code Online (Sandbox Code Playgroud)

但是你可以在你的每个枚举元素中实现接口:

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; } }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我在界面中使用默认实现来减少您需要在枚举中输入的数量。

关于接口的必要性:我尝试将接口中的方法添加为枚举顶部的抽象方法,Eclipse 似乎允许它并坚持在枚举元素中实现,但随后未能正确编译这些方法。所以看起来没有接口应该是可能的,但也许它尚未在编译器中实现。