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

发布于 2024-08-25 17:57:20 字数 582 浏览 4 评论 0原文

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

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

I have an enum, which looks like

public enum Animal {
  ELEPHANT,
  GIRAFFE,
  TURTLE,
  SNAKE,
  FROG
}

and I want to do something like

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

I simplified the example for didactic purposes, but this would be really useful to me for my real life example. Can I do it in Java?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

So尛奶瓶 2024-09-01 17:57:20

是的,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 语言规范

Yes Enum is a class in 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; }
}

but in your case for a real system I would make that an Enum as well since there is a fixed set of types of animals.

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...
}

Also note that it is important to make any instance variable final as well.

You can find more details about it in the Java Language Specification.

苄①跕圉湢 2024-09-01 17:57:20

我还有另一个选择:

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。

I have an other option:

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

No need of external Interface and I am quite sure (did not test) it works also on Java7.

画▽骨i 2024-09-01 17:57:20

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

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

Yes, you can. It would look like this:

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

Then you would call it like:

Animal.ELEPHANT.isAmphibian()

美胚控场 2024-09-01 17:57:20

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

As well as using the techniques above which add a field to the enumerated type you can also use a pure method based approach and polymorphism. This is more "OOP style" but I would not say it is necessarily better.

Unfortunately, you may (see the comment below) need to define an interface:

public interface AnimalTraits {
    default boolean isAmphibian()   { return false; };
    default boolean isReptile()     { return false; };
    default boolean isMammal()      { return false; };
}

But then you can them implement the interface in each of your enumeration elements:

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

Note that I use default implementations in the interface to cut down on the amount of typing you need in the enum.

Regarding the necessity of the interface: I tried adding the methods in the interface as abstract methods at the top of the enum and Eclipse seemed to allow it and insisted on implementations in the enum elements, but then failed to compile those properly. So it looks like it ought to be possible without an interface, but perhaps it is not yet implemented in the compiler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文