覆盖java中的变量

时间:2012-02-01 14:18:26

标签: java override

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(f.a);
    }
 }

我得到输出b 3.为什么它不给b13作为输出。任何人都可以解释。

4 个答案:

答案 0 :(得分:4)

假设类Foo声明如下

class Foo 
{

    public int a = 3;

    public void addFive()
    { 
        a += 5; 
        System.out.print("f ");
    }
}
  1. 变量没有覆盖的概念。他们只是蒙面了。
  2. 正在打印3,因为当您使用超类引用访问变量时,它只访问在超类中声明的变量。 请记住,超类对子类一无所知。

答案 1 :(得分:0)

public int a = 8班级而不是Foo班级中声明Bar它应该有效...打印 B 3

但我想您正在讨论Java认证考试中包含的问题,因此您必须更正Foo类添加public int a = 3的代码。

您无法在Java中覆盖变量,但在超类中声明为public(或protected),您也可以在所有继承的类中使用它。

在这种情况下,正确的输出是 B 13 ,因为在测试类中,您使用Bar对象作为Foo对象,因此值{{1 3 而不是 8

答案 2 :(得分:0)

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

答案 3 :(得分:0)

我假设您打算在类a中声明一个整数字段Foo

正如其他人所指出的那样,你的问题的答案与“覆盖”和“隐藏”的概念有关。解释它的另一种方法是,对于成员变量,没有“动态调度”这样的东西。这意味着,如果您访问某个对象的成员,系统会通过查看类层次结构来检查运行时的 您所指的成员。

因此,在调用方法f.addFive时,系统会在运行时看到您的对象实际上是Bar而不是Foo,因此请{{1您在addFive类中定义的函数。

对于成员变量不会发生这种情况:您在print语句中访问Bar,在编译时决定在那里您想要访问字段{{1}在类f.a中声明 - 所以,这就是在运行时会发生的事情。

现在,成员变量访问没有动态调度的原因是性能:每次你只需要查看整个'看看这是什么对象'的逻辑是非常昂贵的想要为成员变量添加一些值。