【问题标题】:Is it possible to extend Java Enums?是否可以扩展 Java 枚举?
【发布时间】:2011-02-08 04:40:41
【问题描述】:

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

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

这样 HexDigits.Digit 包含所有的十六进制数字。这可能吗?

【问题讨论】:

  • 答案是“否”(有关详细信息,请参阅下面的答案)。 Josh Bloch 的书 Effective Java 对此有很好的解释和解决方法。
  • 我试过了,所以才在这里发帖!
  • 所有枚举都隐式扩展 java.lang.Enum。由于 Java 不支持多重继承,枚举不能扩展其他任何东西。

标签: java enums


【解决方案1】:

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

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

【讨论】:

  • @Narayan 有一个小的编译器错误(现已修复),但它可以正常工作。
  • @cletus 为什么你在enum 中使用构造函数?它不能被初始化
  • 如何在项目中使用此代码?你能举个例子吗?
【解决方案2】:

没有。

枚举不能被子类化。

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

【讨论】:

    【解决方案3】:

    不,你不能。如果您查看 Enum 的定义,它的实例是最终的,不能扩展。如果您将枚举理解为有限的 final 值集,那么这是有道理的。

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

    在你的例子中,你需要的是

    • 枚举指定语法数字 (十进制数字和字母 代表合法的符号 十六进制;也就是说,枚举令牌, 和
    • 指定行为的类(或 语法)在语法上需要 将数字表示为数字 (使用数字 [句法] 枚举)。

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

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

    ...你不能,你不应该。枚举并不意味着代表可以扩展的东西。它们用于表示一组常量 常量值。有些东西是不能遗传的。

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

    将一组值作为另一组值的扩展似乎是有意义的。很多时候,事实并非如此。使用继承来重用行为或复杂结构,而不仅仅是那些几乎没有结构以及与之关联的不可重用行为的数据。

    【讨论】:

      【解决方案4】:

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

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

      现在你可以这样做了:

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

      B.THREE 不是A 的有效选项。

      当然你可以让它们不是多态的,但它并没有真正扩展。

      【讨论】:

      • +1 非常简洁地解释了为什么它不起作用 - 它违反了可替代性原则,即在任何情况下,您都应该能够使用子类型的任何实例预计
      猜你喜欢
      • 2014-03-31
      • 2021-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 2010-12-10
      • 2021-02-04
      相关资源
      最近更新 更多