向上投射对象时,哪些部分引用父对象,哪些部分指向子对象

  • 本文关键字:对象 些部 引用 java casting upcasting
  • 更新时间 :
  • 英文 :


在下面的例子中,我很困惑为什么upcasting似乎指的是父类的某些部分和实际类的一些部分。

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中的变量和方法。如果upcasting指的是父级,结果不应该是20 5 10吗?

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

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

  • ((A)b).fi是指A中的变量fi
  • ((A)b).getNum()指的是A中的方法getNum。例如,您可以在A.getNum()声明中添加检查的异常,同时将该异常排除在B.getNum()之外。编译器将要求您捕获或声明((A)b).getNum()可能引发的异常,而它允许您在不进行此类更改的情况下调用b.getNum()

另一方面,Java对方法有动态调度。动态调度意味着在运行时,JVM查看实际对象的类型。如果对象覆盖了您正在调用的方法,JVM将改为调用覆盖。这意味着:

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

方法由动态类型(B(选择,但属性由静态类型(A(选择。

也许其中一个链接可以帮助你:

  • 关于上行与动态绑定的混淆
  • https://bruck.me/2014/01/08/java-statischer-vs-dynamischer-typ/->德语,但很好

相关内容

  • 没有找到相关文章

最新更新