测试代码如下:
SuperClass.java
public class SuperClass {
public String a = "from super class";
public void hello() {
System.out.println(a);
}
}
SubClass.java
public class SubClass extends SuperClass {
public int a = 3;
@Override
public void hello() {
System.out.println(a);
}
}
Client.java
public class Client {
public static void main(String[] args) {
SuperClass s = new SubClass(); //!!! s 的编译时类型为 SuperClass, 运行时类型为 SubClass
s.hello();
System.out.println(s.a);
}
}
上面的代码中,SubClass
覆盖了SuperClass
的 field a
and its method hello()
. Client
的输出结果会是什么呢?
运行代码,得如下结果:
3
from super class
由此可见,
s.hello()
执行了SubClass.hello()
方法s.a
访问了SuperClass.a
.
初看让人不解,这个 s
访问的内容,SubClass
中都有定义,但为何 SubClass
还是 SuperClass
都被它调用了呢?即SubClass
里也有定义 a
,s.a
仍然用 SuperClass
的 a
. 在 SubClass.hello()
使用的 a
是哪个类中定义的?
这是因为多态有如下一些限定:
- 对象的实例变量不具有多态性。具备多态性的,只有实例的方法。所以访问实例变量,依据其编译时类型访问。
- 在
SubClass.hello()
使用的a
是哪个类SubClass
中定义的。虽然依据第1条的说明,实例变量不具有多态性,但如果通过子类的方法去访问(如通过SubClass.hello()
),它依然可以被访问到,只不过不那么直接罢了。