假設,子類重載父類的方法,並將子類的成員覆蓋。
創建子類對象實例,將其上轉型成父類。
例子1
public class Parent {
public void init() {
System.out.println("1 init parent");
this.demo();
}
public void demo() {
System.out.println("2 demo parent");
}
}
public class Son extends Parent {
public void init(){
super.init();
System.out.println("3 init son");
this.demo();
}
public void demo() {
System.out.println("4 demo Son");
}
public static void main(String[] args) {
//Parent p = new Son();//1
Son son = new Son();//2
son.init(); // init(son)
}
}
當執行1時結果爲:
1 init parent
4 demo Son
3 init son
4 demo Son
當執行2時結果爲:
1 init parent
4 demo Son
3 init son
4 demo Son
情況1和情況2其實是相似的,由於使用new Son()創建實例,上轉型之後,訪問的也是子類重載的方法而Parent中的init()方法中的this也被認爲是指向堆區域中son的實例化對象,故this.demo()訪問的仍然是子類中重載的方法。
例子2
public class Parent {
public String name="tom";
public void init() {
System.out.println(this.name);
}
}
public class Son extends Parent {
public String name="jack";
public void init(){
super.init();
System.out.println(this.name);
}
public static void main(String[] args) {
//1 當前運行類 Son
Son son = new Son();
son.init(); //init(son)
System.out.println("## " + son.name);
//2 當前運行類Parent
Parent p = new Son();
p.init();
System.out.println("** " + p.name);
}
}
當代碼運行1時 我猜測結果應該是:
jack
jack
##jack
但實際結果卻是:
tom
jack
## jack
此時Parent類中this.name指向的是父類中的name值
只有幾種情況可以解釋這種結果
1.this並不指向son在堆中創建的實例
2.創建對象時內存中使用了其他機制來保證這種結果的生成。
翻看了一下《深入理解Java虛擬機 JVM高級特性與最佳實踐》這本書 似乎得出了一些端倪
由此可見當訪問成員變量時,檢測到父類的成員變量之後程序停止繼續尋找。
對於方法,由於其內容存放在方法區內,每個對象的發放應該是通過其自身的this即引用唯一綁定。故就差不多解釋的通了。
《深入理解Java虛擬機 JVM高級特性與最佳實踐》一書的下載地址:
http://www.jb51.net/books/163531.html#down
上面只是個人的一點點猜測 ,不吝賜教。