最初是在java的头版看到 JAVA面试题解惑系列 对java中变量(属性)的覆盖 的一些讨论,那篇确实写的很好!但我有一个对别人说三道四的不好的坏毛病,觉得他的文章中“变量(属性)的覆盖”表述不对,其它也没什么,就发表了一篇对 JAVA面试题解惑系列(三)——变量(属性)的覆盖 的质疑 ,那是我javaeye上面的处女作,o(∩_∩)o...
在以前的那篇文章中只是借鉴其它文章了对子类和父类定义同名成员作了一些总结,正如JAVA面试题解惑系列 的作者所说的那样。但那篇文章也有一定的参考价值,可以仔细的看一下。在这篇文章其实是想作为补充。下面不多说了,将由代码引出问题。
class Parent{
int i=10;// 父类变量
public void setI(int i){
this.i=i;
}
}
class Son extends Parent{
int i=10;// 子类与父类同名的变量
public static void main(String args[]){
Son son=new Son();
System.out.println("son.i="+son.i);
son.setI(100);
System.out.println("After setI(100) : son.i="+son.i);
Parent parent=son;
System.out.println("See son as Parent : son.i="+parent.i);
}
}
看运行的结果:
son.i=10
After setI(100) : son.i=10
See son as Parent : son.i=100
下面来做解释:
在这段代码中,子类定义了一个父类中同名的成员变量int i,在父类中有一个对 i 赋值的方法setI(),而在子类中没有定义这个方法。(请读者对照代码)。当子类调用继承而来的setI()方法对成员变量i进行改变,直接打印son.i(对照代码)时,成员变量i然而却没有改变,是不是很奇怪,o(∩_∩)o...哈哈。当但当把son当作Parent类型来使用,再打印它的成员变量i时,输出的结果就对了,是setI()改变之后的值。
然而这是为什么呢?我到处弄了很久,觉得一种解释很合理:java中类是分层次的,当子类和父类的定义同名时,父类变量被隐藏,父类的实例方法被重写,静态方法属于类级别的方法,在子类和父类中互不相碍。虽然这句话也很简单,但理解起来还是不够明白。我想知道子类的对象创建时,它们在内存中是怎么变化的。
这java语言是java编写者们写的,规则是这么定的。