Java枚举var类型与它们起源的引用类型不兼容

rjjhvcjd  于 2023-06-28  发布在  Java
关注(0)|答案(3)|浏览(116)

我有两个类重用相同的常量,所以我用这些常量创建了一个枚举。

public enum PopularRecipes{
    LASAGNA (new Recipe("LASAGNA", 35, true, "Meat, Cheese, Onions, Garlic, Noodles"))
}

但是当我尝试将这些常量与接受底层类型的方法一起使用时,比如:

class BlueBook {
     private final Recipes PAGE_ONE = new Recipes().addRecipe(PopularRecipes.LASAGNA)
}

我得到以下错误:

The method addRecipe(Recipe) in the type Recipes is not applicable for the arguments (PopularRecipes)

我觉得我误解了一些关于枚举的重要内容,但我在网上看到的任何东西都不意味着这不起作用。有人能解释一下为什么底层的枚举变量改变了类型吗?

djmepvbi

djmepvbi1#

LASAGNA的类型是PopularRecipes,但是addRecipe方法只接受Recipe类型。
在java中,每个枚举常量的类型都是枚举本身。所以这里LASAGNA的类型是PopularRecipes
您可以做的是向PopularRecipes中添加一个方法,以获取与每个枚举类型关联的Recipe,并像

new Recipes().addRecipe(PopularRecipes.LASAGNA.getAssociatedReceipe())
osh3o9ms

osh3o9ms2#

这不是枚举的作用。
枚举表示具有以下属性的类型(例如,'Tree'或'Recipe'):

  • 它是final的--不需要子类化它。你不需要,比如说,“VegetarianRecipe”或“DeciduousTree”。换句话说,该类型的“成员”不需要为该类型的特定物种而改变(即,不需要改变)。如果DeciduousTree需要getLeafFallMonth()方法,而非落叶树根本不应该有该方法,那么不同物种暴露的成员是不同的。在这种情况下,枚举是不合适的)。
  • 对于这种类型,可以存在的示例数量有限,并且它们可以由创建该类型的作者在代码编写时完全指定。例如,如果可以添加食谱(除了应用程序开箱即用的一堆常见食谱之外),那么枚举就不合适

如果上面准确地描述了配方,那么Recipe * 本身 * 需要是枚举:

public enum Recipe {
  LASAGNA("LASAGNA", 35, true, "Meat, Cheese, Onions, Garlic, Noodles"),
  PIZZA(....),
  ;

  Recipe(String code, int price, boolean containsMeaet, String ingredients) {
  ....
}
}

就是怎么做如果任何一个都不适用,那么 * 根本不要使用枚举 *,这不是它们的用途。您可能需要暴露的常量。看起来像:

public Recipe {
  public Recipe(String code, int price, boolean containsMeaet, String ingredients)
  { ....}

  public static final Recipe LASAGNA = new Recipe("LASAGNA", 35, ...);
}

不需要PopularRecipes。如果您真的需要它,它应该是一个类,其唯一目的是作为public static final Recipe LASAGNA和其他流行配方的容器。为了确保没有人尝试一些愚蠢的事情,比如示例化PopularRecipes的新示例,添加一个构造函数,使其成为private

sf6xfgos

sf6xfgos3#

我相信你可能只是误解了错误。

The method addRecipe(Recipe) in the type Recipes is not applicable for the arguments (PopularRecipes)

这是因为 addRecipe 方法具有 Recipe 参数类型,而不是 PopularRecipes 类型。
解决方案是在 PopularRecipes 中创建一个方法,以返回 Recipe 值。

public enum PopularRecipes{
    LASAGNA (new Recipe("LASAGNA", 35, true, "Meat, Cheese, Onions, Garlic, Noodles"));

    private Recipe recipe;

    PopularRecipes(Recipe recipe) {
        this.recipe = recipe;
    }

    public Recipe getRecipe() {
        return recipe;
    }
}

然后,您可以将方法调用应用于 addRecipe 参数。

private final Recipes PAGE_ONE = new Recipes().addRecipe(PopularRecipes.LASAGNA.getRecipe())

作为替代方案,您可以使用 addRecipe 方法进行解析。
所以,你仍然可以只提供 enum 值。

public Recipes addRecipe(PopularRecipes popularRecipes) {
    Recipe recipe = popularRecipes.getRecipe();
    
}
  • "...我觉得我误解了枚举的一些关键..."*

有许多 enum 集合的应用,不一定有一种抽象它的方法。
您所使用的是好的,虽然,有一个更好的方法来组织这些数据。
考虑以下示例。
由于您在多个表单中使用配方名称,请为其创建一个 enum
我还将添加一个新的 Recipe 来表达这个示例。

enum RecipeName {
    Lasagna, BakedZiti
}

此外,由于一种配料可以用于许多不同的食谱,因此也要为此创建一个 enum
这将消除任何可能的错误,可能来自印刷错误,常见的手动输入的文本值,特别是当您键入相同的值,重复。

enum Ingredient {
    Meat, Cheese, Onions, Garlic, Noodles,
    Ziti, TomatoSauce
}

现在,您的 Recipe 类可以使用这两个。
注意,我不确定你的 boolean 值是什么,所以我只是将其命名为 “value”

class Recipe {
    RecipeName name;
    String price;
    boolean value;
    List<Ingredient> ingredients = new ArrayList<>();

    Recipe(RecipeName name) {
        this.name = name;
    }

    void setPrice(String price) {
        this.price = price;
    }

    void setValue(boolean value) {
        this.value = value;
    }

    void addIngredients(Ingredient... ingredients) {
        this.ingredients.addAll(List.of(ingredients));
    }
}

此外,PopularRecipes 类可以是静态结构。
而且,由于我多次重复使用 RecipeNameIngredient,所以我将它们添加为静态导入。

import static Ingredient.*;
import static RecipeName.*;
class PopularRecipes {
    static List<Recipe> list = new ArrayList<>();

    static {
        Recipe lasagna = new Recipe(Lasagna);
        lasagna.setPrice("35");
        lasagna.setValue(true);
        lasagna.addIngredients(Meat, Cheese, Onions, Garlic, Noodles);
        list.add(lasagna);

        Recipe bakedZiti = new Recipe(BakedZiti);
        bakedZiti.setPrice("20");
        bakedZiti.addIngredients(Ziti, Cheese, TomatoSauce, Garlic);
        list.add(bakedZiti);
    }

    /** @return null if not found */
    static Recipe getRecipe(RecipeName recipeName) {
        for (Recipe recipe : list) {
            if (recipe.name == recipeName) return recipe;
        }
        return null;
    }
}

以这种方式组织数据提高了可伸缩性,以用于追加配方集合。
有许多方法可以包含数据,这只是一个例子。

相关问题