【问题标题】:Assinging object of inherited class to reference of super class将继承类的对象分配给超类的引用
【发布时间】:2014-06-01 15:46:08
【问题描述】:

给定以下代码:

public class A {
     int at=2;

    public int m(int i){return at+i;}
}

class B extends A {
     int at=3;

        public int m(int i){return at+5*i;}
}

public class Main {

    public static void main(String args[]){
        A x = new B();

        System.out.println("Output "+x.m(x.at));
    }
}

输出为 13。

它是如何工作的? 我知道它需要 B 的方法,但是参数呢?

【问题讨论】:

  • 您没有将其分配给 object,而是将其分配给 reference
  • 谢谢,我编辑了标题

标签: java


【解决方案1】:

看表达式:x.m(x.at)。由于x被c声明为Ax.at将引用A中的at字段。

但是,当涉及到方法时,它变得更加复杂。虽然x 被声明为A,但x 实际上是B 类型,所以方法m 将从x 的实际类B 中调用。

也许this可以帮忙。

【讨论】:

    【解决方案2】:

    实际上,您有两个at 字段,一个在A 中声明,另一个在B 中声明。 A中的方法m引用A中的字段atB 中的方法m 指的是B 中的归档at。方法被覆盖,字段没有。 x 被声明为 A 的实例,因此 x.at 为 2。当您调用方法 m 时,将调用覆盖的方法 (B.m(2)),因此您得到 3+5*2 = 13。

    在这种情况下,Java Language specification 应该告诉您什么是正确的以及为什么。这个问题的答案可以在8.3. Field Declarations

    如果类声明了一个具有特定名称的字段,那么 据说该字段的声明隐藏了所有可访问的 在超类中声明具有相同名称的字段,以及 类的超接口。

    如果满足以下条件,则可以使用限定名称(第 6.5.6.2 节)访问隐藏字段 它是静态的,或者通过使用包含 关键字 super(第 15.11.2 节)或转换为超类类型。

    转换为超类类型是您的情况。

    【讨论】:

      【解决方案3】:

      变量不会覆盖类似的方法。所以变量值依赖于引用变量而不是这个引用变量所引用的实例。

      示例:在您的情况下。在 main() 方法中

      A x =new B();

      引用变量 x 属于 A 类型,它持有 B 类型实例的引用。

      所以 X 属于 A 类型。当你写 x.at 时,它是指 A 类变量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-26
        • 2020-10-09
        • 1970-01-01
        • 2021-03-03
        • 1970-01-01
        相关资源
        最近更新 更多