【问题标题】:Java Polimorphism calling methods of subclasses on an array of SuperClassJava多态调用SuperClass数组中子类的方法
【发布时间】:2015-06-09 09:28:34
【问题描述】:

我正在开发一个需要我使用多态概念的项目 atm。

我有这个问题:

假设我有一个代表所有哺乳动物的接口,然后我创建以下子类:人类和鲸鱼。

想象一下,现在我想在我的程序中创建一些人类和一些鲸鱼,我会将它们放在一系列哺乳动物中。

问题是,子类HumansolveMathProblem() 方法,而Whale 类没有它,因此哺乳动物也没有。

如何在数组中使用该方法?(例如:mammals[2].solveMathProblem();

这行不通,因为哺乳动物界面中没有指定 solveMathProblem(),因为只有人类才能做到)

我能做些什么来完成这项工作?

【问题讨论】:

  • 由于您只有哺乳动物类型的实例,因此您不能使用任何未在此类型中定义的方法。如果要使用子类型方法,则需要将对象转换为 Human,如果对象不适合新类型,则会失败(通过抛出异常)。 instanceof 运算符也可能会有所帮助。
  • 您可以像((Human)mammals[2]).solveMathProblem(); 一样使用强制转换,但要确保mammals[2] 您需要先检查if (mammals[2] instanceof Human)。还必须经常使用强制转换意味着您的项目应该重新设计,因为 强制转换 不是多态性。
  • @Joao,虽然不是强制性的,但接受一个帮助您回答问题的答案并没有什么坏处[作为对那些花费空闲时间免费帮助您的人表示感谢:)]

标签: java


【解决方案1】:

对子类对象的超类引用不能访问未在超类中定义的方法。

您需要将 Mammal 引用显式转换为 Human 引用,以便能够访问 Human 中存在的方法,如下所示:

((Human)mammals[2]).solveMathProblem();

话虽如此,您应该看一下策略模式,了解如何通过组合添加行为。 This answer 在解释这个概念方面做得很好。在您的特定情况下,您可以通过引入新的行为层次结构来为不同的 Mammal 实现添加不同的行为。

【讨论】:

    【解决方案2】:

    为什么不在循环中使用 instanceof 运算符,然后再调用 solveMathProblem 方法。

    【讨论】:

      【解决方案3】:

      我能想到两种方法,都可能不错:

      1. 您可以为Mammal 声明solveMathProblem interface

        • 声明interface的方法
        • 创建一个class,名为MammalCore
        • implement solveMathProblemMammalCore 中的方法会抛出异常,这将表明该操作不受支持(这样将是默认行为)
        • 覆盖solveMathProblemHuman 这样,如果你在数组中调用 solveMathProblem,Whale 实例将抛出异常,Hule 实例将准确执行该异常
      2. 您可以使用Reflection。在您的循环中,您可以检查每个对象,solveMathProblem 是否存在 (How To Check If A Method Exists At Runtime In Java?) 和 invoke 方法是否存在。

      【讨论】:

      • 我仍然觉得策略模式是一个更好的选择。
      • 基本思想是你不想执行鲸鱼的方法。如果问题是 2+2 并且您调用了 solveMathProblem,如果必须由 Whale 处理,您实际上应该得到一个异常。转换为 Human 并执行该方法是不好的,因为结果将是 Whale 解决了问题,这显然不是应该的。
      猜你喜欢
      • 2012-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多