1. 程式人生 > >java基礎——super關鍵字

java基礎——super關鍵字

一、super關鍵字

  

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

1.1.super關鍵字測試

package cn.galc.test;

/**
 * 父類
 * @author gacl
 *
 */
class FatherClass {
    public int value;
    public void f() {
        value=100;
        System.out.println("父類的value屬性值="+value);
    }
}

/**
 * 子類ChildClass從父類FatherClass繼承
 * @author gacl
 *
 */
class ChildClass extends FatherClass {
    /**
     * 子類除了繼承父類所具有的valu屬性外,自己又另外聲明瞭一個value屬性,
     * 也就是說,此時的子類擁有兩個value屬性。
     */
    public int value;
    /**
     * 在子類ChildClass裡面重寫了從父類繼承下來的f()方法裡面的實現,即重寫了f()方法的方法體。
     */
    public void f() {
        super.f();//使用super作為父類物件的引用物件來呼叫父類物件裡面的f()方法
        value=200;//這個value是子類自己定義的那個valu,不是從父類繼承下來的那個value
        System.out.println("子類的value屬性值="+value);
        System.out.println(value);//打印出來的是子類自定義的那個value的值,這個值是200
        /**
         * 打印出來的是父類裡面的value值,由於子類在重寫從父類繼承下來的f()方法時,
         * 第一句話“super.f();”是讓父類物件的引用物件呼叫父類物件的f()方法,
         * 即相當於是這個父類物件自己呼叫f()方法去改變自己的value屬性的值,由0變了100。
         * 所以這裡打印出來的value值是100。
         */
        System.out.println(super.value);
    }
}

/**
 * 測試類
 * @author gacl
 *
 */
public class TestInherit {
    public static void main(String[] args) {
        ChildClass cc = new ChildClass();
        cc.f();
    }
}

執行結果:

  

1.2. 畫記憶體分析圖瞭解程式執行的整個過程

  分析任何程式都是從main方法的第一句開始分析的,所以首先分析main方法裡面的第一句話:

ChlidClass cc = new ChlidClass();

  程式執行到這裡時,首先在棧空間裡面會產生一個變數cc,cc裡面的值是什麼這不好說,總而言之,通過這個值我們可以找到new出來的ChlidClass物件。由於子類ChlidClass是從父類FatherClass繼承下來的,所以當我們new一個子類物件的時候,這個子類物件裡面會包含有一個父類物件,而這個父類物件擁有他自身的屬性value。這個value成員變數在FatherClass類裡面宣告的時候並沒有對他進行初始化,所以系統預設給它初始化為0,成員變數(在類裡面宣告)在宣告時可以不給它初始化,編譯器會自動給這個成員變數初始化,但區域性變數(在方法裡面宣告)在宣告時一定要給它初始化,因為編譯器不會自動給區域性變數初始化,任何變數在使用之前必須對它進行初始化。

  子類在繼承父類value屬性的同時,自己也單獨定義了一個value屬性,所以當我們new出一個子類物件的時候,這個物件會有兩個value屬性,一個是從父類繼承下來的value,另一個是自己的value。在子類裡定義的成員變數value在宣告時也沒有給它初始化,所以編譯器預設給它初始化為0。因此,執行完第一句話以後,系統記憶體的佈局如下圖所示:

 

接下來執行第二句話:

 cc.f();
  當new一個物件出來的時候,這個物件會產生一個this的引用,這個this引用指向物件自身。如果new出來的物件是一個子類物件的話,那麼這個子類物件裡面還會有一個super引用,這個super指向當前物件裡面的父物件。所以相當於程式裡面有一個this,this指向物件自己,還有一個super,super指向當前物件裡面的父物件。

  這裡呼叫重寫之後的f()方法,方法體內的第一句話:“super.f();”是讓這個子類物件裡面的父物件自己呼叫自己的f()方法去改變自己value屬性的值,父物件通過指向他的引用super來呼叫自己的f()方法,所以執行完這一句以後,父物件裡面的value的值變成了100。接著執行“value=200;”這裡的vaule是子類物件自己宣告的value,不是從父類繼承下來的那個value。所以這句話執行完畢後,子類物件自己本身的value值變成了200。此時的記憶體佈局如下圖所示:

  方法體內的最後三句話都是執行列印value值的命令,前兩句打印出來的是子類物件自己的那個value值,因此打印出來的結果為200,最後一句話列印的是這個子類物件裡面的父類物件自己的value值,打印出來的結果為100。

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