2010-04-15 22 views
18

Esto es lo que estoy buscando lograr, tengo una clase que tiene una enumeración de algunos valores y quiero subclase y agregar más valores a la enumeración. Este es un mal ejemplo, pero:¿Es posible extender 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 
} 
} 

modo que HexDigits.Digit contenga los números hexagonales. ¿Es eso posible?

+1

¿Lo intentó? – bmargulies

+1

La respuesta es 'no' (ver respuestas a continuación para más detalles). Libro de Josh Bloch * Effective Java * tiene una buena explicación y una solución para esto. – David

+1

¡Lo intenté, por eso publiqué aquí! – CaseyB

Respuesta

31

No, no es posible. Lo mejor que puedes hacer es hacer que dos enums implementen e interactúen y luego utilicen esa interfaz en lugar de la enumeración. Por lo tanto:

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

¿Esto compila? ¡Creo que no! – Narayan

+0

@Narayan hubo un error de compilador menor (ahora corregido) pero de lo contrario funciona. – cletus

+0

bueno que lo corrigió, lo voté de todos modos :) – Narayan

5

enumeraciones no puede tener subclases.

El razonamiento aquí es que una enumeración define un número fijo de valores. Subclases rompería esto.

4

No, no puedes. Si observa la definición de Enum, las instancias son definitivas y no pueden extenderse. Esto tiene sentido si comprende las enumeraciones como un conjunto de valores finito, final.

Hay una diferencia entre un numeral (un artefacto sintáctica) que podría ser binario, decimal, hex o lo que sea, y la real semántica número, la entidad numérica representados sintácticamente por un número en un contexto (el sistema de base .)

En su ejemplo, lo que se necesita es

  • enumeraciones que especifican los números sintáctico (dígitos decimales y alfabéticos símbolos que representan legal hexadecimales; es decir, tokens de enumeración, y
  • clases que especifican el comportamiento (o gramática) requerido para sintácticamente que representa un número como un número (utilizando el numeral [sintáctica] enumeraciones).

Es decir, que tienen fichas o símbolos y una gramática/comportamiento que indican si una corriente de fichas representan un número bajo una base dada.

Pero eso está un poco fuera de la tangente (y como dijiste, era solo un ejemplo por ejemplo). Volviendo a extender enumeraciones ...

... no puede y no debe. Los mensajes no están destinados a representar cosas que se pueden extender. Son para representar un constante conjunto de valores constantes. Hay cosas que no son heredables.

Además, no caiga en la trampa de extender por razones de extensión o por tratar de forzar una estructura en su código o modelo.

Puede parecer razonable hacer que un conjunto de valores sea una extensión de otro. La mayoría de las veces, no lo es.Use la herencia para reutilizar el comportamiento o la estructura compleja, no solo los datos que tienen poca o ninguna estructura con comportamientos no reutilizables asociados.

-5

aceptan que las enum no están destinadas a ser ampliadas ... pero cuando se enfrentan con Tapestry 5 seleccionan el componente ... y la versión enum es la mejor versión ... en comparación con el objeto (¿ridículamente?) Complejo ejemplos de modelos por ahí ... podría ver cómo extender y enum es atractivo para este caso ...

btw (seque queja) ¿Qué diablos es con el tapiz tirando en lugar de construir sobre/mejor práctica del marco jsp ? en el mejor de los casos, esto crea una división de desarrollo de la ui, que deja a las tecnologías de Java más débiles para la experiencia ...

+3

La pregunta original no tiene referencias a Tapestry, por lo que es difícil ver cómo esta respuesta podría ayudar al que pregunta. –

0

No es posible. Y hay una razón. Imagínese que usted podría extender una enumeración:

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

Ahora usted puede hacer esto:

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

Pero B.THREE no es una opción válida para A.

Por supuesto que puede hacer que no sean polimórficos, pero en realidad no se extiende.