【问题标题】:Java: Calling a subclass method from superclass variableJava:从超类变量调用子类方法
【发布时间】:2018-05-10 08:51:55
【问题描述】:

(之前问过here的问题。我没有得到想要的答案。)

引用一本书:

如果你想从一个对象调用一个由子类定义的方法怎么办? 是由超类的变量引用的?假设 SoftBall 类 有一个名为riseBall 的方法,它不是由 Ball 类定义的。你怎么 从 Ball 变量中调用它?一种方法是创建子变量 类,然后使用赋值语句来转换对象:

Ball b = new SoftBall();
SoftBall s = (SoftBall)b;
// cast the Ball to a
// SoftBall
s.riseBall();

在上面的代码 sn-p 中,它显示了一个新的 Softball 对象正在创建并分配为对变量 b 的引用,这是完全合法的,因为类SoftballBall 类的子类。然而,引用声明(间接)您必须先将变量转换为类型 Softball,然后才能使用该变量调用 Softball 类中的方法。这是为什么?为什么我不能直接使用 Ball 类型的变量 b(其中包含对垒球对象的引用)来调用所需的方法?变量 b 已经拥有该对象。

(注意:我已经阅读了this 的帖子。)

【问题讨论】:

  • 创建b 类型Ball 的变量是告诉编译器“这个变量中的对象可以是Ball 类型的任何东西”。如果您想让编译器知道变量所持有的对象是SoftBall,请使用SoftBall 类型的变量。这就是变量类型的用途。
  • 引用您引用的答案:The declared type of the variable a is A. The compiler doesn't know (and shouldn't know) what its concrete type at runtime is B.
  • 只有当 Ball 是抽象的并且有一个抽象的 riseBall() 方法时,您的预期场景才有可能。
  • 认为这些概念会帮助你理解答案——java中的多态性和后期绑定

标签: java inheritance


【解决方案1】:

Java 是一种静态类型语言。

这意味着编译器会检查变量的类型是否具有您尝试调用的方法。

变量b 的类型是BallBall 没有 riseBall 方法。

这意味着你的代码会崩溃,除非b 在运行时恰好包含Softball(编译器无法保证)。您可能知道确实如此,但您也必须说服编译器(即为您的变量提供必要的类型)。

【讨论】:

    【解决方案2】:
    Ball b = new SoftBall();
    

    这只是意味着变量b是Ball类型,但是如果类Ball中的方法在扩展类SoftBall中被覆盖,那么使用变量'b',我们将调用类'SoftBall'的方法定义而不是比“球”。 现在,虽然变量b引用了'SoftBall'类的实现,但它仍然是'Ball'类的类型,并且Ball类没有任何方法'riseBall'

    希望这是有道理的。

    【讨论】:

      【解决方案3】:

      因为暴露的方法取决于变量的声明类型。

      Ball b = new SoftBall();
      

      b 实际上是SoftBall,但您正在“隐藏”它,因为您将其声明为Ball 类型。由于Ball 类型没有riseBall 方法,因此您无法通过询问b 来访问它。

      【讨论】:

        【解决方案4】:

        我们知道javastatically typed language

        这是statically-typed languages 的一项功能,其中变量被提前分配类型,并在compile-time 处检查以查看类型是否匹配。

        如果此代码是在 dynamically-typed language 上执行的,在“运行时”检查类型,则可能允许执行以下操作:

        Ball b = new SoftBall();
        if (b instanceof SoftBall){
          b.riseBall();
        }
        

        b.riseBall() 保证仅在实例为SoftBall 时执行,因此对riseBall 的调用将始终有效。

        但是,Java 是一种静态类型的语言,所以这种类型的代码是 不允许。

        【讨论】:

          猜你喜欢
          • 2019-05-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-24
          • 2012-04-18
          • 1970-01-01
          相关资源
          最近更新 更多