是否可以扩展 Java 枚举?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2642281/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 10:15:32  来源:igfitidea点击:

Is it possible to extend Java Enums?

javaenums

提问by CaseyB

Here's what I am looking to accomplish, I have a class that has an enum of some values and I want to subclass that and add more values to the enum. This is a bad example, but:

这就是我想要完成的事情,我有一个类,它包含一些值的枚举,我想对其进行子类化并向枚举添加更多值。这是一个不好的例子,但是:

public class Digits
{
 public enum Digit
 {
  0, 1, 2, 3, 4, 5, 6, 7, 8, 9
 }
}

public class HexDigits extends Digits
{
 public enum Digit
 {
  A, B, C, D, E, F
 }
}

so that HexDigits.Digit contains all Hex Digits. Is that possible?

以便 HexDigits.Digit 包含所有十六进制数字。那可能吗?

采纳答案by cletus

No it's not possible. The best you can do is make two enums implement and interface and then use that interface instead of the enum. So:

不,这是不可能的。您能做的最好的事情是使两个枚举实现和接口,然后使用该接口而不是枚举。所以:

interface Digit {
  int getValue();
}

enum Decimal implements Digit {
  ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE;

  private final int value;

  Decimal() {
    value = ordinal();
  }

  @Override
  public int getValue() {
    return value;
  }
}

enum Hex implements Digit {
  A, B, C, D, E, F;

  private final int value;

  Hex() {
    value = 10 + ordinal();
  }

  @Override
  public int getValue() {
    return value;
  }
}

回答by Thilo

No.

不。

Enums cannot be subclassed.

枚举不能被子类化。

The reasoning here is that an enumeration defines a fixed number of values. Subclassing would break this.

这里的推理是枚举定义了固定数量的值。子类化将打破这一点。

回答by luis.espinal

No, you can't. If you look at the definition of Enum, instances of it are final and can't be extended. This makes sense if you understand enums as a finite, finalset of values.

不,你不能。如果您查看 Enum 的定义,它的实例是最终的并且不能扩展。如果您将枚举理解为一组有限的最终值,这很有意义。

There is a difference between a numeral (an syntactic artifact) which could be binary, decimal, hex or whatever, and the actual semanticnumber, the numerical entity represented syntactically by a numeral in a context (the base system.)

可以是二进制、十进制、十六进制或其他任何形式的数字(句法工件)与实际语义数字(在上下文中由数字在句法上表示的数字实体(基本系统))之间存在差异。

In your example, what you need is

在您的示例中,您需要的是

  • enums specifying syntatic numerals (decimal digits and alphabetic symbols representing legalhexadecimals; that is, enum tokens, and
  • classes specifying behavior (or grammar) required for syntactically representing a number as a numeral (using the numeral [syntactic] enums).
  • 指定语法数字的枚举(代表合法十六进制的十进制数字和字母符号;即枚举标记,以及
  • 指定将数字在句法上表示为数字所需的行为(或语法)的类(使用数字 [语法] 枚举)。

That is, you have tokens or symbols and a grammar/behavior that indicate whether a stream of tokens represent a number under a given base.

也就是说,您有标记或符号以及指示标记流是否表示给定基数下的数字的语法/行为。

But that's a bit off the tangent (and as you said, it was just an example for example's sake). Going back to extending enums...

但这有点偏离正切(正如你所说,这只是一个例子)。回到扩展枚举......

... yo can't and you shouldn't. Enums are not meant to represent things that can be extended. They are for representing a constantset of constant values. There are such things that are un-inheritable.

......你不能也不应该。枚举并不代表可以扩展的东西。他们是代表一个常量集合的常数值。有些东西是不可继承的。

Also, don't fall into the trap of extending for extension's sake or for trying to force an structure into your code or model.

另外,不要陷入为了扩展而扩展或试图将结构强加到您的代码或模型中的陷阱。

It might seem to make sense to make one set of values an extension of another. More often than not, it is not. Use inheritance for reusing behavior or complex structure, not just data that has little to no structure with non-reusable behavior associated to it.

使一组值成为另一组值的扩展似乎是有意义的。通常情况下,事实并非如此。使用继承来重用行为或复杂结构,而不仅仅是那些几乎没有或没有与不可重用行为相关联的结构的数据。

回答by Mark

It's not possible. And there is a reason. Imagine you could extend an enum:

这是不可能的。这是有原因的。想象一下,你可以扩展一个枚举:

enum A { ONE, TWO }
enum B extends A { THREE }  // for a total { ONE, TWO, THREE }

Now you can do this:

现在你可以这样做:

B b = B.THREE
A a = b  // a = B.THREE ?

But B.THREEis not a valid option for A.

B.THREE不是 的有效选项A

Of course you could make them not-polymorphic, but then it's not really extending.

当然,您可以使它们非多态,但它并没有真正扩展。