子父類出現后,類成員的特點:
類中成員:
1、變量
2、函數
3、構造函數
1、變量
如果子類中出現非私有的同名的成員變量時,
子類要訪問本類中的變量,用this關鍵字
子類要訪問父類中的同名變量,用super關鍵字
super和this的使用幾乎一致
this代表的是本類對象的引用
super代表的是父類對象的引用
如果子類和父類有相同名稱的變量時,子類繼承父類后,在子類中默認使用的是自己的變量,
因為在子類中是this.num省略了this。如果要用父類的變量只需要在變量前加上super
2、函數
當子類出現和父類一模一樣的函數時,子類對象調用該函數,會運行子類函數的內容,如同父類的函數被覆蓋了一樣。
這種現象是函數的另一種特性:重寫(覆蓋)
當子類繼承父類,沿襲了父類的功能到子類中,但是子類雖然具備該功能,但是功能的內容卻和父類不一致
這個時候沒有必要重新在子類中定義新功能,只需要重寫父類的方法,代碼如下:
class Fu { void show { System.out.println("Fu"); } } class Zi extends Fu { void show { System.out.println("Zi"); } }
class Zi中的方法show就是重寫了class Fu中的show
覆蓋需要注意的:
1、子類覆蓋父類,必須要保證子類權限大於等於父類權限,才可以覆蓋,否則編譯失敗
2、靜態只能覆蓋靜態
函數重載與重寫的區別
重載:只看函數名的參數列表
重寫:子父類方法要一模一樣
3、子父類中的構造函數
在對子類對象初始化時,父類的構造函數也會運行,因為子類構造函數的第一行都有一條隱式語句super();
super();會訪問父類中空參數的構造函數,而且子類中所有的構造函數默認第一行都是super();
為什么子類一定要訪問父類中的構造函數
因為父類中的數據子類可以直接獲取,所以子類在建立時。需要先查看父類是如何對這些數據進行初始化的
訪問父類中的構造函數可以手動定義super語句的方式來定義
注意:super語句一定要定義在子類構造函數的第一行,並且不能和this();同時出現
子類實例化的過程
結論:
子類的所有的構造函數,默認都會訪問父類中空參數的構造函數
因為子類的所以構造函數第一行都有一句隱式的super();語句
當父類中沒有空參數的構造函數時,子類必須手動通過super語句的形式來指定要訪問父類中的構造函數
子類的構造函數第一行也可以使用this來訪問本類中的構造函數,因為子類中至少會有一個構造函數訪問父類的構造函數
class ExtendsDemo { public static void main(String[] args) { Zi z = new Zi(); } } class Fu { Fu() { System.out.println("Fu"); } } class Zi extends Fu { Zi() { //隱式存在super(); System.out.println("Zi"); } }
上述代碼運行后結果為
Fu
Zi
this();和super();為什么不能同時存在?
因為他們都只能存在於構造函數里面的第一行
為什么都要寫第一行? 因為初始化動作要先做