java回顧之繼承和抽象類
一、繼承
1.1什么是繼承
在java中需要寫類來創建對象,類中需要些代碼來給對象賦予一些功能。
假如現在我需要創建如下三個對象
對象: 功能
學生: 吃飯、睡覺、打游戲
老師:吃飯、睡覺、打學生
家長:吃飯、睡覺、打孩子
孩子:?????
假如沒有繼承,我們在寫學生的時候需要寫一下吃飯、睡覺的代碼,寫老師的時候需要寫一下吃飯、睡覺的代碼,寫家長的時候需要寫一下吃飯、睡覺的代碼。
這樣的話,其實吃飯、睡覺的代碼是一樣的,即使我們可以復制粘貼,這是三個類,如果讓寫一千個類呢?
所以我們可以給這三個類寫一個共同的父類---中國人類,將吃飯、睡覺的代碼寫到中國人類當中,學生只寫打游戲的方法、老師只寫打學生的方法、家長只寫打孩子的方法,吃飯睡覺不需要寫,只要繼承了,創建出來得 對象就具備這兩樣功能。
這樣就解決了代碼冗余,如果覺得這也沒什么,那就想象下一千個類當中有幾十個方法是相同的這種情況,繼承的優越性就體現出來了
-
-
extends表示繼承
1.2繼承圖解
1.3繼承的格式和好處
B類繼承了A類:
public class B extends A{
}
好處:提高了代碼的復用性、繼承是多態的前提
代碼演示
//人類 public class Person { //姓名 String name; //年齡 int age; //吃飯 public void eat(){ System.out.println("一天三頓飯 一頓是半天"); } //睡覺 public void sleep(){ System.out.println("一天睡兩覺 一覺睡半天"); } } //學生類 public class Student extends Person{ //雖然在子類中沒有定義姓名 年齡 吃飯 睡覺 //但是在父類中定義了子類就自動擁有的父類成員 } //測試類 public class Demo繼承的測試 { public static void main(String[] args) { //創建學生對象 Student s = new Student(); //可以賦值 學生類當中什么都沒寫,如果沒有繼承,是賦不了值的 s.name = "石原里美"; s.age =18; //方法 s.eat(); s.sleep(); } }
1.4 繼承的內存圖
二、方法重寫
之所以有方法重寫 是為了解決繼承所產生的一些問題,比如繼承的父類當中有個方法無法滿足子類的需求,這個時候,只要在子類當中將方法重新寫一遍,給此方法賦予新的功能,這就是方法的重寫
-
@Override
這是一個注解,他的作用是檢查這個方法是一個重寫方法,如果這個方法不是重寫方法就會報錯
-
方法名:必須完全相同。
-
參數:參數類型和個數必須完全相同。
-
權限修飾符:子類的權限修飾符必須大於等於父類的權限修飾符
-
返回值類型:子類的返回值類型必須小於等於父類的返回值類型
(小於的意思是說子類的返回值類型可以是父類返回值類型的子類)
-
結論:對於這個規則,不用強求背他,絕大多數的情況都是完全相同的。也就是說權限修飾符和返回值類型特殊情況不多見。
2.2 設么內容不能被子類繼承或訪問
private修飾的成員子類可以繼承,但是不能使用
構造方法是不能被繼承的。這里要注意,每個類被創建的時候,系統都會自動調用空參構造,所以說空參構造是每個類都有的,所以構造方法不會被繼承。
另外如果寫了有參構造的話,類默認的無參構造就會失效,這個時候又有類繼承了這個類,由於父類只有有參沒有無參,這個時候就會報錯,這是因為java中如果創建一個類的話,這個類會回溯到object,默認的無參構造方法就是回溯的路徑,所以當中間某一段,只有有參沒有無參,路徑就斷了,所以在java中我們寫一個類時,會將有參構造和無參構造都寫出來,防止報錯。
2.3this和super關鍵字
this代表成員變量、super代表父類成員
要注意:
this():表示調用本類的構造方法
super():表示調用父類的構造方法
在構造方法中this()和super()只能出現一個,且必須放在方法的第一行
在寫代碼的時候,只需要使用idea生成構造方法就可以了。
2.4 繼承的注意事項
java繼承中一個子類只能繼承一個父類(只能有一個親爹)
java繼承中可以多重繼承,可以有父類,可以有爺爺類(家族體系)
java繼承中只有屬於關系才可以繼承,這不是java代碼規范,這是開發規范,要跟實際生活聯系在一起,你不能讓一個貓的類去繼承汽車類,這是屬於瞎繼承,雖然代碼不會報錯,但是在開發中就是有毛病了。
三、抽象類
3.1 什么是抽象類
父類中的方法,被它的子類們重寫 ,子類各自的實現都不盡相同。那么父類的方法聲明和方法主體,只有方法聲明才有意義(方法的名字),方法的主體則沒有意義(因為要實現的功能不一樣),換句話說,父類可能知道子類應該有哪個功能,但是功能具體怎么實現父類是不清楚的(有子類自己決定),父類完全只需要 提供一個沒有方法體的方法簽名即可,具體實現給子類自己去實現。
我們把沒有方法體的方法稱為抽象方法。java語法規定,包含抽象方法的類就是抽象類,因為不是抽象類也包含不了抽象方法
抽象類格式 public abstract class 類名{ }
抽象方法格式
//抽象方法沒有方法體
public abstract 返回值類型 方法名(參數類型 參數名);
public abstract void eat();
抽象方法可以要求子類必須重寫某個方法,以此來完成某個功能