请教java继承问题

public class test{

public static void main(String args[]){

A a= new B();

System.out.println(a.var);
System.out.println(a.f());

}

}

class A {

int var =1;

int f(){

return var ;

}

}

class B extends A {

int var =2;

int f(){

return var ;

}

}

请问为什么a.var =1,而a.f()=2。a指向子类对象的引用,调用的方法是子类的方法,为什么调用的成员变量却是父类的,请解惑。谢谢。

[b]问题补充:[/b]
第一次发贴,居然没找到地方可以回复。请指点怎样才能回复自己的帖子。


属性的值取父类还是子类并不取决于我们创建对象的类型,而是取决于我们定义的变量的类型”

我也知道是这样子的,但不知道原因所以就来这问了。

[size=medium]不知道楼主对this有了解多少[/size]

[code="java"]System.out.println(a.var);[/code]
[size=medium]这个不用说啦吧,是指向父类的引用,所以打印出来的就是父类的var的值[/size]

[code="java"]System.out.println(a.f());[/code]
[size=medium]这个虽然类型是A但是,是用B的构造方法初始化的,所以引用指向B
在B中的方法是这样的[/size]
[code="java"]int f() {
return var;
}[/code]

改写下会更清晰的
[code="java"]
int f() {
return this.var;
}[/code]

[size=medium]其实jvm也是这么做的,因为引用指向的就是子类B所以打印出来的就是B中var的值[/size]

ps:
不知道这么说楼主明白否~呵呵,不明白可以短消息我哦~ :o

楼主应该仔细研究一下这篇博文:
[url=http://zangweiren.iteye.com/blog/211278]JAVA面试题解惑系列(三)——变量(属性)的覆盖[/url]

不要漏掉下面的回复.

:x 不知道二楼aidiyuxin说的是什么!!!

请教一楼

你给的帖子里用事实证明了一个问题
[quote]属性的值取父类还是子类并不取决于我们创建对象的类型,而是取决于我们定义的变量的类型[/quote]
但是没有解释为什么java这样处理,这样做应该是有某种目的的,并且有官方文档说明。之所以这样说是因为:
当A a=new B();后a的f方法是创建类B的,但a的var成员变量却是A的,直观感觉比较诡异。

请解答谢谢!

抱歉我没地方发就发答案中了

说白了, 就是方法可以Override, 但是成员变量不能.楼主加一条输出:
[code="java"]System.out.println(((B) a).var);[/code], 会发现输出的是2, 也就是说子类和父类各维护自己的一圈成员变量.

当一个对象被实例化的时候,它的父类也会被实例化,递推...此时在堆区中就存在该对象以及该对象的所有父类的实例化了.实例化其实是对对象的成员变量的初始化.至于方法,在下面说.
在对象中有个隐藏的属性super指向它的父类的对象,还有个隐藏的this指向对象自己.
a.var实际取出的是a对象的属性.
而方法,在类被加载的时候就已经被加载到了方法区中了,一个类的所有对象都持有相同的方法指针.在java中,所有的方法都是虚方法,也就是说方法都是动态匹配的,若在子类中找到了fun方法,它就执行子类的,若没找打继续区父类中找...,而类的所有实例方法,在执行的时候(也就是虚拟机执行它的时候),会把this和super两个属性也压入方法栈中,若在方法的局部变量中找不到变量var,则就会区this对象中找.
当执行a.fun()时,其实放回的是this的var属性,而此this就是类B的对象,所以拿到的是2.

来晚了,呵呵
顶这个
改写下会更清晰的
Java代码 复制代码

[code="java"] int f() {

return this.var;

} [/code]

楼主记住一点就明白了。书上应该有提到的。
多态只针对方法,不针对属性的。。。。