【作者前言】:13年入圈鞋邑,分享些本人工作中遇到的點(diǎn)點(diǎn)滴滴那些事兒,17年剛開始寫博客腕窥,高手勿噴粒没!以分享交流為主,歡迎各路豪杰點(diǎn)評改進(jìn)簇爆!
[1]
??知識點(diǎn)內(nèi)容
??1. 編程思想 [2]
把客觀事物封裝成抽象的類
癞松,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對象操作
,對不可信的進(jìn)行信息隱藏
入蛆。在一個(gè)對象內(nèi)部响蓉,某些代碼或某些數(shù)據(jù)可以是私有的,不能被外界訪問哨毁。通過這種方式枫甲,現(xiàn)實(shí)世界可以被描繪成一系列完全自治、封裝的對象扼褪,這些對象通過一個(gè)受保護(hù)的接口訪問其他對象eg:
設(shè)計(jì)一個(gè)類 銀行卡:卡號想幻、身份證號、錢數(shù)
image.png
image.png
通過案例觀察话浇,發(fā)現(xiàn)當(dāng)前類的設(shè)計(jì)并不是很安全!!!
需要將屬性進(jìn)行私有化處理 --- 添加訪問修飾符 --- private
屬性通過私有化之后脏毯,沒有辦法直接進(jìn)行訪問了,如果我還是想修改屬性幔崖,只能調(diào)用方法
image.png
image.png
??2.封裝的好處 [3]
封裝把過程和數(shù)據(jù)包圍起來食店,對數(shù)據(jù)的訪問只能通過已定義的接口。面向?qū)ο缶幊淌加谶@個(gè)基本概念赏寇。即現(xiàn)實(shí)世界可以被描繪成一系列完全自治吉嫩、封裝的對象,這些對象通過一個(gè)受保護(hù)的接口訪問其他對象嗅定。
封裝是一種信息隱藏技術(shù)自娩,在Java中
通過控制成員的訪問權(quán)限實(shí)現(xiàn)封裝,即 使用方法將類的數(shù)據(jù)隱藏起來渠退,控制用戶對類的修改和訪問數(shù)據(jù)的程度忙迁。
適當(dāng)?shù)姆庋b可以讓代碼更容易理解和維護(hù),也加強(qiáng)了代碼的安全性智什。``
??3.封裝的過程 [4]
1动漾、創(chuàng)建好類
2、將屬性進(jìn)行私有化處理private 數(shù)據(jù)類型 變量名
3荠锭、添加構(gòu)造方法(多個(gè)構(gòu)造方法)無參構(gòu)造方法一定要添加
4旱眯、添加get set方法
get(獲取):一般來說是為了獲取數(shù)據(jù)
set(設(shè)置):用來修改數(shù)據(jù)
5证九、編寫自定義方法
??4.快捷鍵說明(開發(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è)過程稱為類繼承
拥坛,新類繼承了原始類的特性
蓬蝶,新類
稱為原始類的派生類
(子類
)尘分,而原始類
稱為新類的基類
(父類
)
派生類可以從它的基類那里繼承方法和實(shí)例變量,并且類可以修改或增加新的方法使之更適應(yīng)特殊的需要
??6. 繼承的意義 [7]
從現(xiàn)實(shí)生活中的繼承丸氛,可以理解為兒子繼承了父親的財(cái)產(chǎn)培愁,即財(cái)產(chǎn)重用;
面向?qū)ο蟪绦蛟O(shè)計(jì)中的繼承缓窜,則是代碼重用
定续;
繼承是利用現(xiàn)有的類創(chuàng)建新類的過程,現(xiàn)有的類作為基類(父類)禾锤,創(chuàng)建的新類稱作派生類(子類)
復(fù)用代碼是Java眾多引人注目的功能之一私股。但要想稱為極具革命性的語言,僅僅能夠復(fù)制代碼并對之加以改變是不夠的恩掷,它還必須能夠做更多的事情倡鲸。盡可能的復(fù)用代碼是程序員一直在追求的,繼承
就是一種復(fù)用代碼的方式螃成,也是Java的三大特性之一
繼承是Java面向?qū)ο缶幊碳夹g(shù)的一塊基石旦签,因?yàn)樗试S創(chuàng)建分等級層次的類
繼承就是子類繼承父類的特征和行為,使得子類對象(實(shí)例)具有父類的實(shí)例域和方法寸宏,或子類從父類繼承方法宁炫,使得子類具有父類相同的行為
繼承是使用已存在的類的定義作為基礎(chǔ)建立新類的技術(shù),新類的定義可以增加新的數(shù)據(jù)或新的功能
氮凝,也可以用父類的功能羔巢,通過使用繼承我們能夠非常方便地復(fù)用以前的代碼,能夠大大的提高開發(fā)效率
??7. Java派生類定義 [8]
在Java中罩阵,使用
extends
關(guān)鍵字描述類與類之間的繼承關(guān)系
竿秆,其基本用法是:
【訪問權(quán)限修飾符】【修飾符】子類名 extends 父類名 {
子類體
}
由于Java是單親繼承體系,因此在描述類與類的繼承關(guān)系時(shí)稿壁,extends關(guān)鍵字后面只能是一個(gè)名字幽钢,而不能是一個(gè)列表(后續(xù)接口繼承的情況,extends 后面可以是一個(gè)列表)
父類↓
image.png
派生類1↓
image.png
派生類2↓
image.png
測試使用↓
image.png
??8. Extends繼承 [9]
繼承定義了類如何相互關(guān)聯(lián)傅是,共享特性匪燕。對于若干個(gè)相同或者相識的類,我們可以抽象出他們共有的行為或者屬相并將其定義成一個(gè)父類或者超類喧笔,然后用這些類繼承該父類帽驯,他們不僅可以擁有父類的屬性、方法還可以定義自己獨(dú)有的屬性或者方法书闸。
子類擁有父類的的屬性和方法
(private成員由于權(quán)限關(guān)系因此不能訪問
)
子類可以擁有自己屬性和方法
尼变,即子類可以對父類進(jìn)行擴(kuò)展
子類可以用自己的方式實(shí)現(xiàn)父類的方法
(后續(xù)介紹)
綜上所述,使用繼承確實(shí)有許多的優(yōu)點(diǎn)浆劲,除了將所有子類的共同屬性放入父類嫌术,實(shí)現(xiàn)代碼共享哀澈,避免重復(fù)外,還可以使得修改擴(kuò)展繼承而來的實(shí)現(xiàn)比較簡單
蛉威。
??9. 構(gòu)造方法與繼承 [10]
通過前面我們知道子類可以繼承父類的屬性和方法
但是有一樣是子類繼承不了的
:構(gòu)造方法
對于構(gòu)造方法
而言日丹,它只能夠被調(diào)用
走哺,而不能被繼承
image.png
當(dāng)構(gòu)建子類對象時(shí)會優(yōu)先隱式自動調(diào)用父類的無參構(gòu)造方法
蚯嫌,而且這個(gè)構(gòu)建調(diào)用過程是從父類“向外”遞歸
擴(kuò)散的,也就是從父類開始向子類一級一級地完成構(gòu)建丙躏,即如果C繼承自B择示,而B繼承自A,那么構(gòu)建C的對象時(shí)晒旅,會先調(diào)用A的構(gòu)造方法栅盲,然后調(diào)用B的構(gòu)造方法,最后調(diào)用C的構(gòu)造方法废恋,以此類推
image.png
父類使用private
修飾構(gòu)造方法谈秫,子類就會報(bào)錯(cuò),子類無法構(gòu)建父類
image.png
根據(jù)上述示例鱼鼓,對于繼承而已拟烫,子類會默認(rèn)調(diào)用父類的無參構(gòu)造方法,也就是說子類必須能夠訪問父類的一個(gè)構(gòu)造方法迄本,并且一定會調(diào)用
??10. super [11]
image.png
java.lang.NullPointerException
:表示空指針異常硕淑,使用對象調(diào)用方法,但是對象是null
那么嘉赎,如果父類不具備無參的構(gòu)造方法怎么辦呢置媳?
Java 語言中,要求子類有責(zé)任保證它所繼承的父類盡快進(jìn)入到一個(gè)穩(wěn)定公条、完整的狀態(tài)中拇囊。如果沒有這個(gè)約束,那么子類的某個(gè)繼承自父類的方法可能會使用到父類中的一些變量靶橱,而這些變量并沒有進(jìn)行初始化寥袭,從而產(chǎn)生一些難以預(yù)料的后果
如果沒有無參的父類構(gòu)造方法
,子類
必須要顯式的調(diào)用父類的構(gòu)造方法
抓韩,而且必須是在子類構(gòu)造器中做的第一件事
通過super
關(guān)鍵字可以在子類構(gòu)造方法中
顯式調(diào)用父類的構(gòu)造方法
纠永,該調(diào)用必須位于子類構(gòu)造方法的第一行
super
調(diào)用其他的方法
super | this |
---|---|
表示父類引用 | 表示當(dāng)前對象引用 |
super可以調(diào)用父類構(gòu)造 | 調(diào)用當(dāng)前對象構(gòu)造方法 |
不能當(dāng)成參數(shù)返回值使用 引用不能傳遞 | 當(dāng)成參數(shù)或者返回值使用,可以傳遞 |
image.png
??11. 繼承-小結(jié)【5-11】 [12]
- 類的繼承由關(guān)鍵字
extends
確定谒拴,Java語言為單親繼承
尝江,即一個(gè)子類只有一個(gè)父類,而一個(gè)父類可以有多個(gè)子類
- 子類可以重寫父類中的某一個(gè)方法英上,稱為方法覆蓋炭序,也稱方法重寫啤覆,是繼承中非常重要的知識點(diǎn)。如果
子類需要修改從父類繼承到的方法的方法體惭聂,就可以使用方法覆蓋
image.png
image.png
image.png
當(dāng)創(chuàng)建子類對象時(shí)會優(yōu)先隱式自動調(diào)用父類的無參構(gòu)造方法窗声,而且這個(gè)構(gòu)建調(diào)用過程是從父類"向外"遞歸擴(kuò)散的,也就是從父類開始向子類一級一級地完成構(gòu)建辜纲,即如果C繼承自B笨觅,而B繼承自A,那么構(gòu)建C的對象時(shí)耕腾,會先調(diào)用A的構(gòu)造方法见剩,然后調(diào)用B的構(gòu)造方法,最后調(diào)用C的構(gòu)造方法扫俺,以此類推
如果沒有無參的父類構(gòu)造方法苍苞,子類必須要使用super顯式的調(diào)用父類的構(gòu)造方法,而且必須是在子類構(gòu)造器中做的第一件事
this引用對象自身狼纬,調(diào)用自己的構(gòu)造方法羹呵,而super調(diào)用父類定義的成員變量、方法或構(gòu)造方法疗琉,super不能當(dāng)做引用傳遞給其他的調(diào)用者列粪,而this可以
?? 12. 方法的重寫 與 方法的重載 有何區(qū)別? [13]
方法的重寫(Override) | 方法的重載(Overload) |
---|---|
在繼承父類的子類中 | 在同一個(gè)類中 |
方法名稱纽门、參數(shù)列表一致 | 方法名稱相同欢揖、參數(shù)列表不同 |
返回值也要一致 | 與返回值類型無關(guān) |
-
方法重載
方法重載:同一個(gè)類中反镇,方法名相同、參數(shù)列表不同(類型送火、個(gè)數(shù)拳话、順序)、返回類型可以相同或不同种吸、訪問權(quán)限可以相同或不同的方法 -
方法重寫
繼承的作用就是復(fù)用弃衍,即子類直接使用父類的屬性和方法
然而,有些時(shí)候坚俗,子類希望修改父類的方法的方法體镜盯,可以怎么做呢?
第一種做法是子類創(chuàng)建一個(gè)不同名字的新方法猖败,實(shí)現(xiàn)新的邏輯速缆,然而,這種做法會導(dǎo)致子類依然包含父類中的那個(gè)方法恩闻,卻不應(yīng)該使用艺糜,破壞封裝性
我們希望子類中的方法依然和父類方法的聲明形式一樣,但是具體方法體卻不同,這種做法就叫做方法覆蓋/方法重寫 -
對比方法重寫與重載
發(fā)生方法覆蓋
的兩個(gè)方法的方法名
破停、參數(shù)列表
必須完全一致
(子類重寫父類的方法
) 翅楼,方法返回值如果是基本數(shù)據(jù)類型,則返回值應(yīng)該保持一致
真慢,如果返回值是類毅臊,則子類覆蓋方法的返回值必須是父類方法返回值或其的子類(協(xié)變返回類型)
子類拋出的異常不能超過父類相應(yīng)方法拋出的異常(子類異常不能大于父類異常
) (異常處理后面詳細(xì)介紹)
子類方法的訪問級別不能低于父類相應(yīng)方法的訪問級別(子類訪問級別不能低于父類訪問級別
)
13. 多態(tài) [14]
Animal a; //定義了一個(gè)引用類型a
a = new Animal(); // 實(shí)例化一個(gè)Animal對象給引用a
引用類型 與 實(shí)例化類型 一致
指著老虎說 這是什么動物, 將老虎當(dāng)成了動物
Animal a = new Tiger();
總結(jié):
1黑界、子類引用可以存放到父類引用中
2管嬉、把子類對象當(dāng)成父類對象看待 (把老虎 當(dāng)成 動物)
3、對象的數(shù)據(jù)類型不變
java.lang.ClassCastException
:
類型轉(zhuǎn)換異常
變量名 instanceof 類名 :判斷變量(引用) 是否是屬于 后面類型 屬于 true 不屬于 false
image.png
4园爷、子類引用存放到父類引用中宠蚂,引用只能調(diào)用其引用類型聲明的方法,并且調(diào)用的方法是子類覆蓋父類的方法
image.png
image.png
image.png
14. 對象向上造型 [15]
簡而言之:白馬是馬童社,馬非白馬的問題
在繼承關(guān)系中,
繼承者可以完全替換被繼承者著隆,反之則不可以
eg:
人類是人類扰楼,男人女人都是人類,一個(gè)人是男人美浦,一定也是人弦赖,所以向上轉(zhuǎn)型不需要強(qiáng)制,但是一個(gè)人是人浦辨,但不一定是男人蹬竖,所以需要強(qiáng)制轉(zhuǎn)換
從實(shí)例上來看:
Person p = new Man(); //是合理的
Man m = new Person();//則不合理
所謂的對象向上造型,就是父類的引用(棧中)指向子類的對象(堆中)
image.png
父類引用指向子類對象
子類引用不能指向父類對象
15. 編譯期與運(yùn)行期 [16]
在進(jìn)行對象造型時(shí)流酬,用來
聲明引用的父類類型
我們稱為編譯期類型
币厕,而實(shí)際用于構(gòu)建對象的子類類型
我們稱為運(yùn)行期類型
image.png
那么這個(gè)時(shí)候直接使用bird對象調(diào)用成員變量和成員方法究竟應(yīng)該調(diào)用編譯器類型中聲明的還是調(diào)用運(yùn)行期類型中重寫的呢?
引用變量在編譯階段只能調(diào)用其編譯時(shí)類型所具有的方法芽腾,但運(yùn)行時(shí)則執(zhí)行它運(yùn)行時(shí)類型所具有的方法
因此旦装,編寫Java代碼時(shí),引用只能調(diào)用編譯器類型里包含的成員
例如摊滔,通過Object p =new Persion()代碼定義一個(gè)變量p阴绢,則這個(gè)p只能調(diào)用Object類的方法,而不能調(diào)用Persion類里定義的方法
16. 對象向下造型 [17]
對象在滿足條件的情況下也能進(jìn)行向下造型艰躺,即顯式的將父類引用指向的對象轉(zhuǎn)換為子類類型向下造型的要求是:進(jìn)行向下造型的對象的運(yùn)行期類型必須是子類或以子類為根的繼承樹中的其他類型(Ostrich extends Bird)
image.png
17. 多態(tài)環(huán)境下對屬性和方法的調(diào)用特點(diǎn) [18]
Java代碼中的數(shù)據(jù)和行為(變量和方法)在進(jìn)行綁定(即通過對象調(diào)用成員變量或方法時(shí)究竟調(diào)用哪個(gè)版本呻袭,如覆蓋后的方法)的時(shí)候劃分為兩種類型:
靜態(tài)綁定
動態(tài)綁定
靜態(tài)綁定發(fā)生在編譯時(shí)期,動態(tài)綁定發(fā)生在運(yùn)行時(shí)
類的成員變量
(屬性
)都是靜態(tài)綁定的
(編譯時(shí)
)腺兴,也就是說左电,類中聲明的成員變量不能被子類中的同名屬性覆蓋
,通過該類的引用調(diào)用成員,始終調(diào)用該類自身中聲明的屬性(即始終調(diào)用編譯期類型中的屬性)
image.png
image.png
image.png
對于Java中的方法而言券腔,除了final
(后續(xù)詳細(xì)介紹
)伏穆,static
(后續(xù)詳細(xì)介紹
),private
和構(gòu)造方法
是靜態(tài)綁定外纷纫,其他的方法全部為動態(tài)綁定枕扫,這就意味著方法調(diào)用將動態(tài)使用運(yùn)行期類型版本)
- 由上述特點(diǎn)可以看出:
重載方法中具體調(diào)用哪個(gè)版本是通過靜態(tài)綁定在編譯期就決定了的
重寫覆蓋的方法調(diào)用哪個(gè)版本是通過動態(tài)綁定在運(yùn)行期決定的
18. 多態(tài)的應(yīng)用 [19]
將多態(tài)作為方法參數(shù)、返回值進(jìn)行應(yīng)用
-
方法參數(shù)
案例:動物園管理員 喂食動物------(參數(shù)是一個(gè)父類 只要是子類 都可以傳遞進(jìn)來
)
image.png
image.png
image.png
image.png
-
方法返回值
案例:動物管理員辱魁,有一個(gè)小女兒烟瞧,想養(yǎng)一只小動物,養(yǎng)什么動物 根據(jù)你有多少錢---(返回值類型是父類類型 子類得任何對象都可以作為返回值進(jìn)行返回
)
image.png
19. 多態(tài)的可變參數(shù) [20]
image.png
20. 多態(tài)參數(shù)的使用 [21]
如果將方法的
形參參數(shù)聲明為父類類型
染簇,結(jié)合前面介紹的方法參數(shù)的功能(即調(diào)用方法代碼前會隱式執(zhí)行形參和實(shí)參之間的賦值操作)参滴,由于子類的對象賦值給父類的引用是合法的,那么在調(diào)用方法時(shí)锻弓,實(shí)參
就可以是以形參類型為根的繼承樹中的任意類型
此時(shí)形參對應(yīng)的運(yùn)行期類型和傳進(jìn)來的實(shí)參運(yùn)行期類型保持一致
21. instanceof [22]
實(shí)參可能是形參的任意子孫類砾赔,某些時(shí)候需要在方法中明確究竟參數(shù)的運(yùn)行期類型是什么,那么
instanceof
運(yùn)算符提供了一種解決方法
運(yùn)算符instanceof
用來判斷對象是否屬于某個(gè)類的實(shí)例
青灼,具體語法如下:
對象 instanceof 類
該表達(dá)式為一個(gè)boolean表達(dá)式暴心,如果對象的類型是后面提供的類或其子類
,則返回true
杂拨,反之返回false
22. 多態(tài)的總結(jié) [23]
//多態(tài)在執(zhí)行期間判斷所引用對象的實(shí)際類型专普,根據(jù)其實(shí)際的類型調(diào)用其相應(yīng)的方法
多態(tài)存在的三個(gè)必要條件
· 繼承
· 重寫覆蓋
· 對象向上造型-父類引用指向子類對象
多態(tài)的好處:
· 可替換性(substitutability)
多態(tài)對已存在代碼具有可替換性
· 可擴(kuò)充性(extensibility)
多態(tài)對代碼具有可擴(kuò)充性。增加新的子類不影響已存在類的多態(tài)性弹沽、繼承性檀夹,以及其他特性的運(yùn)行和操作。實(shí)際上新加子類更容易獲得多態(tài)功能
· 接口性(interface-ability)
多態(tài)是超類通過方法簽名策橘,向子類提供了一個(gè)共同接口炸渡,由子類來完善或者覆蓋它而實(shí)現(xiàn)的
· 靈活性(flexibility)
它在應(yīng)用中體現(xiàn)了靈活多樣的操作,提高了使用效率
· 簡化性(simplicity)
多態(tài)簡化對應(yīng)用軟件的代碼編寫和修改過程役纹,尤其在處理大量對象的運(yùn)算和操作時(shí)偶摔,這個(gè)特點(diǎn)尤為突出和重要
??2.應(yīng)用場景:
??3.實(shí)現(xiàn)目標(biāo):
??4.代碼實(shí)現(xiàn):
-
??【知識點(diǎn)回顧·簡介】 ↓↓↓
? -
??[編程思想] ?
-
??[封裝的好處] ?
-
??[封裝的過程] ?
-
??[快捷鍵說明] ?
-
??[繼承(重用、擴(kuò)展)] ?
-
??[繼承的意義] ?
-
??[Java派生類 定義] ?
-
??[Extends繼承] ?
-
??[構(gòu)造方法與繼承] ?
-
??[super] ?
-
??[繼承-小結(jié)] ?
-
??[方法的重寫 與 方法的重載 有何區(qū)別促脉?] ?
-
??[多態(tài)] ?
-
??[多態(tài)-對象向上造型] ?
-
??[編譯期與運(yùn)行期] ?
-
??[對象向下造型] ?
-
??[多態(tài)環(huán)境下對屬性和方法的調(diào)用特點(diǎn)] ?
-
??[多態(tài)的應(yīng)用] ?
-
??[多態(tài)的可變參數(shù)] ?
-
??[多態(tài)參數(shù)的使用] ?
-
??[instanceof] ?
-
??[多態(tài)的總結(jié)] ?