首页 > 解决方案 > 向上转换对象时,哪些部分引用父对象,哪些部分引用子对象?

问题描述

在下面的示例中,我很困惑为什么向上转换似乎是指父类的某些部分和实际类的某些部分。

public class B extends A{
   int fi = 15;
   public static void main(String[] args){
       B b = new B();
       b.fi = 20;
       System.out.println(b.fi);
       System.out.println(  (  (A) b  ).fi  );
       System.out.println(  (  (A) b  ).getNum());
   }
   public int getNum(){
       return fi;
   }
}
class A{
   final int fi = 5;
   public int getNum(){
       return fi * 2;
}

打印结果如下:

20
5
20

我知道这段代码是以一些低效的方式编写的,但它类似于我得到的 OCA 练习题。我想知道为什么 ((A)b).fi 指的是 A 中的变量,但是 ((A)b).getNum() 使用了 B 中的变量和方法。如果向上转换指的是父级,应该结果20 5 10不是吗?

标签: javacastingupcasting

解决方案


这里有两种力量在起作用:

一方面,Java 编译器使用引用类型将名称解析为类成员。因为((A)b)有类型A

  • ((A)b).fifiA中的变量。
  • ((A)b).getNum()getNumA 中的方法。例如,您可以通过在声明中添加已检查异常A.getNum(),同时将异常排除在B.getNum(). 编译器将要求您捕获或声明((A)b).getNum()可能抛出的异常,同时它允许您在b.getNum()不进行此类更改的情况下调用。

另一方面,Java 具有方法的动态分派。动态分派意味着在运行时,JVM 查看实际对象的类型是什么。如果对象覆盖了您正在调用的方法,则 JVM 会改为调用覆盖。这表示:

  • ((A)b).getNum()将在运行时调用 B 中定义的方法。

推荐阅读