Content:
- 每個對象都有一個接口
- 每個對象都提供服務(wù)
- 被隱藏的具體實現(xiàn)
- 復用具體實現(xiàn)
每一個對象都有一個接口
- 所有的對象都是唯一的,就像再相似的雙胞胎也存在差異,彼此也是唯一的,因為個體差異存在
- 而有若干對象但卻有著很多共性,就是草原上一群奔騰的駿馬,雖然各自唯一但卻有相同的行為和特性,如此我們把具有相同特性和行為的一個群體或者集合抽象為一個類,,這就是類的概念。
- 經(jīng)典的銀行出納員問題:
- 在銀行出納員問題中,有出納,賬號,客戶,交易,和貨幣單位等許多的"對象"。
- 然后在這些對象中:每個出納都有自己的名字,工號,年薪,性別,住址,級別,待遇,能執(zhí)行入賬,出賬操作;每一個賬號有余額,種類,消費。同時,每個賬號會有不同的余額種類和消費,每個出納也有自己的名字,工號和性別。
- 上面問題中的出納,賬號,客戶,交易和貨幣都是一個類,而出納001,出納002,客戶張三,客戶李四都是一個個鮮活的對象,它們是抽象概念的實例。
- 類是對象的集合,對象是類的實例,對象之間存在個體差異。在程序執(zhí)行期間具有不同的狀態(tài)而其他方面都相似的對象會被分組到對象的類中。
-
面向?qū)ο蟮拈_發(fā),實質(zhì)上是在創(chuàng)造新的數(shù)據(jù)類型,所以一個類實際上是一個數(shù)據(jù)類型。開發(fā)中我們直接或間接的使用了別人的類,然后在獨特的業(yè)務(wù)驅(qū)動下去創(chuàng)造自己的類。
比如:API給出的int,float,list,map,是java內(nèi)置的類,而Jvm也欣然接受新的類,并和內(nèi)置類有相同的管理機制。比如我們可以創(chuàng)造:User.class,Test.class,Car.class。 - 面向?qū)ο笳驹诟叩慕鉀Q問題的角度,不僅僅是解決一個問題,而是提供了一套解決問題的方案。一旦一個類被創(chuàng)建,那么我們可以在以后的任何地方去創(chuàng)建該類的對象去解決相應的問題。正是如此,java中才會有很多高質(zhì)量的第三方開源庫。比如:我需要解決網(wǎng)絡(luò)通信問題,那么為可以從架構(gòu)上開發(fā)一套網(wǎng)絡(luò)通信框架,然后再其他需要網(wǎng)絡(luò)通信的地方直接使用。這也是面向?qū)ο笳Z言的強大之處。
- 每個對象都能滿足某些請求,提供某些服務(wù)。比如,我在建設(shè)房子的時候,需要若干個燈泡,這些燈泡就是一個個對象,他們能為我們提供照明的服務(wù)。所以我可以抽象出:
<code>
interface Light{
public void on();
public void off();
public boolean isOn();
...
}
</code>
這是Light的一個抽象接口,接下來可以創(chuàng)建MyLight具有每個方法的實現(xiàn)。在層次結(jié)構(gòu)上,這些是底層的準備工作,底層準備好之后,那么就直接使用:我裝修房子需要燈,車庫需要燈,樓梯也需要燈,那此時:
<code>
MyLight lt01 = new MyLight();
lt01 .on();//
MyLight lt02 = new MyLight();
lt02 .on();//
MyLight lt03 = new MyLight();
lt03 .on();//
</code>
一號燈解決房間照明,二號燈解決車庫照明,三號燈解決樓梯照明....很多相同問題得以解決。而我們解決問題的套路是,得到一個燈的對象,然后使用它提供的服務(wù),即調(diào)用對象的接口。
每個對象都提供服務(wù)
- 當正在試圖開發(fā)或者理解一個程序設(shè)計時,最好的方法之一就是將對象想象為服務(wù)提供者。
- 程序本身將向用戶提供服務(wù),而開發(fā)程序時也是調(diào)用其它對象服務(wù)來滿足自己的需求。程序開發(fā)者的目標就是:去創(chuàng)建(或者最好是在現(xiàn)有代碼庫中去尋找,比較不同的第三方開源庫)能夠提供理想的服務(wù)來解決問題的一序列對象。
- 將對象看作是服務(wù)提供者還有一個附帶的好處:它有助于提高程序的內(nèi)聚性。每個對象完成各自分內(nèi)的事情,提供各自的服務(wù),各施其職,然后程序則是若干對象的集合,若此協(xié)調(diào)工作解決需求問題。
- 將對象作為服務(wù)提供者是一件偉大的簡化工具,這不僅在設(shè)計過程中非常有用,而且當其他人試圖理解你的代碼或重用某個對象時,依據(jù)服務(wù)來理解將會事半功倍。就像一個Project中總會有:Db模塊,net模塊,Utils模塊...這也是對服務(wù)的一種劃分,思維清晰。
被隱藏的具體實現(xiàn)
將呈現(xiàn)開發(fā)人員按照角色分為類創(chuàng)建者(那些新的數(shù)據(jù)類型的創(chuàng)建者)和客戶端程序猿(使用別人類和庫的類消費者,比如調(diào)用別人的API等),很顯然,類創(chuàng)建者是值得敬畏的程序猿,因為他們扮演著軟件世界里上帝的角色。
客戶端程序猿的目標是搜集各種用來實現(xiàn)快速應用開發(fā)的類。類創(chuàng)建者的目標是構(gòu)建類。類的創(chuàng)建者一般只是希望將類的接口暴露給客戶端程序員,而不希望客戶端程序員能看見和修改自己接口的內(nèi)部實現(xiàn)。這時就需要將自己的內(nèi)部實現(xiàn)隱藏起來,出現(xiàn)了訪問控制機制。
訪問機制存在的第一個原因是:讓客戶端程序員無法觸及它們不應該觸及的部分,比如類的內(nèi)部數(shù)據(jù)和對象以及業(yè)務(wù)邏輯。客戶端程序員只能享受服務(wù)而不能制定服務(wù)規(guī)則。
訪問機制存在的第二個原因是:允許類庫的設(shè)計者可以改變類內(nèi)部的工作方式而不影響客戶端程序員。比如:一開始的時候暴露了某個搜索排序的接口,但是后來你發(fā)現(xiàn)一種速度更快效果更優(yōu)的算法,此時就可以在客戶端程序員毫不知情的情況下,修改接口的實現(xiàn)。接口和實現(xiàn)分離,實現(xiàn)了高內(nèi)聚,低耦合。
-
Java提供了三個關(guān)鍵字用于劃分內(nèi)部邊界:public private 、protected。
- public 表示被其修飾的對象,方法和數(shù)據(jù),可以被任何人使用。
- private 則是與public完全相反,只能被類創(chuàng)建者和類內(nèi)部的方法所使用,客戶端程序員或者第三方類是完全看不見的,它就像在類創(chuàng)建著和使用類的人直接建立了一堵高墻。
- protected關(guān)鍵字和private作用相當,差別僅在于類的繼承著可以訪問和使用被Protected修飾的對象方法或數(shù)據(jù)。
Java還提供了一種默認的訪問權(quán)限,即包訪問權(quán)限,當前對象方法未被 修飾時,即默認包訪問權(quán)限--同一包下的其他類可以訪問。
注意:接口中聲明的成員變量默認都是 public static final 的,必須顯示的初始化。因而在常量聲明時可以省略這些修飾符。接口中的方法默認都是public abstract的。
復用具體實現(xiàn)
- 一旦一個類被創(chuàng)建并被測試完,那么它就應該代表一個有用的代碼單元。
- 代碼復用是面向?qū)ο笳Z言所提供最了不起的優(yōu)點之一。
- 最簡單的復用是組合,Has-a的關(guān)系,比如汽車擁有引擎,電腦擁有主機。組合帶來了極大的靈活性,新類的成員對象通常被修飾為private的,其實也是一種封裝。
- 另一種方式是繼承,實際優(yōu)先考慮組合,因為它更加靈活簡單。