覆盖java中的变量
public class Foo { public int a = 3; public void addFive(){ a += 5; System.out.print("f "); } }
public class Bar extends Foo { public int a = 8; public void addFive(){ this.a += 5; System.out.print("b " ); } }
public class Test { public static void main(String args[]){ Foo f = new Bar(); f.addFive(); System.out.println(fa); } }
我得到输出b 3.为什么它不给b13作为输出。任何人都可以解释。
假设类Foo声明如下
class Foo { public int a = 3; public void addFive() { a += 5; System.out.print("f "); } }
- 变量没有覆盖的概念。 他们只是掩盖了。
- 它是打印3,因为当您使用超类引用访问变量时,它只访问在超类中声明的变量。 请记住,超类对子类一无所知。
class Foo { public void addFive() { a += 5; System.out.print("f "); } }
你没有定义’a’变量,所以这个例子甚至没有编译。
正确代码:
class Foo { public int a; public void addFive() { a += 5; System.out.print("f "); } }
并查看链接https://stackoverflow.com/a/2464254/1025312
我假设您打算在类Foo
声明一个整数字段a
。
正如其他人所指出的那样,你的问题的答案与“覆盖”和“隐藏”的概念有关。 解释它的另一种方法是,对于成员变量,没有“动态调度”这样的东西。 这意味着,如果您访问某个对象的成员,系统会在运行时通过查看类层次结构来检查您所指的成员。
因此,在调用方法f.addFive
,在运行时,系统将看到您的对象实际上是一个Bar
而不是Foo
,因此请使用您在Bar
类中定义的addFive
函数。
成员变量不会发生这种情况:你在print语句中访问fa
,并且在编译时决定在那里你想要访问在Foo
类中声明的字段 – 所以,这就是在运行时会发生的事情时间。
现在,成员变量访问没有动态调度的原因是性能:每次只想为成员变量添加一些值时,要经历整个’看看这是什么对象’的逻辑是非常昂贵的。
在Foo
类中声明public int a = 8
而不是Bar
类它应该可以工作…打印B 3 。
但是我想你正在谈论Java认证考试中包含的一个问题,所以你必须纠正添加public int a = 3
的Foo
类的代码。
您不能在Java中覆盖变量,但在超类中声明为public
(或protected
),您也可以在所有inheritance的类中使用它。
在这种情况下,右输出是B 13,因为在测试类中,您使用Bar
对象作为Foo
对象,因此a
值为3而不是8 。