我需要有人帮助这个小代码片段;为什么输出:b 3而不是预期的b 13?
public class Foo{
int a = 3;
public void addFive() { a+=5; System.out.println("f");}
}
class Bar extends Foo{
int a = 8;
public void addFive() { this.a+=5; System.out.println("b");}
public static void main(String[] args) {
Foo f = new Bar();
f.addFive();
System.out.println(f.a);// why b 3 and not b 13 ??
}
}
答案 0 :(得分:9)
Foo
和Bar
有两个不同的 a
字段; Java没有任何字段覆盖的概念。
调用f.addFive()
调用方法的派生版本(因为Java会执行方法覆盖),这会修改Bar.a
。
但是,访问f.a
会返回Foo.a
(因为f
被声明为Foo
),但从未更改。
答案 1 :(得分:0)
实际上有两个名为a
的变量:一个在Foo
中,另一个在Bar
中。
在Bar.addFive
中,您正在修改a
中声明的变量Bar
(而不是Foo
中声明的变量)。
此外,由于变量不显示多态行为,因此您正在访问main方法中a
中声明的变量Foo
。
答案 2 :(得分:0)
您要修改a
中的Bar
与a
中的Foo
不一致,并且您的代码正在打印a
Foo
}
以下是一些代码示例,可能会让您了解最新情况
Foo f = new Bar();
f.addFive();
System.out.println(f.a);//3
System.out.println(((Bar)f).a);//13
Bar b = new Bar();
b.addFive();
System.out.println(b.a);//13
答案 3 :(得分:0)
Java没有动态绑定变量实例,只是对方法。当您访问某个字段时,不会选择最专业的字段(在名称冲突的情况下,如您的示例中所示)。
所选择的将是已声明变量的那个,而不是运行时变量。要进行动态调整,你应该使用一个getter而不是直接引用变量。
答案 4 :(得分:0)
规则很简单。
多态性不适用于:
以上所有内容都发生在编译时,称为编译时绑定或静态绑定
动态绑定或运行时绑定在方法覆盖中完成。
答案 5 :(得分:0)
我知道了,首先是JAVA压倒一切。但是,如果你这样做,你所做的不是覆盖方法,它可以按你的意愿工作:
public class Foo{
int a = 3;
public void addFive() { a+=5; System.out.println("f");}
public int getA() {return a;}
}
class Bar extends Foo{
int a = 8;
public void addFive() { this.a+=5; System.out.println("b");}
public int getA() {return a;}
}
我希望你能解决问题。
答案 6 :(得分:0)
Foo f = new Bar();
f.addFive();
f.addFive()执行Bar类的overriden方法。在下一行
的System.out.println(f.a);
这将检索Foo类的变量a,该变量为3(因为它未被更改)。 所以你有3个回答。