2010-04-15 94 views
18

以下是我期待完成的工作,我有一个具有某些值的枚举类,并且我想要继承该类并向枚举中添加更多值。这是一个坏例子,但是:是否可以扩展Java Enums?

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包含所有的十六进制数字。那可能吗?

+1

你试过了吗? – bmargulies 2010-04-15 02:00:03

+1

答案是'不'(详见下面的答案)。 Josh Bloch的书* Effective Java *对此有一个很好的解释和解决方法。 – David 2010-04-15 02:03:39

+1

我尝试过,这就是为什么我张贴在这里! – CaseyB 2010-04-15 15:21:21

回答

31

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

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

这是编译吗?我认为它不会! – Narayan 2010-04-15 04:57:31

+0

@Narayan有一个小小的编译器错误(现在已修复),但它不起作用。 – cletus 2010-04-15 05:51:00

+0

不错,你纠正它,我upvoted你反正:) – Narayan 2010-04-15 08:03:57

5

枚举不能被继承。

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

4

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

可能是二进制,十进制,十六进制或其他什么的数字(语法工件)与实际的数字实体之间存在差异,数字实体在语境中由上下文中的数字表示(基本系统。)

在你的榜样,你需要的是

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

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

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

...哟不能,你不应该。枚举并不代表可以扩展的东西。它们代表常数一套常数值。有这样的东西是不可继承的。

此外,不要陷入扩展的缘故或试图强制结构到您的代码或模型的陷阱。

将一组值设为另一组的值可能看起来有意义。往往不是,它不是。使用继承来重用行为或复杂的结构,而不仅仅是那些结构很少或没有与其相关的不可重用行为的数据。

-5

同意枚举的意思不是要扩展......但是当面对Tapestry 5选择组件......并且它的枚举版本是最好的版本......与(可笑的)复杂对象相比模型示例在那里...可以看到如何扩展和枚举是有吸引力的这种情况...

btw(seque抱怨)什么是挂毯扔掉,而不是建立/最佳实践的jsp框架?充其量,这创建了一个UI开发部门,这使得Java技术在体验方面变得更加弱化了...

+3

原始问题没有提及Tapestry,所以很难看到这个答案如何帮助提问者。 – 2013-01-17 09:08:22

0

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

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的有效选项。

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