Java代码说明

时间:2011-03-13 18:16:11

标签: java

class Base 
{
    int i = 99;
    public void amethod()
    {
        System.out.println("Base.amethod()");
    }

    Base()
    {
        amethod();
    }
}
public class Derived extends Base
{
    int i = -1;

    public static void main(String argv[])
    {
        Base b = new Derived();
        System.out.println(b.i);
        b.amethod();
    }

    public void amethod()
    {
        System.out.println("Derived.amethod()");
    }
}

为什么此代码会打印b.i = 99而不是b.i = -1? 谢谢。

4 个答案:

答案 0 :(得分:4)

这是因为您正在引用对象的成员变量而不是方法。由于它被声明为Base对象,因此它将使用Base.i,因为成员变量不会受益于方法提供的多态性。如果你为这两个类添加了一个getI()方法并调用它而不仅仅是b.i,那么它将按预期工作。

public int getI() {
    return this.i;
}


    Base b = new Derived();
    System.out.println(b.getI());

答案 1 :(得分:2)

您有两个名为i的不同字段; Base中的一个和Derived中的一个。

由于b被声明为Baseb.i会从i类返回Base字段。

您可能希望在i构造函数中设置Derived字段,而不是创建新字段。

答案 2 :(得分:2)

因为在这个例子中b.i说((Base).i)意味着它将引用Base的i变量而不是Derived i。如果相反你做了b.getI()并且每个Base和Dervid实现了他们自己的getI并返回他们自己的i它将返回-1。

解释为什么Base正在调用Derived的方法。 Java方法调用是动态的,并在运行时确定。在你的情况下Base b = new Derived() b这里是Derived类型。 Java运行时将实现b的类型并调用最接近Derived创建的amethod。

所以,如果你有

class Base{
  int i =99;
  public int getI(){
    return i;
  } 
}
class Derived extends Base{
  int i =-1;
  public int getI(){
    return i;
  }
}

Derived的getI()方法将被调用(并返回-1),即使它被定义为Base b = new Derived();

答案 3 :(得分:1)

可以覆盖方法,但是字段掩码,因此您的子类定义了一个名为i的新字段。超类方法引用超类中定义的旧字段i