Java 继承:return语句的意外输出
我正在参加Java认证的实践测试,并得到了以下问题: 下面的代码将打印什么 这就是答案:Java 继承:return语句的意外输出,java,inheritance,Java,Inheritance,我正在参加Java认证的实践测试,并得到了以下问题: 下面的代码将打印什么 这就是答案: 贝塔44 444 贝塔44 44 44 我的问题:为什么主类返回的4,而不是子类返回的44?它不应该回来吗 我也没有看到任何变量被范围更近的同名变量所隐藏 (对不起,我说英语。我说法语。)这是因为Beta.h和Baap.h是不同的字段。在b.h中,调用Baap.h(即4)和bb.h,Beta.h(即44)。不同之处在于b.getH()调用Beta.getH()(因为b是newbeta()),但正在读取Baa
贝塔44 444
贝塔44 44 44 我的问题:为什么主类返回的4,而不是子类返回的44?它不应该回来吗 我也没有看到任何变量被范围更近的同名变量所隐藏
(对不起,我说英语。我说法语。)这是因为
Beta.h
和Baap.h
是不同的字段。在b.h
中,调用Baap.h
(即4)和bb.h
,Beta.h
(即44)。不同之处在于b.getH()
调用Beta.getH()
(因为b是newbeta()
),但正在读取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.
}
}
根据该报告,有人写道:
在子类中可以做什么
- 继承的字段可以像其他字段一样直接使用
- 您可以在子类中声明一个与超类中的字段同名的字段,从而将其隐藏(不推荐)
- 您可以在子类中编写一个新的实例方法,该子类具有与超类中相同的签名,从而覆盖它
- 可以在子类中声明不在超类中的新字段
- 这是因为
Beta.h
和Baap.h
是不同的字段。在b.h
中,调用Baap.h
(即4)和bb.h
,Beta.h
(即44)。不同之处在于b.getH()
调用Beta.getH()
(因为b是newbeta()
),但正在读取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.
}
}
根据该报告,有人写道:
在子类中可以做什么
- 继承的字段可以像其他字段一样直接使用
- 您可以在子类中声明一个与超类中的字段同名的字段,从而将其隐藏(不推荐)
- 您可以在子类中编写一个新的实例方法,该子类具有与超类中相同的签名,从而覆盖它
- 可以在子类中声明不在超类中的新字段
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
,因此您的问题是为什么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
字段不遵循重写。讲法语的人写印地语类:)字段不遵循重写。讲法语的人写印地语类:)因此返回h;语句是序列中最后一个要处理的语句。我以为这是继b.getH()之后第二个被处理的;方法调用。非常感谢you@Rahoul:是的,事实上getH()
在println()
中被调用,并且使用println()
会使事情变得混乱。在System.out.println(b.h+“”+b.getH())语句中,我本来希望先打印“b.h”,因为它是println语句的第一个成员,但它没有。你能告诉我为什么吗;语句是序列中最后一个要处理的语句。我以为这是继b.getH()之后第二个被处理的;方法调用。非常感谢you@Rahoul:是的,事实上getH()
在println()
中被调用,并且使用println()
会使事情变得混乱。在System.out.println(b.h+“”+b.getH())语句中,我本来希望先打印“b.h”,因为它是println语句的第一个成员,但它没有。你能告诉我为什么吗?