天天看小說

第229章

大B:“我來講講我個(gè)人對(duì)設(shè)計(jì)模式的理解吧?!?

小A:“呵呵!好?。 ?

大B:“也許能讓你更好地理解23種設(shè)計(jì)模式?!?

1、Adapter(適配器)模式:旨在提供用戶期望的接口,以便利用具有不同接口的類的服務(wù)。

(1)個(gè)人理解:實(shí)際上只是把客戶調(diào)用,轉(zhuǎn)變爲(wèi)調(diào)用已經(jīng)存在的方法。適配器的作用可以理解爲(wèi)提供一個(gè)人人皆知的,顧名思義的新方法名。

(2)提示代碼:

publicdoublegetMass(){

returnrocket.getMass(simTime);

}

2、Facade(外觀)模式:旨在爲(wèi)子系統(tǒng)提供一個(gè)接口,使之更加容易使用。

(1)經(jīng)典範(fàn)例:JOptionPane類,JOptionPane.showConfirmDialog(……)

(2)個(gè)人理解:構(gòu)建一個(gè)個(gè)目的明確的類,比如典型的靜態(tài)方法的使用。

(3)提示代碼:

intoption;

option=JOptionPane.showConfirmDialog(……);//靜態(tài)方法創(chuàng)建對(duì)話框

(4)提示關(guān)鍵字:外觀類,工具類,實(shí)例類

3、Composite(組合)模式:旨在讓用戶能夠用統(tǒng)一的接口處理單個(gè)對(duì)象以及對(duì)象組合。

(1)經(jīng)典範(fàn)例:組合,樹,環(huán)

щшш? тTkan? ℃o

(2)個(gè)人理解:其他很多模式的基礎(chǔ),羣組可以包含羣組或者個(gè)體,羣組和個(gè)體有共同的接口。

(3)提示代碼:

MachineComponentmc=(MachineComponent)i.next();

count+=mc.getMachineCount();

(4)提示關(guān)鍵字:遞歸

4、責(zé)任型模式Bridge(橋接)模式:旨在將依賴抽象操作的類與這些抽象操作的實(shí)現(xiàn)相分離,從而使得抽象類與實(shí)現(xiàn)能夠獨(dú)立變化。

(1)經(jīng)典範(fàn)例:驅(qū)動(dòng)程序

(2)個(gè)人理解:將抽象和方法的具體實(shí)現(xiàn)分離,抽象類中包含一個(gè)driver對(duì)象,driver對(duì)象即是對(duì)方法的具體實(shí)現(xiàn)。

(3)提示關(guān)鍵字:裝載

5、ChainofResponsibility(責(zé)任鏈)模式:旨在將一個(gè)方法調(diào)用請(qǐng)求沿著責(zé)任鏈依次轉(zhuǎn)發(fā)給下一個(gè)對(duì)象,讓每個(gè)對(duì)象都有一次機(jī)會(huì)決定自己是否處理該請(qǐng)求,從而降低請(qǐng)求的發(fā)送者與其接受者之間的耦合程度。

(1)個(gè)人理解:尋找責(zé)任的請(qǐng)求在鏈中傳遞,如果責(zé)任人已經(jīng)找到則終止,否則繼續(xù)向其他對(duì)象轉(zhuǎn)發(fā)責(zé)任。

(2)提示代碼:

publicEngineergetResponsible(VisualizationItemitem){

if(iteminstanceoftool){

Toolt=(Tool)item;

returnt.getToolCart().gerResponsible();

}

if(iteminstanceofToolCart){

ToolCarttc=(ToolCart)item;

returntc.gerResponsible();

}

}

(3)提示關(guān)鍵字:轉(zhuǎn)發(fā)

6、Singleton(單例)模式:旨在確保某個(gè)類只有一個(gè)實(shí)例,並且爲(wèi)之提供一個(gè)全局訪問點(diǎn)。

(1)個(gè)人理解:創(chuàng)建一個(gè)類的唯一實(shí)例,可以作爲(wèi)全局變量。

(2)提示代碼:

publicstaticFactorygetFactory(){

if(factory……null)

factory=newFactory();

returnfactory;

}

7、Observer(觀察者)模式:旨在在多個(gè)對(duì)象之間定義一對(duì)多的依賴關(guān)係,以便當(dāng)一個(gè)對(duì)象狀態(tài)改變時(shí),其他所有依賴這個(gè)對(duì)象的對(duì)象都能夠被通知,並自動(dòng)更新。

(1)經(jīng)典範(fàn)例:GUI(MVC中分離M和VC)

(2)個(gè)人理解:當(dāng)一個(gè)對(duì)象發(fā)生改變的時(shí)候,其他關(guān)心該對(duì)象的對(duì)象能夠得到通知,並且更新自身狀態(tài)。

(3)提示代碼:

publicvoidnotifyObservers(){

observers.update();

}

(4)提示關(guān)鍵字:註冊(cè),監(jiān)聽

8、Mediator(中介者)模式:旨在定義一個(gè)對(duì)象來封裝一組對(duì)象之間交互的方式,這樣可避免對(duì)象間的顯示引用,而且還可以獨(dú)立對(duì)這些對(duì)象的交互進(jìn)行修改。

(1)經(jīng)典範(fàn)例:GUI(特指MVC中的controller)

(2)個(gè)人理解:中介者類專門用於處理對(duì)象間的交互,與GUI的佈局組件分離

(3)提示代碼:

publicvoidsetLocation(Machinevalue){

returnmediator.set(this,value);

}

9、Proxy(代理)模式:旨在爲(wèi)某個(gè)對(duì)象提供一個(gè)代理來控制對(duì)該對(duì)象的訪問。

(1)經(jīng)典範(fàn)例:圖像代理(長(zhǎng)時(shí)間載入內(nèi)存前的Loading提示)

(2)個(gè)人理解:提供一個(gè)代理來承擔(dān)責(zé)任(轉(zhuǎn)發(fā)請(qǐng)求),實(shí)際操作的對(duì)象並不是根本對(duì)象,而是一個(gè)用戶和真正實(shí)現(xiàn)之間的中間角色。

(3)提示代碼:

setImage(LOADING.getImage());

callbackFrame.repaint();

newThread(this).start();

(4)提示關(guān)鍵字:佔(zhàn)位

10、Flyweight(享元)模式:旨在通過共享來爲(wèi)大量的細(xì)粒度對(duì)象提供有效的支持。

(1)個(gè)人理解:很多類具有相同的且不變的屬性,可以將這些屬性提取出來構(gòu)成享元,在一個(gè)特定的工廠類中作爲(wèi)內(nèi)部類,具有static的get方法,便於外部類共享。

(2)提示代碼:

publicclassChemicalFactory{

privatestaticMaochemicals=newHashMap();

ChemicalImp{

//someattributesandmethods

}

static{

chemicals.put(newChemicalImp());

}

publicstaticChemicalgetChemical(Stringname){

return***;

}

}

(3)提示關(guān)鍵字:共享對(duì)象

11、Builder(生成器)模式:旨在把構(gòu)造對(duì)象實(shí)例的代碼邏輯移到要實(shí)例化的類的外部,以便於細(xì)化構(gòu)造過程,或者簡(jiǎn)化對(duì)象。

(1)經(jīng)典範(fàn)例:解析文本構(gòu)造對(duì)象

(2)個(gè)人理解:用一個(gè)builder類收集構(gòu)造信息,在確定信息足夠(或者滿足構(gòu)造的最低要求)的時(shí)候,再生成對(duì)象。

(3)提示代碼:

Stringsample=“*****”;

ReservationBuliderbuilder=newUnforgivingBuilder();

newReservationParser(builder).parse(sample);

Resercationres=builder.build();

(4)提示關(guān)鍵字:逐步構(gòu)造

12、FactoryMethod(工廠方法)模式:旨在定義一個(gè)用於創(chuàng)建對(duì)象的接口,同時(shí)控制對(duì)哪個(gè)類進(jìn)行實(shí)例化。

(1)經(jīng)典範(fàn)例:迭代器

(2)個(gè)人理解:爲(wèi)相關(guān)的多個(gè)類提供一個(gè)共同的接口,客戶不需要知道該實(shí)例化哪個(gè)類,具體實(shí)例化的類由服務(wù)的提供者決定。

(3)提示代碼:

Listlist=Arrays.asList(newString[]{“1”,“2”,“3”});

Iteratoriter=list.iterator();

(4)提示關(guān)鍵字:共同接口

13、AbstractFactory(抽象工廠)模式:旨在創(chuàng)建一系列相互關(guān)聯(lián)或相互依賴的對(duì)象。

(1)經(jīng)典範(fàn)例:GUI工具包

(2)個(gè)人理解:創(chuàng)建一系列相關(guān)的對(duì)象,也就是把創(chuàng)建一個(gè)大對(duì)象所需要的子操作聚合起來。

(3)提示代碼:

publicJButtoncreateButtonOK(){

JButtonb=super.createButtonOk();

b.setIcon(getIcon(“images/123.gif”));

returnb;

}

(4)提示關(guān)鍵字:外觀和感覺

14、Prototype(原型)模式:通過拷貝一個(gè)現(xiàn)有對(duì)象生成新的對(duì)象。

(1)個(gè)人理解:通過複製一個(gè)已經(jīng)存在的對(duì)象,保存原來對(duì)象的狀態(tài),在此基礎(chǔ)上進(jìn)行進(jìn)一步的改動(dòng)。

(2)提示代碼:

publicOzPanelcopy2(){

OzPanelresult=newOzPanel();

result.setBackground(this.getBackground());

//moreresult.set***methods……

returnresult;

}

(3)提示關(guān)鍵字:複製

15、Memento(備忘錄)模式:旨在爲(wèi)對(duì)象提供狀態(tài)存儲(chǔ)和狀態(tài)恢復(fù)功能。

(1)經(jīng)典範(fàn)例:撤銷操作

(2)個(gè)人理解:使用棧進(jìn)行撤銷和恢復(fù)的操作,棧頂部是當(dāng)前的狀態(tài)。更多的,可以把相關(guān)狀態(tài)進(jìn)行持久性存儲(chǔ)。

(3)提示代碼:

publicvoidundo(){

if(!canUndo())return;

mementos.pop();

}

(4)提示關(guān)鍵字:redo,undo

16、TemplateMethod(模板方法)模式:旨在一個(gè)方法中實(shí)現(xiàn)一個(gè)算法,並遵循算法中某些步驟的定義,從而使得其他類可以重新定義這些新步驟。

(1)經(jīng)典範(fàn)例:(根據(jù)不同規(guī)則)排序

(2)個(gè)人理解:在算法的實(shí)現(xiàn)中,把一些需要自定義的部分(通常是算法的核心部分),留在外部的類來實(shí)現(xiàn)。並可以需要實(shí)現(xiàn)的部分設(shè)置鉤子。

(3)提示代碼:

Array.sout(rockets,newApogeeComparator());

publicclassApogeeComparatorimplementsComparator{

//basemethodaboutsort……

}

(4)提示關(guān)鍵字:算法框架+算法步驟

17、State(狀態(tài))模式:旨在將與狀態(tài)有關(guān)的處理邏輯分散到代表狀態(tài)的各個(gè)類中。

(1)個(gè)人理解:將所有的狀態(tài)都構(gòu)建成一個(gè)相應(yīng)的類,它們的超類對(duì)外部各個(gè)事件提供相應(yīng)的同意接口,使得調(diào)用者無需判斷當(dāng)前狀態(tài)。

(2)提示代碼:

publicclassDoor2extendsObservable{

publicvoidtouch(){

state.touch();

}

}

publicclassDoorOpenextendsDoorState{

publicvoidtouch(){

door.setState(door.STAYOPEN);

}

}

(3)提示關(guān)鍵字:狀態(tài)處理分散

18、Strategy(策略)模式:旨在把可選的策略或方案封裝到不同的類中,並在這些類中實(shí)現(xiàn)一個(gè)共同的操作。

(1)個(gè)人理解:爲(wèi)不同的解決方案建立類,在執(zhí)行的時(shí)候選擇一個(gè)策略執(zhí)行。與State模式比較,兩者很接近,前者傾向在可選的方案中選擇,後者是在不同的狀態(tài)之間遷移。

(2)提示代碼:

privateAdvisorgetAdvisor(){

if(advisor……null){

if(promotionAdvisor.hasItem())

advisor=promotionAdvisor;

//maybemoreelseif

}

returnadvisor;

}

(3)提示關(guān)鍵字:策略選擇+策略執(zhí)行

19、Command(命令)模式:旨在將請(qǐng)求封裝爲(wèi)一個(gè)對(duì)象,並將該請(qǐng)求對(duì)象作爲(wèi)參數(shù);客戶可以提供不同的請(qǐng)求對(duì)象,如隊(duì)列請(qǐng)求,時(shí)間請(qǐng)求或者日誌請(qǐng)求;也可以讓客戶準(zhǔn)備調(diào)用該請(qǐng)求的特定上下文。

(1)經(jīng)典範(fàn)例:菜單命令(actionPerformed())

(2)個(gè)人理解:將方法(一般是execute()方法)封裝在對(duì)象中,使用時(shí)直接調(diào)用相關(guān)mand對(duì)象的execute()方法即可??梢宰鳡?wèi)Template模式的替代模式。

(3)提示代碼:

Commanddoze=newCommand(){

publicvoidexecute(){

//dosomething

}

}

publicclassCommandTimer{

Publicstaticlongtime(Commandmand){

mand.execute();

}

}

longactual=CommandTimer.time(doze);

(4)提示關(guān)鍵字:封裝對(duì)象

20、Interpreter(解釋器)模式:旨在使開發(fā)者可以根據(jù)自己定義的組合規(guī)則生成可執(zhí)行的對(duì)象。

(1)個(gè)人理解:常與Command和Composite模式配合使用,對(duì)命令進(jìn)行組合使用,有點(diǎn)像編程中使用語句構(gòu)造功能。

(2)提示代碼:

publicclassIfCommandextendsCommand{

protectedTermterm;

protectedCommandbody;

protectedCommandelseBody;

publicIfCommand(Termterm,Commandbody,CommandelseBody){

this.term=term;

this.body=body;

this.elseBody=elseBody;

}

publicvoidexecute(){

if(term.eval()!=null)

body.execyte();

else

elseBody.execute();

}

}

(3)提示關(guān)鍵字:解釋器,組合對(duì)象

21、Decorator(裝飾器)模式:旨在使開發(fā)者能夠動(dòng)態(tài)地組織對(duì)象的行爲(wèi)。

(1)經(jīng)典範(fàn)例:流和輸出器,函數(shù)包裝器

(2)個(gè)人理解:在運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建不同的變化

(3)提示代碼:

BufferedOutputStreamout=

newBufferedOutputStream(

newGZIPOutputStream(

newFileOutputStream(args[1])));

(4)提示關(guān)鍵字:動(dòng)態(tài)組合

22、Iterator(迭代器)模式:旨在爲(wèi)開發(fā)人員提供一種順序訪問集合元素的方法。

(1)個(gè)人理解:在新建一個(gè)結(jié)構(gòu)的時(shí)候,爲(wèi)順序訪問其元素,可以同樣新建一個(gè)對(duì)應(yīng)的迭代器類。也可以自定義訪問元素的其他方式(比如逆序)。

(2)提示代碼:

Listemployees;

ListIteratorforward(employees);

ReverseListIteratorbackward(employees);

PrintEmployees(forward);

PrintEmployees(backward);

(3)提示關(guān)鍵字:訪問元素

23、Visitor(訪問者)模式:旨在讓開發(fā)者能夠在不修改現(xiàn)有類層次結(jié)構(gòu)的前提下擴(kuò)展該類層次結(jié)構(gòu)的行爲(wèi)。

(1)個(gè)人理解:在開發(fā)類的時(shí)候,留有一個(gè)accept()操作,該操作接受一個(gè)visitor參數(shù)。在需要爲(wèi)類增加新的操作時(shí),無需改變?cè)瓉淼念悓哟?,直接編輯visitor中的visit操作,然後使用accept()方法接受即可。

(2)提示代碼:

publicclassFindVisitorimplementsMachineVisitor{

publicMachineComponetfind(MachineComponetmc){

mc.accept(this);

}

publicvoidvisit(MachineCompositemc){

//dosomething

}

}

MachineComponentfactory=OozinozFactory.dublin();

MachineComponentmachine=newFindVisitor().find(factory,3404);

(3)提示關(guān)鍵字:不改變類層次附錄:面向?qū)ο蠡A(chǔ)

小A:“爲(wèi)什麼要‘面向?qū)ο蟆???

大B:“面向?qū)ο蠓椒ㄊ箻?gòu)建系統(tǒng)更容易,因爲(wèi):解決正確的問題,正常工作,易維護(hù),易擴(kuò)充,易重用。大家發(fā)現(xiàn)面向?qū)ο蟾桌斫?,?shí)現(xiàn)可以更簡(jiǎn)單。把數(shù)據(jù)和功能組合在一起簡(jiǎn)單而自然,分析和實(shí)現(xiàn)之間的概念跨度更小,設(shè)計(jì)良好的一組對(duì)象能彈性地適應(yīng)重用和變化,可視化模型提供更有效的溝通,建模過程有助於創(chuàng)建通用詞彙以及在開發(fā)者和用戶/客戶之間達(dá)成共識(shí)。非計(jì)算機(jī)編程人員也能理解對(duì)象模型,這些好處可以使用面向?qū)ο蠓椒ǐ@得,但面向?qū)ο蠓椒ú荒鼙WC這一點(diǎn)?!?

小A:“怎樣才能變成優(yōu)秀的面向?qū)ο笤O(shè)計(jì)者?”

大B:“只有靠經(jīng)驗(yàn)和聰明的頭腦才能做到?!?

過程化方法(TheProceduralApproach)

小A:“怎樣過程化方法?”

大B:“系統(tǒng)由過程(procedures)組成,過程之間互相發(fā)送數(shù)據(jù),過程和數(shù)據(jù)各自獨(dú)立,集中於數(shù)據(jù)結(jié)構(gòu)、算法和運(yùn)算步驟的先後順序,過程經(jīng)常難以重用,缺乏具有較強(qiáng)表現(xiàn)力的可視化建模技術(shù),分析與實(shí)現(xiàn)之間需要進(jìn)行概念轉(zhuǎn)換,本質(zhì)上是機(jī)器/彙編語言的抽象,從設(shè)計(jì)模型到代碼實(shí)現(xiàn)跨度很大。”

面向?qū)ο蠓椒?

大B:“系統(tǒng)由對(duì)象組成,對(duì)象互相發(fā)送消息(過程調(diào)用)相關(guān)的數(shù)據(jù)和行爲(wèi)緊密地綁定在對(duì)象中,把問題領(lǐng)域建模成對(duì)象,要解決的問題自然的映射爲(wèi)代碼的實(shí)現(xiàn),可視模型表現(xiàn)力強(qiáng),相對(duì)容易理解,集中於實(shí)現(xiàn)之前所確定的職責(zé)(responsibilities)和接口。強(qiáng)有力的概念:接口,抽象,封裝,繼承,委託(delegation)和多態(tài)。問題的可視模型逐漸進(jìn)化成解決方案模型,設(shè)計(jì)模型與代碼實(shí)現(xiàn)之間跨度較小努力縮減軟件的複雜度?!?

溫度換算

大B:“下面我就以溫度換算爲(wèi)例?!?

過程/函數(shù)化方法

floatc=getTemperature();//假定爲(wèi)攝氏度。

floatf=toFarenheitFromCelcius(c);

floatk=toKelvinFromCelcius(c);

floatx=toKelvinFromFarenheit(f);

floaty=toFarenheitFromKelvin(k);

面向?qū)ο蠓椒?

Temptemp=getTemperature();

floatc=temp.toCelcius();

floatf=temp.toFarenheit(); ωωω¤Tтkan¤¢O

floatk=temp.toKelvin();

包含有數(shù)據(jù)的Temp的內(nèi)部單元是什麼?

建模(Modeling)

小A:“成功的程序能解決真實(shí)世界的問題?!?

大B:“嗯,是的。它們緊密對(duì)應(yīng)於需要解決的問題。對(duì)問題領(lǐng)域和用戶活動(dòng)進(jìn)行建模?!?

小A:“建模促進(jìn)與用戶更好的可視化交流?!?

大B:“成功的面向?qū)ο笤O(shè)計(jì)總是一開始就由領(lǐng)域?qū)<液蛙浖O(shè)計(jì)者建立一個(gè)反映問題領(lǐng)域的可視化的‘對(duì)象模型’?!?

小A:“嗯。是的?!?

大B:“你願(yuàn)意讓承包人在沒有設(shè)計(jì)藍(lán)圖的情況下建造你的新房子嗎?”

小A:“那當(dāng)然不行啦?!?

對(duì)象

大B:“你知道怎樣去理解什麼是對(duì)象嗎?”

小A:“對(duì)象代表真實(shí)或抽象的事物,有一個(gè)名字,有明確的職責(zé)(well-definedresponsibilities),展示良好的行爲(wèi)(well-definedbehavior),接口清晰,並且儘可能簡(jiǎn)單、自相容,內(nèi)聚,完備(self-consistent,coherent,andplete)。”

大B:“嗯,對(duì)。(通常)不是很複雜或很大,只需要理解自己和一小部分其他對(duì)象的接口,與一小部分其它對(duì)象協(xié)同工作(teamplayers),儘可能地與其它對(duì)象鬆散耦合(looselycoupled),很好地文檔化,以便他人使用或重用,對(duì)象是類的實(shí)例,每一個(gè)對(duì)象都有唯一的標(biāo)識(shí),類定義一組對(duì)象的接口和實(shí)現(xiàn),即定義了這些對(duì)象的行爲(wèi),抽象類不能擁有實(shí)例,只要有抽象類(如寵物),通常就會(huì)有能夠?qū)嵗木唧w類(如貓,狗等),一些面嚮對(duì)象語言(如Smalltalk)支持元類(metaclass)的概念,程序員可以隨時(shí)(on-the-fly)定義一個(gè)類,然後實(shí)例化。這種情況下,類也是一個(gè)對(duì)象,即元類。對(duì)象一旦實(shí)例化,就不能更改它的類?!?

對(duì)象的特徵

大B:“那你知道對(duì)象有什麼特徵嗎?”

小A:“有唯一標(biāo)識(shí),可以分成許多種類(即類),可以繼承或聚合。行爲(wèi)、職責(zé)明確,接口與實(shí)現(xiàn)分離,隱藏內(nèi)部結(jié)構(gòu),有不同的狀態(tài),可以提供服務(wù),可以給其它對(duì)象發(fā)送消息,從其它對(duì)象接收消息,並做出相應(yīng)響應(yīng),可以把職責(zé)委託給其它對(duì)象。”

大B:“對(duì),說得非常全面?!?

小A:“怎麼樣才叫類呢?”

大B:“有公共的屬性和行爲(wèi)的一組對(duì)象可以抽象成爲(wèi)類,對(duì)象通常根據(jù)你所感興趣的屬性而分類?!?

小A:“喔?!?

大B:“例如:街道,馬路,高速公路……不同的程序?qū)λ鼈兎诸愐膊煌?。交通模擬器程序,單行道,雙通道,有分車道的,住宅區(qū)的,限制通行的維護(hù)調(diào)度程序,路面材料,重型卡車運(yùn)輸類本身也可以有屬性和行爲(wèi)。例如:養(yǎng)老金管理程序中的‘僱員’類僱員總數(shù),僱員編制多少,不同語言對(duì)類的支持略有不同:Smalltalk把類當(dāng)作對(duì)象(很有好處),C++提供最小限度的支持(有時(shí)會(huì)帶來很多煩惱),Java位於上述兩者之間,類也是對(duì)象,類可以有屬性‘僱員’類可以有一個(gè)包含其所有實(shí)例的列表(list)‘彩票’類可以有一個(gè)種子(seed)用於產(chǎn)生隨機(jī)票號(hào),該種子被所有實(shí)例共享,類可以有行爲(wèi),僱員”類可以有g(shù)etEmployeeBySerialNum行爲(wèi)?!势薄惪梢杂術(shù)enerateRandomNumber行爲(wèi)。

封裝

大B:“只暴露相關(guān)的細(xì)節(jié),即公有接口(publicinterface)?!?

小A:“封裝什麼?如何封裝?”

大B:“隱藏‘齒輪和控制桿’只暴露客戶需要的職責(zé),防止對(duì)象受到外界干擾,防止其它對(duì)象依賴可能變化的細(xì)節(jié),信息隱藏有助於對(duì)象和模塊之間的鬆散耦合,使得設(shè)計(jì)更加靈活,更易於重用,減少代碼之間的依賴,‘有好籬笆纔有好鄰居’。例如:汽車的氣動(dòng)踏板。”

小A:“怎樣才能更好地實(shí)踐?”

大B:“最佳實(shí)踐:對(duì)象之間只通過方法(函數(shù))互相訪問。切忌直接訪問屬性?!?

classPerson{

publicintage;

}

classBetterPerson{

privateintage;//changetodateOfBirth

publicintgetAge(){returnage;}

}

更完善的Person類可能是:privatedateOfBirth

抽象

小A:“什麼是抽象?”

大B:“抽象使得泛化(generalizaions)成爲(wèi)可能,簡(jiǎn)化問題-忽略複雜的細(xì)節(jié),關(guān)注共性,並且允許變更,人類經(jīng)常使用泛化。當(dāng)你看見約翰和簡(jiǎn)家裡的那頭灰德國(guó)牧羊犬時(shí),你有沒有……想到‘狗’這個(gè)詞?抽象同樣能簡(jiǎn)化計(jì)算機(jī)程序。例如,軟件中有兩個(gè)重要抽象:客戶端和服務(wù)器(clientsandservers)。”

小A:“喔?!?

大B:“在圖形用戶界面中,系統(tǒng)可能會(huì)詢問用戶各種問題:是或不是多選一?輸入數(shù)字,任意文本問題統(tǒng)一處理這些問題會(huì)顯得很簡(jiǎn)單,每一個(gè)問題都作爲(wèi)Question類的特例(specialization);程序只需維護(hù)這些問題的實(shí)例列表,分別調(diào)用各自的askTheUser()方法。”

繼承

小A:“什麼是繼承?”

大B:“繼承用於描述一個(gè)類與其它類的不同之處。例如:類Y像類X,但有下列不同……”

小A:“爲(wèi)什麼使用繼承?”

大B:“你有兩種類型,其中一種是另一種的擴(kuò)展。有時(shí)(不是所有時(shí)候)你想忽略對(duì)象之間的不同,而只關(guān)注它們的共同之處(基類)。這就是泛化。假如某系統(tǒng)需要對(duì)不同的形狀進(jìn)行操作(經(jīng)典例子):有時(shí)你並不關(guān)心你正在操作的形狀的種類(例如,移動(dòng)形狀時(shí))有時(shí)你必須知道形狀的種類(在顯示器上繪製形狀)”

小A:“怎樣去理解派生類?”

大B:“派生類繼承自基類;派生類擴(kuò)展了基類;派生類是基類的特殊化(specialization)。派生類能夠提供額外的狀態(tài)(數(shù)據(jù)成員),或額外的行爲(wèi)(成員函數(shù)/方法),或覆蓋所繼承的方法。基類是所有它的派生類的泛化。如:通常所有寵物都有名字。基類(BaseClass)=父類(parentclass)=超類(superclass)派生類(DerivedClass)=子類(childclass)=子類(subclass)”

小A:“喔?!?

大B:“繼承含有(有些,不是全部)是一個(gè)(is-a)或是一種(is-a-kind-of)的關(guān)係,正方形是一種矩形(使用繼承),Leroy是一種狗(不使用繼承),傳統(tǒng)的過程分析和設(shè)計(jì)中不能很好地模擬這種關(guān)係。繼承是一種強(qiáng)有力的機(jī)制,使我們關(guān)注共性,而不是特定的細(xì)節(jié)。使得代碼可以重用且富有彈性(能適應(yīng)變化)?!?

小A:怎樣去實(shí)現(xiàn)繼承?

大B:“實(shí)現(xiàn)繼承(Implementationinheritance):派生類繼承基類的屬性和行爲(wèi)。”

小A:“又應(yīng)該怎樣去接口繼承?”

大B:“接口繼承(Interfaceinheritance):類實(shí)現(xiàn)抽象接口的方法,保留既定語義(intendedsemantics)C++允許多重實(shí)現(xiàn)繼承。Java規(guī)定派生類只能有一個(gè)基類,但可以繼承自多個(gè)接口。”

多態(tài)

小A:“什麼是多態(tài)?”

大B:“多態(tài)是一種允許多個(gè)類針對(duì)同一消息有不同的反應(yīng)的能力。對(duì)於任何實(shí)現(xiàn)了給定接口的對(duì)象,在不明確指定類名的情況下,就可以使用。例如:question.askTheUser();當(dāng)然,這些不同反應(yīng)都有類似的本質(zhì)儘可能使用接口繼承和動(dòng)態(tài)(運(yùn)行期)綁定Liskov替換原則:如果Y是X的子類,那麼在任何使用X實(shí)例的地方都可以用Y的實(shí)例來替換。”

演示多態(tài)的Java代碼

//File:question/QuestionTest.java

//下面的代碼將輸出什麼?

//RefertotheBeginningJavalinkonthecoursewebsite.

packagequestion;

abstractclassQuestion{//Fullclassnameisquestion.QuestionTest

publicQuestion(Stringtext){//Constructor

theText=text;

}

publicabstractvoidaskTheUser();

protectedStringtheText;

}

classYesNoQuestionextendsQuestion{

publicYesNoQuestion(Stringtext){super(text);}

publicvoidaskTheUser(){

System.out.println(theText);

System.out.println(“YESorNO……?”);

}

}

classFreeTextQuestionextendsQuestion{

publicFreeTextQuestion(Stringtext){super(text);}

publicvoidaskTheUser(){

System.out.println(theText);

System.out.println(“Well……?Whatstheanswer……?”);

}

}

publicclassQuestionTest{

publicstaticvoidmain(String[]args){

Question[]questions=getQuestions();

for(inti=0;i

本書完結(jié),看看其他書:
第189章第142章第122章第57章第51章第33章第111章第11章第205章第150章第98章第62章第223章第221章第23章第55章第153章第190章第45章第219章第140章第93章第25章第51章第69章第24章第189章第20章第23章第1章第160章第6章第175章第81章第139章第178章第164章第13章第216章第65章第6章第122章第201章第194章第126章第36章第72章第32章第69章第164章第151章第120章第182章第210章第122章第59章第18章第108章第134章第16章第213章第194章第67章第18章第200章第38章第20章第216章第144章第188章第194章第75章第10章第79章第140章第204章第78章第187章第155章第221章第38章第162章第135章第137章第202章第75章第130章第142章第81章第81章第195章第135章第157章第207章第103章第143章第165章第5章第89章第51章
第189章第142章第122章第57章第51章第33章第111章第11章第205章第150章第98章第62章第223章第221章第23章第55章第153章第190章第45章第219章第140章第93章第25章第51章第69章第24章第189章第20章第23章第1章第160章第6章第175章第81章第139章第178章第164章第13章第216章第65章第6章第122章第201章第194章第126章第36章第72章第32章第69章第164章第151章第120章第182章第210章第122章第59章第18章第108章第134章第16章第213章第194章第67章第18章第200章第38章第20章第216章第144章第188章第194章第75章第10章第79章第140章第204章第78章第187章第155章第221章第38章第162章第135章第137章第202章第75章第130章第142章第81章第81章第195章第135章第157章第207章第103章第143章第165章第5章第89章第51章
主站蜘蛛池模板: 周至县| 贺州市| 兖州市| 遵义市| 右玉县| 深圳市| 西藏| 郯城县| 万源市| 股票| 孝义市| 凤阳县| 大丰市| 宁安市| 卢湾区| 鹰潭市| 泰州市| 凤山市| 柘荣县| 东安县| 龙门县| 罗平县| 西峡县| 濉溪县| 保定市| 泸定县| 蛟河市| 龙陵县| 栾川县| 永春县| 霸州市| 无极县| 高州市| 旺苍县| 天长市| 定安县| 扬州市| 神农架林区| 赤壁市| 土默特左旗| 酒泉市|