Prefacio: Ya he investigado por qué la " herencia de enumeración " es ilegal en Java.
Mi problema es el siguiente: dada una Recipe de clase, quiero que su category de propiedad sea una lista de valores constantes como APPETIZER, BREAKFAST, DESSERT, MAIN_COURSE, SOUP . Lógicamente uso enumeraciones para esto.
Mi pregunta entonces es: si quisiera que cada una de estas enumeraciones tuviera "hijos propios" (por ejemplo: SWEET y SAVORY para BREAKFAST , o CAKE , MUFFIN y BISCUITS para DESSERT ), de modo que:
myRecipe.setCategory(DESSERT) debe generar una excepción);SOUP.BISCUITS debería generar una excepción);myRecipe.setCategory(DESSERT.CAKE) ) - u otra sintaxis " ligera " similar.No he podido encontrar ninguna solución limpia en Java que se ajuste a los tres requisitos.
¿Hay algún patrón de diseño "esotérico" para esto? ¿Cómo implementarías esto?
Crear una categoría de clase. Dentro de Categoría, declare todas las clases de enumeración.
public class Category { public enum APPETIZER { } public enum BREAKFAST { SWEET, SAVORY } public enum DESSERT { CAKE, MUFFIN, BISCUITS } public enum MAIN_COURSE { } } Dentro de la clase Receta , la categoría debe ser del tipo DESSERT . Tengo una clase de categoría importada estática.
public class Recipe { DESSERT category; public void setCategory(DESSERT category) { this.category = category; } public static void main(String[] args) { Recipe myRecipe = new Recipe(); myRecipe.setCategory(DESSERT.BISCUITS); // statements below give compile time errors // myRecipe.setCategory(DESSERT); // myRecipe.setCategory(BREAKFAST.SWEET); } } Convierta Categoría en una interfaz de marcador. Todas las categorías como DESSERT , BREAKFAST , etc. deben implementar Categoría.
interface Category {} enum APPETIZER implements Category { } enum BREAKFAST implements Category { SWEET, SAVORY } enum DESSERT implements Category { CAKE, MUFFIN, BISCUITS } enum MAIN_COURSE implements Category { }Hacer receta genérica.
public class Recipe <T extends Category> { T category; public void setCategory(T category) { this.category = category; } public static void main(String[] args) { Recipe<DESSERT> myRecipe = new Recipe<>(); myRecipe.setCategory(DESSERT.BISCUITS); // statements below give compile time errors // myRecipe.setCategory(DESSERT); // myRecipe.setCategory(BREAKFAST.SWEET); } }Estos no son patrones de diseño. Son de autoejecución.
Puedes hacerlo:
class Recipe { private final Meal meal; private final MealCategory category; public <T extends Meal> Recipe(T meal, MealCategory<T> category) { this.meal = meal; this.category = category; } } abstract class Meal {} class Breakfast extends Meal {} class Dinner extends Meal {} class MealCategory<T extends Meal> {} class Cereal extends MealCategory<Breakfast> {} class Meat extends MealCategory<Dinner> {} public class Test { public static void main(String[] args) { Recipe r = new Recipe(new Breakfast(), new Cereal()); Recipe r2 = new Recipe(new Breakfast(), new Meat()); // compile time error } }