Java語言進階 #繼承&多態 #Day9 #繼承 #重寫 #抽象 #發紅包案例

一、繼承

面向對象三大特徵:封裝繼承多態

繼承是多態的前提

繼承: 師傅會的徒弟都會,主要解決的是共性抽取

1. 共性抽取

  1. 有這樣兩個類,我們發現,他們有共性
    在這裏插入圖片描述
  2. 如果存在一個父類 ,正好有這些共性,就可以省下存儲空間。
    在這裏插入圖片描述

注意: 一個先有父類,再有子類,上面的只是用於理解的推導。

  • 父類 也叫基類 ,也叫超類 (super())。
  • 子類 也叫派生類

2. 繼承的格式

體會一下這句話:在繼承的關係中,子類就是一個父類 (父類是官員,子類是文官。文官就是一個官員。是一個is a的關係。也就是說,子類可以當做父類對待

  • 父類格式 :
public class 父類名 {}
  • 子類格式:
public class 子類名 extends 父類名稱 {}

3. 示例

  1. 創建一個父類
    在這裏插入圖片描述
  2. 創建一個空的子類
    在這裏插入圖片描述
  3. 在另一個文件創建子類對象。調用父類方法成功。
    在這裏插入圖片描述

4. 成員變量/方法的4種訪問特點

  1. 子類創建的對象,調用成員方法或使用成員變量,會優先在子類 中找,找不到就向上一級找,實在找不到就報錯。 即以子類爲起點,向上查找。
  2. 子類調用的方法,如果使用了某個變量,則以該方法的所屬者向上查找。
  3. 所屬的概念,不僅是類的範疇。局部變量所屬者是其方法區塊,向上是本類變量,再向上是父類變量。所以當各種重名時,是會先從局部開始找起。
  4. 如果使用某特定部位的變量,則可用使用:局部變量this.成員變量super.成員變量名,來指定調用局部、本類還是父類的變量。
  • 總結一下邏輯,太好理解了: 爲啥吃飽了撐的,要定義重名變量(方法)?就是因爲直接使用上一級的變量(方法)不滿足需求,纔會重新定義。而有時確實有用到上一級的需求,只要使用有this關鍵字和super關鍵字即可。

5. 方法重寫override

重寫: 在繼承關係中,方法名與父類方法名相同,參數列表也一樣。也叫覆蓋、覆寫
重載: 方法名相同,參數列表不同的一組方法。


  1. 名稱必須相同,參數列表也必須相同
@Override  // 檢測是否是重寫,如果不是會報錯。
public void method() {}  // 方法名和父類相同

@的意思是註解。@Override可以不寫(不寫時,只要格式正確,也是正確的重寫),但最好寫上,起到一個安全檢測的功能。


  1. 子類方法的返回值必須【小於等於】父類方法的返回值範圍
  • java.lang.Object類是所有類的祖宗類
  • 比如父類方法返回值是Object類,子類方法是String類,這就行。反之不行。 (當初定義這個父類方法,是拿來返回無所不包的Object的。子類重寫方法,只能得到String之類的,Object範圍的子集。也就是說,重寫時,父類的方法是一種限制。前面的1. 講的是怎麼重寫。)

  1. 子類方法的權限 必須【大於等於】父類方法的權限修飾符
  • 權限修飾符:public > protected > (default) > private
  • 備註: (default)不是關鍵字default,而是什麼都不寫,留空

在絕大多數情況下,父類和子類的返回值和權限是一致的。

6. 方法的重寫實例

爲什麼要進行方法重寫:

  • 設計模式: 對於已經投入使用的類,儘量不要進行修改 。最好定義一個 的類,來重複利用其中共性內容,並且添加改動新內容。
  • 這就是繼承 ,宏觀上叫更新迭代

  1. 父類:
    在這裏插入圖片描述
  2. 子類: 輸入要重寫的方法名,出現提示,按回車,自動完成重寫方法
    在這裏插入圖片描述
  3. 子類: 利用super.方法名()來調用父類方法(上一步中已經被IDEA寫好了),再添加新代碼
    在這裏插入圖片描述

7. 構造方法的4種訪問特點

  1. 構造方法,會先執行父類 ,再執行子類 。(因爲先有父,纔有子)
    1.1 先寫一個父類
    在這裏插入圖片描述
    1.2 再寫一個子類
    在這裏插入圖片描述
    1.3 運行,發現父類構造方法先執行了
    在這裏插入圖片描述

  1. 子類構造方法中,會默認隱含super();調用。(這是一個無參構造的調用,如果要調用有參的重載形式,需要手動使用super(參數);
    2.1 父類不變
    2.2 子類全參構造方法,手動加上super(參數);(當然,可以使用Alt + Insert讓IDE幫你加)
    在這裏插入圖片描述
    2.3 創建全參子類對象
    在這裏插入圖片描述

  1. 只有子類的構造方法,可以利用super();調用父類的構造方法,且這個構造方法,必須是子類構造方法的第一個語句

  1. 子類必須調用父類構造方法,不寫就贈送,寫了就用新寫的

8. super & this

8.1 super關鍵字的3種用法:

  1. super.成員變量名 訪問父類成員變量
  2. super.成員方法名() 訪問父類成員方法
  3. super(); 訪問父類構造方法

8.2 this關鍵字的3種用法:

  1. 在本類的成員方法中,訪問本類的成員變量
  2. 在本類的成員方法中,訪問本類的另一個成員變量
  3. 在本類的構造方法中,訪問另一個構造方法()
    (比如無參構造,調用有參構造。this();也必須爲第一個語句。)
    super();this();都必須是第一個,不能同時使用,如果使用了this();那麼super();不再贈送。
    - 如果構造方法循環調用 (比如:無參調1參,1參調全參,全參調無參),會報錯

8.3 Demo

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

8.4 內存圖

在這裏插入圖片描述

  1. 最開始,方法區載入三個類(特別注意,子類有一個指向父類的[[super_class]],這是程序自動編寫的)。然後檢測到main()方法,使其進棧。
    在這裏插入圖片描述

  2. 創建一個子類對象時,會new進堆。此時在堆中爲子類開闢的內存空間分爲兩部分,外部是子類自己,內部是一個完整的父類結構。
    在這裏插入圖片描述

  3. 調用子類method();方法。子類通過super.去子類內部找到父類的method();方法。結束之後彈棧
    在這裏插入圖片描述

  4. 調用子類打印變量方法
    在這裏插入圖片描述

9. Java繼承的特點

  1. Java語言是單繼承 的。一個類的直接父類只能有唯一一個。(Python中,可以多繼承是由於__mor__繼承順序)
  2. Java語言可以多級繼承,一個類的父類的父類還是它的父類,只不過不是直接父類。
  3. java.lang.Object是一切類的祖宗類

二、抽象類

1. 什麼是抽象

你能知道圖形類的計算面積方法嘛?
在這裏插入圖片描述
如果父類中的方法不確定如何進行具體實現,那麼這就是一個抽象方法

2. 抽象的格式

創建一個圖形類:
在這裏插入圖片描述

  1. 抽象方法必須在抽象類內部
  2. 抽象類和抽象方法都用abstract修飾

3. 抽象方法的使用

  1. 不能直接創建抽象類對象(無意義),需用子類來繼承創建
  2. 子類需要重寫(也叫實現)父類的所有抽象方法(沒有abstract關鍵字,有方法體)

在這裏插入圖片描述

注: Math.pow(a, b)表示a的b次方

在這裏插入圖片描述


注意:

  1. 抽象方法也可以有構造方法,是供子類super();調用時使用的。
  2. 抽象類可以沒有抽象方法。此時是爲了,不讓調用這直接創建該類對象。
  3. 抽象類的子類,必須重寫父類所有抽象方法,除非這個子類也是抽象類。

Test:發紅包

需求分析

在這裏插入圖片描述

  • 需求分析: 羣主和羣成員都有各自姓名和餘額。
  • 羣主: 羣主發紅包,成員收紅包。 羣主需要知道當前有多少羣成員,以便把紅包分成多少份。返回的紅包錢數用ArrayList返回(因爲不確定長度,所以用可以變化長度的集合來做)。羣主只能發比自己餘額少的錢數。
  • 羣成員: 需要接收紅包,加入自己餘額

代碼實現

以下僅展示主要方法
父類
在這裏插入圖片描述
羣主類
在這裏插入圖片描述
成員類
在這裏插入圖片描述


運行調用:
在這裏插入圖片描述
結果
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章