【问题标题】:Cannot call a method with a type after an instanceof check [duplicate]在instanceof检查后无法调用具有类型的方法[重复]
【发布时间】:2019-11-26 15:35:36
【问题描述】:

我有一份杂货清单,里面存放了一些食物和饮料。 Grocery 是一个抽象类,Food 和 Beverage 都扩展了它。

我在 Grocery 中创建了一个静态方法来将杂货列表保存在文件中。此方法扫描整个列表,并且对于其中的每个元素,如果元素是食物,它应该调用 Food 类中的 saveToFile 方法,如果元素是饮料,它应该调用 Beverage 类中的 saveToFile 方法。

public static void saveListToFile(ArrayList<Grocery> groceries) {
    for(int i = 0; i < groceries.size(); i++) {
        if(groceries.get(i) instanceof Food) {
            Food.saveToFile(groceries.get(i));
        }
        else
            Beverage.saveToFile(groceries.get(i));
    }
}

这不会编译。相反,我收到以下错误:Food 类型中的方法 saveToFile() 不适用于参数(杂货店)。

【问题讨论】:

  • 你想做什么,你面临的问题是什么?上面的代码几乎没有提供任何上下文。
  • 如果Grocery 上有一个saveToFile() 方法,你为什么不直接调用它呢?多态性的全部意义在于底层对象知道自己的类型并将调用正确的实现。
  • 嗯,我想我已经很好地解释了我在我写的描述中想要做什么。这是我得到的错误:Food 类型中的方法 saveToFile() 不适用于参数(杂货店)。
  • 这可能是您必须将groceries.get(i) 的结果转换为FoodBeverage:Food.saveToFile((Food) groceries.get(i))。不幸的是,您没有发布编译器的错误消息或Food.saveToFile/Beverage.saveToFile的声明
  • @stoneburner:我确实用错误消息更新了您的问题(这有助于回答大量问题的人)。我还删除了“我是菜鸟”部分——每个人都必须从某个地方开始,其他有同样问题的人会更容易找到你的问题。

标签: java


【解决方案1】:

正如azurefrog 建议的那样,我在 Grocery 中编写了一个抽象的 saveToFile 方法:

public abstract void saveToFile();

然后我像这样重写了 saveListToFile:

public static void saveListToFile(ArrayList<Grocery> groceries) {
    for(Grocery item: groceries)
        item.saveToFile();
}

这种方式之所以有效,是因为它使用多态性并在每个项目的正确类中运行正确的方法。

谢谢!

【讨论】:

  • 如果您在课堂上学习,很可能会在您的手动instanceof 检查之后显示通过多态的这种实现 - 以证明多态性而不是手动检查的有用性。跨度>
【解决方案2】:

在检查其类型后立即尝试转换它,例如:

if (groceries.get(i) instanceof Food) {
   Food.saveToFile((Food)groceries.get(i));
}
else
   Beverage.saveToFile((Beverage)groceries.get(i));

【讨论】:

    【解决方案3】:

    使用 instanceof 的代码部分正确地执行了您想要的操作(即使这是不好的做法。

    如果您的代码未在编译时出现错误“Food 类型中的方法 saveToFile() 不适用于参数 (Grocery)。”这意味着您的方法 saveToFile 采用食物或饮料参数而不是杂货店。您需要在应用该方法之前强制转换项目。 (如果我假设这里缺少的食品和饮料类的内容是正确的)

    public static void saveListToFile(ArrayList<Grocery> groceries) {
    for(int i = 0; i < groceries.size(); i++) {
        if(groceries.get(i) instanceof Food) {
            Food.saveToFile((Food)groceries.get(i));
        }
        else
            Beverage.saveToFile((Beverage)groceries.get(i));
      }
    }
    

    我不知道您的确切需求,但我认为您可以使用继承设计一个更好的解决方案。 saveToFile 不一定是静态的。您可以在 Food and Beverage 中有 2 个不同的实现,例如,这两个实现中的每一个都可以使用来自其他类的静态函数写入特定文件。

    【讨论】:

      猜你喜欢
      • 2022-01-03
      • 2015-08-05
      • 2018-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多