我正在学习Java,我在这里感到困惑:这段代码究竟是如何工作的?
class A
{
int n = 9;
void show()
{
System.out.println(n);
}
}
class B extends A
{
void show()
{
System.out.println(n+" "+super.n+" "+a.n);
}
int n = 4;
static A a = new A();
public static void main(String[] args)
{
B b = new B();
a.show();//9, expected
a = b;
/*Line A*/ a.show();//4 9 9
/*Line B*/ b.show();//4 9 9
}
}
在A行中,将调用B中的函数,这是预期的。但为什么要打印4 9 9?
答案 0 :(得分:2)
您将b
放入a
,但b
始终保留B Class
- 背景中的对象。
你可以像这样打印出来:
/*Line B*/ b.show();//4 9 9
System.out.println(a.getClass());
引用来自类型A
,但堆上的对象是相同的b
对象。
答案 1 :(得分:2)
排队
else
静态变量a = b;
设置为类a
的实例。这是可能的,因为B
继承自B
。
因此,系列调用来自班级A
的方法show()
,而不是B
。
有关详细信息,请搜索material on Polymorphism。
答案 2 :(得分:1)
在A行中,我们实际上是在.show()
类型的引用上调用方法class A
。这里class B
是class A
的子类。在Java中,父类引用可以指向子类对象。
当JVM看到这个调用时,它实际上会检查引用实际指向的对象。在我们的例子中,它指向类型为class B
的子类对象。此处,show
方法也在class B
中声明。这意味着,它成功地覆盖了父方法。当JVM看到它时,它实际上调用子类方法而不是父类。整个过程称为polymorphism
。