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
?
谢谢。
答案 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
被声明为Base
,b.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
。