【Java 溫故而知新系列】基礎(chǔ)知識(shí)-05 面向?qū)ο?/span>
1、面向?qū)ο蟾攀?/h1>
面向?qū)ο螅∣bject-Oriented,簡(jiǎn)稱OO)是一種編程思想,核心思想是將現(xiàn)實(shí)世界中的事物抽象為程序中的“對(duì)象”,通過對(duì)象之間的交互來解決問題。
對(duì)象
-
對(duì)象是面向?qū)ο缶幊痰幕締卧?strong>數(shù)據(jù)(屬性)和行為(方法)。
-
例如,一個(gè)“汽車”對(duì)象可以有屬性(顏色、品牌)和方法(啟動(dòng)、停止)。
類
-
類是對(duì)象的模板或藍(lán)圖,定義了對(duì)象的屬性和方法。
-
例如,“汽車”類可以定義所有汽車共有的屬性和行為,而具體的汽車則是該類的實(shí)例。
2、面向?qū)ο蟮奶匦?/h1>
面向?qū)ο笥兴拇筇匦裕悍庋b,繼承,多態(tài),抽象;也有3大特性的說法通常是指:封裝、繼承和多態(tài)。
1、封裝就是將類的信息隱藏在類內(nèi)部,不允許外部程序直接訪問,而是通過該類的方法實(shí)現(xiàn)對(duì)隱藏信息的操作和訪問。 良好的封裝能夠減少耦合。
2、繼承是從已有的類中派生出新的類,新的類繼承父類的屬性和行為,并能擴(kuò)展新的能力,大大增加程序的重用性和易維護(hù)性。在Java中是單繼承的,也就是說一個(gè)子類只有一個(gè)父類。
- 子類擁有父類非 private 的屬性和方法。
- 子類可以擁有自己屬性和方法,即子類可以對(duì)父類進(jìn)行擴(kuò)展。
- 子類可以用自己的方式實(shí)現(xiàn)父類的方法。
3、多態(tài)是同一個(gè)行為具有多個(gè)不同表現(xiàn)形式的能力。在不修改程序代碼的情況下改變程序運(yùn)行時(shí)綁定的代碼。實(shí)現(xiàn)多態(tài)的三要素:繼承、重寫、向上轉(zhuǎn)型(父類引用指向子類對(duì)象)。只有滿足了上述三個(gè)條件,我們才能夠在同一個(gè)繼承結(jié)構(gòu)中使用統(tǒng)一的邏輯實(shí)現(xiàn)代碼處理不同的對(duì)象,從而達(dá)到執(zhí)行不同的行為。父類或接口定義的引用變量可以指向子類或具體實(shí)現(xiàn)類的實(shí)例對(duì)象。提高了程序的拓展性。對(duì)于Java而言,它多態(tài)的實(shí)現(xiàn)機(jī)制遵循一個(gè)原則:當(dāng)超類對(duì)象引用變量引用子類 對(duì)象時(shí),被引用對(duì)象的類型而不是引用變量的類型決定了調(diào)用誰的成員方法,但是這個(gè)被調(diào)用的方法必須是在超類中定義過的,也就是說被子類覆蓋的方法。
- 靜態(tài)多態(tài)性:通過方法重載(overload)實(shí)現(xiàn),是編譯時(shí)的多態(tài)性(也稱為前綁定),相同的方法有不同的參數(shù)列表,可以根據(jù)參數(shù)的不同,做出不同的處理。
- 動(dòng)態(tài)多態(tài)性:也叫運(yùn)行時(shí)的多態(tài)性(也稱為后綁定)。一個(gè)引用變量到底會(huì)指向哪個(gè)類的實(shí)例對(duì)象,該引用變量發(fā)出的方法調(diào)用到底是 哪個(gè)類中實(shí)現(xiàn)的方法,必須在由程序運(yùn)行期間才能決定在多個(gè)子類中重寫父類的方法繼承 和接口 (實(shí)現(xiàn)接口并覆蓋接口中同一方法)都能實(shí)現(xiàn)多態(tài)。運(yùn)行期間判斷所引用對(duì)象的實(shí)際類型,根據(jù)其實(shí)際類型調(diào)用相應(yīng)的方法。
4、抽象。把客觀事物用代碼抽象出來。
3、面向?qū)ο蠡驹瓌t
- 單一職責(zé)原則SRP(Single Responsibility Principle)
類的功能要單一、職責(zé)明確,不能包羅萬象,是個(gè)萬能對(duì)象(比如商品類,里面相關(guān)的屬性和方法都必須跟商品相關(guān),不能出現(xiàn)訂單等不相關(guān)的內(nèi)容。這里的類可以是模塊、類庫、程序集,而不單單指類)。
- 開放封閉原則OCP(Open-Close Principle)
一個(gè)模塊對(duì)于拓展是開放的,對(duì)于修改是封閉的。
- 迪米特法則(Law of Demeter,LoD)
高內(nèi)聚,低耦合。盡量不要依賴細(xì)節(jié)。 一個(gè)對(duì)象應(yīng)盡可能少地了解其他對(duì)象,只與直接朋友(即成員變量、方法參數(shù)、返回值等)交互。
- 里式替換原則LSP(the Liskov Substitution Principle LSP)
子類能夠完全替代父類,反之則不行。通常用于實(shí)現(xiàn)接口時(shí)運(yùn)用。這也是多態(tài)的基本要素。因?yàn)樽宇惸軌蛲耆娲ǜ福╊悾敲催@樣父類就擁有很多子類,在后續(xù)的程序擴(kuò)展中就很容易進(jìn)行擴(kuò)展,程序完全不需要進(jìn)行修改即可進(jìn)行擴(kuò)展
- 依賴倒置原則DIP(the Dependency Inversion Principle DIP)
高層模塊不應(yīng)該依賴于低層模塊;二者都應(yīng)該依賴于抽象;抽象不應(yīng)該依賴于細(xì)節(jié);細(xì)節(jié)應(yīng)該依賴于抽象
面向抽象編程。也就是參數(shù)傳遞,或者返回值,可以使用父類類型或者接口類型。從廣義上講:基于接口編程,提前設(shè)計(jì)好接口框架。
- 接口分離原則ISP(the Interface Segregation Principle ISP)
設(shè)計(jì)時(shí)采用多個(gè)與特定客戶類有關(guān)的接口比采用一個(gè)通用的接口要好。就比如一個(gè)手機(jī)擁有打電話,看視頻,玩游戲等功能,把這幾個(gè)功能拆分成不同的接口,比在一個(gè)接口里要好的多。
4、Spring Boot框架中對(duì)面向?qū)ο螅∣OP)的思想體現(xiàn)在
封裝(Encapsulation):
Spring Boot 通過使用 @Component, @Service, @Repository 和 @Controller 等注解來定義類的角色,并將功能相關(guān)的代碼封裝在一起。
使用 private 關(guān)鍵字限制對(duì)類屬性的直接訪問,提供 getter 和 setter 方法來控制對(duì)這些屬性的訪問。
繼承(Inheritance):
繼承可以在 Spring Boot 中用來創(chuàng)建具有共同行為或?qū)傩缘慕M件。
可以通過擴(kuò)展 Spring 框架提供的抽象類或?qū)崿F(xiàn)接口來定制應(yīng)用程序的行為。
多態(tài)(Polymorphism):
多態(tài)性允許你使用父類類型的引用指向子類的對(duì)象,這在 Spring Boot 中可以通過依賴注入來實(shí)現(xiàn),例如,你可以注入一個(gè)接口的實(shí)現(xiàn),并在運(yùn)行時(shí)改變具體實(shí)現(xiàn)。
Spring Boot 支持方法重寫,這可以讓你根據(jù)需要自定義或修改已有方法的行為。
抽象(Abstraction):
抽象化是隱藏復(fù)雜的實(shí)現(xiàn)細(xì)節(jié)并僅向用戶暴露必要的部分。
在 Spring Boot 中,許多復(fù)雜配置被簡(jiǎn)化為簡(jiǎn)單的注解或自動(dòng)配置,如 @SpringBootApplication 注解,它隱藏了很多底層的初始化工作。
依賴注入(Dependency Injection, DI):
雖然依賴注入不是 OOP 的核心原則,但它與 OOP 密切相關(guān),并且是 Spring 框架的一個(gè)重要特性。
通過依賴注入,對(duì)象不再負(fù)責(zé)創(chuàng)建它們所依賴的對(duì)象,而是由 Spring 容器負(fù)責(zé)管理和提供這些依賴。這有助于提高代碼的可測(cè)試性和松耦合。
面向接口編程(Programming to an Interface):
推薦的做法是依賴于接口而不是具體的實(shí)現(xiàn)類,這樣可以使代碼更加靈活,易于擴(kuò)展和維護(hù)。
Spring Boot 鼓勵(lì)開發(fā)者使用接口定義服務(wù)層、數(shù)據(jù)訪問層等,然后在運(yùn)行時(shí)選擇適當(dāng)?shù)膶?shí)現(xiàn)。
組合(Composition):
組合是將對(duì)象組合成更復(fù)雜的結(jié)構(gòu),而不需要使用繼承。Spring Boot 應(yīng)用程序中經(jīng)常使用組合來構(gòu)建功能模塊,比如通過組合不同的服務(wù)來完成業(yè)務(wù)邏輯。
設(shè)計(jì)模式的應(yīng)用:
Spring Boot 廣泛應(yīng)用了各種設(shè)計(jì)模式,如工廠模式、單例模式、模板方法模式等,這些都是 OOP 設(shè)計(jì)原則的具體體現(xiàn)。
5、Java中抽象類和接口的對(duì)比
抽象類是用來捕捉子類的通用特性的。接口是抽象方法的集合。
從設(shè)計(jì)層面來說,抽象類是對(duì)類的抽象,是一種模板設(shè)計(jì),接口是行為的抽象,是一種行為的規(guī)范。
相同點(diǎn):
- 接口和抽象類都不能實(shí)例化
- 都位于繼承的頂端,用于被其他實(shí)現(xiàn)或繼承
- 都包含抽象方法,其子類都必須覆寫這些抽象方法
不同點(diǎn):
| 比較點(diǎn) | 抽象類 | 接口 |
| 聲明 | 抽象類使用abstract關(guān)鍵字聲明 | 接口使用interface關(guān)鍵字聲明 |
| 實(shí)現(xiàn) | 子類使用extends關(guān)鍵字來繼承抽象類。如果子類 不是抽象類的話,它需要提供抽象類中所有聲明 的方法的實(shí)現(xiàn) | 子類使用implements關(guān)鍵字來實(shí)現(xiàn) 接口。它需要提供接口中所有聲明的 方法的實(shí)現(xiàn) |
| 構(gòu)造器 | 抽象類可以有構(gòu)造器 | 接口不能有構(gòu)造器 |
| 訪 問 修 飾 符 | 抽象類中的方法可以是任意訪問修飾符 |
接口方法默認(rèn)修飾符是public。并且
不允許定義為 private 或者
protected
|
| 多 繼 承 | 一個(gè)類最多只能繼承一個(gè)抽象類 | 一個(gè)類可以實(shí)現(xiàn)多個(gè)接口 |
| 字 段 聲 明 | 抽象類的字段聲明可以是任意的 |
接口的字段默認(rèn)都是 static 和 final的
|
-
- 行為模型應(yīng)該總是通過接口而不是抽象類定義,所以通常是優(yōu)先選用接口,盡量少用抽象類。
- 選擇抽象類的時(shí)候通常是如下情況:需要定義子類的行為,又要為子類提供通用的功能。

浙公網(wǎng)安備 33010602011771號(hào)