第一篇:Java 面向?qū)ο?6種設(shè)計原則總結(jié)版(模版)
Java 面向?qū)ο?6種設(shè)計原則
一 類的設(shè)計原則 依賴倒置原則-Dependency Inversion Principle(DIP)2 里氏替換原則-Liskov Substitution Principle(LSP)3 接口分隔原則-Interface Segregation Principle(ISP)4 單一職責(zé)原則-Single Responsibility Principle(SRP)5 開閉原則-The Open-Closed Principle(OCP)
二 包的設(shè)計原則 重用發(fā)布等價原則-Release Reuse Equivalency Principle(REP)7 無環(huán)依賴原則-The Acyclic Dependencies Principle(ADP)8 穩(wěn)定依賴原則-The Stable Dependencies Principle(SDP)9 穩(wěn)定抽象等價原則-The Stable Abstractions Principle(SAP)10 共同封閉原則-The Common Closure Principle(CCP)11 全部重用原則-The Common Reuse Principle(CRP)
三 擴展原則
迪米特法則 -Least Knowledge Principle(LKP)13 黑盒原則- BBP(Black Box Principle)14 缺省抽象原則 -DAP(Default Abstraction Principle)15 接口設(shè)計原則 -IDP(Interface Design Principle)16 不要構(gòu)造具體的超類原則 -DCSP(Don't Concrete Supperclass Principle)
1.Dependency Inversion Principle(DIP)里氏替換原則
所有引用基類的地方必須能透明地使用其子類的對象。也就是說,只有滿足以下2個條件的OO設(shè)計才可被認為是滿足了LSP原則:
A 不應(yīng)該在代碼中出現(xiàn)if/else之類對子類類型進行判斷的條件。以下代碼就違反LSP定義。if(obj typeof Class1){ do something } else if(obj typeof Class2){ do something else } B 子類應(yīng)當(dāng)可以替換父類并出現(xiàn)在父類能夠出現(xiàn)的任何地方,或者說如果我們把代碼中使用基類的地方用它的子類所代替,代碼還能正常工作。
里氏替換原則LSP是使代碼符合開閉原則的一個重要保證。同時LSP體現(xiàn)了:
1)類的繼承原則:如果一個繼承類的對象可能會在基類出現(xiàn)地方出現(xiàn)運行錯誤,則該子類不應(yīng)該從該基類繼承,或者說,應(yīng)該重新設(shè)計它們之間的關(guān)系。
2)動作正確性保證:從另一個側(cè)面上保證了符合LSP設(shè)計原則的類的擴展不會給已有的系統(tǒng)引入新的錯誤。
類的繼承原則:
Robert C.Martin舉了Rectangle和Square的例子。這里沿用這個例子,但用Java語言對其加以重寫,并忽略了某些細節(jié)只列出下面的精要部分來說明 里氏替換原則 對類的繼承上的約束。
1.class Rectangle { 2.double width;3.double height;4.5.public double getHeight(){ 6.return height;7.} 8.public void setHeight(double height){ 9.this.height = height;10.} 11.public double getWidth(){ 12.return width;13.} 14.public void setWidth(double width){ 15.this.width = width;16.} 17.} 18.19.class Square extends Rectangle { 20.public void setHeight(double height){ 21.super.setHeight(height);22.super.setWidth(height);23.} 24.25.public void setWidth(double width){ 26.super.setHeight(width);27.super.setWidth(width);28.} 29.}
這里Rectangle是基類,Square從Rectangle繼承。這種繼承關(guān)系有什么問題嗎?
假如已有的系統(tǒng)中存在以下既有的業(yè)務(wù)邏輯代碼: void g(Rectangle r){ r.setWidth(5);r.setHeight(4);if(r.getWidth()* r.getHeight()!= 20){ throw new RuntimeException();} }
則對應(yīng)于擴展類Square,在調(diào)用既有業(yè)務(wù)邏輯時: Rectangle square = new Square();g(square);時會拋出一個RuntimeException異常。這顯然違反了LSP原則。
動作正確性保證:
因為LSP對子類的約束,所以為已存在的類做擴展構(gòu)造一個新的子類時,根據(jù)LSP的定義,不會給已有的系統(tǒng)引入新的錯誤。Design by Contract 根據(jù)Bertrand Meyer提出的Design by Contract(DBC:基于合同的設(shè)計)概念的描述,對于類的一個方法,都有一個前提條件以及一個后續(xù)條件,前提條件說明方法接受什么樣的參數(shù)數(shù)據(jù)等,只有前提條件得到滿足時,這個方法才能被調(diào)用;同時后續(xù)條件用來說明這個方法完成時的狀態(tài),如果一個方法的執(zhí)行會導(dǎo)致這個方法的后續(xù)條件不成立,那么此方法也不應(yīng)該正常返回。
現(xiàn)在把前提條件以及后續(xù)條件應(yīng)用到繼承子類中,子類方法應(yīng)該滿足: 1)前提條件不強于基類. 2)后續(xù)條件不弱于基類.
換句話說,通過基類的接口調(diào)用一個對象時,用戶只知道基類前提條件以及后續(xù)條件。因此繼承類不得要求用戶提供比基類方法要求的更強的前提條件,亦即,繼承類方法必須接受任何基類方法能接受的任何條件(參數(shù))。同樣,繼承類必須順從基類的所有后續(xù)條件,亦即,繼承類方法的行為和輸出不得違反由基類建立起來的任何約束,不能讓用戶對繼承類方法的輸出感到困惑。這樣,我們就有了基于合同的LSP,基于合同的LSP是LSP的一種強化。
在很多情況下,在設(shè)計初期我們類之間的關(guān)系不是很明確,LSP則給了我們一個判斷和設(shè)計類之間關(guān)系的基準:需不需要繼承,以及怎樣設(shè)計繼承關(guān)系。
3.Interface Segregation Principle(ISP)單一職責(zé)原則
永遠不要讓一個類存在多個改變的理由。換句話說,如果一個類需要改變,改變它的理由永遠只有一個。如果存在多個改變它的理由,就需要重新設(shè)計該類。
SRP(Single Responsibility Principle)原則的核心含意是:只能讓一個類有且僅有一個職責(zé)。這也是單一職責(zé)原則的命名含義。
為什么一個類不能有多于一個以上的職責(zé)呢?
如果一個類具有一個以上的職責(zé),那么就會有多個不同的原因引起該類變化,而這種變化將影響到該類不同職責(zé)的使用者(不同用戶):
1,一方面,如果一個職責(zé)使用了外部類庫,則使用另外一個職責(zé)的用戶卻也不得不包含這個未被使用的外部類庫。
2,另一方面,某個用戶由于某原因需要修改其中一個職責(zé),另外一個職責(zé)的用戶也將受到影響,他將不得不重新編譯和配置。這違反了設(shè)計的開閉原則,也不是我們所期望的。
職責(zé)的劃分
既然一個類不能有多個職責(zé),那么怎么劃分職責(zé)呢?
Robert.C Martin給出了一個著名的定義:所謂一個類的一個職責(zé)是指引起該類變化的一個原因。如果你能想到一個類存在多個使其改變的原因,那么這個類就存在多個職責(zé)。
Single Responsibility Principle(SRP)的原文里舉了一個Modem的例子來說明怎么樣進行職責(zé)的劃分,這里我們也沿用這個例子來說明一下:
SRP違反例: Modem.java interface Modem { public void dial(String pno);//撥號 public void hangup();//掛斷
public void send(char c);//發(fā)送數(shù)據(jù) public char recv();//接收數(shù)據(jù) } 咋一看,這是一個沒有任何問題的接口設(shè)計。但事實上,這個接口包含了2個職責(zé):第一個是連接管理(dial, hangup);另一個是數(shù)據(jù)通信(send, recv)。很多情況下,這2個職責(zé)沒有任何共通的部分,它們因為不同的理由而改變,被不同部分的程序調(diào)用。所以它違反了SRP原則。
下面的類圖將它的2個不同職責(zé)分成2個不同的接口,這樣至少可以讓客戶端應(yīng)用程序使用具有單一職責(zé)的接口:
讓ModemImplementation實現(xiàn)這兩個接口。我們注意到,ModemImplementation又組合了2個職責(zé),這不是我們希望的,但有時這又是必須的。通常由于某些原因,迫使我們不得不綁定多個職責(zé)到一個類中,但我們至少可以通過接口的分割來分離應(yīng)用程序關(guān)心的概念。事實上,這個例子一個更好的設(shè)計應(yīng)該是這樣的,如圖:
小結(jié)
Single Responsibility Principle(SRP)從職責(zé)(改變理由)的側(cè)面上為我們對類(接口)的抽象的顆粒度建立了判斷基準:在為系統(tǒng)設(shè)計類(接口)的時候應(yīng)該保證它們的單一職責(zé)性。
5.The Open-Closed Principle(OCP)對擴展開放(open)重用發(fā)布等價原則
包的內(nèi)部關(guān)系方面(聚合性)的原則,重用粒度等價于發(fā)布粒度。重用主要是從用戶的觀點來看的。對用戶來說,使用某個發(fā)布單位(組件,類,類群等),如果作者因為某種原因?qū)ζ渥髁诵薷亩l(fā)布了一個新的版本,用戶會期望在升級為新版本之后,不會影響到原系統(tǒng)的正常運作。也就是說,對于一個可重用(能供其它用戶或系統(tǒng)使用)的元素(組件,類,類群等),作者應(yīng)該承諾新版本能夠兼容舊版本。否則,用戶將拒絕使用該元素。
Robert C.Martin給出的對重用的定義:
代碼可以看作為可重用的代碼,當(dāng)且僅當(dāng):用戶只需聯(lián)結(jié)靜態(tài)庫或包含動態(tài)庫
-當(dāng)庫發(fā)生改變(錯誤糾正,功能增強)時,用戶只需要得到一個新的版本便能集成到原有的系統(tǒng)
怎么做到重用呢?
一個組件要做到能夠重用,它必須有一個得到良好設(shè)計的結(jié)構(gòu),它所包含所有元素必須也是可以重用的。
因為如果一個為重用而設(shè)計的發(fā)布單位里,包含了不可重用的元素,當(dāng)不可重用的元素發(fā)生改變時,用戶也不得不改變原有系統(tǒng)以適應(yīng)新的版本。這顯然違反了重用的定義規(guī)則。
也就是說,一個為重用目的而設(shè)計的發(fā)布單位里,不能包含不可重用的元素;如果包含了不可重用的元素,它將變得不可重用。
發(fā)布單位
當(dāng)用戶使用的重用組件被作者修改后,用戶希望得到通知,然后決定是否升級或升級的時機。為了能使升級后的系統(tǒng)也能正常運作,用戶也希望作者有一個規(guī)范的發(fā)布,包括版本號,類庫的說明等等。
一旦用戶決定升級新版本,不管這些修改是否影響到用戶,用戶也不得不包含新版本所包含的所有類庫。
REP規(guī)定重用粒度不能小于發(fā)布粒度,所有重用元素也必須被一起發(fā)布。
發(fā)布粒度可以為包(組件)或類等實體,但一個應(yīng)用往往包含了很多類,所以,具有更大的尺度的包(組件)更加適合作為發(fā)布粒度。
重用發(fā)布等價原則為我們指明了包的設(shè)計方針:一個包中的元素(類)要么都可重用,要么都不可重用。
小結(jié)
重用發(fā)布等價原則(REP)從用戶觀點的角度上為我們規(guī)范了包設(shè)計的原則:在設(shè)計包時,包中應(yīng)該包含的元素要么都可以重用,要么都不可以重用。
7.The Acyclic Dependencies Principle(ADP)穩(wěn)定依賴原則
一個設(shè)計中的包之間的依賴應(yīng)該朝著穩(wěn)定的方向進行。一個包只應(yīng)該依賴那些比自己更穩(wěn)定的包。換成另一個說法是: 朝著穩(wěn)定的方向進行依賴。包之間的關(guān)系方面(耦合性)的原則。
包的依賴
如果一個包A 中的類引用了包B中的類,我們稱包A依賴包B。
“依賴”在具體的程序語言中表現(xiàn)為,如果A依賴B,C/C++語言則在A包的文件/類中通過#include語句包含B包中的文件/類;Java語言則A包的類中通過import語句引入B包中的類。
圖1(包A依賴包B)
虛線表示一種依賴關(guān)系,箭頭表示依賴的方向,箭頭所在的一側(cè)就是被依賴的包。
包的穩(wěn)定依賴原則
包應(yīng)該依賴比自己更穩(wěn)定的包。因為如果依賴一個不穩(wěn)定的包,那么當(dāng)這個不穩(wěn)定的包發(fā)生變化時,本身穩(wěn)定的包也不得不發(fā)生變化,變得不穩(wěn)定了。
所謂穩(wěn)定,在現(xiàn)實生活中是指一個物體具有穩(wěn)固不變的屬性使它很難發(fā)生變化。應(yīng)用到軟件概念上,我們認為一個軟件是穩(wěn)定的,是因為這個軟件很難發(fā)生改變,或更確切地說,是不需要發(fā)生改變。一個設(shè)計良好,能應(yīng)對各種變化不需要修改的軟件當(dāng)然是穩(wěn)定的了,但事實上,往往一個軟件常常需要對應(yīng)某個事先沒有預(yù)測到的用戶需求而不得不發(fā)生改變,當(dāng)這種改變發(fā)生時,能把修改控制在最小的范圍之內(nèi),并能穩(wěn)定的工作(包括軟件本身以及依賴它的其它軟件實體等),我們也會認為該軟件是相對穩(wěn)定的。
怎么樣讓一個軟件足夠穩(wěn)定呢?一個確切的方法是,讓大量其它軟件的包依賴它。一個包被很多其他包依賴是非常穩(wěn)定的,這是因為被依賴的包為了協(xié)調(diào)其他包必須做很多的工作來對應(yīng)各種變化(責(zé)任的負擔(dān)者)。
圖1:穩(wěn)定的包X 我們認為X是穩(wěn)定的,因為:
X沒有依賴別的包,它是獨立的。
相反,下面列出了一個非常不穩(wěn)定的包Y,如圖:
圖2:不穩(wěn)定的包Y 我們認為Y是不穩(wěn)定的,因為:
-Y沒有被其他的包所依賴。不是責(zé)任的擔(dān)當(dāng)著。穩(wěn)定抽象等價原則
最穩(wěn)定的包應(yīng)該是最抽象的包。不穩(wěn)定的包應(yīng)該是具體的包。包的抽象程度跟它的穩(wěn)定性成正比。穩(wěn)定的包應(yīng)該是抽象的包。
包的穩(wěn)定抽象等價原則
我們在The Stable Dependencies Principle(SDP)它們是具體的包實現(xiàn)
穩(wěn)定的(不容易改變的)包處于下層共同封閉原則
一個包中所有的類應(yīng)該對同一種類型的變化關(guān)閉。一個變化影響一個包,便影響了包中所有的類。一個更簡短的說法是:一起修改的類,應(yīng)該組合在一起(同一個包里)。包的內(nèi)部關(guān)系方面(聚合性)的原則
如果必須修改應(yīng)用程序里的代碼,我們希望所有的修改都發(fā)生在一個包里(修改關(guān)閉),而不是遍布在很多包里。
CCP原則就是把因為某個同樣的原因而需要修改的所有類組合進一個包里。如果2個類從物理上或者從概念上聯(lián)系得非常緊密,它們通常一起發(fā)生改變,那么它們應(yīng)該屬于同一個包。
CCP跟開閉原則(OCP: Open Closed Principle)有著很深的淵源關(guān)系,CCP的“關(guān)閉”(closure)就是OCP所提倡的:classes should be closed for modification but open for extension.類應(yīng)該對修改關(guān)閉,對擴展開放。但我們知道,100%的“關(guān)閉”是不現(xiàn)實的,我們在設(shè)計系統(tǒng)時,只能盡量地保持對大多數(shù)可預(yù)見的修改關(guān)閉。
CCP延伸了OCP的“關(guān)閉”概念,當(dāng)因為某個原因需要修改時,把需要修改的范圍限制在一個最小范圍內(nèi)的包里。CCP原則幫助我們決定哪些類應(yīng)該被放到同一個包里。
小結(jié)
共同封閉原則(CCP)從軟件功能的角度上為我們規(guī)范了包設(shè)計的一個原則:在設(shè)計包時,相互之間緊密關(guān)聯(lián)的類應(yīng)該放在同一包里。
11.The Common Reuse Principle(CRP)Single Responsibility Principle(SRP)就一個類而言,應(yīng)該僅有一個引起它變化的原因。(職責(zé)即為“變化的原因”。)2.開放-封閉原則Liskov Substitution Principle(LSP)子類型(subclass)必須能夠替換掉它們的基類型(superclass)。
4.依賴倒置原則(IoCP)或 依賴注入原則-Dependence Inversion Principle(DIP)抽象不應(yīng)該依賴于細節(jié)。細節(jié)應(yīng)該依賴于抽象。(Hollywood原則: “Don't call us, we'll call you”.程序中所有的依賴關(guān)系都應(yīng)該終止于抽象類和接口。針對接口而非實現(xiàn)編程。
任何變量都不應(yīng)該持有一個指向具體類的指針或引用。任何類都不應(yīng)該從具體類派生。
任何方法都不應(yīng)該覆寫他的任何基類中的已經(jīng)實現(xiàn)了的方法。)5.接口隔離原則(ISP)不應(yīng)該強迫客戶依賴于它們不用的方法。接口屬于客戶,不屬于它所在的類層次結(jié)構(gòu)。(多個面向特定用戶的接口勝于一個通用接口。)
----包內(nèi)聚原則----
6.重用發(fā)布等價原則(REP)重用的粒度就是發(fā)布的粒度。7.共同封閉原則(CCP)包中的所有類對于同一類性質(zhì)的變化應(yīng)該是共同封閉的。一個變化若對一個包產(chǎn)生影響,則將對該包中的所有類產(chǎn)生影響,而對于其他的包不造成任何影響。8.共同重用原則(CRP)一個包中的所有類應(yīng)該是共同重用的。如果重用了包中的一個類,那么就要重用包中的所有類。
(相互之間沒有緊密聯(lián)系的類不應(yīng)該在同一個包中。)----包耦合原則
9.無環(huán)依賴原則(ADP)在包的依賴關(guān)系圖中不允許存在環(huán)。10.穩(wěn)定依賴原則(SDP)朝著穩(wěn)定的方向進行依賴。
應(yīng)該把封裝系統(tǒng)高層設(shè)計的軟件(比如抽象類)放進穩(wěn)定的包中,不穩(wěn)定的包中應(yīng)該只包含那些很可能會改變的軟件(比如具體類)。11.穩(wěn)定抽象原則(SAP)包的抽象程度應(yīng)該和其穩(wěn)定程度一致。
(一個穩(wěn)定的包應(yīng)該也是抽象的,一個不穩(wěn)定的包應(yīng)該是抽象的.)
----其它擴展原則----
12.BBP(Black Box Principle)黑盒原則 多用類的聚合,少用類的繼承。
13.DAP(Default Abstraction Principle)缺省抽象原則
在接口和實現(xiàn)接口的類之間引入一個抽象類,這個類實現(xiàn)了接口的大部分操作.14.IDP(Interface Design Principle)接口設(shè)計原則 規(guī)劃一個接口而不是實現(xiàn)一個接口。
15.DCSP(Don't Concrete Supperclass Principle)不要構(gòu)造具體的超類原則 避免維護具體的超類。16.迪米特法則
一個類只依賴其觸手可得的類。
第二篇:Java面向?qū)ο缶幊塘?xí)題總結(jié)
第一章
面向?qū)ο箝_發(fā)方法概述
1.面向?qū)ο蟮能浖_發(fā)有哪些優(yōu)點?
1)
把軟件系統(tǒng)看成是各種對象的集合,這更接近人類的自然思維方式。
2)
軟件需求的變動性往往是功能的變動,而功能的執(zhí)行者——對象,一般不會有多大的變化,比結(jié)構(gòu)化更穩(wěn)定。
3)
對象包括屬性和行為,對象把數(shù)據(jù)及方法的具體實現(xiàn)方式一起封裝起來,使得方法與之相關(guān)的數(shù)據(jù)不再分析,提高了每個子系統(tǒng)的相對對立性,從而提高軟件的可維護性。
4)
支持封裝,抽象,繼承和多態(tài)。提高了軟件的可重用性,可維護性和可擴展性。
2.在軟件系統(tǒng)中,為什么說一個孤立的不對外提供任何服務(wù)的對象是沒有意義的?
1)
每個對象都具有特定的功能,相對于其他對象而言,它的功能就是為其他對象提供的服務(wù)。
2)
從使用者角度出發(fā),整個軟件系統(tǒng)就是一個服務(wù)的提供者。
3)
在系統(tǒng)內(nèi)部,每個子系統(tǒng)也都是服務(wù)的提供者,它們其他子系統(tǒng)提供服務(wù)。
4)
因此說一個孤立的部隊為提供任何服務(wù)的系統(tǒng)是美歐任何意義的。
3.列舉一些現(xiàn)實生活中的例子,來說明什么是依賴關(guān)系、什么是聚集關(guān)系,以及什么是關(guān)聯(lián)關(guān)系。
1)
關(guān)聯(lián)關(guān)系:關(guān)聯(lián)是指類之間的特定對應(yīng)關(guān)系,可以分為單向關(guān)聯(lián)和雙向關(guān)聯(lián),也可以分為一對一關(guān)聯(lián)、一對多關(guān)聯(lián)以及多對多關(guān)聯(lián)。A關(guān)聯(lián)B,是指Class A與Class B之間存在特定的對應(yīng)關(guān)系。舉例如學(xué)生和老師,訂單和客戶。
2)
依賴關(guān)系:類之間的調(diào)用關(guān)系。A依賴B,Class A訪問Class B提供的服務(wù)。如Panel與Shape的關(guān)系。
3)
聚集關(guān)系:是整體與部分之間的關(guān)系
4.列舉一些顯示生活中的例子,來說明什么是封裝,什么是接口。
1)
接口:對象中所有向使用者公開的方法的聲明構(gòu)成了對象的接口。
2)
封裝:隱藏對象的屬性和實現(xiàn)細節(jié),僅僅對外公開接口。
3)
接口的優(yōu)點:a.提高系統(tǒng)之間松散耦合b.提高了系統(tǒng)的可擴展性。
4)
封裝的有點:
a.便于使用者正確、方便地理解和使用系統(tǒng),防止使用者錯誤修改系統(tǒng)的屬性。
b.有助于建立各個系統(tǒng)之間的松耦合關(guān)系,提高系統(tǒng)的獨立性。
c.提高軟件的可重用性,沒個系統(tǒng)都是一個相對獨立的整體,可以在多種環(huán)境中得到重用。
d.降低構(gòu)建大型系統(tǒng)的風(fēng)險,即使整個系統(tǒng)不成功,個別的獨立子系統(tǒng)有可能依然有價值。
5.抽象的最主要特征是什么?
抽象是指從特定角度出發(fā),從已經(jīng)存在的一些事物中抽取我們所關(guān)注的特性,形成一個新的事物的思維過程。
6.在建立對象模型時,要經(jīng)歷哪些抽象思維過程?
1)
從問題領(lǐng)域的事物到軟件模型中對象的抽象。
2)
從對象到類的抽象。
3)
從子類到父類的抽象
7.類就是程序員自定義的類型。這種說法是否正確?
不正確,類是一組具有相同屬性和行為的對象的抽象。類及類的關(guān)系構(gòu)成了對象模型的主要內(nèi)容。開發(fā)人員需要根據(jù)先識別對象,然后再進行分類(創(chuàng)建任意的數(shù)據(jù)模型)的思路來建立對象模型。
8.小王本來體重70kg,經(jīng)過減肥,體重降到45kg,試從這個問題領(lǐng)域中識別對象、類、屬性、狀態(tài)和狀態(tài)的變化。
1)
類:人。
2)
對象:小王。
3)
屬性:體重。
4)
狀態(tài):70kg。
5)
狀態(tài)的變化:小王的減肥行為導(dǎo)致體重下降。
9.在UML圖中哪些框圖描述了系統(tǒng)的動態(tài)結(jié)構(gòu),哪些框圖描述了系統(tǒng)的靜態(tài)結(jié)構(gòu)?
1)
用例圖、類框圖、組件圖、部署圖構(gòu)成了系統(tǒng)的靜態(tài)模型。
2)
狀態(tài)轉(zhuǎn)換圖、時序圖、協(xié)作圖則構(gòu)成了系統(tǒng)的動態(tài)模型。
第二章
第一個Java應(yīng)用
1.把一個類放在包里有什么用?
答:把類分包的作用:
(1)
能夠區(qū)分名字相同的類
(2)
有助于實施訪問權(quán)限控制
(3)
有助于劃分和組織Java應(yīng)用中的各個類
2.JavaDoc文檔是不是為軟件的終端用戶提供的使用指南?
答:不是的,JavaDoc文檔是供Java開發(fā)人員閱讀的,他們通過JavaDoc文檔來了解其他開發(fā)人員開發(fā)的類的用法。Java開發(fā)人員應(yīng)該養(yǎng)成經(jīng)常閱讀JavaDoc文檔的良好習(xí)慣。
3.對于com.abc.dollapp.AppMain類,使用以下命令進行編譯,編譯出來的.class文件位于什么目錄下?
java –d C:classes –sourcepath C:src C:srccomabcdollappAppMain.java
答:將會存放在C:classescomabcdollapp下。
4.對于以上編譯出來的AppMain類,以下哪個java命令能正確運行它?
(a)
java C:classescomabcdollappAppMain.class
(b)
java –classpath C:classes AppMain
(c)
java –classpath C:classescomabcdollapp AppMain
(d)
java –classpath C:classes com.abc.dollapp.AppMain
答:(b)
5.以下哪些main()方法的聲明能夠作為程序的入口方法?
(a)
public static void main()
(b)
public static void main(String[] string)
(c)
public static void main(String args)
(d)
static public int main(String[] args)
(e)
static void main(String[] args)
答:(b),主函數(shù)必須以public static void形式存在,參數(shù)必須為String數(shù)組形式。
6.假定以下程序代碼都分別放在MyClass.java文件中,哪些程序代碼能夠編譯通過?
(a)
import java.awt.*;package Mypackage;
class MyClass{};
(b)
package MyPackage;
import java.awt.*;
class MyClass{};
(c)
/*This is comment*/
package MyPackage;
import java.awt.*;
public class MyClass{};
答:(c),程序順序必須按照import, package, class走,源文件必須以public類型的類命名。
7.對于以下Myprog類,運行命令”java Myprog good morning”,將會得到打印結(jié)果?
public class Myprog {
public static void main(String argv[])
{
System.out.println(argv[2]);
} }
答:打印結(jié)果為空。argv[0] = “good”, argv[1] = “morning”。
8.下面哪些是Java的關(guān)鍵字?
(a)
default
(b)
NULL
(c)
String
(d)
throws
(e)
long
(f)
true
答:(a),(d),(e),(f),java中所有的關(guān)鍵字都是小寫。
9.當(dāng)AppMain類的main()方法創(chuàng)建了5個Doll對象時,運行時數(shù)據(jù)區(qū)的數(shù)據(jù)如何分布的?參考2.4節(jié)的圖2-13,畫出此時運行時數(shù)據(jù)區(qū)的狀態(tài)圖。
運行時數(shù)據(jù)區(qū)(內(nèi)存)
Java棧區(qū)
執(zhí)行main()方法的主線程的方法調(diào)用棧
局部變量beibei
局部變量jingjing
局部變量huanhuan
局部變量yingying
局部變量nini
堆區(qū)
Doll實例
name:貝貝
Doll實例
name:晶晶
Doll實例
name:歡歡
Doll實例
name:迎迎
Doll實例
name:妮妮
方法區(qū)
Doll類型信息
AppMain類型信息
(包含main()方法信息)
10.下面哪些是合法的Java標(biāo)識符?
(a)
#_pound
(b)
_underscore
(c)
5Interstate
(d)
Interstate5
(e)
_5_
(f)
class
答:(b),(d),(e)標(biāo)識符命名規(guī)則如下:
(1)
標(biāo)識符首字母必須為字母、下劃線“_”、美元“$”、人民幣“¥”(2)
標(biāo)識符由數(shù)字、大寫字母、小寫字母、下劃線以及美元等組成
(3)
不能把關(guān)鍵字和保留字作為標(biāo)識符
(4)
標(biāo)識符沒有長度的限制
(5)
標(biāo)識符是大小寫敏感的第三章
數(shù)據(jù)類型和變量
1.對于以下程序,運行“java Abs”,將得到什么打印結(jié)果?
public class Abs
{
static int a = 0x11;
//十六進制
static int b = 0011;
//八進制
static int c = 'u0011';
//十六進制數(shù)據(jù)的Unicode字符編碼
static int d = 011;
//八進制
/**
* @param args
*/
public static void main(String[] args)
{
System.out.println(“a=”+a);
System.out.println(“b=”+b);
System.out.println(“c=”+c);
System.out.println(“d=”+d);
} }
答:輸出如下
a=17 b=9 c=17 d=9
2.以下哪段代碼能正確編譯通過?
(a)
char a = ?a?;
char b = 1;
char c = 08;
(b)
int a = ?a?;
(c)
long a =?u00FF?;
(d)
char a = ?u0FF?;
(e)
char d = “d”;
答:(b)、(c)能通過編譯。(a)中“char c=08”將int賦值給char需要部分強制轉(zhuǎn)換,“char c=8”就正確;(d)中unicode編碼錯誤,java采用的是UCS-2編碼,共16位;(e)字符賦值是使用單引號,字符串String賦值時才使用雙引號。
3.下面哪些代碼能編譯通過?
(a)
short myshort=99S;
(b)
String name = ?Excellent tutorial Mr Green?;(c)
char c = 17c;
(d)
int z = 015;
答:(d)可以編譯通過。(a)中char賦值給short需要強制轉(zhuǎn)換;(b)中String類型賦值用雙引號;(c)中int賦值給char需要部分強制轉(zhuǎn)換。
4.字符“A”的Unicode字符編碼為65.下面哪些代碼正確定義了一個代表字符“A”的變量?
(a)
Char ch=65;
(b)
Char ch=?65?;
(c)
Char ch =?u0041?;
(d)
Char ch=?A?;
(e)
Char ch =”A”
答:(c)、(d)可以得到”A”。(b)的輸出為5,其他無法編譯通過。
5.以下代碼共創(chuàng)建了幾個對象?
String s1=new String(“hello”);
String s2=new String(“hello”);
String s3=s1;
String s4=s2;
答:共創(chuàng)建了2個對象。棧區(qū)4個局部變量分別引用了堆區(qū)的2個實例,而2個實例又引用了工作區(qū)的同一個類。
6.以下代碼能否編譯通過?假如能編譯通過,運行時將得到什么打印結(jié)果?
class Test {
static int myArg = 1;
public static void main(String[] args)
{
Int myArg;
System.out.println(myArg);
} }
答:無法編譯通過,因為局部變量myArg聲明之后Java虛擬機就不會自動給它初始化為默認值,若在使用前未被初始化,編譯會報錯。
7.對于以下程序,運行“java Mystery Mighty Mouse”,將得到什么打印結(jié)果?
public class Mystery
{
public static void main(String[] args)
{
Changer c = new Changer();
c.method(args);
System.out.println(args[0]+“ ”+args[1]);
}
static class Changer
{
void method(String[] s)
{
String temp = s[0];
s[0] = s[1];
s[1] = temp;
}
} }
答:打印結(jié)果為“Mighty Mystery”
8.對于以下程序,運行“java Pass”,將得到什么打印結(jié)果?
public class Pass
{
static int j = 20;
public static void main(String[] args)
{
int i=10;
Pass p = new Pass();
p.amethod(i);
System.out.println(“i=”+i);
System.out.println(“j=”+j);
}
public void amethod(int x)
{
x*=2;
j*=2;
} }
答:打印結(jié)果是
i=10 j=40
其中“int x”是傳參,作用域僅在amethod之中。
第四章 操作符
1.以下哪些程序代碼能夠編譯通過?
(a)
int i=0;if(i){
System.out.println(“hello”);}
(b)
boolean b1=true;
boolean b2=true;
if(b1==b2){
System.out.println(“So true”);}
(c)
int i=1;
int j=2;
if(i==1||j==i){
System.out.println(“ok”);}
(d)
int i=1;
int j=2;
if(i==1&|j==i){
System.out.println(“ok”);}
答:(b)、(c)能編譯通過。(a)中int不能作為boolean出現(xiàn),(d)中不能出現(xiàn)&|該操作符。
2.運行以下程序,將得到什么打印結(jié)果?
System.out.println(-1>>>1);
System.out.println(-1>>1);
System.out.println(2>>1);
System.out.println(1<<<1);
答:>>>是邏輯右移位操作符,也稱不帶符號右移位操作符,在移位的過程中二進制數(shù)開頭填0;>>是右移位操作符,也稱帶符號右移位操作符,舍棄末尾,在開頭填符號位;<<<操作符不存在;
11111111 11111111 11111111 11111111
-1>>>1
01111111 11111111 11111111 11111111
11111111 11111111 11111111 11111111
-1>>1
11111111 11111111 11111111 11111111
00000000 00000000 00000000 00000010
2>>1
00000000 00000000 00000000 00000001
2147483647-1 1
3.以下temp變量最終取值是什么?
long temp =(int)3.9;
temp %= 2;
答:取值為1。
4.以下代碼能否編譯通過?假如能編譯通過,運行時將得到什么打印結(jié)果?
if(5 & 7 > 0 && 5 | 2)System.out.println(“true”);
答:int型不能作為boolean型出現(xiàn)。
5.以下代碼能否編譯通過?假如編譯通過,運行時將得到什么打印結(jié)果?
int output=10;
boolean b1 = false;
if((b1==true)&&((output+=10)==20)){
System.out.println(“We are equal”+output);} else {
System.out.println(“Not equal!”+output);}
答:Not equal!10
6.以下代碼能否編譯通過?假如能編譯通過,運行時將得到什么打印結(jié)果?
int output=10;
boolean b1 = false;
if((b1==true)&((output+=10)==20)){
System.out.println(“We are equal”+output);} else {
System.out.println(“Not equal!”+output);}
答:Not equal!20
7.對于以下聲明:
String s1=new String(“Hello”);
String s2=new String(“there”);
String s3=new String();
下面哪些是合法的操作?
(a)
s3=s1+s2;
(b)
s3=s1-s2;
(c)
s3=s1&s2;
(d)
s3=s1&&s2;
答:(a)是合法操作。除了“+”能用于字符串的連接以外,其他操作符(如“-”、“&”、“&&”等)都不支持String類型的操作元。
第五章
流程控制
1.運行以下代碼,將得到什么打印結(jié)果?
int i = 3;
int j = 0;
double k = 3.2;
if(i < k)
if(i == j)
System.out.println(i);
else
System.out.println(j);
else
System.out.println(k);
答:0
2.以下代碼能否編譯通過?假如能編譯通過,運行時將得到什么打印結(jié)果?
int i = 4;
switch(i){
default:
System.out.println(“default”);
case 0:
System.out.println(“zero”);
break;
case 1:
System.out.println(“one”);
case 2:
System.out.println(“two”);}
答:可以編譯通過,打印結(jié)果是:
default
zero
分析:default可以放在任何位置上,一旦符合一個case即從頭執(zhí)行到尾,不再判斷case。
3.以下哪些是合法的
(a)
int i;for(i=5, int j=10;i<10;j--){}
(b)
int i,j;for(i=0, j=10;i<10, j>0;i++, j--){}
(c)
int i,k;for(i=0, k=9;(i<10 && k>0);i++, k--){}
(d)
int i,j;for(i=0;j=10;i<10;i++,j--){} 答:(a)for語句中int定義要放在開頭。編譯不通過。
(b)循環(huán)判斷語句不可以用逗號連接。編譯不通過。
(c)合法。
(d)分號只能有2個。
4.運行以下代碼,將得到什么打印結(jié)果?
int i = 1;
switch(i){
default:
System.out.println(“default”);
case 0:
System.out.println(“zero”);
break;
case 1:
System.out.println(“one”);
case 2:
System.out.println(“two”);}
答:分析同1,運行結(jié)果如下:
one
two
5.以下哪些代碼合法?
(a)
float x=1;
switch(x){
case 1;
System.out.println(“Got a 1”);
}
(b)
long x=1;
switch(x){
case 1;
System.out.println(“Got a 1”);
}
(c)
byte x=1;
switch(x){
case 1/1;
System.out.println(“Got a 1”);
}
(d)
int x=1;
int c=1;
switch(c){
case x;
System.out.println(“Got a 1”);}
(e)
short x=1;
switch(x){
case 3.2/2;
System.out.println(“Got a 1”);
}
(f)
short x=1;
switch(x){
case 1,2,3;
System.out.println(“Got a 1”);
}
答:只有(c)是合法的。
6.以下代碼能否編譯通過?假如能編譯通過,運行時將得到什么打印結(jié)果?
for(int a=0, b=0;a<2;b=++a, System.out.println(“b=”+b)){
System.out.println(“a=”+a);}
答:可以通過編譯,打印結(jié)果:
a=0 b=1 a=1 b=2
7.以下代碼能否編譯通過?假如能編譯通過,運行時將得到什么打印結(jié)果?
int x=0;one:
while(x<10)
{
two:
System.out.println(++x);
if(x>3)
break two;
}
答:不能通過編譯。
第三篇:java面向?qū)ο蟮膶W(xué)習(xí)心得
Java面向?qū)ο蟮膶W(xué)習(xí)心得
大三的時候?qū)W校組織我們?nèi)ヌK州NIIT參加四個月的java實訓(xùn),我開始系統(tǒng)的學(xué)習(xí)期java,之前大學(xué)的時候?qū)W的比較寬泛,沒有專門的正對java的學(xué)習(xí)。
首先我是從學(xué)習(xí)Java編程開始接觸OOP(面向?qū)ο缶幊?,剛開始使用Java編寫程序的時候感覺很別扭,因為我早以習(xí)慣用C來編寫程序,很欣賞C的簡潔性和高效性,喜歡C簡練而表達能力豐富的風(fēng)格,特別忍受不了Java運行起來慢吞吞的速度,相對冗長的代碼,而且一個很簡單的事情,要寫好多類,一個類調(diào)用一個類,心里的抵觸情緒很強。
我對Java的面向?qū)ο蟮奶匦宰聊チ季?,自認為有所領(lǐng)悟,也開始有意識的運用OOP風(fēng)格來寫程序,然而還是經(jīng)常會覺得不知道應(yīng)該怎樣提煉類,面對一個具體的問題的時候,會覺得腦子里千頭萬緒的,不知道怎么下手,一不小心,又會回到原來的思路上去。
舉個例子,要發(fā)廣告郵件,廣告郵件列表存在數(shù)據(jù)庫里面。倘若用C來寫的話,一般會這樣思考,先把郵件內(nèi)容讀入,然后連接數(shù)據(jù)庫,循環(huán)取郵件地址,調(diào)用本機的qmail的sendmail命令發(fā)送。
然后考慮用Java來實現(xiàn),既然是OOP,就不能什么代碼都塞到main過程里面,于是就設(shè)計了三個類:
一個類是負責(zé)讀取數(shù)據(jù)庫,取郵件地址,調(diào)用qmail的sendmail命令發(fā)送; 一個類是讀郵件內(nèi)容,MIME編碼成HTML格式的,再加上郵件頭;
一個主類負責(zé)從命令讀參數(shù),處理命令行參數(shù),調(diào)用發(fā)email的類。
把一件工作按照功能劃分為3個模塊分別處理,每個類完成一件模塊任務(wù)。
仔細的分析一下,就會發(fā)現(xiàn)這樣的設(shè)計完全是從程序員實現(xiàn)程序功能的角度來設(shè)計的,或者說,設(shè)計類的時候,是自低向上的,從機器的角度到現(xiàn)實世界的角度來分析問題的。因此在設(shè)計的時候,就已經(jīng)把程序編程實現(xiàn)的細節(jié)都考慮進去了,企圖從底層實現(xiàn)程序這樣的出發(fā)點來達到滿足現(xiàn)實世界的軟件需求的目標(biāo)。
這樣的分析方法其實是不適用于Java這樣面向?qū)ο蟮木幊陶Z言,因為,如果改用C語言,封裝兩個C函數(shù),都會比Java實現(xiàn)起來輕松的多,邏輯上也清楚的多。
我覺得面向?qū)ο蟮木柙谟诳紤]問題的思路是從現(xiàn)實世界的人類思維習(xí)慣出發(fā)的,只要領(lǐng)會了這一點,就領(lǐng)會了面向?qū)ο蟮乃季S方法。
舉一個非常簡單的例子:假使現(xiàn)在需要寫一個網(wǎng)頁計數(shù)器,客戶訪問一次頁面,網(wǎng)頁計數(shù)器加1,計數(shù)器是這樣來訪問的后臺有一個數(shù)據(jù)庫表,保存每個id(一個id對應(yīng)一個被統(tǒng)計訪問次數(shù)的頁面)的計數(shù)器當(dāng)前值,請求頁面一次,對應(yīng)id的計數(shù)器的字段加1(這里我們忽略并發(fā)更新數(shù)據(jù)庫
表,出現(xiàn)的表鎖定的問題)。
如果按照一般從程序?qū)崿F(xiàn)的角度來分析,我們會這樣考慮:首先是從HTTP GET請求取到id,然后按照id查數(shù)據(jù)庫表,獲得某id對應(yīng)的訪問計數(shù)值,然后加1,更新數(shù)據(jù)庫,最后向頁面顯示訪問計數(shù)。
現(xiàn)在假設(shè)一個沒有程序設(shè)計經(jīng)驗的人,他會怎樣來思考這個問題的呢?他會提出什么樣的需求呢?他很可能會這樣想:
我需要有一個計數(shù)器,這個計數(shù)器應(yīng)該有這樣的功能,刷新一次頁面,訪問量就會加1,另外最好還有一個計數(shù)器清0的功能,當(dāng)然計數(shù)器如果有一個可以設(shè)為任意值的功能的話,我就可以作弊了。
做為一個沒有程序設(shè)計經(jīng)驗的人來說,他完全不會想到對數(shù)據(jù)庫應(yīng)該如何操作,對于HTTP變量該如何傳遞,他考慮問題的角度就是我有什么需求,我的業(yè)務(wù)邏輯是什么,軟件應(yīng)該有什么功能。
按照這樣的思路(請注意,他的思路其實就是我們平時在生活中習(xí)慣的思維方式),我們知道需要有一個計數(shù)器類 Counter,有一個必須的和兩個可選的方法:
getCount()// 取計數(shù)器值方法
resetCounter()// 計數(shù)器清0方法
setCount()// 設(shè)計數(shù)器為相應(yīng)的值方法
把Counter類完整的定義如下:
public class Counter {
public int getCount(int id){}
public void resetCounter(int id){}
public void setCount(int id, int currentCount){}
}
解決問題的框架已經(jīng)有了,來看一下如何使用Counter。在count.cgi里面調(diào)用Counter來計數(shù),程序片斷如下:
// 這里從HTTP環(huán)境里面取id值
...Counter myCounter = new Counter();// 獲得計數(shù)器
int currentCount = myCounter.getCount(id);// 從計數(shù)器中取計數(shù)
// 這里向客戶瀏覽器輸出
...程序的框架全都寫好了,剩下的就是實現(xiàn)Counter類方法里面具體的代碼了,此時才去考慮具體的程序語言實現(xiàn)的細節(jié),比如,在getCount()方法里面訪問數(shù)據(jù)庫,更新計數(shù)
值。
從上面的例子中看到,面向?qū)ο蟮乃季S方法其實就是我們在現(xiàn)實生活中習(xí)慣的思維方式,是從人類考慮問題的角度出發(fā),把人類解決問題的思維方式逐步翻譯成程序能夠理解的思維方式的過程,在這個翻譯的過程中,軟件也就逐步被設(shè)計好了。
在運用面向?qū)ο蟮乃季S方法進行軟件設(shè)計的過程中,最容易犯的錯誤就是開始分析的時候,就想到了程序代碼實現(xiàn)的細節(jié),因此封裝的類完全是基于程序?qū)崿F(xiàn)邏輯,而不是基于解決問題的業(yè)務(wù)邏輯。
學(xué)習(xí)JDBC編程的經(jīng)典錯誤問法是:“我怎樣封裝對數(shù)據(jù)庫的select操作?”
面向?qū)ο蟮脑O(shè)計是基于解決業(yè)務(wù)問題的設(shè)計,而不是基于具體編程技術(shù)的設(shè)計。我不會去封裝select語句的,我只封裝解決問題的業(yè)務(wù)邏輯,對數(shù)據(jù)庫的讀取是在業(yè)務(wù)邏輯的編碼實現(xiàn)階段才去考慮的問題。
回過頭看上面那個發(fā)廣告郵件的例子,應(yīng)該如何應(yīng)用面向?qū)ο蟮乃季S方法呢?
對于一個郵件來說,有郵件頭,郵件體,和郵件地址這三個屬性,發(fā)送郵件,需要一個發(fā)送的方法,另外還需要一個能把所有郵件地址列出來的方法。所以應(yīng)該如下設(shè)計:
類JunkMail
屬性:
head
body
address
方法:
sendMail()// 發(fā)送郵件
listAllMail()// 列郵件地址
用Java來表示:
public class JunkMail {
private String head;
private String body;
private String address;
public JunkMain(){ // 默認的類構(gòu)造器
// 從外部配置文件讀郵件頭和郵件體
this.head=...;
this.body=...;
}
public static boolean sendMail(String address){
// 調(diào)用qmail,發(fā)送email
}
public static Collection listAllMail(){
// 訪問數(shù)據(jù)庫,返回一個郵件地址集合}
}
當(dāng)把JunkMail設(shè)計好了以后,再調(diào)用JunkMail類完成郵件的發(fā)送,將是非常輕松的事情。
如果說傳統(tǒng)的面向過程的編程是符合機器運行指令的流程的話,那么面向?qū)ο蟮乃季S方法就是符合現(xiàn)實生活中人類解決問題的思維過程。
在面向?qū)ο蟮能浖治龊驮O(shè)計的時候,要提醒自己,不要一上來就去想程序代碼的實現(xiàn),應(yīng)該拋開具體編程語言的束縛,集中精力分析我們要實現(xiàn)的軟件的業(yè)務(wù)邏輯,分析軟件的業(yè)務(wù)流程,思考應(yīng)該如何去描述和實現(xiàn)軟件的業(yè)務(wù)。畢竟軟件只是一個載體,業(yè)務(wù)才是我們真正要實現(xiàn)的目標(biāo)。
但是在設(shè)計過程中,心里卻往往在擔(dān)心,如果我完全不去考慮程序代碼的實現(xiàn)的話,那么我怎么知道我的設(shè)計一定合理呢?我怎么知道我設(shè)計的類、接口一定可以實現(xiàn)呢?所以經(jīng)??梢钥吹降默F(xiàn)象就是:
在設(shè)計過程中,雖然知道不能過早考慮代碼實現(xiàn),但是每設(shè)計一個類,一個接口,心里都要不知不覺的用自己熟悉的編程語言大概的評估一下,看看能否編出來,因此,一不小心,就會又回到按照程序功能實現(xiàn)的思路進行設(shè)計的老路上去了。
舉個例子來說明,在做Web程序設(shè)計的時候,經(jīng)常要遇到分頁顯示數(shù)據(jù)的情況。比如說需要把系統(tǒng)中所有的用戶都列出來這樣的功能。假設(shè)使用User類來表示用戶,增加用戶addUser(),刪除用戶deleteUser(),查詢所有用戶listUsers()方法。而數(shù)據(jù)庫中有一個user表,一條記錄是一個用戶的信息。下面考慮一下User類的方法的實現(xiàn):
addUser()和deleteUser()方法都好實現(xiàn),就是對數(shù)據(jù)庫增加記錄和刪除記錄。對于listUsers()方法,其實就是對user表的select,取出一個記錄集。但是該怎么從listUsers()方法中得到所有用戶的列表呢?
一個方法調(diào)用的返回值只有一個,沒有多個,所以很多情況下采用的辦法就是返回值定義為集合類型,比如Vector。這樣就可以在listUsers()方法的具體代碼實現(xiàn)的時候,從數(shù)據(jù)庫依次取出一個個記錄,插入到Vector里面來。在主程序里面,調(diào)用listUsers()方法可以返回一個Vector,然后再對Vector遍歷操作,就可以得到用戶列表了。
public class User {
public static void addUser(...){
// 數(shù)據(jù)庫insert一條記錄
}
public static void deleteUser(...){
// 數(shù)據(jù)庫delete一條記錄
}
public Vector listUsers(...){
// 數(shù)據(jù)庫select結(jié)果放到一個集合里面
}
}
這樣的設(shè)計基本合理,但是仍然有點小問題。因為在設(shè)計的時候,就考慮到了用Java的集合類Vector來實現(xiàn)對不定長數(shù)據(jù)集的存放,因而違反了面向?qū)ο笤O(shè)計的一個原則:在設(shè)計的時候不應(yīng)過早的考慮具體程序語言的實現(xiàn)。所以必須用抽象的方法,和具體實現(xiàn)無關(guān)的方法來表達業(yè)務(wù)邏輯。
我們知道,通常對具有集合特征的數(shù)據(jù)結(jié)構(gòu)進行遍歷通常可以使用next和hasNext方法,next實現(xiàn)取下一個用戶,hasNext判斷是否還有元素。因此我們定義一個接口Iterator,這個接口中定義兩個方法next和hasNext:
public interface Iterator {
public boolean hasNext(){}
public Object next(){}
}
而User類的listUses方法返回值改為Iterator接口的實現(xiàn)類:
public class User {
...public Iterator listUsers(){
}
...}
這樣就把User類的設(shè)計和具體的實現(xiàn)方法分離開了,因為此時任何實現(xiàn)了next()和hasNext()方法的類都可以做為listUsers的返回值,都可以被用來表達“用戶列表”,而不僅僅可以使用Vector而已。比如,我可以用ArrayList來表達用戶列表,因為ArrayList也實現(xiàn)了Iterator,當(dāng)然我也可以自己專門寫一個類來存放用戶列表,只要實現(xiàn)next()和hasNext()方法就行了。
這樣在具體的編寫代碼的時候,程序員具有了最大的靈活性,可以根據(jù)具體的情況,采用不同的編程方法來存放用戶列表。特別是降低了程序的耦合度,提高了程序的可移植性。對于上面那個JunkMail的listAllMail()方法也同樣應(yīng)該改為接口類型。
然后,在主程序里面就這樣來使用User類的listUsers方法:
User myUser = new User();
Iterator iterator = myUser.listUsers();
while(iterator.hasNext()){
iterator.next();
}
這樣就可以完全不用考慮程序代碼實現(xiàn)了,從高層次上把功能抽象出來,定義成為接口,同時又可以把系統(tǒng)設(shè)計的很合理,完全根據(jù)業(yè)務(wù)的需求來進行設(shè)計。
結(jié)語
通過上面的幾個例子的設(shè)計說明,使用面向?qū)ο蟮乃季S方法,其實是一個把業(yè)務(wù)邏輯從具體的編程技術(shù)當(dāng)中抽象出來的過程,而這個抽象的過程是自上而下的,非常符合人類的思維習(xí)慣,也就是先不考慮問題解決的細節(jié),把問題的最主要的方面抽象成為一個簡單的框架,集中精力思考如何解決主要矛盾,然后在解決問題的過程中,再把問題的細節(jié)分割成一個一個小問題,再專門去解決細節(jié)問題。
因而一旦牢牢的抓住了這一點,你就會發(fā)現(xiàn)在軟件設(shè)計和開發(fā)過程中,你自己總是會不知不覺的運用面向?qū)ο蟮乃季S方法來設(shè)計和編寫程序,并且程序的設(shè)計和開發(fā)也變得不再那么枯燥,而一個合理運用面向?qū)ο蠹夹g(shù)進行設(shè)計和架構(gòu)的軟件,更是具備了思維的藝術(shù)美感。
最后,愿面向?qū)ο蟮乃季S方法也能給您的程序設(shè)計之路帶來創(chuàng)作的樂趣。
第四篇:java面向?qū)ο蟪绦蛟O(shè)計教案
武漢大學(xué)珞珈學(xué)院 系/教研室 Java 面 向 對 象 程 序 設(shè) 計 課 教 案
主講教師:熊春秀 編寫時間:2011-4-30
第一章:概述
第 1、2 節(jié):面向?qū)ο蟮幕靖拍睢⒚嫦驅(qū)ο蟪绦蛟O(shè)計概述 授課時間:2011-2-
22、23
計劃學(xué)時數(shù):1 教學(xué)任務(wù)與目的:讓學(xué)生理解面向?qū)ο蟮幕靖拍?教學(xué)重點:掌握面向?qū)ο蟮幕靖拍?教學(xué)難點:理解面向?qū)ο蟪绦蛟O(shè)計的方法 教學(xué)方法:多媒體+板書 參考書目:《面向?qū)ο蟪绦蛟O(shè)計導(dǎo)論》,[美]C.Thomas wu著,電子工業(yè)出版社 專業(yè)詞匯:Java虛擬機、Applet程序 備注
第二章:Java特點及運行環(huán)境
第 1、2、3 節(jié):Java語言特點、Java應(yīng)用程序及運行環(huán)境、Java Applet程序及運行環(huán)境 授課時間:2011-2-
22、23
計劃學(xué)時數(shù):3 教學(xué)任務(wù)與目的:讓學(xué)生學(xué)會JDK的下載、安裝與環(huán)境配置。教學(xué)重點:掌握編譯和執(zhí)行Java程序的基本步驟
教學(xué)難點:理解Java程序的入口并能夠通過命令行傳遞參數(shù) 教學(xué)方法:多媒體+板書 參考書目:《面向?qū)ο蟪绦蛟O(shè)計導(dǎo)論》,[美]C.Thomas wu著,電子工業(yè)出版社 專業(yè)詞匯:JDK、lib、bin 備注 第三章:Java語言基礎(chǔ)
第 1、2 節(jié):Java程序的構(gòu)成、數(shù)據(jù)類型、表達式以及流程控制語句 授課時間:2011-3-
1、2
計劃學(xué)時數(shù):3 教學(xué)任務(wù)與目的:讓學(xué)生學(xué)會Java基本的數(shù)據(jù)類型和表示方法、數(shù)值類型的運算、邏輯運算和比較、條件執(zhí)行語句(包括三種條件語句和switch語句)、循環(huán)控制語句(包括for、while、do while循環(huán)及相應(yīng)的輔助語句)、字符串類String和BufferString以及數(shù)組的聲明及使用。
教學(xué)重點:掌握Java基本的數(shù)據(jù)類型和表示方法
教學(xué)難點:理解Java程序的循環(huán)控制語句(包括for、while、do while循環(huán)及相應(yīng)的輔助語句)
教學(xué)方法:多媒體+板書 參考書目:《Java語言與面向?qū)ο蟪绦蛟O(shè)計》,印旻編著,清華大學(xué)出版社 專業(yè)詞匯:變量、數(shù)據(jù)類型、循環(huán)控制語句 備注 第三章:Java語言基礎(chǔ) 第 3 節(jié):Java與C比較
授課時間:2011-3-
8、9
計劃學(xué)時數(shù):3 教學(xué)任務(wù)與目的:讓學(xué)生在C語言的基本上進一步學(xué)習(xí)Java語言。教學(xué)重點:掌握Java語言與C語言的區(qū)別與聯(lián)系。教學(xué)難點:理解Java語言在C語言上的改進。教學(xué)方法:多媒體+板書 參考書目:《Java2參考大全(第四版)》,[美]Herbert Schildt著,張玉清、吳浦峰、尚勇等譯,清華大學(xué)出版社。專業(yè)詞匯:Java、C 備注 第四章:抽象、封裝與類
第 1 節(jié):抽象、封裝與Java類的概念
授課時間:2011-3-
15、16
計劃學(xué)時數(shù):3 教學(xué)任務(wù)與目的:讓學(xué)生學(xué)會面向?qū)ο蟮幕咎卣?、掌握如何定義一個類以及如何生成對象、深入掌握方法的定義及技巧、深入掌握類的訪問權(quán)限與封裝機制、深入掌握包的定義與包的使用方法。
教學(xué)重點:掌握類的定義與對象的生成。教學(xué)難點:理解類的抽象與封裝機制。教學(xué)方法:多媒體+板書 參考書目:《Java2 實用教程》,耿祥義、張躍平編著,清華大學(xué)出版社。專業(yè)詞匯:抽象、封裝、類 備注 第四章:抽象、封裝與類 第 2 節(jié):系統(tǒng)定義的類
授課時間:2011-3-
22、23
計劃學(xué)時數(shù):3 教學(xué)任務(wù)與目的:讓學(xué)生學(xué)會使用系統(tǒng)定義的類,并掌握與用戶自定義類的區(qū)別。教學(xué)重點:掌握如何定義所需要的類。
教學(xué)難點:熟悉Java平臺定義了哪些經(jīng)常要用到、而且滿足我們需要的類。教學(xué)方法:多媒體+板書 參考書目:《Java2 實用教程》,耿祥義、張躍平編著,清華大學(xué)出版社。專業(yè)詞匯:系統(tǒng)定義的類、用戶自定義類 備注 第四章:抽象、封裝與類
第 3 節(jié):類、域和方法的修飾符
授課時間:2011-3-
29、30
計劃學(xué)時數(shù):3 教學(xué)任務(wù)與目的:讓學(xué)生學(xué)會類的聲明。
教學(xué)重點:掌握如何定義類的修飾和方法的修飾符。教學(xué)難點:熟悉類的變量的定義與使用方法。教學(xué)方法:多媒體+板書 參考書目:《Java2 實用教程》,耿祥義、張躍平編著,清華大學(xué)出版社。專業(yè)詞匯:成員變量、類變量、成員方法、類方法 備注 第五章:繼承與多態(tài)
第 1、2 節(jié):Java的繼承與派生、域的繼承與隱藏 授課時間:2011-4-
5、6
計劃學(xué)時數(shù):3 教學(xué)任務(wù)與目的:讓學(xué)生全面掌握面向?qū)ο蟮幕咎卣?、掌握如何使用繼承性來到達軟件的重用、深入掌握繼承過程中域的隱藏和方法的覆蓋技巧。教學(xué)重點:掌握如何使用繼承性來到達軟件的重用。教學(xué)難點:熟悉繼承過程中域的隱藏和方法的覆蓋技巧。教學(xué)方法:多媒體+板書 參考書目:《Java2 實用教程》,耿祥義、張躍平編著,清華大學(xué)出版社。專業(yè)詞匯:繼承派生、域、隱藏 備注 第五章:繼承與多態(tài)
第 3、4 節(jié):方法的繼承、重載與覆蓋、this與super、構(gòu)造函數(shù)的繼承與重載 授課時間:2011-4-
12、13
計劃學(xué)時數(shù):3 教學(xué)任務(wù)與目的:讓學(xué)生通過繼承可以更有效地組織程序結(jié)構(gòu),明確類之間的關(guān)系,并充分利用已有的類來創(chuàng)建新類,通過繼承可以實現(xiàn)代碼的重用,以完成更復(fù)雜的設(shè)計、開發(fā)。教學(xué)重點:掌握類的重載與覆蓋的區(qū)別與聯(lián)系。教學(xué)難點:熟悉類的重載與覆蓋使用方法。教學(xué)方法:多媒體+板書 參考書目:《Java語言與面向?qū)ο蟪绦蛟O(shè)計》,印旻編著,清華大學(xué)出版社。專業(yè)詞匯:繼承、重載、覆蓋、this、super 備注 第五章:繼承與多態(tài)
第 5、6 節(jié):多態(tài)性的實現(xiàn)、接口聲明與實現(xiàn) 授課時間:2011-4-
19、20
計劃學(xué)時數(shù):3 教學(xué)任務(wù)與目的:讓學(xué)生深入掌握抽象類和抽象方法的定義,掌握多態(tài)通過統(tǒng)一多個相關(guān)類的對外接口,在運行時根據(jù)不同的情況執(zhí)行不同的操作,提高類的抽象度和靈活性,深入掌握接口的定義和使用技巧。
教學(xué)重點:熟悉多態(tài)性實現(xiàn)的兩種方式以及接口的實現(xiàn)。教學(xué)難點:熟悉多態(tài)性與接口的實現(xiàn)方法。教學(xué)方法:多媒體+板書 參考書目:《Java語言與面向?qū)ο蟪绦蛟O(shè)計》,印旻編著,清華大學(xué)出版社。專業(yè)詞匯:多態(tài)性、接口 備注 第六章:工具類與算法
第 1、2 節(jié):語言基礎(chǔ)類庫、Applet類與小程序的基本原理 授課時間:2011-4-
26、27
計劃學(xué)時數(shù):3 教學(xué)任務(wù)與目的:深入了解Applet生命周期的主要方法和特點、熟練掌握Applet程序的編寫方法、深入了解Applet的安全機制及其合理運用。教學(xué)重點:熟練掌握Applet程序的編寫方法。
教學(xué)難點:深入了解Applet的安全機制及其合理運用。教學(xué)方法:多媒體+板書 參考書目:《Java語言與面向?qū)ο蟪绦蛟O(shè)計》,印旻編著,清華大學(xué)出版社。專業(yè)詞匯:Applet、生命周期 備注 第六章:工具類與算法
第 3、4 節(jié):數(shù)組、字符串、常用算法
授課時間:2011-5-
3、4
計劃學(xué)時數(shù):3 教學(xué)任務(wù)與目的:讓學(xué)生學(xué)會字符串類String和BufferString、數(shù)組的聲明及使用。教學(xué)重點:熟練掌握字符串與數(shù)組的使用方法。教學(xué)難點:深入了解數(shù)組的使用方法。教學(xué)方法:多媒體+板書 參考書目:《Java語言與面向?qū)ο蟪绦蛟O(shè)計》,印旻編著,清華大學(xué)出版社。專業(yè)詞匯:數(shù)組、字符串 備注 第七章:用戶圖形界面的設(shè)計
第 1、2 節(jié):用戶自定義成分、事件驅(qū)動設(shè)計 授課時間:2011-5-
10、11
計劃學(xué)時數(shù):3 教學(xué)任務(wù)與目的:讓學(xué)生學(xué)會使用面向?qū)ο蟮某绦蛟O(shè)計方法構(gòu)建圖形用戶界面、深入了解抽象窗口工具包(AWT)、掌握事件處理基本原理和方法。教學(xué)重點:熟練掌握圖形用戶界面的開發(fā)方法。教學(xué)難點:深入了解圖形界面的各種事件。教學(xué)方法:多媒體+板書 參考書目:《Java語言與面向?qū)ο蟪绦蛟O(shè)計》,印旻編著,清華大學(xué)出版社。專業(yè)詞匯:AWT、GUI 備注 第七章:用戶圖形界面的設(shè)計
第 3、4 節(jié):GUI對象,包括:按鈕、文本框、鼠標(biāo)、鍵盤等事件的處理、布局設(shè)計 授課時間:2011-5-
17、18
計劃學(xué)時數(shù):3 教學(xué)任務(wù)與目的:讓學(xué)生深入了解GUI構(gòu)件及掌握布局控制方法、熟練掌握菜單和對話框、掌握簡單繪圖方法。
教學(xué)重點:熟練使用Java語言提供的布局管理器來管理組件在容器中的布局。教學(xué)難點:深入了解組件在程序中安排中位置和大小使用方法。教學(xué)方法:多媒體+板書 參考書目:《Java語言與面向?qū)ο蟪绦蛟O(shè)計》,印旻編著,清華大學(xué)出版社。專業(yè)詞匯:布局管理器、容器 備注 第八章:Java高級編程
第 1、2、3節(jié):異常處理、多線程機制、Java程序?qū)W(wǎng)上資源的訪問 授課時間:2011-5-
24、25
計劃學(xué)時數(shù):3 教學(xué)任務(wù)與目的:讓學(xué)生深入理解多線程的基本概念、熟練掌握創(chuàng)建線程的兩種基本方法、熟練處理線程的同步問題和死鎖問題、深入理解異常的基本概念、熟悉和掌握Java平臺定義異常類、熟練掌握創(chuàng)建自定義異常類的方法。教學(xué)重點:熟練掌握創(chuàng)建線程的兩種基本方法。教學(xué)難點:深入了解線程的同步問題和死鎖問題。教學(xué)方法:多媒體+板書 參考書目:《Java語言與面向?qū)ο蟪绦蛟O(shè)計》,印旻編著,清華大學(xué)出版社。專業(yè)詞匯:同步、死鎖、多線程、異常
第五篇:Java面向?qū)ο蟪绦蛟O(shè)計教學(xué)大綱
Java面向?qū)ο蟪绦蛟O(shè)計課程教學(xué)大綱
Object-Oriented Programming with Java Syllabus
課程名稱 課程類別 建設(shè)單位/教研室 前后課程 適用專業(yè)、層次 Java面向?qū)ο蟪绦蛟O(shè)課程英文名Object-Oriented Programming with Java 計 稱 專業(yè)必修課 學(xué)分/學(xué)時 4.0/42+42 計算機系/軟件工程教研室 考核方式 考試 C語言程序設(shè)計
軟件工程、計算機科學(xué)與技術(shù)、網(wǎng)絡(luò)工程
Upon completion of this course, students should master the basic knowledge of Java language, understand and grasp the basic object-oriented programming design ideas and skillfully use Java language to write, compile and debug programs.These would lay a good foundation for students on independently finish the work of program development with Java in the future.教學(xué)目的
The emphasis: 1.The origin of Java, Why should we learn Java language, Java cross-platform principle analysis(JVM)and Java Environment variable configuration.2.Data and Expressions: including Character Strings, Variables and Assignment, Primitive Data Types, Expressions, Data Conversion, Interactive Programs.3.Oriented object programming ideas: including Class, Object, Variables, Methods, Encapsulation, Inheritance, Polymorphism, Interface and so on.4.Java statements: including conditionals and loops statements.5.Arrays: Declaring and using one-dimensional arrays and two-dimensional arrays.6.Exceptions: including exception handling, uncaught exceptions, and try-catch statement and so on.7.GUI: including event handling and graphics user interface.The difficulty:
Object-oriented concept and idea, establishing application model and algorithm of description, the algorithm optimization of program and so on.教材和主要參考資料: Text and references Text :
John Lewis “Java程序設(shè)計教程(第六版)英文版” 電子工業(yè)出版社 ISBN-978-7-121-08808-7 References:
1.《Java編程思想(英文版 第3版)》,(美)Bruce Eckel編,機械工業(yè)出版社出版社; 2.Java程序設(shè)計基礎(chǔ)》,(美)Gary J.Bronson編, 趙德奎 林仕平譯,北京大學(xué)出版社。
3.Cay S.Horstmann, Gary Cornell.Java 2核心技術(shù) 卷I:基礎(chǔ)知識.機械工業(yè)出版社, 2001.4.Cay S.Horstmann, Gary Cornell.Java 2核心技術(shù) 卷II:高級特性.機械工業(yè)出版社, 2001.教學(xué)內(nèi)容 學(xué)時 基本要求
按章、節(jié)具體列出
教學(xué)內(nèi)容 Topic 具體列出教學(xué)的基本要求,如了解、理解、掌握及應(yīng)用等。
By the end of chapter ,students should understand Chapter 1 Introduction
Chapter 2 Data and ExpressionsChapter 3 Using Classes and Objects Chapter 4 Writing Classes 3+3 To be able to have a fundamental understanding of software role in a computer system.? To know components of a computer ? To understand how those components interact ? To grasp how computers store and manipulate information ? To know how computers are connected into networks to share information.? To profile programming and programming languages ? To profile an introduction to Java ? To grasp object-oriented concepts 3+6 Explore some of the basic types of data used in a Java program and the use of expressions to perform calculations.? To understand character strings, concatenation, and escape sequences.? To grasp the declaration and use of variables.? To be familiar with Java primitive data types.? To understand expressions and operator precedence.? To grasp the syntax and processing of expressions.? To understand the types of data conversions and the mechanisms for
accomplishing them.? To know how to create interactive programs.? To understand the basic graphic concepts and the techniques for drawing
shapes.? To know the concept of a Java applet.4+4 Use the predefined classes in the Java class library that are provided to us to make the process of writing programs easier.? To grasp the creation of objects and the use of object reference variables.? To be familiar with the services provided by the String class.? To know how the java standard class library is organized into packages.? To be familiar with the services provided by the Random and Math class.? To grasp ways to format output using the NumberFormat and DecimalFormat
classes.? To be familiar with enumerated types.? To understand wrapper classes and the concept of autoboxing.? To understand components and containers used in graphics user interfaces.? To know a label component and the use of images.6+6 We've been using predefined classes.Now we will learn to write our own classes to define objects.? To grasp the structure and content of a class definition.? To understand the concept of object state using instance data.? To know the effect of visibility modifiers on methods and data.? To grasp the structure of a method definition, including parameters and return
values.? To grasp the structure and purpose of a constructor.? To grasp the creation of graphical objects.? To understand the concepts needed to create an interactive graphical user
interface.Chapter 5 Conditionals and Loops
Chapter 6 OBJECT-ORIENTED DESIGN
Chapter 7 Arrays
Chapter 8 Inheritance ? To know some basic GUI components and events.4+4 Now we will examine programming statements that allow us to make decisions and repeat processing steps in a loop.? To know the flow of control through a method.? To understand Boolean expressions that can be used to make decisions.? To grasp to perform basic decision making using if and switch statements.? To understand issues pertaining to the comparison of certain types of data.? To grasp familiarly to execute statements repetitively using while, do, and for
loops.? To understand the concept of an iterator object and use one to read a text file.? To know how to draw with the aid of conditionals and loops.? To know more GUI components and events.4+4 Now we can extend our discussion of the design of classes and objects ? To know key issues related to the design of object-oriented software.? To techniques for identifying the classes and objects needed in a program.? To understand the relationships among classes.? To understand the effect on the static modifier on methods and data.? To grasp the creation of a formal object interface.? Further grasp the definition of enumerated type classes.? To grasp issues related to the design of methods, including method
overloading.? To know issues related to the design of graphics user interface, including
layout managers.6+3 Arrays are objects that help us organize large amounts of information ? Define and use arrays for basic data organization.? To know bounds checking and techniques for managing capacity.? To learn to compare the issues related to arrays as objects and arrays of
objects.? To grasp the use of command-line arguments.? To grasp the syntax and use of variable-length parameter lists.? To be familiar with the creation and use of multidimensional arrays.? To be familiar with the ArrayList class and its generic parameter.? To know more mouse and keyboard events.6+6 Inheritance is a fundamental object-oriented design technique used to create and organize reusable classes.? To know the derivation of new classes from existing ones.? To understand the concept and purpose of method overriding.? To grasp the design of class hierarchies.? To grasp the issue of visibility as it relates to inheritance.? To have the ability to derive on interface from another.? To grasp object-oriented design in the context of inheritance.? To know the inheritance structure for GUI components.? To explore the creation of listeners by extending adaptor classes.Chapter 9 Polymorphism 3+3 Chapter 10 Exceptions 3+3 有關(guān)說明:
擬稿(簽名):謝彥麒 Polymorphism is an object-oriented concept that allows us to create versatile software designs ? To understand polymorphism and explore its benefits.? To understand the concept of dynamic binding.? To grasp to use inheritance relationships to create polymorphic references.? To grasp to use interfaces to create polymorphic references.? To grasp sorting and searching using polymorphic implementations.? To be familiar with object-oriented design in the context of polymorphism.? To know the processing of events as an example of polymorphism.? To know more GUI components.Exception handling is an important aspect of object-oriented design ? To know the purpose of exceptions.? To know exception messages and the call stack trace.?
To be familiar with the usage of the try-catch statement for handling exception.? To understand the concept of exception propagation.?
To be familiar with the exception class hierarchy in the Java standard class library.? To be familiar with I/O exception and the ability to write text files.? To know how to create GUI using mnemonics and tool tips.?
To know additional GUI components and containers.核稿(簽名): 審批(簽名): 年 月 日