java super關鍵字
我們已經知道,如果子類中定義的成員變量和父類中的成員變量同名時,則父類中的成員變量不能被繼承,此時稱子類的成員變量隱藏了父類的成員變量。
當子類中定義了一個方法,並且這個方法的名字,返回類型,參數個數以及類型和父類的某個方法完全相同時,父類的這個方法將被隱藏(重寫),既不能被子
類繼承下來。如果我們在子類中想使用被子類隱藏的父類的成員變量或方法就可以使用關鍵字super。因此,super是用在子類中,目的是訪問直接父類中被屏蔽
的成員,註意是直接父類(就是類之上最近的超類)。
1 使用super調用父類的構造方法
子類不繼承父類的構造方法。因此,子類如果想使用父類的構造方法,必須在子類的構造方法中使用,並且必須使用關鍵字super來表示。而且super必須是
子類構造方法中的頭一條語句(也就是說父類必須自己負責初始化她自己的狀態而不是讓子類來做)。
需要註意的是:如果在子類的構造方法中,沒有顯示地使用super關鍵字調用父類的某個構造方法,那麽默認地有 super();語句,即調用父類的不帶參數的構
造方法。如果父類沒有提供不帶參數的構造方法,就會出現錯誤。特別註意:當存在有參構造器時,無參構造器就不存在了,必須顯示的聲明空構造器。
2 使用super操作被隱藏的成員變量和方法
如果我們在子類中想使用被子類隱藏了的父類的成員變量或方法就可以使用關鍵字super。比如super.x,super.play(),就是被子類隱藏的父類的成員變量x和方法play()。
關鍵字super和繼承一起建立類和它的父類的緊密聯系。例如,當我們要調用一個實例方法時,如果實例本身並沒有定義該方法,那我們自然地會得到它的父類中定義的同名方法。
盡管會因為方法的覆蓋或者使用定義與父類一樣的實例或類變量(叫做“隱藏”)而失去這種訪問的權力。這就是為什麽要使用super這個關鍵字,它顯式地指出子類可以直接訪問父類中的某些部分,
盡管有時這種訪問會因為種種原因被屏蔽了的方法在其父類中的原始代碼。
關鍵字Super在構造函數的使用中是非常重要的,和方法不同,構造函數是不被繼承的;因此super是訪問父類中構造函數的惟一途徑。在子類的構造函數 中,
使用super( )和適當的參數表可以觸發對父類構造函數的一個調用,如果父類沒有相應的構造函數,編譯器會報錯,這就是每個實例實現的初始化的過程鏈。
實例先把自己作為一個Object實例進行初始化,然後從它的直接子類開始按照繼承鏈依次調用構造函數直到最後將與當前類直接相關的內容初始化完畢。
子類的構造函數如果要引用super的話,必須把super放在函數的首位,不然會出現這樣的報錯:
Checket.java:10: call to super must be first statement in
constructor
那麽在類中用super調用父類構造函數時,為什麽調用語句必須是子類的第一條語句?
答案:如果想用super繼承父類構造的方法,但是沒有放在第一行的話,那麽在super之前的語句,肯定是為了滿足自己想要完成某些行為的語句,但是又用了super繼承父類的構造方法。那麽以前所做的修改就都回到以前了,就是說又成了父類的構造方法了
下面總結一下super的用法:
第一、在子類構造方法中要調用父類的構造方法,用“super(參數列表)”的方式調用,參數不是必須的。
同時還要註意的一點是:“super(參數列表)”這條語句只能用在子類構造方法體中的第一行。
第二、當子類方法中的局部變量或者子類的成員變量與父類成員變量同名時,也就是子類局部變量覆蓋父類成員變量時,
用“super.成員變量名”來引用父類成員變量。當然,如果父類的成員變量沒有被覆蓋,也可以用“super.成員變量名”來引用父類成員變量,不過這是不必要的。
第三、當子類的成員方法覆蓋了父類的成員方法時,也就是子類和父類有完全相同的方法定義(但方法體可以不同),此時,用“super.方法名(參數列表)”的方式訪問父類的方法。
第四、super關鍵字只能用在類體中非靜態部分,比如構造函數與成員方法中,若在main函數中調用或靜態方法中編譯會出錯,報Cannot use super in a static context的錯誤!
註意:父類的屬性和方法必須是哪些protected或者public等可以讓子類訪問的屬性或者方法。
java super關鍵字