我正在接受Java认证的练习测试,并得到了这个问题:
下面的代码会打印什么?
class Baap {
public int h = 4;
public int getH() {
System.out.println("Baap "+h);
return h;
}
}
class Beta extends Baap {
public int h = 44;
public int getH() {
System.out.println("Beta " + h);
return h;
}
public static void main(String[] args) {
Baap b = new Beta();
System.out.println(b.h + " " + b.getH());
Beta bb = (Beta) b;
System.out.println(bb.h + " " + bb.getH());
}
}
这是答案:
Beta 44
4 44
Beta 44
44 44
我的问题:为什么来自主类的 4 而不是来自子类的 44 ?难道它不会返回44吗?
我也没有看到任何被另一个变量影响的变量,该变量具有更接近范围的相同名称。
(对不起我的英文。我说法语。)
答案 0 :(得分:2)
这是因为Beta.h
和Baap.h
是不同的字段。在b.h
中,调用Baap.h
(即4)并调用bb.h
,Beta.h
(即44)。区别在于b.getH()
调用Beta.getH()
(因为b为new Beta()
),但正在阅读Baap.h
字段,而bb.getH()
则调用Beta.getH()
。
查看main()
方法:
class Baap {
public int h = 4;
public int getH() { System.out.println("Baap "+h); return h; }
}
class Beta extends Baap {
public int h = 44;
public int getH() { System.out.println("Beta "+h); return h; }
public static void main(String[] args) {
Baap b = new Beta();
System.out.println(b.h + " " + b.getH());
/* The string concatenation gets compiled to:
* new StringBuffer().append(b.h).append(" ").append(b.getH()).toString();
* \ This is Baap.h \ This prints Beta 44 and returns 44 from Beta.h
*/
// Printed "Beta 44" from b.getH().
// Printed "4 44" from statements concatenation.
Beta bb = (Beta) b;
System.out.println(bb.h + " " + bb.getH());
/* The string concatenation gets compiled to:
* new StringBuffer().append(bb.h).append(" ").append(bb.getH()).toString();
* \ This is Beta.h \ This prints Beta 44 and returns 44 from Beta.h
*/
// Printed "Beta 44" from b.getH().
// Printed "44 44" from statements concatenation.
}
}
从Oracle JavaTM Tutorials - Inheritance开始写道:
您可以在子类中执行的操作
- 可以直接使用继承的字段,就像任何其他字段一样。
- 您可以在子类中声明一个与超类中的字段同名的字段,从而将其隐藏(不推荐)。
- 您可以在子类中编写一个新实例方法,该方法与超类中的签名具有相同的签名,从而覆盖它。
- 您可以在子类中声明不在超类中的新字段。
了解更多:
答案 1 :(得分:2)
因此,您的问题是b.h
评估为4
而不是44
的原因:
Baap b = new Beta();
System.out.println(b.h + " " + b.getH());
^^^ why is this 4?
原因是Java中没有数据多态性。即使它们共享相同的名称,Baap.h
和Beta.h
也是不相关的字段。
当编译器解析b.h
时,它会查看b
的静态(即编译时)类型,而不是其动态(即运行时)类型。
b
的静态类型为Baap
,因此b.h
解析为Baap.h
,即4
。