關于this和super又必要理解清楚的地方!重要的,多態的關鍵
二話不說,先來一段代碼,比較短,需要付出一點點耐心(估計一上來就是代碼,又會趕走很多人吧.....)
//父類
class FatherClass {
public int value;
public void f() {
this.run();//注意這兒的是this,注意
}
public void run(){
System.out.println("FatherClass.run():"+this.value);
}
}
//子類
class ChildClass extends FatherClass {
public int value = 100;
public void ff() {
super.run();//注意這兒的是super,注意
}
//重寫
public void run(){
System.out.println("ChildClass.run():"+super.value);
}
}
//孫子類,這兒用了一個拼音,偷懶一下,記不到那個孫子的單詞了。寒啊...當初還過四級,現在忘光光
class SunziClass extends ChildClass {
public int value = 200;
//再次重寫
public void run() {
System.out.println("SunziClass.run():"+super.value);
}
}
//這兒是調用的Main
public class TestInherit {
public static void main(String[] args) {
FatherClass fc = new ChildClass();
fc.f();
FatherClass fc1 = new SunziClass();
fc1.f();
ChildClass cc = new SunziClass();
cc.ff();
}
}
想一想運行結果,注意那個this和super。有點暈頭把,不要暈,穩?。∽约合胍幌陆Y果,然后再來看運行結果。
運行結果如下:
ChildClass.run():0;
SunziClass.run():100;
FatherClass.run():0;
估計有不少人會大吃一驚!其他不吃驚的人可以散了!吃驚的人繼續看下面的。
this代表什么?這兒代表New出來的那個玩意兒在堆空間的引用地址
對于下面的這一句:
FatherClass fc1 = new SunziClass();
fc1這個變量里面放的就是this,是new SunziClass()這個玩意兒在堆空間的引用地址.
只是這兒fc1是定義成FatherClass,只有FatherClass的屬性和方法是可見的,不過這不是本文討論的重點.
所以說在父類里面寫的this其實就是這個父類或者他的子類,孫子類,曾孫子類... 在運行的時候[重復一次哈,運行的時候runtime], New 子類()或者New 孫子類()或者New 曾子類()或者....的堆空間的引用地址.
[再重復一次,FatherClass里面的this,子類里面的this...都是一樣的,指向New出來的那玩意兒的引用地址]
很神奇哈!!嘿嘿,這個其實就是 多態的體現,也是多態的實現基礎.看父類或者接口定義了方法調用的邏輯,子類可以根據需要改變算法! 這樣就可以將關注的方面分為兩個層面,一:關注方法調用的業務邏輯[做什么],二:關注方法的實現[怎么做]. "做什么和怎么做",這玩意兒好像在軟件工程里面比較眼熟哦!!!!
問題分解了,而且可復用性也大大提高了.
好了,this總結完了,好像越說越暈了... 再穩一下,看看Super
下面再來說super
說之前,分析一下內存多,這個圖,挖卡,蜘蛛網來也....

現在看這兩句:
ChildClass cc = new SunziClass();
cc.ff();
這兒SunziClass里面沒有重寫父類ChildClass的ff方法,
所以是執行的父類ChildClass的ff方法.這個方法里面有一個super.Run();
這兒實際上就執行到了FatherClass的Run()方法.
這說明什么啦.
說明super只是記錄對象內部的父類的特征(屬性和方法)的一個引用
(注意哈:這兒super不是指向父類對象的引用地址哈,new出來的玩意兒才在堆里面分配空間有引用地址,這兒沒有去new一個父類對象哈,只是執行了父類的構造函數將父類的特征生成了,但是屬于New出來的那個子類對象)
估計上面這段話也夠暈人了...
實踐一下,你可以寫
public FatherClass getThis()
{
return this;
}
編譯通過,沒有任何問題
但是你寫
public FatherClass getSuper()
{
return super;
}
嘿嘿,編譯出錯! 為什么啦,
因為super并不是一個堆空間里面的一個對象的引用地址,而this才是堆空間里面的一個對象的引用地址
super只能在對象內部使用,而this可以在對象內部使用也可以返回出對象外.
super是死的,編譯的時候就定死了super的指向了,而this是活的,在運行時候決定其指向.
再說一下,子類實例化對象,并沒有去實例化他的父類對象,也就是說,那個子類對象里面并沒有一個父類對象,
那你說沒有父類對象,為什么子類構造函數要執行父類的構造函數啦,那是因為需要創建父類的特征賦予子類,但是是由子類所有,而super就是用來區別是是否是父類對象的特征的.
重寫父類方法屬性,就是再創建了一個子類的特征,當你用this的時候,就覆蓋了父類的特征了,但是父類特征還在那兒,用super就能訪問道,但是只能在對象的內部使用.對象外面就只能看到覆蓋了父類特征的子類特征了.
寫完收工,我Cao,寫了2個小時.....
其實寫了這么一大堆,就是一句:"this是當前對象在堆空間的引用地址,super是當前對象的父類特征的引用"
有什么不同的見解歡迎討論...共同進步!!!