Java中關鍵字super與this的區別


一、super關鍵字

在JAVA類中使用super來引用父類的成分,用this來引用當前對象,如果一個類從另外一個類繼承,我們new這個子類的實例對象的時候,這個子類對象里面會有一個父類對象。怎么去引用里面的父類對象呢?使用super來引用,this指的是當前對象的引用,super是當前對象里面的父對象的引用。

class Student {
	public int age;
	public void std(){ //聲明Student類的方法std()
		age = 15;
		System.out.println("學生平均年齡為:"+age);
	}
}

class ThisStudent extends Student{
	public int age;
	public void std(){
		super.std();  //使用super作為父類對象的引用對象來調用父類對象里面的Std()方法
		age = 18;
		System.out.println("這個學生的年齡為:"+age);
		System.out.println(super.age);  //使用super作為父類對象的引用對象來調用父類對象中的age值
		System.out.println(age);
	}
}

public class TestDif {
    public static void main(String[] args) {
    	ThisStudent a = new ThisStudent();
    	a.std();
    }
}

 執行結果:

學生平均年齡為:15
這個學生的年齡為:18
15
18

二、上述程序的內存分析

ThisStudent a = new ThisStudent();

程序執行到這里時,首先在棧空間里面會產生一個變量a,a里面的值是什么這不好說,總而言之,通過這個值我們可以找到new出來的ThisStudent對象。由於子類ThisStudent是從父類Student繼承下來的,所以當我們new一個子類對象的時候,這個子類對象里面會包含有一個父類對象,而這個父類對象擁有他自身的屬性age。這個age成員變量在Student類里面聲明的時候並沒有對他進行初始化,所以系統默認給它初始化為0,成員變量(在類里面聲明)在聲明時可以不給它初始化,編譯器會自動給這個成員變量初始化,但局部變量(在方法里面聲明)在聲明時一定要給它初始化,因為編譯器不會自動給局部變量初始化,任何變量在使用之前必須對它進行初始化。

子類在繼承父類age屬性的同時,自己也單獨定義了一個age屬性,所以當我們new出一個子類對象的時候,這個對象會有兩個age屬性,一個是從父類繼承下來的age,另一個是自己的age。在子類里定義的成員變量age在聲明時也沒有給它初始化,所以編譯器默認給它初始化為0。因此,執行完第一句話以后,系統內存的布局如下圖所示:

a.std();

當new一個對象出來的時候,這個對象會產生一個this的引用,這個this引用指向對象自身。如果new出來的對象是一個子類對象的話,那么這個子類對象里面還會有一個super引用,這個super指向當前對象里面的父對象。所以相當於程序里面有一個this,this指向對象自己,還有一個super,super指向當前對象里面的父對象。

這里調用重寫之后的std()方法,方法體內的第一句話:“super.std();”是讓這個子類對象里面的父對象自己調用自己的f()方法去改變自己age屬性的值,父對象通過指向他的引用super來調用自己的std()方法,所以執行完這一句以后,父對象里面的age的值變成了15。接着執行“age=18;”這里的age是子類對象自己聲明的value,不是從父類繼承下來的那個age。所以這句話執行完畢后,子類對象自己本身的age值變成了18。此時的內存布局如下圖所示:

方法體內的最后三句話都是執行打印age值的命令,前兩句打印出來的是子類對象自己的那個age值,因此打印出來的結果為18,最后一句話打印的是這個子類對象里面的父類對象自己的age值,打印出來的結果為15。

到此,整個內存分析就結束了,最終內存顯示的結果如上面所示。

(參考自孤傲蒼狼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM