Java語言的面向?qū)ο缶幊蘝第1頁
Java語言的面向?qū)ο缶幊蘝第2頁
Java語言的面向?qū)ο缶幊蘝第3頁
Java語言的面向?qū)ο缶幊蘝第4頁
Java語言的面向?qū)ο缶幊蘝第5頁
已閱讀5頁,還剩34頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、第三章 面向?qū)ο蟮木幊汤碚摫菊聦?dǎo)讀在本章中,我們將討論Java語言的面向?qū)ο蟮奶卣?。正如前面所介紹的,Java語言是一種標(biāo)準(zhǔn)的面向?qū)ο蟮木幊陶Z言,它具具的面向?qū)ο蟮奶卣鞣浅?qiáng)大,使用非常方便,同時,其語言本身又具有C+語言的靈活性。這也是我們推廣Java語言的原因之一。接口是Java語言中非常重要的概念,由于Java不支持多繼承,因此引入了接口的概念,用來完成多繼承的一些功能,同時接口還是面向?qū)ο笠粋€重要思想設(shè)計與實(shí)現(xiàn)的分離的體現(xiàn)。使用接口進(jìn)行設(shè)計,然后通過類來實(shí)現(xiàn)這些接口,這是一種非常高效的編程方式。在本章介紹接口的時候,我們首先介紹抽象類和抽象方法,它們提供了一定程度的抽象,也體現(xiàn)了設(shè)計與

2、實(shí)現(xiàn)的分離。接口比抽象類和抽象方法提供了更高層次的抽象。包是Java語言中引入的另一個重要概念。包使得類庫的組織更加條理,包還可以提供一定程度的封裝和訪問控制。Java語言中很多訪問控制都限制在包的層次上。本章的內(nèi)容既多又繁雜,在介紹一種新的概念時,我們重點(diǎn)從兩方面進(jìn)行介紹,一是關(guān)于概念的理解,介紹的方式是將很多Java語言中的術(shù)語與現(xiàn)實(shí)生活中的一些術(shù)語對應(yīng)起來;二是關(guān)于概念的應(yīng)用,介紹的方法是通過規(guī)則描述和舉例的方式進(jìn)行。我們希望這樣做,既能使您在語法上有清晰的認(rèn)識,又能使您準(zhǔn)確地把握概念的內(nèi)涵,并且能夠在編程中熟練的使用,使您真正掌握面向?qū)ο蟮木幊汤碚?。本章?nèi)容面向?qū)ο蟮睦碚摗⒏拍?。Jav

3、a語言中的類和對象的定義。類定義、屬性定義、方法定義。繼承的概念,以及由此引出的方法和屬性的繼承、隱藏、覆蓋。接口定義/包定義。如何創(chuàng)建接口與包,如何訪問包中的類和接口。關(guān)于類、抽象類、接口的使用原則。學(xué)習(xí)目標(biāo)掌握面向?qū)ο蟮睦碚撝R。學(xué)會類的定義,類實(shí)例化的方法。學(xué)會接口、包的定義。學(xué)會用面向?qū)ο蟮睦碚摼幊獭?.1面向?qū)ο蟮木幊汤碚摗懊嫦驅(qū)ο蟆笔墙陙鞩T行業(yè)非常流行的概念。在現(xiàn)實(shí)世界中,可能用的更多的是“對象”這個名詞,對象的概念很難定義,但我們都理解其所具有的含義。按照正規(guī)的定義,對象是指行動或思考時作為目標(biāo)的人或事物,強(qiáng)調(diào)的是把對象作為一個獨(dú)立、完整的目標(biāo)來對待,這也是IT行業(yè)引用對象這

4、個概念的初衷。在介紹面向?qū)ο蟮木幊汤碚撝埃紫冉榻B一個已經(jīng)使用幾十年的結(jié)構(gòu)化編程理論。結(jié)構(gòu)化編程的思想強(qiáng)調(diào)的是一個系統(tǒng)由一個個獨(dú)立的、較小的功能組成。隨著軟件系統(tǒng)的規(guī)模越來越大,這種編程理論遇到了較大的挑戰(zhàn),一個系統(tǒng)可能由成千上萬個功能組成,而且它們之間相互調(diào)用,設(shè)計起來很難理順?biāo)鼈兊年P(guān)系,在維護(hù)時,更會造成一動而引發(fā)全身的系列行為,大大增加了維護(hù)的難度。為了克服結(jié)構(gòu)化編程的缺點(diǎn),人們在設(shè)計和實(shí)現(xiàn)一個系統(tǒng)時,開始把分析一個系統(tǒng)的視角由一個個功能轉(zhuǎn)移到系統(tǒng)所包含的對象上來。如對一個人事管理信息系統(tǒng),它所處理的對象包括一個單位不同部門的人員,每個部門的人員可能具有不同的特點(diǎn)和分工,如行政人員強(qiáng)調(diào)

5、的是行政級別,開展的是一些管理工作;技術(shù)級別強(qiáng)調(diào)的是技術(shù)職稱,開展的是一個技術(shù)研究工作等等。他們的有些工作是共性的,如完成年度總結(jié),但大部分工作是與他們的分工相關(guān)的,如果我們在設(shè)計一個系統(tǒng)時,能夠?qū)⒁恍┕δ芘c完成這些功能的人對應(yīng)起來,并把人與事放在一起管理,在出現(xiàn)一些功能變化時,我們只須針對與之相關(guān)的方面進(jìn)行調(diào)整即可,這就是面向?qū)ο蟮脑O(shè)計思想。在現(xiàn)代軟件工程設(shè)計中,面向?qū)ο蟮乃枷朐谲浖O(shè)計和軟件編程方面得到了深入的應(yīng)用。面向?qū)ο蟮膬?nèi)容很豐富,要想全面的了解面向的對象的程序設(shè)計方法,您可能需要花上幾年的時間。在本書中,我們只介紹一些與編程有關(guān)的、基礎(chǔ)性的一些概念。面向?qū)ο蟮姆治龇椒梢哉f是方法論

6、中的一個新理論,在社會學(xué)理論中也有非常重要的意義,尤其是在管理理論方面,應(yīng)用的非常廣泛,如目標(biāo)管理關(guān)注的就是結(jié)果,而對實(shí)現(xiàn)的過程關(guān)不關(guān)心,這和面向?qū)ο蟮睦碚撌且恢碌?。面向?qū)ο蟮睦碚搧碓次椅覀儗ΜF(xiàn)實(shí)世界的認(rèn)識過程?,F(xiàn)實(shí)世界就是由各種各樣的有形或無形的事與物構(gòu)成的,人們通過判斷這事物的基本特征,識別出不同的事物,例如,我們通過花紋和大小,能夠分辯出足球與籃球;我們通過社會不同的不同,將所有人分成工人、農(nóng)民、軍人等,他們從事的工作有很大差別。有的事物在宇宙中只有一個,有的可能有千千萬萬,這種數(shù)量上的差別也會隨著我們分析事物的視角不同而不同,例如,太陽只有一個,但但它只是無數(shù)恒星中的一員。我們常常把這

7、種具有相同特征的事與物劃分成 “類”來表示,典型的例子就是我們?nèi)祟悾恳粋€人都具有人類一些共性,如一個鼻子,兩只眼睛等等,但世界上不同的民族又具有各自的特征,如黃種人的頭發(fā)是黑的,歐洲人的頭發(fā)是黃的等等。從性別上又可分為男人和女人,從年齡上可分為幼兒、少年、青年、中年、老年,從性格上分可分為內(nèi)向型的和外向型的等等。正是這些豐富的特征構(gòu)成了豐富的人類社會。面向?qū)ο蟮姆治觯∣OD,Object Oriented Design)和面向?qū)ο缶幊蹋∣OP,Object Oriented Programming)就是從我們認(rèn)識世界的方法中提煉出來,并應(yīng)用到軟件工程中的一項(xiàng)革命性的軟件開發(fā)理論,成為二十世紀(jì)

8、八十年代以來的最主流的軟件工程方法之一。我們對事物的分析一般有兩個視角,一個是個體特征,另一個是群體特征,所謂個體,就是指一個具體的物或事,例如我們班上的張三,是全班學(xué)生中的一員。所謂群體,就是指具有共同特征的個體的總稱,例如我們現(xiàn)在所在的班級全體學(xué)生。通過描述群體成員中的具體特征,我們可以定位到每一個個體,如我們可以通過姓名從全班學(xué)生中找到叫張三的人。我們在分析群體時,往往是強(qiáng)調(diào)的是群體中所有個體均具有的共同特征,如通過籃球的生產(chǎn)廠家確定某某品牌的籃球質(zhì)量好,這就將某某品牌的籃球確定為一類。在JAVA語言中,我們首先定義一個群體,也就是類,再由它確定一個個個體,也就是對象或稱為實(shí)例。類和對象

9、的概念是面向?qū)ο蟪绦蛟O(shè)計的核心,這兩個概念既基礎(chǔ)又重要。這里還需要強(qiáng)調(diào)的是類的共同特征問題,在我們分析一個事物時,如果一個群體與另一個群體具有明顯的差異,而且我們就是在強(qiáng)調(diào)這種差異,那么這兩個群體則不能劃分為一個群體,但如果我們強(qiáng)調(diào)的是這兩個群體的共性,那么這兩個群體則有可以劃分為一個大的群體,如人類有別于其它動物,如果我們分析人類的一些商業(yè)行為時,一般不會過多地分析其它動物是否也具有這樣的行為,但如果我們分析人類和其它動物飲食區(qū)別時,我們又常常將人類和其它動物類統(tǒng)統(tǒng)放在動物類加以研究。我們在分析一個事物時,往往將這些事物的特征分為兩類,一類在相對靜止不變的特征,如太陽是圓的;一個人有姓名、出

10、生時間、性別等特征,我們稱這些特征為屬性;另一類是動態(tài)的特征,如太陽發(fā)光;人會走路等特征,我們稱這些特征為行為,在JAVA語言中,將這些行為稱為方法。同時,我們在分析一個事物時,往往采用由表及里、由外到內(nèi)的認(rèn)識過程,如一個人有兩條腿,每條腿是由大腿、小腿和腳組成的,這樣一直可以分解到細(xì)胞或分子的深度。同時在我們走路時,只有我們的大腿、小腿、腳進(jìn)行有機(jī)的配合,甚至還需要我們上肢的合作,我們才能運(yùn)動自由。上述分析對應(yīng)在面向?qū)ο蟮木幊踢^程中,只不過是將軟件開發(fā)中所需要面對的對象進(jìn)行歸納,形成了一個個對象的模型?,F(xiàn)實(shí)世界中的對象不是孤立的,任何對象都要和其它的對象發(fā)生關(guān)系。比如人可以啟動汽車并駕駛汽車

11、,足球運(yùn)動員可以讓足球以很快的速度射向球門,等等。在面向?qū)ο蟮木幊讨?,對象之間也是可以相互作用的,它們通過收發(fā)消息相互聯(lián)系,相互作用。一個對象如果想要求另外一個對象執(zhí)行某種行為,就可以向它發(fā)送消息,接收消息的對象對消息做出響應(yīng),執(zhí)行自己的某些行為。例如,有兩個對象:人和汽車,如果人要啟動汽車,就需要發(fā)送消息給汽車(在現(xiàn)實(shí)中,這種消息可能是插入鑰匙并踩住油門),汽車對這個消息做出響應(yīng),執(zhí)行自己的啟動程序來啟動汽車。收發(fā)消息是對象之間通信的一種方式,我們往往將注意力集中在這一層面上,但對發(fā)動機(jī)是如何啟動的,汽車是如何被燃燒的等等細(xì)節(jié)并不關(guān)心,只要汽車能夠正常啟動和行駛就足夠了。這也是程序設(shè)計中封裝

12、這個概念的由來。通過歸納和分析,我們可以將對象定義為由屬性和行為組成的封裝體。并且具有如下的特點(diǎn):針對性。對象的針對性是指我們在認(rèn)識一個對象時,總是對應(yīng)一個具體的物體或事件,它是具體的一個,而不是抽象的、無法確定的一批。對于這一點(diǎn),必須有一個清楚的認(rèn)識,否則會與類的概念相混淆。自治性。對象的自治性是指對象具有一定的行為能力。對于一定的消息輸入,對象能夠做出反應(yīng),執(zhí)行一定的行為,從而改變自身的屬性或者產(chǎn)生某種輸出。封閉性。對象的封閉性是指對象包括了屬性和行為,這些屬性和行為的實(shí)現(xiàn)細(xì)節(jié)對于其它對象來說關(guān)系不太,而且在處理其它對象時,我們不必關(guān)心本對象的實(shí)現(xiàn)細(xì)節(jié)。關(guān)聯(lián)性。對象的通信性是指對象具有和其

13、它對象通信的能力,即對象能夠接收其它對象發(fā)來的消息,也能向其它對象發(fā)送消息。通信性反映了對象之間的某種聯(lián)系,通過這種聯(lián)系,許多對象可以協(xié)同完成某項(xiàng)任務(wù)。類的概念是對對象的分析總結(jié)后得出的一個重要概念,它是為描述具有相同特征的對象而引入的,在面向?qū)ο蟮木幊讨?,?shí)際的操作是首先創(chuàng)建類,然后再通過類創(chuàng)建對象即實(shí)例,再通過些實(shí)例完成業(yè)務(wù)功能。練習(xí)3-1請列出一些具有類和對象的一些例子。練習(xí)3-2對比一個類與對象這兩個概念的相同點(diǎn)和不同點(diǎn)。3.2創(chuàng)建類前面,您已經(jīng)了解了面向?qū)ο缶幊痰囊恍┗镜睦碚?。在本?jié)中,我們將向您介紹如何創(chuàng)建自己的類,包括類的聲明、屬性的聲明、和方法的聲明。在Java語言中,沒有獨(dú)

14、立于類之外的變量、屬性、函數(shù)及方法。在Java語言中,類也是一種數(shù)據(jù)類型,它屬于引用類型。創(chuàng)建一個類,就是聲明了一種新的數(shù)據(jù)類型,并且定義了它是如何實(shí)現(xiàn)的。3.2.1類的定義在Java語言中,類的定義形式如下:修飾符 class類名 extends超類名 implements接口名 類體注意:用方括號“”括起來的部分表示是可選的,即可有可無的。class 是類定義關(guān)鍵字。類名是所創(chuàng)建的類的名字,在程序中是通過類名來引用一個類的,因而類名是必需的。類名可以是任意合法的Java標(biāo)識符,根據(jù)命名的約定,類名的每個有意義的單詞的首字母要大寫,其余字母小寫。extends是引用超類的關(guān)鍵字。超類名用來表

15、明新創(chuàng)建的類是從哪個類繼承而來的,被繼承的類稱為此類的超類,也稱為父類,extends后面只能跟一個超類名稱。implements是引用接口的關(guān)鍵字。接口名用來聲明這個類實(shí)現(xiàn)了哪些接口,接口名可以有多個。關(guān)于超類和接口的區(qū)別,我們將在后面進(jìn)行詳細(xì)討論。類體定義了類的具體的實(shí)現(xiàn),它是用大括號括起來的一個塊,如下所示:屬性的聲明方法的聲明類體中可以有屬性的聲明(用來定義對象的屬性),方法的聲明(用來定義對象的行為)。它們都是可選的。其中屬性的聲明和方法的聲明屬于類的成員聲明。類體中的這些聲明沒有先后順序之分,您可以以任意的順序聲明它們。但為了類的可讀性,我們建議您按照上面出現(xiàn)的順序聲明它們。修飾符

16、有三個,它們分別是public、abstract、final。public修飾符表示定義的這個類可以在它所在的包以外聲明及使用;abstract表示定義的類是一個抽象類;final表示定義的類是一個最終類,即它不能作為其它類的超類。一個類可以有多個修飾符,但是不能有幾個相同的修飾符,比如兩個public是錯誤的。當(dāng)一個類有多個修飾符時,這些修飾符無先后順序之分,您可以任意的排列它們,但是我們建議您按照public abstract final的順序?qū)?。例如:public abstract ClassB extends ClassA注意:abstract和final不能同時作為一個類的修飾符。因

17、為抽象類只是一個沒有實(shí)現(xiàn)的虛類,必須再為實(shí)定義一個實(shí)類,才能被使用,其原因我們將在以后講述。下面這一個“人”的類的例子,在生成這個類文件時,應(yīng)在JAVA開發(fā)工具中,新建一個Java源文件People.java,在其中加入如下的代碼:package com.mysite;public class Peopleprivate Name name;/姓名private String gender;/性別public People()/構(gòu)造方法gender=”男”;name=new Name();public String getGender()/獲取性別return gender;public vo

18、id setGender(String peoplegender) /設(shè)置性別gender =peoplegender;public void changeFirstname(Name n,String newfirstname)/修改姓名n.setFirstname(newfirstname);newfirstname="王五"public final void changeFirstname(String newfirstname)/修改姓名name.setFirstname(newfirstname);public static void main(String ar

19、gs)People p=new People();.setFirstname("張三");System.out.println("張三當(dāng)前的名字是:"+.getFirstname();String nn="李四"p.changeFirstname(,nn);System.out.println("張三的名字改為:"+.getFirstname();System.out.println("nn的值是:"+nn);在這個類中: public class

20、 People定義了一個類名為People的類,注意在保存這個文件時,文件名應(yīng)為People.java。private String gender;/性別表示在People類中定義了一個性別屬性,屬性變量名為gender,類型為字符型。public String getGender()/獲取性別return gender;public void setName(String peoplegender)/設(shè)置性別gender =peoplegender;表示在People類中定義了兩個方法,一個為獲取一個人性別的方法getGender(),一個為設(shè)置一個人性別的方法setGender()。在Ja

21、va語言中,通常將一個類聲明的文件稱作一個編譯單元。您可以在一個編譯單元中聲明多個類,但最多只能聲明一個public的類。編譯單元的文件名要和其中的聲明為public的類名完全一樣,連大小寫都要一樣,否則就會產(chǎn)生編譯錯誤。如在一個編譯單元中定義多個類時,這些類不能重名,否則會產(chǎn)生編譯錯誤,因?yàn)楫?dāng)您使用重名的類時,編譯器將無法弄清楚您指的是哪一個類。在以后您還會看到,不僅僅是在一個編譯單元中,在一個包中也不允許有相同名稱的多個類,即使它們并不是定義在一個編譯單元中。如果在一個類文件中包括多個類,不帶public修飾符的類稱為私有類,即這些類只能在這個包(即此文件所在目錄中的所有類的總稱)中調(diào)用,

22、而不能被其它包調(diào)用,否則會產(chǎn)生編譯錯誤。編譯器在編譯Java源程序的時候,會為每個類產(chǎn)生一個以類名為名稱、以.class為后綴的字節(jié)碼文件,保存的位置依包定義而定。如果一個編譯單元中聲明了多個類,正確編譯以后就會產(chǎn)生多個字節(jié)碼文件。這些文件的名稱只與類名有關(guān),和源程序文件名無關(guān)。例如,People.java文件中增加如下一段代碼:class Nameprivate String surname;/ 姓private String firstname;/名public String getSurname()/獲取姓return surname;public String getFirstname

23、()/獲取名return firstname;public void setSurname(String sn)/設(shè)置姓firstname=sn;public void setFirstname(String fn)/設(shè)置名firstname=fn;編譯此文件,會在com.mysite中得到兩個結(jié)果文件:Pelple.className.class我們再建一個學(xué)生類文件。這個類是由People類繼承而來。源程序如下:package com.mysite;public class Student extends Peoplepublic String levelname;/所在學(xué)段,如高中、初中

24、、小學(xué)private String gradename;/所在年級private String classname;/所在班級public void changeFirstname(Name n,String newfirstname)/修改姓名n.setFirstname(newfirstname);public String getFirstname()/獲取學(xué)生名return name.getFirstname();這樣,就定義了一個People類的子類,在后面我們會介紹一個子類會從父類中繼承哪些功能。練習(xí)3-3有下面一個類定義代碼:public final class Name ext

25、ends People,Nameprivate String oldname;public String getOldName()return oldname;請總結(jié)一下這個類定義中存在哪些問題。3.2.2屬性的聲明屬性是指封裝在類體中變量,是類成員的一部分。Java語言中屬性的聲明形式如下:屬性修飾符 變量類型 變量名=初始值;變量類型可以是任意的Java數(shù)據(jù)類型,也可以是已定義過的類類型。變量名可以是任意合法的Java標(biāo)識符,屬性的變量名稱也簡稱作屬性名。在一個類中,屬性名不能重復(fù)定義,否則會產(chǎn)生編譯錯誤。如People類中g(shù)ender即是一個屬性名。屬性修飾符有以下幾種:publicpr

26、otectedprivatefinalstatictransietvolatile其中public、protected、private規(guī)定了屬性的訪問權(quán)限,一個屬性只能從中選擇一個或不選,它們分別代表的意義是:public表示該屬性可以多層繼承,并可直接進(jìn)行讀取及賦值操作;protected 表示該屬性只能被本包中的其它類繼承,并可直接進(jìn)行讀取及賦值操作;private 表示該屬性不能被子類繼承,也不能直接進(jìn)行讀取及賦值操作。如果一個屬性前不加上述public、protected、private修飾符,表示這個屬性只能在本包中的類中使用。final規(guī)定了屬性是不能改變的,因此我們常常用這個修飾

27、符定義一些常量,如對這些屬性進(jìn)行賦值操作,將會出現(xiàn)錯誤。static表示這個屬性是類屬性,也稱靜態(tài)屬性,Java語言是多任務(wù)和多線程的系統(tǒng),一個類可能同時被多個應(yīng)用調(diào)用,Java虛擬機(jī)為第一個實(shí)例化的類生成一個包括屬性和方法的實(shí)例,在定義其它實(shí)例時,對于除static類型的屬性和方法,系統(tǒng)將在每次實(shí)例化一個實(shí)例時,生成一個屬性及方法的考貝,然后處理之;而對于static類型的屬性(包括方法),只在第一次類實(shí)例化時進(jìn)行定義,在定義該類的其它實(shí)例時,將不再定義static類型的屬性和方法,而是共用第一次實(shí)例化的屬性及方法,也就是說,對于static屬性,相當(dāng)于多個實(shí)例共用一個屬性。對于static

28、方法,相當(dāng)于多個實(shí)例共用一個方法,系統(tǒng)因此可以節(jié)省一些存貯空間,在定義常量時,也應(yīng)加上這個修飾符。static屬性在多任務(wù)處理及池處理等方面十分重要。如我們限制一個類最多只能同時運(yùn)行十個實(shí)例,這時我們可以在這個類中增加一個靜態(tài)變量,初始值為0,每實(shí)例化一次,便自動增1,如果這個變量大于10,則不能再進(jìn)行實(shí)例化,以此達(dá)到限制類同時運(yùn)行個數(shù)的目的。這在網(wǎng)站系統(tǒng)限制用戶訪問數(shù)時常常用到的方法。static屬性在初始化時也是比較特殊的,一般是在定義屬性時直接賦給一個初始值,這個賦值只在第一次實(shí)例化時起作用,生成其它實(shí)例時,將不再進(jìn)行賦值。例如:package com.mysite;public cla

29、ss Example2_1public static int counter=0;public Example2_1() throws Exceptionif(counter>=5)throw new Exception("不能再創(chuàng)建實(shí)例!");counter+;System.out.println("第"+counter+"實(shí)例完成!");public static void main(String args)tryExample2_1 e1=new Example2_1();Example2_1 e2=new Example

30、2_1();Example2_1 e3=new Example2_1();Example2_1 e4=new Example2_1();Example2_1 e5=new Example2_1();Example2_1 e6=new Example2_1();catch(Exception e)System.out.println(e.toString();編譯及運(yùn)行結(jié)果如下:從這個例子我們可以看出,static屬性所具有的特殊作用。transiet表示此屬性不是對象的持續(xù)屬性的一部分,volatile用于線程中,表示每次線程訪問一個屬性時都保證變量在線程中的考貝和主考貝相一致。valatil

31、e和transiet在一般編程中很少使用。屬性的賦值與變量賦值是相同的,并且每一個屬性均可在該類的方法(除main()方法)中使用。如果在父類中定義了一個屬性,在它的子類中仍可定義與之同名的屬性名,但在訪問本類中的屬性時,應(yīng)在屬性前加“this.”(如無重名的變量,也可不加)來明確是本類中的屬性,在屬性前加“super.”來明確是父類中的屬性。例如:package com.mysite;public class Example2_3 extends Example2_2public String name="我是張三"public Example2_3()System.ou

32、t.println(name);System.out.println();public static void main(String args)Example2_3 e=new Example2_3();class Example2_2public String name="我是李四"編譯及運(yùn)行結(jié)果如下:3.2.3方法的聲明方法是指封裝在類體中的一段可執(zhí)行代碼,您可以傳給方法一定數(shù)目的參數(shù)并調(diào)用它,它也是類成員的一部分。在Java語言的類定義中,方法聲明的格式如下:方法修飾符 返回值類型 方法名(參數(shù)列表) throws異常列表 方法體方法名是用來調(diào)用

33、此方法的名字,它可以是Java語言中任意合法的標(biāo)識符。按照命名的約定,方法名命名時應(yīng)該是有意義的動詞或動詞短語組成,它的第一個字母一般要小寫,其它有意義的單詞的首字母要大寫,其余字母小寫。如Pelple類中的getGender()方法中,getGender即是該方法的方法名。返回值類型是指方法返回的結(jié)果的數(shù)據(jù)類型,可以是任意的Java數(shù)據(jù)類型,包括類類型。如果方法沒有返回值,則用void表示。如果在一個方法中想中途返回,應(yīng)使用return語句。如果是void類型,則無需返回結(jié)果,可直接用return;返回,如是其它類型,在return 后面必須有一個符合方法返回值類型要求的值,Java編譯器會

34、檢查您的代碼中是否存在應(yīng)該返回值的地方,如無返回一個值,在編譯時將會報錯。參數(shù)列表表示在調(diào)用一個參數(shù)時,可為其設(shè)置一些初始的參數(shù),方法中會根據(jù)不同的參數(shù)獲得不同的結(jié)果,參數(shù)列表是可選的。如果方法沒有參數(shù),就不用寫參數(shù)列表,只要有一對小括號“()”就行了,比如People類中g(shù)etGender()方法無參數(shù),而setGender()方法中則有一個叫peoplegender的參數(shù)。參數(shù)的定義與變量的定義相同,但不可賦初始值,參數(shù)列表的形式如下:類型 參數(shù)名,省略號表示可以有多個參數(shù),它們之間用逗號分開。在調(diào)用方法的時候,應(yīng)該為每一個參數(shù)賦一個符合類型的值,且必須按照方法定義中的順序排列。在Java

35、語言中,參數(shù)傳遞值是比較復(fù)雜的。但我們只須記住一點(diǎn),凡是基本數(shù)據(jù)類型的參數(shù),參數(shù)傳遞采用的是值傳遞方式,參數(shù)變量的值在方法中發(fā)生值變化時,不影響原實(shí)際參數(shù);凡是引用類型的參數(shù),參數(shù)傳遞采用的是傳引用值的方式,參數(shù)變量的值在方法中發(fā)生變化時,會影響其實(shí)際參數(shù),這種參數(shù)傳遞的方式與變量賦值是一致的。在我們編程過程中,一定要注意參數(shù)值變化是否會影響到變量值的問題,防止因此而出現(xiàn)的意外錯誤。throws子句定義了在方法執(zhí)行中可能導(dǎo)致的異常聲明。豐富的異常處理是Java語言的一大優(yōu)勢,這方面的詳細(xì)內(nèi)容請參見第二章和第四章的相關(guān)內(nèi)容。方法體是一個實(shí)現(xiàn)了這個方法功能的代碼塊,也可簡單的是一個分號“;”。當(dāng)且

36、僅當(dāng)方法的修飾符中有abstract或native時,方法體是一個分號。方法修飾符用于限定方法的訪問權(quán)限和實(shí)現(xiàn)機(jī)制,可以是以下幾種:public、protected、private、abstract、final、synchronized、native。其中public、protected、private表明了方法的訪問權(quán)限,含義與屬性中的含義相同。abstract說明此方法為抽象方法。抽象方法是指未定義方法體的方法,其方法體將在實(shí)方法中定義。final說明此方法為最終方法,以此方法名命名的方法不能在這個類的子類中重新定義,不管子類方法中的參數(shù)是否與其參數(shù)相匹配,這和屬性中final的含義不同。

37、static說明此方法為類方法或稱靜態(tài)方法,其含義在介紹static屬性時已有介紹。有static修飾符的方法中不能調(diào)用本類中的非靜態(tài)屬性或方法,否則編譯時會出錯,這也是是否使用static修飾符的原則,如編譯不出錯,應(yīng)盡量使用static修飾符,以減少方法考貝浪費(fèi)的空間。例如:package com.mysite;public class Example2_4 public static String name="我是張三"public String gender="男"public static String getName()return name

38、;public String getGender()return gender;在這個例子中,因name是一個靜態(tài)屬性,因此,可將getName()方法可設(shè)為靜態(tài)方法,而getGender()方法中使用了非靜態(tài)屬性gender,因此,不能設(shè)定為靜態(tài)方法。練習(xí)3-4:上例中如將getGender()方法設(shè)置為靜態(tài)方法(增加static修飾符),結(jié)果會如何?synchronized用于在執(zhí)行該方法之前給方法上鎖,上鎖的目的是保證該方法只能有一個調(diào)用在執(zhí)行,只有調(diào)用這個方法的進(jìn)程執(zhí)行完畢后,其它進(jìn)程才能調(diào)用。這在多任務(wù)和多進(jìn)程的系統(tǒng)中,防止一個方法同時執(zhí)行多個造成沖突的情況。native指明此方法為

39、本地方法。所謂本地方法,是指針對具體的操作(如對windows系統(tǒng)的操作),通過其它語言(如C+),將一些要實(shí)現(xiàn)的功能編譯成動態(tài)執(zhí)行庫(DLL),然后通過一定的機(jī)制,由java語言調(diào)用。JAVA語言在實(shí)現(xiàn)硬件控制及要求響應(yīng)速度較高的功能時,常常采用這種方法,事實(shí)上,在JDK中,也有大量方法采用了這種方式。jre中的很多動態(tài)庫就是用于處理本地方法的。本地方法的實(shí)現(xiàn)可參見附錄二。在一個類中,方法名相同的方法可以有多個,但這些方法所帶的參數(shù)個數(shù)、參數(shù)數(shù)據(jù)類型及參數(shù)的順序不能完全一樣,Java語言在調(diào)用時,會根據(jù)參數(shù)情況選擇合適的方法。這些方法的返回值可以相同,也可以不同。這體現(xiàn)出面向?qū)ο缶幊讨械囊粋€

40、非常重要的特性:重載。如在People類中定義了兩個changeFirstname()方法:public final void changeFirstname(Name n,String newfirstname)/修改姓名n.setFirstname(newfirstname);newfirstname="王五"public final void changeFirstname(String newfirstname)/修改姓名name.setFirstname(newfirstname);類中有這兩個方法是合法的,但要注意這兩個方法中的參數(shù)個數(shù)不同。方法名可以和其超類的

41、方法名(包括參數(shù))相同,如果有方法名和參數(shù)名完全一樣的方法,java語言在調(diào)用時首先調(diào)用本類中的方法,這體現(xiàn)出對象的又一個非常重要的特性:覆蓋。如Student類中的方法changeFirstname(String newfirstname)將覆蓋People類同相同的方法changeFirstname(String newfirstname),但不覆蓋方法名相同,而參數(shù)不同的另一方法changeFirstname(Name n,String newfirstname)。在子類中重新定義與超類中方法名和參數(shù)相同的方法時,如超類中的方法是一個類方法(即有static修飾符的方法),則子類中也只能

42、再定義類方法。但如果參數(shù)不同,則無此約束。練習(xí)3-5將Student類中public static void testMethodOverride()方法中的static去掉,編譯結(jié)果如何?如在Student類中增加如下代碼,編譯結(jié)果又如何?publicvoid testMethodOverride(String s) /測試方法覆蓋int i=11;重載與覆蓋的區(qū)別:重載是方法名相同而參數(shù)(個數(shù)、順序及類型)不同的多個方法,包括本類與超類中的方法;覆蓋是指在本類中定義一個方法名和參數(shù)(包括順序及類型)均與超類中的方法相同的方法,覆蓋不能在本方法中進(jìn)行,也無意義。在本類中可調(diào)用直接超類的pro

43、tected方法以及所有public方法,這體現(xiàn)出對象的另一個非常重要的特性:繼承。如在學(xué)生類的下述方法中:public String getFirstname()/獲取學(xué)生名return name.getFirstname();name屬性則是繼承了People類中的name屬性。在方法名定義中,有幾個特殊命名的方法,這些方法具有特殊的含義,它們是:構(gòu)造方法。即方法名和類名完全一樣(包括大小寫),在為類進(jìn)行實(shí)例化時調(diào)用就是這個方法。構(gòu)造方法不是必須定義的,但我們常常定義一個,用于初始化一些數(shù)據(jù)。構(gòu)造方法可以有多個,但所有構(gòu)造方法均不得定義返回值類型。如People類的構(gòu)造方法如下:publi

44、c People()/構(gòu)造方法不帶參數(shù)的構(gòu)造方法即使不定義,Java語言的編譯器會自動為這個類創(chuàng)建這個類。main()方法。這是直接運(yùn)行Java類的默認(rèn)調(diào)用的方法,其帶參數(shù)為String args,即在運(yùn)行java類時所帶的參數(shù)。在DOS窗口執(zhí)行一個類文件時,其格式如下:java 類名 參數(shù)名,參數(shù)名所帶的參數(shù)名將會傳遞給args參數(shù)。main方法也不是必須的,但我們?yōu)榱诉\(yùn)行一些簡單的任務(wù)或進(jìn)行方法的測試,常常加上這個方法,在程序正式發(fā)布時,除非是直接使用main()方法進(jìn)行處理,否則,建議將這個方法中的方法體注釋掉。main方法必須是public static 型的,一般返回類型為void。

45、雖然main()方法是放在了類的方法里,但在main()中不能直接操作該類中的屬性和方法,必須首先對這個類進(jìn)行實(shí)例化后,才能使用該類的屬性或方法。如在People類的main()方法中,定義了一個對象名為p的對象后,才可進(jìn)行相應(yīng)的操作。public static void main(String args)People p=new People();.setFirstname("張三");System.out.println("張三當(dāng)前的名字是:"+.getFirstname();String nn="李四"p

46、.changeFirstname(,nn);System.out.println("張三的名字改為:"+.getFirstname();System.out.println("nn的值是:"+nn);在方法體中,可以直接調(diào)用本類及其超類中的屬性與方法。如果有重載或者覆蓋的方法,可通過在屬性名或方法名前加“this.”表示調(diào)用本類中的屬性或方法,在屬性名或方法名前加“super.”方法表示調(diào)超類中的屬性或方法,“super.”可重調(diào)用,如是合法的。super.方法針對所有超類中的public 屬性及方

47、法適用,如果超類中的屬性或方法定義為private或非直接超類中的方法或?qū)傩远x為protected類型,則不能使用“super.”來調(diào)用。在Java語言機(jī)中,如果我們需要使用一個類,Java虛擬機(jī)會首先裝入這個類(詳細(xì)知識以后會介紹),我們可能需要在裝入一個類時就執(zhí)行一段代碼(如只進(jìn)行一次初始化),如果把這段代碼放入構(gòu)造方法中,則會出現(xiàn)每次實(shí)例化一個對象時,就要執(zhí)行一次,為此Java語言專門有實(shí)現(xiàn)此功能的機(jī)制,可稱為“類裝入初始化”,即通過定義一個static語句塊來實(shí)現(xiàn),其形式如下:static .如果有多個這樣的語句塊,這些塊將按順序執(zhí)行。這些語句只在第一次裝入時執(zhí)行一次,以后將不再執(zhí)行

48、。這些代碼將先于構(gòu)造方法執(zhí)行,這一點(diǎn)是非常重要的。當(dāng)然,如果你要求每次實(shí)例化就要執(zhí)行一段代碼,把這段代碼放入構(gòu)造方法中即可。例如:package com.mysite;import java.io.*;import java.util.*;public class Example2_5public static void main(String args)B b1=new B();B b2=new B();class Bpublic B()System.out.println("初始化B");static System.out.println("執(zhí)行代碼1&quo

49、t;);static System.out.println("執(zhí)行代碼2");編譯及執(zhí)行后,執(zhí)行結(jié)果如下:3.3創(chuàng)建對象(類實(shí)例化)Java是一種面向?qū)ο蟮木幊陶Z言,使用Java編程的時候,您必然要處理大量的對象。您要創(chuàng)建它們,修改它們,改變它們的屬性,調(diào)用它們的方法,將它們和其它對象有機(jī)地組織起來,完成一個的功能。下面我們分別介紹這些內(nèi)容。創(chuàng)建對象當(dāng)您編寫Java程序的時候,您定義了一些類。正如前面所介紹的,類是對象的模板,在大多數(shù)情況下,您需要使用類創(chuàng)建對象,然后和這些對象打交道。字符串對象是一個特殊的類,創(chuàng)建時最為簡單,您只需要將一個字符序列用雙引號括起來即可。編譯器

50、會自動的為這些字符串文字創(chuàng)建對象,而不需要您顯式地去創(chuàng)建對象。您可以把這樣的字符串賦給一個字符串類型的變量。例如:String s = "I am a String object."也可以用標(biāo)準(zhǔn)的方法定義字符串類,例如:String s = new String("I am a String object.");Java編譯器會為字符串文字顯式的創(chuàng)建對象,對于其它類,必須采用下面的方法定義類的實(shí)例: 類名 實(shí)例變量 = new 類的構(gòu)造方法(參數(shù)列表);類名是定義要創(chuàng)建的實(shí)例所屬的類的名字。new是一個創(chuàng)建實(shí)例所必須的關(guān)鍵字。類的構(gòu)造方法是指類及其子類的

51、構(gòu)造方法,因在定義構(gòu)造方法是與類名或子類名一樣的,原則上類名與構(gòu)造方法名相同,但如果類名與構(gòu)造方法名所指的類存在超類與子類的關(guān)系,Java語言就可以進(jìn)行類型轉(zhuǎn)換。參數(shù)列表是指類的構(gòu)造方法所帶的參錯,當(dāng)找不到與參數(shù)列表中的參數(shù)表達(dá)式類型和個數(shù)相匹配的構(gòu)造方法時,會產(chǎn)生編譯錯誤。3.3.2對象的引用Java語言中的引用概念在前面已經(jīng)介紹過,在Java語言中,引用值是隱藏的,不能在程序中直接操作。這樣的設(shè)計大大增強(qiáng)了Java語言的安全性,基于這一特點(diǎn),我們也稱java語言是健壯的。當(dāng)您使用對象的時候,您實(shí)際上是通過對象的引用值來定位和使用對象的。當(dāng)您將一個對象賦給一個類型匹配的變量時,您實(shí)際上是把這

52、個對象的引用值賦給了這個變量,當(dāng)對一個類變量的屬性進(jìn)行改變時,這種改變將直接作用在該變量所對應(yīng)的實(shí)例的屬性,如果有幾個變量同時指向該實(shí)例,則其它變量所對應(yīng)的屬性值也會同時變化。這和采用值傳遞方式的基本數(shù)據(jù)類型是有很大區(qū)別的。另外,針對字符串類型,其賦值是采用引用方式的,但其處理全部采用的是生成新字符串的方式處理的,因此,在字符串變量值的變化方式有點(diǎn)向基本數(shù)據(jù)類型。對象引用的方式會對程序處理有很大變化,我們應(yīng)該牢記。例如:package com.mysite;import java.util.*;public class Example2_6 public void testReference(

53、int i,String s,Vector v)i+;s="新字符串"v.set(0,"新元素");public static void main(String args)Example2_6 e=new Example2_6();System.out.println("執(zhí)行testReference前:");int i=5;String s="舊字符串"Vector v=new Vector();v.add("舊元素");System.out.println("i="+i+

54、"ns="+s+"nv1="+(String)v.elementAt(0);e.testReference(i,s,v);System.out.println("執(zhí)行testReference后:");System.out.println("i="+i+"ns="+s+"nv1="+(String)v.elementAt(0);執(zhí)行結(jié)果如下:通過對testReference()方法的幾個參數(shù)的分析,可以更好的理解不同數(shù)據(jù)類型作為參數(shù)引用時的方法。其中基本數(shù)據(jù)類型(i)和字符串

55、類型(s)在執(zhí)行testReference()方法后,并未影響原變量,而類類型變量(v)在調(diào)用后,原變量的內(nèi)容發(fā)生了變化。3.3.3對象的類型轉(zhuǎn)換在Java語言中,如果兩個類在繼承上存在子類或超類的關(guān)系,一個類的實(shí)例就可以轉(zhuǎn)換為另一個類的實(shí)例。具體說來,如果類A是類B的子類或超類,那么類A的實(shí)例就可以轉(zhuǎn)換為類B的實(shí)例。對象的類型轉(zhuǎn)換有兩種方式:隱式轉(zhuǎn)換和顯示轉(zhuǎn)換。這和基本數(shù)據(jù)類型的轉(zhuǎn)換是類似的。隱式轉(zhuǎn)換是指在實(shí)例化一個對象時,直接調(diào)用子類的構(gòu)造方法來實(shí)現(xiàn)。如:People p=new Student();這也符合一個常理,因?yàn)橐粋€學(xué)生首先是一個人。注意:不能通過隱式轉(zhuǎn)換將一個類的超類實(shí)例化后給

56、子類對象。顯示轉(zhuǎn)換是指在一個對象前直接聲明一個類名的方式進(jìn)行強(qiáng)制轉(zhuǎn)換,如:Stuent s= new Student();People p=(Student)s;在Java語言中,有一個類是所有類的超類,那就是Object類,很多JDK中的類(如Vector)就是直接操作Object類的,我們可以通過顯式轉(zhuǎn)換的方式,將我們需要處理的對象看作是Object對象來對待。例如:package com.mysite;import java.util.*;public class Example2_7 public static void main(String args)Vector v=new Ve

57、ctor();Date d1=new Date();v.add(d1);Date d2=(Date)v.elementAt(0);System.out.println(d2);在這個例子中,Vector對象中保存的是Object對象,在v.add(d1)語句中,因編譯器知道任意對象均為Object的子類,因此可直接保存,而在Date d2=(Date)v.elementAt(0);語句中,因編譯器不知道Vector對象中保存的對象與Date對象之間的關(guān)系,因此必須通過顯示轉(zhuǎn)換才能進(jìn)行賦值操作。練習(xí)3-6:如果刪除上例中的“(Date)”代碼,編譯及運(yùn)行結(jié)果會如何?下面一段代碼:package com.mysite;public class Example2_8

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論