對象是一個自包含的實體,用一組可識別的特性和行爲來標識。java
本人對於可識別特性的認知是就是類的屬性。就像是一個「人」的類,那麼它做爲一個類就須要有些屬性,讓咱們瞭解它爲何是「人」。每一個人出生的時候都會有一個特別的標識,就是身份證ID,那麼它就是屬於「人」的可識別特性。設計模式
而行爲就是方法了,通俗的將就是動做。仍是那個問題,「人」會有什麼動做呢?比方說吃飯(eat),睡覺(sleep)等等。全部「人」能夠作的動做均可以寫到方法之中,而寫代碼時候,也許咱們並不須要這麼多動做,就能夠按照需求來選擇。函數
因此用一段學術一點的講法就是說:類就是具備相同的屬性和功能的對象的抽象的集合。this
這個時候你們可能對於類已經有一個基本的瞭解了,在java中,「類」是java的四大特性中兩種特性的體現:封裝和抽象。這個時候讀者們可能會有疑問,什麼是封裝和抽象呢?設計
先來聊聊「封裝」吧。上度娘你們輸入「封裝」,在百度百科中有對封裝的詳細解釋,固然咱們只需看程序部分的。對象
封裝就是將抽象獲得的數據和行爲(或功能)相結合,造成一個有機的總體,也就是將數據與操做數據的源代碼進行有機的結合,造成「類」,其中數據和函數都是類的成員。(引自百度百科)blog
看起來是不很深奧?那麼就能夠跳過上段直接從頭開始看,告訴你,只要你已經瞭解了前三段,那麼你就已經摸到封裝的門檻。其實就是把「人」的特性和「人」的動做(即屬性和方法)放在一個類中,那麼這種寫代碼的行爲就是封裝了。封裝有不少好處,第一:良好的封裝可以減小耦合;第二:類內部的實現能夠自由地修改;第三:類具備清晰的對外接口。繼承
而且你還同步瞭解了什麼是抽象了呢,知道麼?把一個實實在在的東西從現實中提取出來,放到代碼中的行爲就是抽象了。以後要寫的「人」的類那就不是真的在現實中存在的,而是咱們把它提取出來,讓他在代碼世界中存在了呢。這麼一想,是否是有一種本身是造物主的感受呢,是否是還有點小激動呢?接口
動手一塊兒來寫一個「人」的類吧。get
圖 1
Ok,Now let's take a look at this picture parsing.
圖 2
也許讀者會有一個疑問,爲何要把ID屬性的修飾符設置爲private,而不是public,直接設置爲public是能夠作到對變量的既讀有些。是的,只是修改ID,那麼把ID的屬性設置爲public也是能夠的,可是做爲一個「人」,是有隱私的,咱們其實並不但願其餘「人」可以直接知道本身的身份證號,而是當他詢問的時候,再告訴他,將修飾符設置爲public就好像,你直接把身份證號貼在本身的身上而後再大路上走,而改成private,那麼身份證號就只有本身知道了,只有別人問你(即訪問get方法)時,你才告訴他本身的身份證號。而這個屬性只有get方法,表示這個屬性是隻讀的,其餘人沒有辦法來修改這個屬性。
建立了類以後,咱們該如何訪問這個類呢?
有基礎的人必定想到了,對的,就是將類實例化。實例化,就是建立對象的過程,使用new關鍵字來建立的。來看看代碼吧。
圖 3
圖4
有人會問在(圖 1)的時候,並無寫過構造方法,那麼那個時候People類有構造方法麼?固然是有的,若是不在類中寫構造方法,那麼系統就會默認生成一個空的構造方法,但若是你有寫過構造方法,那麼這個空的構造方法就會消失了。
將時間推到(圖 1),這個時候,筆者並無寫構造方法,那麼怎麼對People類進行實例化呢?很簡單,只要這樣寫就行了:People people = new People();
你們想到了麼?
如今咱們,爲這個People類,多增長一個屬性name。先不要看代碼,來試試看。
圖 5
接下來,筆者來說講繼承。
先來創造兩個類,分別是學生(Student)和老師(Teacher)。
學生類:屬性:ID,name,answer(答案);方法:eat(),exam(int a,int b);
老師類:屬性:ID,name;方法:eat(),correct(int answer);
圖 6
仔細比較代碼,有沒有以爲這個代碼中有不少重複的代碼呢?那麼咱們就得思考,如何將這些代碼拿出,可使這個代碼看起來更簡單整潔。
其實,老師和學生,若是無論他們的身份,那麼他們其實有個共通,就是他們都是「人」。因爲老師和學生都是人,就一樣擁有身份證號屬性和姓名屬性,而且都擁有吃飯的的行爲,因此老師和學生與人之間是繼承關係。
對象的繼承表明了一種「is a」的關係,若是兩個對象A和B,能夠描述爲「B」是「A」。老師是人,就說明了老師和人之間是繼承和被繼承的關係,實際上,繼承者還能夠理解爲是對被繼承者的特殊化,由於它除了具有被繼承者的特性以外,還具有之間獨有的個性。好比學生有一個「exam(考試)」的方法,而老師沒有,老師有一個「correct(批改)」的方法,而學生沒有。繼承定義了類如何相互關聯,共享特性。繼承的工做方式是,定義父類(基類)和子類(派生類),其中子類繼承父類的全部特性。子類不但繼承了父類的全部特性,還能夠定義新的特性。按照以前的例子,並非全部的人都有考試的方法和改卷的方法的,所以在人的子類學生或老師中,就要突出這種特性,寫上這些方法。
Let’s to try.
圖 7
圖 8
對比如今和以前的代碼,是否是簡潔了不少呢?這就是繼承的優勢。不用繼承的話,若是要修改功能,就必須在全部重複的方法中修改,代碼越多,出錯的可能性就越大,而繼承的優勢是,繼承使得全部子類公共的部分都放在了父類,使得代碼獲得了共享,這樣就避免的重複,另外,繼承可以使得修改或擴展繼承而來的實現都較爲容易。
可是繼承也是有缺點的,就是活若是父類變的話,那麼子類就不能不變了,若是讓學生去繼承老師,那麼就亂套了。另外,繼承爲破壞包裝,把父類實現細節暴露給子類,這實際上是增大了兩個類之間的耦合性的。繼承是一種類與類之間強耦合的關係。不過,當兩個類之間具有「is a」關係時,就能夠考慮用繼承了。
學好繼承最好是記住三句話:若是子類繼承於父類,第1、子類擁有父類非private的屬性和功能;第2、子類具備本身的屬性和功能,即子類能夠擴展父類沒有的屬性和功能;第3、子類還能夠以本身的方式實現父類的功能(方法重寫)。
對於方法重寫,筆者如今來舉個例子。
對於學生來講,吃飯是要到學生食堂吃的,而對於老師來講,吃飯就是要到職工食堂吃了。但是若是調用學生或者老師的eat方法時,只能在控制檯輸出I’m eating.若是要實現以上的兩種狀況,那麼這個時候就要使用方法的重寫了。
圖 9
圖 10
最後,來聊聊java中面向對象的最後一個特性:多態。
多態表示不一樣的對象能夠執行相同的動做,可是要經過他們本身的實現代碼來執行。打個比方吧,學校經費不足了,因此要關閉一個食堂,把你們都叫到一個食堂去吃飯,這個時候只要是「人」就均可以去食堂吃飯了,而這個食堂是不檢驗進入食堂的人的身份的,只要是人就能進去了。
這裏要注意幾點:第1、子類是以父類的身份出現的;第2、子類在工做時以本身的方式來實現;第3、子類以父類的身份出現時,子類特有的屬性和方法就不可使用。這樣說來其實方法的重寫就是一種多態的體現形式了。不一樣的對象能夠執行相同的動做,可是要經過它們本身的實現代碼來執行。
圖 11
到這裏爲止,面向對象的四大特性就都介紹完了,但願以上的文章對你們有所幫助,最後謝謝《大話設計模式》給了全面複習面向對象的四大特性的機會,而且給予我寫這篇文章的理論基礎。
部分段落摘自《大話設計模式》