Java開(kāi)發(fā) 封裝+繼承+多態(tài)【學(xué)習(xí)篇7】

【作者前言】:13年入圈,分享些本人工作中遇到的點(diǎn)點(diǎn)滴滴那些事兒,17年剛開(kāi)始寫博客,高手勿噴!以分享交流為主,歡迎各路豪杰點(diǎn)評(píng)改進(jìn)!
{\color{#3f48cc}{\pmb{點(diǎn)擊右上角小【1】快速預(yù)覽本文內(nèi)容}}} [1]

??知識(shí)點(diǎn)內(nèi)容

??1. 編程思想 [2]

把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對(duì)象操作,對(duì)不可信的進(jìn)行信息隱藏。在一個(gè)對(duì)象內(nèi)部,某些代碼或某些數(shù)據(jù)可以是私有的,不能被外界訪問(wèn)。通過(guò)這種方式,現(xiàn)實(shí)世界可以被描繪成一系列完全自治、封裝的對(duì)象,這些對(duì)象通過(guò)一個(gè)受保護(hù)的接口訪問(wèn)其他對(duì)象

eg:
設(shè)計(jì)一個(gè)類 銀行卡:卡號(hào)、身份證號(hào)、錢數(shù)

image.png

image.png

通過(guò)案例觀察,發(fā)現(xiàn)當(dāng)前類的設(shè)計(jì)并不是很安全!!!
需要將屬性進(jìn)行私有化處理 --- 添加訪問(wèn)修飾符 --- private
屬性通過(guò)私有化之后,沒(méi)有辦法直接進(jìn)行訪問(wèn)了,如果我還是想修改屬性,只能調(diào)用方法
image.png

image.png

??2.封裝的好處 [3]

封裝把過(guò)程和數(shù)據(jù)包圍起來(lái),對(duì)數(shù)據(jù)的訪問(wèn)只能通過(guò)已定義的接口。面向?qū)ο缶幊淌加谶@個(gè)基本概念。即現(xiàn)實(shí)世界可以被描繪成一系列完全自治、封裝的對(duì)象,這些對(duì)象通過(guò)一個(gè)受保護(hù)的接口訪問(wèn)其他對(duì)象。封裝是一種信息隱藏技術(shù),在Java中通過(guò)控制成員的訪問(wèn)權(quán)限實(shí)現(xiàn)封裝,即 使用方法將類的數(shù)據(jù)隱藏起來(lái),控制用戶對(duì)類的修改和訪問(wèn)數(shù)據(jù)的程度。適當(dāng)?shù)姆庋b可以讓代碼更容易理解和維護(hù),也加強(qiáng)了代碼的安全性。``

??3.封裝的過(guò)程 [4]

1、創(chuàng)建好類
2、將屬性進(jìn)行私有化處理 private 數(shù)據(jù)類型 變量名
3、添加構(gòu)造方法(多個(gè)構(gòu)造方法) 無(wú)參構(gòu)造方法一定要添加
4、添加get set方法
get(獲?。阂话銇?lái)說(shuō)是為了獲取數(shù)據(jù)
set(設(shè)置):用來(lái)修改數(shù)據(jù)
5、編寫自定義方法

??4.快捷鍵說(shuō)明(開(kāi)發(fā)時(shí)使用) [5]

當(dāng)類編寫好屬性之后,
shift+alt+s(相當(dāng)于點(diǎn)擊了工具中的 source)


image.png

image.png

image.png

??5. 繼承(重用、擴(kuò)展) [6]

繼承是一種連接類的層次模型,并且允許和鼓勵(lì)類的重用,它提供了一種明確表述共性的方法
一個(gè)新類可以從現(xiàn)有的類中派生,這個(gè)過(guò)程稱為類繼承,新類繼承了原始類的特性,新類稱為原始類的派生類子類),而原始類稱為新類的基類父類
派生類可以從它的基類那里繼承方法和實(shí)例變量,并且類可以修改或增加新的方法使之更適應(yīng)特殊的需要

??6. 繼承的意義 [7]

從現(xiàn)實(shí)生活中的繼承,可以理解為兒子繼承了父親的財(cái)產(chǎn),即財(cái)產(chǎn)重用;
面向?qū)ο蟪绦蛟O(shè)計(jì)中的繼承,則是代碼重用
繼承是利用現(xiàn)有的類創(chuàng)建新類的過(guò)程,現(xiàn)有的類作為基類(父類),創(chuàng)建的新類稱作派生類(子類)
復(fù)用代碼是Java眾多引人注目的功能之一。但要想稱為極具革命性的語(yǔ)言,僅僅能夠復(fù)制代碼并對(duì)之加以改變是不夠的,它還必須能夠做更多的事情。盡可能的復(fù)用代碼是程序員一直在追求的,繼承就是一種復(fù)用代碼的方式,也是Java的三大特性之一
繼承是Java面向?qū)ο缶幊碳夹g(shù)的一塊基石,因?yàn)樗试S創(chuàng)建分等級(jí)層次的類
繼承就是子類繼承父類的特征和行為,使得子類對(duì)象(實(shí)例)具有父類的實(shí)例域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為
繼承是使用已存在的類的定義作為基礎(chǔ)建立新類的技術(shù),新類的定義可以增加新的數(shù)據(jù)或新的功能,也可以用父類的功能,通過(guò)使用繼承我們能夠非常方便地復(fù)用以前的代碼,能夠大大的提高開(kāi)發(fā)效率

??7. Java派生類定義 [8]

在Java中,使用extends關(guān)鍵字描述類與類之間的繼承關(guān)系,其基本用法是:
【訪問(wèn)權(quán)限修飾符】【修飾符】子類名 extends 父類名 {
子類體
}
由于Java是單親繼承體系,因此在描述類與類的繼承關(guān)系時(shí),extends關(guān)鍵字后面只能是一個(gè)名字,而不能是一個(gè)列表(后續(xù)接口繼承的情況,extends 后面可以是一個(gè)列表)
父類↓

image.png

派生類1↓
image.png

派生類2↓
image.png

測(cè)試使用↓
image.png

??8. Extends繼承 [9]

繼承定義了類如何相互關(guān)聯(lián),共享特性。對(duì)于若干個(gè)相同或者相識(shí)的類,我們可以抽象出他們共有的行為或者屬相并將其定義成一個(gè)父類或者超類,然后用這些類繼承該父類,他們不僅可以擁有父類的屬性、方法還可以定義自己獨(dú)有的屬性或者方法。
子類擁有父類的的屬性和方法private成員由于權(quán)限關(guān)系因此不能訪問(wèn)
子類可以擁有自己屬性和方法,即子類可以對(duì)父類進(jìn)行擴(kuò)展
子類可以用自己的方式實(shí)現(xiàn)父類的方法(后續(xù)介紹)
綜上所述,使用繼承確實(shí)有許多的優(yōu)點(diǎn),除了將所有子類的共同屬性放入父類,實(shí)現(xiàn)代碼共享,避免重復(fù)外,還可以使得修改擴(kuò)展繼承而來(lái)的實(shí)現(xiàn)比較簡(jiǎn)單。

??9. 構(gòu)造方法與繼承 [10]

通過(guò)前面我們知道子類可以繼承父類的屬性和方法
但是有一樣是子類繼承不了的構(gòu)造方法
對(duì)于構(gòu)造方法而言,它只能夠被調(diào)用,而不能被繼承

image.png

當(dāng)構(gòu)建子類對(duì)象時(shí)會(huì)優(yōu)先隱式自動(dòng)調(diào)用父類的無(wú)參構(gòu)造方法,而且這個(gè)構(gòu)建調(diào)用過(guò)程是從父類“向外”遞歸擴(kuò)散的,也就是從父類開(kāi)始向子類一級(jí)一級(jí)地完成構(gòu)建,即如果C繼承自B,而B(niǎo)繼承自A,那么構(gòu)建C的對(duì)象時(shí),會(huì)先調(diào)用A的構(gòu)造方法,然后調(diào)用B的構(gòu)造方法,最后調(diào)用C的構(gòu)造方法,以此類推
image.png

父類使用private修飾構(gòu)造方法,子類就會(huì)報(bào)錯(cuò),子類無(wú)法構(gòu)建父類
image.png

根據(jù)上述示例,對(duì)于繼承而已,子類會(huì)默認(rèn)調(diào)用父類的無(wú)參構(gòu)造方法,也就是說(shuō)子類必須能夠訪問(wèn)父類的一個(gè)構(gòu)造方法,并且一定會(huì)調(diào)用

??10. super [11]

image.png

java.lang.NullPointerException表示空指針異常,使用對(duì)象調(diào)用方法,但是對(duì)象是null
那么,如果父類不具備無(wú)參的構(gòu)造方法怎么辦呢?
Java 語(yǔ)言中,要求子類有責(zé)任保證它所繼承的父類盡快進(jìn)入到一個(gè)穩(wěn)定、完整的狀態(tài)中。如果沒(méi)有這個(gè)約束,那么子類的某個(gè)繼承自父類的方法可能會(huì)使用到父類中的一些變量,而這些變量并沒(méi)有進(jìn)行初始化,從而產(chǎn)生一些難以預(yù)料的后果
如果沒(méi)有無(wú)參的父類構(gòu)造方法子類必須要顯式的調(diào)用父類的構(gòu)造方法,而且必須是在子類構(gòu)造器中做的第一件事
通過(guò)super關(guān)鍵字可以在子類構(gòu)造方法中顯式調(diào)用父類的構(gòu)造方法,該調(diào)用必須位于子類構(gòu)造方法的第一行

super調(diào)用其他的方法

super this
表示父類引用 表示當(dāng)前對(duì)象引用
super可以調(diào)用父類構(gòu)造 調(diào)用當(dāng)前對(duì)象構(gòu)造方法
不能當(dāng)成參數(shù)返回值使用 引用不能傳遞 當(dāng)成參數(shù)或者返回值使用,可以傳遞
image.png

??11. 繼承-小結(jié)【5-11】 [12]

  • 類的繼承由關(guān)鍵字extends確定,Java語(yǔ)言為單親繼承,即一個(gè)子類只有一個(gè)父類,而一個(gè)父類可以有多個(gè)子類
  • 子類可以重寫父類中的某一個(gè)方法,稱為方法覆蓋,也稱方法重寫,是繼承中非常重要的知識(shí)點(diǎn)。如果子類需要修改從父類繼承到的方法的方法體,就可以使用方法覆蓋

image.png

image.png

image.png

當(dāng)創(chuàng)建子類對(duì)象時(shí)會(huì)優(yōu)先隱式自動(dòng)調(diào)用父類的無(wú)參構(gòu)造方法,而且這個(gè)構(gòu)建調(diào)用過(guò)程是從父類"向外"遞歸擴(kuò)散的,也就是從父類開(kāi)始向子類一級(jí)一級(jí)地完成構(gòu)建,即如果C繼承自B,而B(niǎo)繼承自A,那么構(gòu)建C的對(duì)象時(shí),會(huì)先調(diào)用A的構(gòu)造方法,然后調(diào)用B的構(gòu)造方法,最后調(diào)用C的構(gòu)造方法,以此類推
如果沒(méi)有無(wú)參的父類構(gòu)造方法,子類必須要使用super顯式的調(diào)用父類的構(gòu)造方法,而且必須是在子類構(gòu)造器中做的第一件事
this引用對(duì)象自身,調(diào)用自己的構(gòu)造方法,而super調(diào)用父類定義的成員變量、方法或構(gòu)造方法,super不能當(dāng)做引用傳遞給其他的調(diào)用者,而this可以

?? 12. 方法的重寫 與 方法的重載 有何區(qū)別? [13]

方法的重寫(Override) 方法的重載(Overload)
在繼承父類的子類中 在同一個(gè)類中
方法名稱、參數(shù)列表一致 方法名稱相同、參數(shù)列表不同
返回值也要一致 與返回值類型無(wú)關(guān)
  • 方法重載
    方法重載:同一個(gè)類中,方法名相同、參數(shù)列表不同(類型、個(gè)數(shù)、順序)、返回類型可以相同或不同、訪問(wèn)權(quán)限可以相同或不同的方法
  • 方法重寫
    繼承的作用就是復(fù)用,即子類直接使用父類的屬性和方法
    然而,有些時(shí)候,子類希望修改父類的方法的方法體,可以怎么做呢?
    第一種做法是子類創(chuàng)建一個(gè)不同名字的新方法,實(shí)現(xiàn)新的邏輯,然而,這種做法會(huì)導(dǎo)致子類依然包含父類中的那個(gè)方法,卻不應(yīng)該使用,破壞封裝性
    我們希望子類中的方法依然和父類方法的聲明形式一樣,但是具體方法體卻不同,這種做法就叫做方法覆蓋/方法重寫
  • 對(duì)比方法重寫與重載
    發(fā)生方法覆蓋的兩個(gè)方法的方法名、參數(shù)列表必須完全一致(子類重寫父類的方法) ,方法返回值如果是基本數(shù)據(jù)類型,則返回值應(yīng)該保持一致,如果返回值是類,則子類覆蓋方法的返回值必須是父類方法返回值或其的子類(協(xié)變返回類型)
    子類拋出的異常不能超過(guò)父類相應(yīng)方法拋出的異常(子類異常不能大于父類異常) (異常處理后面詳細(xì)介紹)
    子類方法的訪問(wèn)級(jí)別不能低于父類相應(yīng)方法的訪問(wèn)級(jí)別(子類訪問(wèn)級(jí)別不能低于父類訪問(wèn)級(jí)別)

13. 多態(tài) [14]

Animal a; //定義了一個(gè)引用類型a
a = new Animal(); // 實(shí)例化一個(gè)Animal對(duì)象給引用a
引用類型 與 實(shí)例化類型 一致
指著老虎說(shuō) 這是什么動(dòng)物, 將老虎當(dāng)成了動(dòng)物
Animal a = new Tiger();
總結(jié):
1、子類引用可以存放到父類引用中
2、把子類對(duì)象當(dāng)成父類對(duì)象看待 (把老虎 當(dāng)成 動(dòng)物)
3、對(duì)象的數(shù)據(jù)類型不變
java.lang.ClassCastException
類型轉(zhuǎn)換異常
變量名 instanceof 類名 :判斷變量(引用) 是否是屬于 后面類型 屬于 true 不屬于 false

image.png

4、子類引用存放到父類引用中,引用只能調(diào)用其引用類型聲明的方法,并且調(diào)用的方法是子類覆蓋父類的方法
image.png

image.png

image.png

14. 對(duì)象向上造型 [15]
簡(jiǎn)而言之:白馬是馬,馬非白馬的問(wèn)題

在繼承關(guān)系中,繼承者可以完全替換被繼承者,反之則不可以
eg:
人類是人類,男人女人都是人類,一個(gè)人是男人,一定也是人,所以向上轉(zhuǎn)型不需要強(qiáng)制,但是一個(gè)人是人,但不一定是男人,所以需要強(qiáng)制轉(zhuǎn)換
從實(shí)例上來(lái)看:
Person p = new Man(); //是合理的
Man m = new Person();//則不合理
所謂的對(duì)象向上造型,就是父類的引用(棧中)指向子類的對(duì)象(堆中)

image.png

父類引用指向子類對(duì)象
子類引用不能指向父類對(duì)象

15. 編譯期與運(yùn)行期 [16]

在進(jìn)行對(duì)象造型時(shí),用來(lái)聲明引用的父類類型我們稱為編譯期類型,而實(shí)際用于構(gòu)建對(duì)象的子類類型我們稱為運(yùn)行期類型

image.png

那么這個(gè)時(shí)候直接使用bird對(duì)象調(diào)用成員變量和成員方法究竟應(yīng)該調(diào)用編譯器類型中聲明的還是調(diào)用運(yùn)行期類型中重寫的呢?
引用變量在編譯階段只能調(diào)用其編譯時(shí)類型所具有的方法,但運(yùn)行時(shí)則執(zhí)行它運(yùn)行時(shí)類型所具有的方法
因此,編寫Java代碼時(shí),引用只能調(diào)用編譯器類型里包含的成員
例如,通過(guò)Object p =new Persion()代碼定義一個(gè)變量p,則這個(gè)p只能調(diào)用Object類的方法,而不能調(diào)用Persion類里定義的方法

16. 對(duì)象向下造型 [17]

對(duì)象在滿足條件的情況下也能進(jìn)行向下造型,即顯式的將父類引用指向的對(duì)象轉(zhuǎn)換為子類類型向下造型的要求是:進(jìn)行向下造型的對(duì)象的運(yùn)行期類型必須是子類或以子類為根的繼承樹(shù)中的其他類型(Ostrich extends Bird)


image.png

17. 多態(tài)環(huán)境下對(duì)屬性和方法的調(diào)用特點(diǎn) [18]

Java代碼中的數(shù)據(jù)和行為(變量和方法)在進(jìn)行綁定(即通過(guò)對(duì)象調(diào)用成員變量或方法時(shí)究竟調(diào)用哪個(gè)版本,如覆蓋后的方法)的時(shí)候劃分為兩種類型:
靜態(tài)綁定
動(dòng)態(tài)綁定
靜態(tài)綁定發(fā)生在編譯時(shí)期,動(dòng)態(tài)綁定發(fā)生在運(yùn)行時(shí)
類的成員變量屬性)都是靜態(tài)綁定的編譯時(shí)),也就是說(shuō),類中聲明的成員變量不能被子類中的同名屬性覆蓋,通過(guò)該類的引用調(diào)用成員,始終調(diào)用該類自身中聲明的屬性(即始終調(diào)用編譯期類型中的屬性)

image.png

image.png

image.png

對(duì)于Java中的方法而言,除了final后續(xù)詳細(xì)介紹),static后續(xù)詳細(xì)介紹),private構(gòu)造方法是靜態(tài)綁定外,其他的方法全部為動(dòng)態(tài)綁定,這就意味著方法調(diào)用將動(dòng)態(tài)使用運(yùn)行期類型版本)

  • 由上述特點(diǎn)可以看出:
    重載方法中具體調(diào)用哪個(gè)版本是通過(guò)靜態(tài)綁定在編譯期就決定了的
    重寫覆蓋的方法調(diào)用哪個(gè)版本是通過(guò)動(dòng)態(tài)綁定在運(yùn)行期決定的

18. 多態(tài)的應(yīng)用 [19]
將多態(tài)作為方法參數(shù)、返回值進(jìn)行應(yīng)用

  • 方法參數(shù)案例:動(dòng)物園管理員 喂食動(dòng)物------(參數(shù)是一個(gè)父類 只要是子類 都可以傳遞進(jìn)來(lái)
image.png

image.png

image.png

image.png
  • 方法返回值案例:動(dòng)物管理員,有一個(gè)小女兒,想養(yǎng)一只小動(dòng)物,養(yǎng)什么動(dòng)物 根據(jù)你有多少錢---(返回值類型是父類類型 子類得任何對(duì)象都可以作為返回值進(jìn)行返回
image.png

19. 多態(tài)的可變參數(shù) [20]

image.png

20. 多態(tài)參數(shù)的使用 [21]

如果將方法的形參參數(shù)聲明為父類類型,結(jié)合前面介紹的方法參數(shù)的功能(即調(diào)用方法代碼前會(huì)隱式執(zhí)行形參和實(shí)參之間的賦值操作),由于子類的對(duì)象賦值給父類的引用是合法的,那么在調(diào)用方法時(shí),實(shí)參就可以是以形參類型為根的繼承樹(shù)中的任意類型
此時(shí)形參對(duì)應(yīng)的運(yùn)行期類型和傳進(jìn)來(lái)的實(shí)參運(yùn)行期類型保持一致

21. instanceof [22]

實(shí)參可能是形參的任意子孫類,某些時(shí)候需要在方法中明確究竟參數(shù)的運(yùn)行期類型是什么,那么instanceof運(yùn)算符提供了一種解決方法
運(yùn)算符instanceof用來(lái)判斷對(duì)象是否屬于某個(gè)類的實(shí)例,具體語(yǔ)法如下:
對(duì)象 instanceof 類
該表達(dá)式為一個(gè)boolean表達(dá)式,如果對(duì)象的類型是后面提供的類或其子類,則返回true,反之返回false

22. 多態(tài)的總結(jié) [23]

//多態(tài)在執(zhí)行期間判斷所引用對(duì)象的實(shí)際類型,根據(jù)其實(shí)際的類型調(diào)用其相應(yīng)的方法
多態(tài)存在的三個(gè)必要條件
· 繼承
· 重寫覆蓋
· 對(duì)象向上造型-父類引用指向子類對(duì)象

多態(tài)的好處:
· 可替換性(substitutability)
多態(tài)對(duì)已存在代碼具有可替換性
· 可擴(kuò)充性(extensibility)
多態(tài)對(duì)代碼具有可擴(kuò)充性。增加新的子類不影響已存在類的多態(tài)性、繼承性,以及其他特性的運(yùn)行和操作。實(shí)際上新加子類更容易獲得多態(tài)功能
· 接口性(interface-ability)
多態(tài)是超類通過(guò)方法簽名,向子類提供了一個(gè)共同接口,由子類來(lái)完善或者覆蓋它而實(shí)現(xiàn)的
· 靈活性(flexibility)
它在應(yīng)用中體現(xiàn)了靈活多樣的操作,提高了使用效率
· 簡(jiǎn)化性(simplicity)
多態(tài)簡(jiǎn)化對(duì)應(yīng)用軟件的代碼編寫和修改過(guò)程,尤其在處理大量對(duì)象的運(yùn)算和操作時(shí),這個(gè)特點(diǎn)尤為突出和重要


??2.應(yīng)用場(chǎng)景:


??3.實(shí)現(xiàn)目標(biāo):


??4.代碼實(shí)現(xiàn):




  1. ??【知識(shí)點(diǎn)回顧·簡(jiǎn)介】 ↓↓↓

    ?
  2. ??[編程思想] ?

  3. ??[封裝的好處] ?

  4. ??[封裝的過(guò)程] ?

  5. ??[快捷鍵說(shuō)明] ?

  6. ??[繼承(重用、擴(kuò)展)] ?

  7. ??[繼承的意義] ?

  8. ??[Java派生類 定義] ?

  9. ??[Extends繼承] ?

  10. ??[構(gòu)造方法與繼承] ?

  11. ??[super] ?

  12. ??[繼承-小結(jié)] ?

  13. ??[方法的重寫 與 方法的重載 有何區(qū)別?] ?

  14. ??[多態(tài)] ?

  15. ??[多態(tài)-對(duì)象向上造型] ?

  16. ??[編譯期與運(yùn)行期] ?

  17. ??[對(duì)象向下造型] ?

  18. ??[多態(tài)環(huán)境下對(duì)屬性和方法的調(diào)用特點(diǎn)] ?

  19. ??[多態(tài)的應(yīng)用] ?

  20. ??[多態(tài)的可變參數(shù)] ?

  21. ??[多態(tài)參數(shù)的使用] ?

  22. ??[instanceof] ?

  23. ??[多態(tài)的總結(jié)] ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容