面向對象四大特徵:編程
1、抽象
抽象就是將一類實體的共同特性抽象出來,封裝在一個新的概念(類) 中,因此抽象是面嚮對象語言的基礎。好比鳥就是一個對象,可是咱們在研究這個對象的時候把它的一些同類放到一塊兒,一塊兒來考慮,並且抽象的時候,只考慮咱們感興趣的一些數據;假設你本身是一個普通人,那麼你可能關心的數據是,鳥類飛行的方法,鳥類吃東西的方法;假設你本身是一個生物專家,那麼你可能關心的數據時,鳥類的體重,鳥類的爪子的大小,鳥類的食量等等。
咱們能夠經過抽象處理複雜性。例如,人們不會把一輛汽車想象成由幾萬個互相獨立的部分所組成的一套裝置,而是把汽車想成一個具備本身獨特行爲的對象。這種抽象令人們能夠很容易地將一輛汽車開到雜貨店,而不會因組成汽車各部分零件過於複雜而不知所措。他們能夠忽略引擎、傳動及剎車系統的工做細節,將汽車做爲一個總體來加以利用。ui
2、封裝
在面嚮對象語言中,封裝特性是由類來體現的。咱們將現實生活中的一類實體定義成類,其中包括屬性和行爲(在Java中就是方法),就好像人類,能夠具備name,gender,age等屬性,同時也具備eat(),sleep(),咱們在行爲中實現必定的功能,也可操做屬性,這是面向對象的封裝特性;
封裝是將代碼及其處理的數據綁定在一塊兒的一種編程機制,該機制保證了程序和數據都不受外部干擾且不被誤用。能夠理解爲把它想成一個黑匣子,它能夠阻止在外部定義的代碼隨意訪問內部代碼和數據。對黑匣子內代碼和數據的訪問經過一個適當定義的接口嚴格控制。
封裝的步驟:
一、修改屬性的可見性來限制對屬性的訪問
二、爲每一個屬性建立賦值和取值的方法,用於對這些屬性的訪問
三、在賦值和取值的方法中,加入對屬性的存儲限制
封裝的好處:
一、實現了專業的分工
二、類內部的結構可以自由修改
三、可以對成員進行更精確的控制
四、隱藏信息,實現細節
五、良好的封裝可以減小耦合設計
3、繼承
繼承就像是咱們現實生活中的父子關係,兒子能夠遺傳父親的一些特性,在面嚮對象語言中,就是一個類能夠繼承另外一個類的一些特性,從而能夠代碼重用,其實繼承體現的是is-a關係,父類和子類在本質上仍是一類實體。
繼承是一個對象得到另外一個對象的屬性的過程。繼承很重要,由於它支持了按層分類的概念。好比:藏獒是狗類的一部分,狗類又是哺乳動物的一部分,哺乳動物又是動物類的一部分。若是不使用層級的概念,咱們就不得不分別定義每一個動物的全部屬性。而使用了繼承,一個對象就只須要定義是它在所屬類中獨一無二的屬性便可,由於它能夠從它的父類那兒繼承全部的通用屬性。能夠這樣說,正是繼承機制使一個對象成爲一個更具通用類的一個特定實例成爲可能。
繼承的特徵:
一、可傳遞可擴展。若類C繼承類B,類B繼承類A(多繼承),則類C既有從類B那裏繼承下來的屬性與方法,也有從類A那裏繼承下來的屬性與方法,還能夠有本身新定義的屬性和方法。繼承來的屬性和方法儘管是隱式的,但還是類C的屬性和方法。
二、可複用。若類B繼承類A,那麼創建類B時只須要再描述與基類(類A)不一樣的少許特徵(數據成員和成員方法)便可。這種作法能減少代碼和數據的冗餘度,大大增長程序的重用性。
三、可維護性。繼承經過加強一致性來減小模塊間的接口和界面,大大增長了程序的易維護性。對象
4、多態
多態是容許一個接口被多個同類動做使用的特性,具體使用哪一個動做與應用場合有關。多態就是經過傳遞給父類對象引用不一樣的子類對象從而表現出不一樣的行爲,多態可爲程序提供更好的可擴展性,一樣也能夠代碼重用。
要理解多態性,首先要知道什麼是「向上轉型」。
我定義了一個子類Dog,它繼承了Animal類,那麼後者就是前者的父類。能夠經過:
Dog d = new Dog(); 例化一個Dog對象。
但當我這樣定義時: Animal a = new Dog();
它表示我定義了一個Animal類型的引用,指向新建的Dog類型的對象。因爲Dog是繼承自它的父類Animal,因此Animal類型的引用是能夠指向Dog類型的對象的。那麼這樣作有什麼意義呢?由於子類是對父類的一個改進和擴充,因此通常子類在功能上較父類更強大,屬性較父類更獨特,定義一個父類類型的引用指向一個子類的對象既可使用子類強大的功能,又能夠抽取父類的共性。因此, 父類引用只能調用父類中存在的方法和屬性,不能調用子類的擴展部分;由於父類引用指向的是堆中子類對象繼承的父類;(可是若是強制把超類轉換成子類的話,就能夠調用子類中新添加而超類沒有的方法了。)
同時,父類中的一個方法只有在父類中定義而在子類中沒有重寫的狀況下,才能夠被父類類型的引用調用;
對於父類中定義的方法,若是子類中重寫了該方法,那麼父類類型的引用將會調用子類中的這個方法,這就是動態鏈接。繼承
面向對象五大原則:接口
(1)單一職責原則(Single-Resposibility Principle)ip
一個類應該僅有一個引發它變化的緣由ci
職員類例子: 好比在職員類裏,將工程師、銷售人員、銷售經理這些狀況都放在職員類裏考慮,其結果將會很是混亂,在這個假設下,職員類裏的每一個方法都要ifelse判斷是哪一種狀況,從類結構上來講將會十分臃腫,而且上述三種的職員類型,不論哪種發生需求變化,都會改變職員類!這個是你們所不肯意看到的!it
(2)開放封閉原則(Open-Closed principle)io
對擴展是開放的,對更改是封閉的!
變化來臨時,若是沒必要改動軟件實體裁的源代碼,就能擴充它的行爲,那麼這個軟件實體設計就是知足開放封閉原則的。若是說咱們預測到某種變化,或者某種變化發生了,咱們應當建立抽象類來隔離之後發生的同類變化。
(3)里氏替換原則(Liskov-Substituion Principle)
子類能夠替換父類而且出如今父類可以出現的任何地方,貫徹GOF倡導的面向接口編程
在這個原則中父類應儘量使用接口或者抽象類來實現!
子類經過實現了父類接口,可以替父類的使用地方!
經過這個原則,咱們客戶端在使用父類接口的時候,經過子類實現!
意思就是說咱們依賴父類接口,在客戶端聲明一個父類接口,經過其子類來實現
這個時候就要求子類必須可以替換父類所出現的任何地方,這樣作的好處就是,在根據新要求擴展父類接口的新子類的時候而不影響當前客戶端的使用!
(4)依賴倒置原則(Dependecy-Inversion Principle)
傳統的結構化編程中,最上層的模塊一般都要依賴下面的子模塊來實現,也稱爲高層依賴低層!
因此DIP原則就是要逆轉這種依賴關係,讓高層模塊不要依賴低層模塊,因此稱之爲依賴倒置原則!
(5)ISP 接口隔離原則(Interface-Segregation Principle)
使用多個專門的接口比使用單個接口要好的多!
這個我有體會,在我實際編程中,爲了減小接口的定義,將許多相似的方法都放在一個接口中,最後發現,維護和實現接口的時候花了太多精力,而接口所定義的操做至關於對客戶端的一種承諾,這種承諾固然是越少越好,越精練越好,過多的承諾帶來的就是你的大量精力和時間去維護!