Java中super關鍵字的用法和細節

前言

    因為西安疫情的原因在宿舍擺瞭一個月,最近在復習前面學過的知識的時候發現,自己在初學面向對象時對Super關鍵字的理解不夠深刻,所以現在重新學習一下super關鍵字的用法和細節。

 1. super關鍵字的用法

    在Java中,super關鍵字共有三種用法,分別是:

通過 super.屬性名 來訪問父類中的成員變量

通過super.方法名(參數列表) 來訪問父類中的成員方法

通過super(參數列表) 來訪問父類的構造方法

調用父類的成員變量:

class Person {
    protected int age;
}
class Student extends Person{
    public void func(){
        int age = super.age;	//通過super.屬性名訪問父類的成員變量
    }
}
調用父類中的成員方法:
class Person {
    protected void func(){
        
    }
}
class Student extends Person{
    public void func(){
        super.func();	//通過super.方法名調用父類的成員方法
    }
}
調用父類的構造器:
class Person {
    String name;
    public Person(String name) {
        this.name = name;
    }
}
class Student extends Person{
    public Student(String name) {
        super(name);	//通過super(參數列表)調用父類的構造方法
    }
    
}
註意:

子類無法通過super關鍵字訪問父類中private修飾的屬性和方法,因為private修飾的屬性和方法隻能在當前類的內部進行訪問在子類的構造器中通過super關鍵字調用父類的構造器時,super關鍵字必須出現在構造器的第一行且僅能出現一次

2. super關鍵字的使用細節

當我們查找子類中的方法時,調用規則如下:

當子類中存在需要調用的方法時,直接調用即可如果子類中不存在該方法,則向上尋找父類,如果父類中存在該方法,則調用父類中的方法若父類中不存在該方法,那麼向上尋找父類的父類,直到找到Object類

提示:如果直到Object類依然沒有找到該方法,那麼會提示方法不存在,但如果向上找到瞭這個方法但沒有權限訪問(例如該方法被private修飾),則會產生錯誤。

public class Test extends Test2{
    public static void main(String[] args) {
        Test test = new Test();
        test.func1();	
    }
    public void func1(){
        System.out.println("子類中的func1()");
        func2();
    }
}
class Test2{
    public void func2(){
        System.out.println("父類中的func2()");
    }
}
//結果:
子類中的func1()
父類中的func2()

    在上述代碼中,子類中的func1()方法在調用func2()方法時會在子類中查找是否存在func2()方法,未找到時會在其父類中查找func2()方法。

    當我們將func1()中的語句 func2(); 改為 this.func2(); 此時語義未發生改變,依然會先在子類中查找,沒有找到時會在其父類中查找。

    當我們再將 this.func2(); 改為 super.func2(); 這時語義就發生瞭變化,上面提到過,super.方法名()調用的是父類中的方法,那麼這條語句就不會檢測當前類中是否存在func2()方法,隻會在其父類中依次向上進行檢測。例如:

public class Test extends Test2{
    public static void main(String[] args) {
        Test test = new Test();
        test.func1();
    }
    public void func1(){
        System.out.println("子類中的func1()");
        super.func2();	//這裡編譯無法通過
    }
    public void func2(){
        System.out.println("字類中的func2()");
    }
}
class Test2{
    public void func3(){
        System.out.println("父類中的func3()");
    }
}
//編譯未通過,提示無法解析Test2中的方法func2()

註:成員屬性與成員方法同理。

    我們已經知道瞭,super關鍵字的訪問並不僅僅局限於父類,即使是父類的父類,父類的父類的父類,甚至再往上,都可以通過super關鍵字訪問到。那麼,如果子類上面的多個類中都存在同樣的成員,此時使用super關鍵字訪問的是哪個類中的成員呢?

    當子類要訪問上級類的某個成員,而子類的多個上級類都有該成員時,我們對super關鍵字的使用采用就近原則,也就是訪問super關鍵字向上找到的第一個成員。例如:

public class Test extends Test2{
    public static void main(String[] args) {
        Test test = new Test();
        test.func1();
    }
    public void func1(){
        System.out.println("子類中的func1()");
        super.func2();	//子類通過super關鍵字訪問上級類中的func2()
    }
}
class Test2 extends Test3{
    public void func2(){
        System.out.println("父類中的func2()");
    }
}
class Test3{
    public void func2(){
        System.out.println("父類的父類中的func2()");
    }
}
//結果:
子類中的func1()
父類中的func2()

    在上述代碼中,子類通過super關鍵字訪問上級類中的func2()方法,子類繼承Test2,Test2繼承Test3,此時Test2和Test3中都存在func2(),此時子類先訪問其父類Test2,Test2中存在func2()方法,那麼直接訪問Test2中的func2()即可,若Test2中不存在func2(),則super關鍵字會繼續向上訪問。

3. super和this關鍵字的比較

    下面這個表格列出瞭super關鍵字和this關鍵字的區別:

請添加圖片描述

總結

到此這篇關於Java中super關鍵字的用法和細節的文章就介紹到這瞭,更多相關Java super關鍵字內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: