在这个程序中
class a
{
int a=25;
public void aa()
{
System.out.println(a);
}
}
class b extends a
{
int a=2;
public static void main(String[] args) {
b x=new b();
x.aa();
}
}
为什么" x.aa()"打印25 ans为什么不是2?,背后的原因是什么?
class a
{
int a=25;
public void aa()
{
System.out.println(a);
b();
}
public void b()
{
System.out.println("this should print");
}
}
class b extends a
{
int a=2;
public static void main(String[] args) {
b x=new b();
x.aa();
}
public void b()
{
System.out.println("this should not print");
}
}
如果我们考虑上面的输出,那么上面的b()的输出应该打印"这应该打印"但是我们正在从sublcass获得输出"这不应该打印"
答案 0 :(得分:1)
B类继承A类,所以当你调用x.aa时,它调用的是a类的方法。类a的成员a初始化为25,因此它打印25.类a不知道类b的成员a。
答案 1 :(得分:1)
无法覆盖字段,也不是虚拟字段。 B.a
*独立于A.a
,以至于它们实际上可以有不同的类型。 B
无法让A
知道B.a
代替A.a
。 B
的实例实际上会有两个名为a
的字段,但另一个字段被另一个字段隐藏(“阴影”)。 (如果需要,代码B
可以通过编写A.a
来引用其((A)this).a
字段。这是因为根据类型选择了适当的a
((A)this)
的{{1}},而不是实例的运行时类型,它是A
或子类型B
。 )
*注意:我已将您的类重命名为B
和A
:根据Java命名约定,类名以大写字母开头。
答案 2 :(得分:0)
b x=new b();
当你这样做时,这将打印出构造函数的put作为它的给定,因为它明确地使b类的对象,而在该类的类A的情况下 b()作为方法,所以当你制作b类对象时它不会调用。
,而在
的情况下b x=new b();
x.aa();
这将默认调用继承,并在输出时打印。 还有一件事。
public void aa()
{
System.out.println(a);
}
在这种情况下,它将使用该特定类的局部变量,因此它将打印您在该类上定义的任何内容。在您的情况下 a = 25;
顺便问一下。
答案 3 :(得分:0)
方法aa()是类a的成员。所以,方法aa()可以看到/访问类a的实例成员。 现在,您继承了a到b的类。它意味着b类的对象可以访问/调用aa()。但是,这并不意味着允许aa()访问类b的变量a。这就是为什么方法aa()打印它自己的类的变量a并打印25。
现在关于你的第二个项目。在b类中,你重写方法b()。在调用重写方法时,方法的选择(无论是来自子类还是超类)是基于调用对象的实例(分别是子类或超类)来完成的。 你用方法b的实例调用了方法aa(),这就是调用类b的方法b()的原因。