谈谈java面向对象思想_对于Java面向对象思想的理解
在Java中,除了8種基本數據類型。其他皆為對象!
面向對象主要有
三個基本特征:封裝,繼承,多態。
封裝
主要概念是指:隱藏對象的屬性和實現細節,僅對外暴露公共的訪問方式。封裝是面向對象最基本的特征之一,是類和對象概念的主要特性。
良好的封裝所具有的優點:
1,隱藏信息和細節,提高安全性
2,良好的封裝可以減少耦合性,提高復用性
3,對類內部結構可以隨意修改,只要保證公有接口始終返回正確的結果即可。
在Java中的體現:
public default protected private等設置訪問權限的關鍵字
例如,類的屬性私有化private修飾,提供公有的setter getter方法對值進行獲取和修改。
同時,還可以在setter getter函數里進行數據校驗和對返回值做限制。這就是提高安全性的體現。
繼承
繼承是一種聯結類的層次模型,Java允許并且鼓勵代碼的重用,繼承提供了一種明確表示共性的方法,來使代碼可以進行復用。
繼承的出現,讓類與類之間產生了關聯,提供了多態的前提條件。
講到繼承,就要提到三個東西:構造器,protected關鍵字,向上轉型:
1,構造器:我們已經知道,父類中private修飾的屬性和方法子類是無法繼承的,而還有一個無法繼承的就是構造器。構造器只能調用而不能被繼承。
類在實例化的時候會調用自身構造器,而java編譯器會默認在子類構造器的第一行用super()先調用父類的無參構造器。如果父類沒有無參構造器,則子類在實例化的時候會報錯。這個時候就需要顯示的在子類構造器第一行(必須在第一行)指定構造器super(args)來指定調用父類哪個構造器。
2,protected關鍵字:proctected關鍵字修飾的屬性和方法,可以隔絕外部其他類的訪問,卻可以讓子類有權限訪問。
但是最好還是把屬性都以private修飾,父類中希望子類可以訪問到,又不希望公有的方法,可以用protected修飾
3,向上轉型:最典型的還是List list = new ArrayList()將子類的實例聲明為父類的類型,提高了通用性,也隱藏了子類的具體實現。因為這是一個由專用向通用的轉換,所以總是安全的。唯一缺陷就是專有屬性和方法的丟失。
但是繼承同時又存在缺陷:
1),繼承是一種強耦合關系,子類會由于父類的改變而改變
2),繼承破壞了封裝的特性,對于父類而言,它的實現和細節對于子類來說都是透明的
所以到底要不要繼承:《Thinking in java》提供了一個解決方案:問一問自己是否需要從子類向父類進行向上轉型。如果必須向上轉型,則繼承是必要的,但是如果不需要,則應當好好考慮自己是否需要繼承
使用繼承的時候,一定要注意,兩個類之間是從屬關系,父子關系的。子類應該是基于父類原有的特性,派生出來,并在無需編父類代碼的情況下,提供擴展的功能和方法。
不要為了使用某個類的其中一個特性,而去繼承該類!!!!
多態
多態,指的就是:
程序中定義的引用變量所指向的具體類型,和通過該引用變量發出的方法調用,在編程期間并不確定,而是在程序運行期間才確定。
1、如何理解多態:
因為在程序運行時才確定到具體的類,所以不用修改源碼,就能讓引用變量綁定到不同的類型實現上,從而導致引用調用的方法發生改變,即不修改具體代碼,就可以讓程序在運行時改變綁定的具體代碼,表現不同的運行狀態。這就是多態性。
2、多態的好處:
多態允許不同類對象,對同一個消息作出響應。即同一個消息可以根據發送對象的不同而采用不同的行為方式(發送消息就是函數調用)。
主要好處如下:
1)可替換性。多態對已存在的代碼具有可替換性。
2)可擴充性。新增加的子類不影響已經存在的類結構。
3)接口性。多態是父類通過方法簽名,向子類提供一個公共接口,由子類來完善或者重寫它來實現的。
4)靈活性。
5)簡化性。
3、Java中多態的體現:
重寫(覆蓋)
動態鏈接(動態調用)
重載
4、多態的三個必要條件:
繼承
重寫
向上轉型。
5、多態的作用:
我們知道,封裝可以隱藏細節,使得代碼模塊化,繼承可以擴展已存在的模塊化代碼(父類),實現代碼的復用。
而多態,則是實現了接口的復用,多態的作用,就是在類的實現和派生的時候,保證使用基類下面,任意一個子類實例的屬性和方法,都可以正確調用。
6、虛擬機如何實現多態:
在JVM中,是使用了動態綁定技術(dynamic binding),執行期間判斷所引用對象的實際類型,根據實際類型調用對應的方法.
重載嚴格意義上并不屬于多態,重載的具體實現是:編譯器根據不同的參數表,對同名函數的名稱做修飾,然后這些同名函數就變成了不同的函數。對重載函數的調用,在編譯期間就已經確定了,是靜態的(注意!是靜態的),因此,重載和多態無關。
真正和多態相關的是重寫,當子類重寫了父類中的函數后,父類的 指針,根據賦值給它不同的子類對象指針,動態的調用屬于子類的該函數,這樣在編譯期間是無法確定的,只有在運行期間,才會把動態鏈接轉變為直接引用(稱為動態鏈接,詳見JVM內存模型-棧幀)
五個基本原則
1、單一職責原則(Single-Resposibility Principle? SRP)
對一個而言,應該僅有一個引起它變化的原因
本原則是我們非常熟悉的"高內聚原則"的引申。同時,本原則還揭示了內聚性和耦合性:如果一個類承擔的職責過多,那么這些職責就會相互依賴,一個職責的變化可能會影響另一個職責的履行。其實OOP的實質,就是合理進行類的職責分配
2、開—閉原則(Open-Closed principle? OCP)
軟件應該是可以擴展的,但是不可以修改
也就是對擴展開放,對修改封閉。當變化來臨時,不需要(或者不允許)修改原來的代碼,只需要在原有的基礎上擴展(同時原有的代碼也要求支持擴展),那么這個軟件設計就是滿足開閉原則的。
此原則在Java中最典型的體現就是:抽象類抽象基類和接口。通過抽象類,把一些不可變的操作封裝起來,而提供抽象接口供子類實現,來實現各自變化的需求。
這個原則應用在類的設計中,要滿足該原則就要充分的考慮到接口封裝,抽象機制和多態。
3、里氏替換原則(Liskov-Substituion Principle? LSP)
子類型必須能夠替換掉它們的基類型
本原則和開閉原則關系密切,正是基于子類的可替換性,才使得基類可以無需修改,只要子類繼承就可以實現擴展特性。這是保證繼承復用的基礎
在Java中的典型體現就是 基于接口的框架設計,例如JDBC,集合類。
JDBC只提供了基本的接口,返回的對象類型也是接口,這樣就在選擇返回對象的時候,有了更大的靈活性:只要是繼承了返回接口類型的子類實例,都可以作為結果返回。而服務提供者無需暴露子類的實現,調用者也無需關心子類的實現。而提供者在對實現進行優化升級時,對調用者也是不可見,同時也沒有影響的。
集合類提供了一些基本集合的接口,例如 List Map Set。我們可以在聲明時用這些接口類型作為聲明對象,無需關心具體的實現類型是如何操作的,集合框架可以很好的把實現類型和代碼隱藏起來,對調用者透明。例如List可以用來接收ArrayList,也可以用來接收LinkedList。可以用來接收任何實現了List接口的類的實例。
以上兩點,充分的利用了里氏替換原則的特性,實現了封裝的基本特征。
4、接口隔離原則(Interface-Segregation Principle ISP)
多個專用接口優于一個單一的通用接口
本原則是單一職責原則用于接口設計的自然結果。基本思想就是,不要讓客戶端依賴他們不需要的接口。
一個接口應該保證,實現該接口的實例對象可以只呈現一個單一的角色。這樣當接口發生改變時,對其他客戶端造成的影響會更小。
把多個不同職責的功能分到不同的接口中去,提高代碼的靈活性和穩定性,降低耦合性。
5、依賴倒置原則(Dependecy-Inversion Principle DIP)
抽象不應該依賴于細節,細節應該依賴于抽象
具體來說就是,軟件設計中,高層不依賴于低層,兩者都依賴于抽象。抽象應該依賴于抽象,而不依賴于具體實現細節。即:對接口編程
在Java中的體現還是,接口和抽象類
拿最簡單的Spring IOC來說,當我們注入的時候,接收參數類型應該是接口,而注入的對象,可以是實現了接口的各種子類,當我們想改變接口表現的特性的時候,無需修改代碼,只要修改注入的實現類對象就可以。
RPC框架(例如Dubbo)開放的接口也同樣基于這個原則。
上面說的JDBC,集合類框架 都基于這個原則來提供實現。提供接口對象,而把實現類隱藏在內部。
總結
以上是生活随笔為你收集整理的谈谈java面向对象思想_对于Java面向对象思想的理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php面向对象异常处理,PHP 错误和异
- 下一篇: Java Lambda 表达式讲解