this指针应该代表被实力化的对象。
如果调用的是一个子类对象继承了父类方法,那么this指针应该仍然代表子类对象。这种情况下如果子类复写了父类方法,调用的应该是覆盖之后的子类方法。
例如:class Father {
public String s() {
            return "Father";
         }      
public void show() {
System.out.print(this.s());  // this代表子类对象?
}
}class Son extends Father {
public String s() {  // 复写了父类同名方法
           return "Son";
         }
}
Son s = new Son();  // 创建子类对象
s.show(); // 调用子类继承的父类方法,此时this仍然表示子类对象,所以s()是子类复写的方法!java输出Son.但是如果将函数改为属性会出现不同的结果:class Father {
public String s = "Father";
          public void show() {
System.out.print(this.s);  // this代表子类对象?
}
}class Son extends Father {
public String s = "Son";
}
Son s = new Son();  // 创建子类对象
s.show(); 此时将输出Father
我的问题就是为什么第二种情况不会出现子类覆盖父类的情况,是因为this区分对待方法和属性,还是因为java不覆盖属性?

解决方案 »

  1.   

    这是个好题,我解释过类似的题目。在Java Language Spec里面讲得很清楚。
    看看你能不能等到正确的解释吧。
      

  2.   

    可以参考一下这个:
    http://community.csdn.net/Expert/TopicView3.asp?id=5513661
      

  3.   

    晕...第二个例子中..子类的变量属性不会覆盖父类的变量,这个你要了解一下JAVA虚拟机初始化时的相关绑定机制覆盖只是指方法的覆盖两个例子中的this并无矛盾...都是指当前类..例子一中当前类中的s()方法被子类覆盖..故调用子类的方法
      

  4.   

    this表示的当前的类,第一个是方法的重写,所以调用的是子类的show方法,显示的也是子类的show方法.第2个,因为属性没有重写,所以,只是调用父类的方法,显示的是父类的属性.
      

  5.   

    实质上在编译的时候继承就是把父的方法。属性全COPY到子类来
    然后再编译子类的方法。第一例从重写了父类的方法。
    所以只有子类的方法
    而后一例没有重写所以就实质上是你类的方法
    这就好像构造方法一样你不写构造方法系统就给你一个默认的
    你写了他就把那个默认搞掉了。当然我是说参数和类型完全一样
      

  6.   

    关键要记住一点  你可以把this 理解成 当前类的一个对象:
      不知道说的对不对  呵呵
      

  7.   

    谢谢大家的回复,我这个问题是在最近学习php5时联想到的。php5的子类就会覆盖掉父类的同名方法和属性。看来java和php在这点上还是有一些区别。那么请问大家其他面向对象的语言在此处有没有什么异同呢?比如说C#,C++,或者Delphi,他们的子类会覆盖掉父类的属性吗?ps: php真是一个恶心的东西,越学越觉的好笑,里面很多规定都很混乱。
    ps2: 不好意思,最近没怎么上网,不过帖子肯定会结。谢谢大家帮我解答。
      

  8.   

    其实子类继承父类进行方法的重写。
    那么你可以记得,如果事例化吊用,那么是调用子类的方法(重写父类的),或者调用父类的成员变量(就是父类的属性)楼主的THIS指针可以充分的证明这点。其实有些东西是记住就行。如果你想知道为什么不是调用子类的属性,但他又用子类的方法,其实是想不大通的。
    PS:面试题很容易出这个题目。
      

  9.   

    其实记住this就是代表当前类的对象,因为Son继承了Father,所以在Son调用父类的show()时这个show()已经被认为是它自己的了,所以this也就代表是Son了,那么也就相应的调用Son重写的父类的s()方法了。
    PS:不知道这样解释对不对?