validar semana recorrer programacion herencia enum dias clase java enums

java - semana - ¿Por qué un Enum implementaría una interfaz?



recorrer enum java (14)

Aquí hay un ejemplo (uno similar / mejor se encuentra en Effective Java 2nd Edition):

public interface Operator { int apply (int a, int b); } public enum SimpleOperators implements Operator { PLUS { int apply(int a, int b) { return a + b; } }, MINUS { int apply(int a, int b) { return a - b; } }; } public enum ComplexOperators implements Operator { // can''t think of an example right now :-/ }

Ahora para obtener una lista de los Operadores Simple + Complex:

List<Operator> operators = new ArrayList<Operator>(); operators.addAll(Arrays.asList(SimpleOperators.values())); operators.addAll(Arrays.asList(ComplexOperators.values()));

Entonces, aquí usa una interfaz para simular enumeraciones extensibles (que no sería posible sin usar una interfaz).

Acabo de descubrir que Java permite que las enumeraciones implementen una interfaz. ¿Cuál sería un buen caso de uso para eso?


Dado que Enums puede implementar interfaces, se pueden usar para aplicar estrictamente el patrón singleton. Tratar de hacer una clase estándar de singleton permite ...

  • para la posibilidad de utilizar técnicas de reflexión para exponer los métodos privados como públicos
  • para heredar de su singleton y anular los métodos de su singleton con otra cosa

Los mensajes como singleton ayudan a prevenir estos problemas de seguridad. Esta podría haber sido una de las razones contribuyentes para que los Enums actúen como clases e implementen interfaces. Solo una suposición.

Consulte https://.com/questions/427902/java-enum-singleton y la clase Singleton en java para obtener más información.


El ejemplo Comparable dado por varias personas aquí es incorrecto, ya que Enum ya lo implementa. Ni siquiera puedes anularlo.

Un mejor ejemplo es tener una interfaz que define, digamos, un tipo de datos. Puede tener una enumeración para implementar los tipos simples y tener clases normales para implementar tipos complicados:

interface DataType { // methods here } enum SimpleDataType implements DataType { INTEGER, STRING; // implement methods } class IdentifierDataType implements DataType { // implement interface and maybe add more specific methods }


El uso más común para esto sería fusionar los valores de dos enums en un grupo y tratarlos de manera similar. Por ejemplo, vea cómo unirse a Fruits y Vegatables .


Es necesario para la extensibilidad: si alguien usa una API que ha desarrollado, las enumeraciones que define son estáticas; no pueden agregarse o modificarse. Sin embargo, si permite que implemente una interfaz, la persona que usa la API puede desarrollar su propia enumeración utilizando la misma interfaz. Luego puede registrar esta enumeración con un administrador de enumeración que conglomere las enumeraciones junto con la interfaz estándar.

Editar: @Helper Method tiene el ejemplo perfecto de esto. Piense en tener otras bibliotecas que definan nuevos operadores y luego diciéndole a una clase de gerente que ''hey, esta enumeración existe, regístrela''. De lo contrario, solo podrá definir Operadores en su propio código; no habrá extensibilidad.


Esta es mi razón por la cual ...

He llenado un ComboBox de JavaFX con los valores de un Enum. Tengo una interfaz, identificable (que especifica un método: identificar), que me permite especificar cómo se identifica cualquier objeto a mi aplicación para fines de búsqueda. Esta interfaz me permite escanear listas de cualquier tipo de objetos (cualquiera sea el campo que el objeto pueda usar para la identidad) para una coincidencia de identidad.

Me gustaría encontrar una coincidencia para un valor de identidad en mi lista de ComboBox. Para usar esta capacidad en mi ComboBox que contiene los valores de Enum, debo poder implementar la interfaz identificable en mi Enum (que, por cierto, es trivial de implementar en el caso de un Enum).


Hay un caso que uso a menudo. Tengo una clase IdUtil con métodos estáticos para trabajar con objetos que implementan una interfaz Identifiable muy simple:

public interface Identifiable<K> { K getId(); } public abstract class IdUtil { public static <T extends Enum<T> & Identifiable<S>, S> T get(Class<T> type, S id) { for (T t : type.getEnumConstants()) { if (Util.equals(t.getId(), id)) { return t; } } return null; } public static <T extends Enum<T> & Identifiable<S>, S extends Comparable<? super S>> List<T> getLower(T en) { List<T> list = new ArrayList<>(); for (T t : en.getDeclaringClass().getEnumConstants()) { if (t.getId().compareTo(en.getId()) < 0) { list.add(t); } } return list; } }

Si creo una enum Identifiable :

public enum MyEnum implements Identifiable<Integer> { FIRST(1), SECOND(2); private int id; private MyEnum(int id) { this.id = id; } public Integer getId() { return id; } }

Entonces puedo obtenerlo por su id esta manera:

MyEnum e = IdUtil.get(MyEnum.class, 1);


Los enum son solo clases disfrazadas, por lo que, en general, todo lo que puedes hacer con una clase lo puedes hacer con una enumeración.

No puedo pensar en una razón por la cual una enumeración no debería ser capaz de implementar una interfaz, al mismo tiempo no puedo pensar en una buena razón para ellos tampoco.

Yo diría que una vez que comiences a agregar cosas como interfaces o método a una enumeración, realmente deberías considerar convertirla en una clase. Por supuesto, estoy seguro de que hay casos válidos para hacer enum no tradicionales, y dado que el límite sería artificial, estoy a favor de dejar que la gente haga lo que quiera allí.


Los enumerados son como las clases de Java, pueden tener constructores, métodos, etc. Lo único que no se puede hacer con ellos es new EnumName() . Las instancias están predefinidas en su declaración enum.


Otra posibilidad:

public enum ConditionsToBeSatisfied implements Predicate<Number> { IS_NOT_NULL(Objects::nonNull, "Item is null"), IS_NOT_AN_INTEGER(item -> item instanceof Integer, "Item is not an integer"), IS_POSITIVE(item -> item instanceof Integer && (Integer) item > 0, "Item is negative"); private final Predicate<Number> predicate; private final String notSatisfiedLogMessage; ConditionsToBeSatisfied(final Predicate<Number> predicate, final String notSatisfiedLogMessage) { this.predicate = predicate; this.notSatisfiedLogMessage = notSatisfiedLogMessage; } @Override public boolean test(final Number item) { final boolean isNotValid = predicate.negate().test(item); if (isNotValid) { log.warn("Invalid {}. Cause: {}", item, notSatisfiedLogMessage); } return predicate.test(item); } }

y usando:

Predicate<Number> p = IS_NOT_NULL.and(IS_NOT_AN_INTEGER).and(IS_POSITIVE);


Por ejemplo, si tiene una enumeración Logger. Entonces debería tener los métodos de registro tales como depuración, información, advertencia y error en la interfaz. Hace que tu código esté débilmente acoplado.


Uno de los mejores casos de uso para usar enum con la interfaz es filtros de predicados. Es una forma muy elegante de remediar la falta de tipicidad de las colecciones de Apache (si no se pueden usar otras bibliotecas).

import java.util.ArrayList; import java.util.Collection; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Predicate; public class Test { public final static String DEFAULT_COMPONENT = "Default"; enum FilterTest implements Predicate { Active(false) { @Override boolean eval(Test test) { return test.active; } }, DefaultComponent(true) { @Override boolean eval(Test test) { return DEFAULT_COMPONENT.equals(test.component); } } ; private boolean defaultValue; private FilterTest(boolean defautValue) { this.defaultValue = defautValue; } abstract boolean eval(Test test); public boolean evaluate(Object o) { if (o instanceof Test) { return eval((Test)o); } return defaultValue; } } private boolean active = true; private String component = DEFAULT_COMPONENT; public static void main(String[] args) { Collection<Test> tests = new ArrayList<Test>(); tests.add(new Test()); CollectionUtils.filter(tests, FilterTest.Active); } }


Usé una enumeración interna en una interfaz que describe una estrategia para mantener el control de instancias (cada estrategia es un Singleton) desde allí.

public interface VectorizeStrategy { /** * Keep instance control from here. * * Concrete classes constructors should be package private. */ enum ConcreteStrategy implements VectorizeStrategy { DEFAULT (new VectorizeImpl()); private final VectorizeStrategy INSTANCE; ConcreteStrategy(VectorizeStrategy concreteStrategy) { INSTANCE = concreteStrategy; } @Override public VectorImageGridIntersections processImage(MarvinImage img) { return INSTANCE.processImage(img); } } /** * Should perform edge Detection in order to have lines, that can be vectorized. * * @param img An Image suitable for edge detection. * * @return the VectorImageGridIntersections representing img''s vectors * intersections with the grids. */ VectorImageGridIntersections processImage(MarvinImage img); }

El hecho de que enum implementa la estrategia es conveniente para permitir que la clase enum actúe como proxy para su instancia adjunta. que también implementa la interfaz.

es una especie de estrategiaEnumProxy: P el código inteligente se ve así:

VectorizeStrategy.ConcreteStrategy.DEFAULT.processImage(img);

Si no implementó la interfaz, había sido:

VectorizeStrategy.ConcreteStrategy.DEFAULT.getInstance().processImage(img);


Los enum no solo tienen que representar conjuntos pasivos (por ejemplo, colores). Pueden representar objetos más complejos con funcionalidad, por lo que es probable que desee agregarles funciones adicionales, por ejemplo, puede tener interfaces como Printable , Reportable , etc. y los componentes que las respaldan.