隐藏在暗中的this指针

来源:互联网 发布:淘宝访问受限怎么回事 编辑:程序博客网 时间:2024/04/26 05:28

同事阅读代码的时候遇到了个颇具迷惑性的问题,拿来问我,我提炼简化了一下,大概是这样:
//Ext.java
public class Ext {

 public static void main(String[] args) {
  Son s = new Son();
  s.method1();
 }

}

//Father.java
public class Father {

 public void method1(){
  System.out.println("father's method1");
  method2();
 }
 
 public void method2(){
  System.out.println("father's method2");
 }
 
}

//son.java
public class Son extends Father {

 public void method1() {
  System.out.println("son's method1");
  super.method1();
 }

 public void method2() {
  System.out.println("son's method2");
 }
 
}

输出结果是:
son's method1
father's method1
son's method2
还是
son's method1
father's method1
father's method2

答案是前者。

如果把main()中的
Son s = new Son();
s.method1();
改成
Father f = new Son();
f.method1();
结果有如何呢?
答案还是前者。

首先来说
Son s = new Son();
s.method1();与
Father f = new Son();
f.method1();
效果是一样的,多态使然。不多说了。

那么输出的最后一行为什么是son's method2而不是father's method2?表面来看Son类的method1调用了其父类Father类的method1,Father类的method1调用了一个method2,而这个method2到底是父类的,还是子类的呢?
其实这行代码里省略了一个this,即this.method2();,那么this指向的是谁,调用的自然就是谁的method2了。很明显this指向的是一个Son的实例,即s,结果也是理所当然的了。
如果还想看看this指向的到底是什么,可以在Father类和Son类的method1、method2方法的原有的System.out.println()语句下增加一行System.out.println(this.toString());。此时输出结果类似于:
son's method1
Son@765291
father's method1
Son@765291
son's method2
Son@765291