有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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


共 (4) 个答案

  1. # 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; } }
    }
    

    请注意,我在接口中使用默认实现来减少在枚举中需要键入的数量

    关于接口的必要性:我尝试将接口中的方法作为抽象方法添加到enum顶部,Eclipse似乎允许这样做,并坚持在enum元素中实现,但随后未能正确编译这些方法。因此,看起来在没有接口的情况下它应该是可能的,但可能它还没有在编译器中实现

  2. # 2 楼答案

    我还有一个选择:

    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. # 3 楼答案

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

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

  4. # 4 楼答案

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

    但是对于一个真实的系统,我也会把它作为一个枚举,因为有一组固定的动物类型

    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 Language Specification中找到有关它的更多详细信息