我对这段代码的工作原理有点困惑,你能帮我吗。我正在努力深入地理解它。因此,请随时参考任何有关主题的深入理解的链接。输出是一个
public class RuntimePolymorphism {
public static void main(String[] args) {
A a = new B();
B b = new B();
System.out.println(a.c + " " + a.getValue()
+ " " + b.getValue() + " " + b.getSuperValue());
}
}
class A {
char c = 'A';
char getValue() {
return c;
}
}
class B extends A {
char c = 'B';
char getValue() {
return c;
}
char getSuperValue() {
return super.c;
}
}
3条答案
按热度按时间yuvru6vn1#
来自a的示例变量c简单地隐藏在b中
–a.c是“a”,因为它设置在a级
–a.getvalue()返回“b”,因为对象属于类型b
tjrkku2a2#
实际上,这是一个有趣的问题;),根据代码,从第一眼看,我会说,它应该输出
A A B A
但它却在生产A B B A
.然后,我发现一个可能的拼写错误(或者是故意的,不知道):
我们有两个
B
在这里,但是在示例化a
变量。即使我们成功了c
字段组件public
它仍然产生相同的结果。但是,另一方面,如果我们更新到这样的代码:
一切如预期:
A A B A
.有趣的发现:如果我们去掉过载
getValue()
从B
类,输出将A A A A
...最后结论:我们可以继承一个非私有字段(也就是说,我们可以从派生类访问它),但是我们不能像处理方法那样“重载”它。
因此,在java中,多态性只对方法起作用,而不是对字段起作用。
vxbzzdmp3#
所以我认为我们应该首先理解隐藏和多态的区别。
当您声明一个子类的变量名与超类变量相同时,子类变量只是隐藏了超类变量。
对于运行时多态性,子类方法需要重写超类方法。当子类中的方法与其超类中的方法具有签名(名称和参数)和相同的返回类型时,子类中的方法将重写超类中的方法。
另一个重要的点是,多态性m(本例中为运行时)作用于在运行时评估的方法。但是变量值的初始化发生在编译时。
那么,什么时候
A a = new B();
被执行,a
的示例变量c
有价值吗'A'
. 所以即使参考文献a
指向一个B
对象,它引用的示例变量将是A
.因此,当我们运行
a.c
会是A
.但是自从这个方法
getValue()
在子类中重写时,将调用重写的方法(因为它指向子类)B
对象)。因此,当我们运行
a.getValue()
会是B
那么,什么时候B b = new B();
被执行,b
的示例变量c
有价值吗'B'
. 这就隐藏了变量c
超类的。如果我们想引用立即超类的示例变量,那么我们可以通过super.<variable_name>
所以即使参考文献a
指向一个B
对象,它引用的示例变量将是A
.参考文献
b
指向类型的对象B
因此它会叫B
的getvalue()方法。因此,当我们运行
b.getValue()
会是B
.如上所述,我们通过
super.<variable_name>
因此,当我们运行b.getSuperValue()
会是A