向上转型对象时,哪些部分引用父对象,哪些部分引用子对象?
When upcasting an object, what parts refer to the parent and what parts refer to the child?
在下面的示例中,我很困惑为什么向上转型似乎指的是父 class 的某些部分和实际 class 的某些部分。
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
吗?
这里有两种力量在起作用:
一方面,Java 编译器使用引用的 类型 将名称解析为 class 成员。因为 ((A)b)
的类型是 A
:
((A)b).fi
指的是A中的变量fi
.
((A)b).getNum()
引用 A 中的方法 getNum
。您可以通过例如向 [=16] 添加 checked exception 来查看事实=] 声明,同时将异常排除在 B.getNum()
之外。编译器将要求您捕获或声明 ((A)b).getNum()
可能抛出的异常,同时它允许您在不进行此类更改的情况下调用 b.getNum()
。
另一方面,Java 有 动态调度 方法。动态调度意味着在 运行 时间,JVM 会查看实际对象的类型。如果对象 覆盖 您正在调用的方法,则 JVM 会调用覆盖。这意味着:
((A)b).getNum()
会在运行时调用B中定义的方法。
方法选择了动态类型(B),属性选择了静态类型(A)。
也许其中一个链接可以帮助您:
在下面的示例中,我很困惑为什么向上转型似乎指的是父 class 的某些部分和实际 class 的某些部分。
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
吗?
这里有两种力量在起作用:
一方面,Java 编译器使用引用的 类型 将名称解析为 class 成员。因为 ((A)b)
的类型是 A
:
((A)b).fi
指的是A中的变量fi
.((A)b).getNum()
引用 A 中的方法getNum
。您可以通过例如向 [=16] 添加 checked exception 来查看事实=] 声明,同时将异常排除在B.getNum()
之外。编译器将要求您捕获或声明((A)b).getNum()
可能抛出的异常,同时它允许您在不进行此类更改的情况下调用b.getNum()
。
另一方面,Java 有 动态调度 方法。动态调度意味着在 运行 时间,JVM 会查看实际对象的类型。如果对象 覆盖 您正在调用的方法,则 JVM 会调用覆盖。这意味着:
((A)b).getNum()
会在运行时调用B中定义的方法。
方法选择了动态类型(B),属性选择了静态类型(A)。
也许其中一个链接可以帮助您: