代码之家  ›  专栏  ›  技术社区  ›  Samuel Carrijo

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

  •  58
  • Samuel Carrijo  · 技术社区  · 15 年前

    我有一个枚举,它看起来像

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

    3 回复  |  直到 7 年前
        1
  •  77
  •   user177800    7 年前

    是的,枚举是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 也。

        2
  •  15
  •   danben    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()

        3
  •  1
  •   rghome    7 年前

    除了使用上面向枚举类型添加字段的技术之外,还可以使用基于纯方法的方法和多态性。这是更“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或以上。