一、繼承
1.1 、什么是繼承?
- 繼承就是把所有的類的公共部分(相同的成員)提取出來,放到一個類中
- 繼承需要使用 extends 關鍵字
public class Animal{
public String name;
}
public class Dog extends Animal{}
Dog 是 Animal 的子類,Animal 是 Dog 的父類,發生繼承關系后子類中包含有父類中的成員(成員方法和成員變量)
- 子類中要有自己特色的代碼,否則直接調用父類就行了,還要子類干嘛?
1.2、為什么繼承?
- 因為繼承是把所有類的公共部分提取取來放到一個類中,那么想用這公共部分的類可以繼承,那么就實現了代碼的復用性
1.3、繼承的好處?
- 我們知道,父類是公共成員,那么子類中也有子類的特色成員,除了實現代碼的復用外,還讓代碼有拓展的能力
1.4、父類成員的訪問
- 當子類繼承父類后,通過子類的對象是可以訪問父類當中的成員變量和成員方法的。
- 就是表明子類創建出來的對象,包含了父類的內容
- 子類和父類的內存布局如下
1.4.1、子類和父類不存在同名成員變量
- 子類new對象,用引用直接訪問就行,比如你訪問的是一個變量,他的機制就是首先在子類中尋找,如果沒有,就到父類中尋找,父類中也沒有的話就會報錯
Dog dog1 = new Dog();
//這樣就能訪問到父類的name
dog1.name;
1.4.2、子類和父類的成員變量同名
- 如果有同名的話,加 this 就是子類中的,加 super 就是父類的
//假如子類中也有name 叫 旺財 , 父類中也有相同的變量name 叫 大黃
this.name; // 那么就會訪問子類中的name輸出旺財
super.name; // 那么就會訪問父類中的name 輸出大黃
如果什么都不加呢?上面我說他的訪問機制是先從子類找,再到父類找,所以優先訪問子類的
1.4.3、子類和父類的成員方法名字不同
- 調用誰就是誰,和成員變量一樣
1.4.4、子類和父類的成員方法名字相同
- 如果完全一樣(包括參數)那么子類的優先, 子類沒有就調用父類的,父類沒有就報錯,如果構成了重載那么就是 調用誰就是誰
1.5、super關鍵字
1.5.1、什么是super關鍵字?
- super 主要作用是在子類中訪問父類的成員
- 如果兩個類發生了繼承關系的話,我們知道子類中有父類的成員,所以如果我們想調用父類的成員那么怎么調用呢?此時就有了super ,super是子類中屬于父類那一部分內存空間的標識,所以就可以使用super調用父類的成員
1.5.2、super 關鍵字的用法?
- super 的用法是訪問父類的成員方法
- 訪問父類的成員變量
- 訪問父類的構造方法
1.5.3、super 關鍵字使用的范圍
- super 只能在非靜態的方法中使用,或者在子類中訪問父類的成員
- super 調用父類構造方法時,和this調用當前類的另一個構造方法一樣,需要調用幾個參數的就調用幾個參數的,并且要放在子類的構造方法中的第一行代碼。我們知道this()也需要放在第一行,所以super()和 this() 不能同時使用,否者不知道哪個是第一行的
1.5.4、super 和 this 的區別
- 修飾變量時 super 調用的是父類中的成員變量,而 this 調用的是當前引用所指的對象的成員變量
- 修飾方法時 super 調用的是父類中的成員方法,而 this 調用的是當前引用所指的對象的成員方法
- 調用構造方法時 super 調用的是父類的構造方法,而this 是調用當前類的另一個構造方法
- 因為在調用完成子類的構造方法之前要調用父類的構造方法,如果父類是系統默認的構造方法(即無參的構造方法),那么在子類的構造方法中系統會在第一行默認隱藏一個super調用父類構造方法的代碼。所以super()系統有時會調用,而this()只能自己寫才調用
1.6、子類構造方法
- 我們知道子類中也會有成員變量的,有變量就少不了初始化,既然子類的需要初始化,那么父類的成員變量也是需要初始化的,究竟該怎么寫構造方法呢?俗話說有父才有子,所以需要初始化父類的成員變量先,再初始化子類的成員變量。那么就有了在子類構造方法完成之前先調用父類的構造方法(即使用super()調用),需注意的是super()必須要放在子類構造方法的第一行
- 子類的構造方法中,一定有super();
1.7、繼承關系上代碼塊等的初始化順序
- 前面我們講過代碼塊的初始化順序,優先執行靜態代碼塊,接著到實例代碼塊,最后到構造方法,同級的按順序
- 那么在繼承關系下,他們的執行順序是怎么樣的呢?
- 我們在上面知道,先有父再有子,先初始化父類,再初始化子類。但是我們也知道,靜態代碼塊只要類一加載便執行,所以綜上所述,先執行父類的靜態代碼塊,再執行子類的靜態代碼塊,接著執行父類的實例代碼塊,父類的構造方法,最后執行子類的構造代碼塊,子類的構造方法
1.8、protected 訪問修飾限定符 的詳解
- 被 protected 修飾后 不同包中的子類可以訪問
- 就是有一個類(Animal)存在包一中,有一個類(Dog)存在包二中,并且這兩個類在包二中發生的了繼承關系,那么在包二 Dog 這個類中可以訪問包一Animal 中 被 protected 修飾過的 成員變量
- 那么在包二中非繼承包一Animal 的類是不能訪問的
- 那么如果在包二中再創建一個 Cat 類 并且繼承于Animal,那么它在自己的類中可以訪問Animal中被 protected 修飾的成員變量,但是當Cat 在 Dog類中實例化對象時,這個引用不能訪問父類中被 protected 所修飾的成員變量,所以說 他只能在自己的(Cat)子類中訪問,不能在其他(Dog)子類中訪問
public class Dog extends Animal{
}
1.9、繼承的方式
- A 繼承 B ,B < — A;單繼承
- A 繼承 B ,B 繼承 C C < — B < — A;多層繼承
在A實例化出來的對象的引用可以訪問 C中的成員
- A 繼承B ,a 繼承 B B < — A , B < — a;一個類被多個類繼承
- 注意:Java不支持一個類同時繼承兩個或兩個以上的類
1.10、final關鍵字
1.10.1、什么是final關鍵字
- final 是不可更改的意思
- 可以修飾變量,語句,方法,類
1.10.2、final 關鍵字修飾變量 或字段
- 當final修飾變量時,把變量變成了常變量,意思就是把一個變量變為常量
1.10.3、final關鍵字修飾方法
- 當final 修飾方法時,表明這個方法不能被重寫
1.10.4、final 關鍵字修飾類
- 當final修飾類時,表明這個類不能被繼承