《Java語言程序設計》課件第3章_第1頁
《Java語言程序設計》課件第3章_第2頁
《Java語言程序設計》課件第3章_第3頁
《Java語言程序設計》課件第3章_第4頁
《Java語言程序設計》課件第3章_第5頁
已閱讀5頁,還剩185頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

3.1引例——“銀行賬戶”

3.2類的定義

3.3類的實例化

3.4使用JavaAPI

3.5字符串類String

3.6數(shù)組

3.7小結3.8習題

1.問題剖析

引例中涉及銀行中的開戶、存款、取款、轉賬業(yè)務,我們可以分述如下:

(1)開戶:首先為賬戶設置一個名字,引例中為“郭敬”、“楊過”,賬戶中設置一個屬性“余額”用來記錄賬戶中金額的多少,開戶時余額的初始設置為0,其后隨著存款、取款等發(fā)生變化,對開立的賬戶(“郭敬”、“楊過”等賬戶)可進行存款、取款、轉賬等操作。

(2)存款:郭敬開戶成功后存入5000元,名為“郭敬”的賬戶余額增加到5000元(即0+5000=5000)。3.1引例?——“銀行賬戶”

(3)取款:郭敬取出300元,從前面的敘述中可判斷當前余額足夠支取,因此“郭敬”的賬戶余額應變?yōu)?700元(5000-300=4700)。

(4)轉賬:從前面敘述中判斷可知“郭敬”的賬戶余額為4700元,足夠支取4500元,故“郭敬”的賬戶余額應變?yōu)?00元(4700-4500=200),而楊過的賬戶余額由開戶成功的0變?yōu)?500元(0+4500=4500)。轉賬實際上是先從一個賬戶取款,然后存入另一個賬戶而已。通過上述分析發(fā)現(xiàn):不管是“郭敬”、“楊過”或是任何其他人在銀行開立個人賬戶,每個賬戶都必須有一個名稱,用以區(qū)分不同人的賬戶;每個賬戶必須至少有一個屬性名為“余額”,用來記錄賬戶主人所存金額的多少;所有賬戶都能進行取款、存款等操作,或者說銀行對所有賬戶都能提供取款、存款等服務。在銀行業(yè)務中將“郭敬”賬戶、“楊過”賬戶等所有人的賬戶統(tǒng)一抽象稱為“銀行賬戶”,用以描述所有“賬戶”這一類整體事物的共有特性。引例中“銀行賬戶”可簡化描述如下:

名稱:銀行賬戶

屬性:戶名,密碼,當前余額(balance)。

服務(操作或行為):

存款

輸入: 存款金額amount。步驟1: 令balance=balance+amount并終止。

取款

輸入: 取款金額amount。

輸出: 已取款金額amount'。

步驟1:如果amount>balance則令amount'=0并轉向步驟2;

否則令amount'=amount、balance=balance-amount并終止。

步驟2:警告余額不足并終止。

2.對象與類

1)對象

在Java語言中,將引例中所述“郭敬”賬戶、“楊過”賬戶或某一個人的賬戶等這樣的個體就稱為一個對象。現(xiàn)實世界中每一個人、每一個動物、每一輛汽車等都是一個對象,可以講舉目所視皆對象。仔細研究程序設計所面對的問題域——客觀世界,我們可以看到:客觀世界是由一些具體的事物構成的,每個事物都具有自己的一組靜態(tài)特征(屬性)和一組動態(tài)特征(行為)。例如,一輛汽車有顏色、型號、馬力、生產(chǎn)廠家等靜態(tài)特征,又具有行駛、轉彎、停車等動態(tài)特征。把客觀世界的這一事實映射到面向對象的程序設計中,則把問題域中的事物抽象成了對象,事物的靜態(tài)特征(屬性)用一組數(shù)據(jù)來描述,事物的動態(tài)特征(行為)則用一組方法來刻畫。因此,從引例分析中可知對象具有下述特征:

(1)對象標識:對象的名字,是一個對象區(qū)別于其他對象的唯一標志,也是用戶和系統(tǒng)識別它的唯一標志。引例中“郭敬”賬戶名可作為對象“郭敬”的標識。在計算機世界中,我們可以把對象存儲到計算機存儲器中一塊可標識的區(qū)域,它能保存固定或可變數(shù)目的數(shù)據(jù)(或數(shù)據(jù)的集合)。

(2)屬性:一組數(shù)據(jù),用來描述對象的靜態(tài)特征。引例中的“賬戶余額”記錄金額多少表示的就是屬性,賬戶還可以有“透支限額”、“賬戶密碼”等一組屬性。在Java程序中,屬性用一組數(shù)據(jù)表示,把其中每一個數(shù)據(jù)稱為“數(shù)據(jù)成員”,這樣屬性可看成是一組數(shù)據(jù)成員。

(3)行為:也稱為服務或操作,它是對象行為動態(tài)特征的描述。引例中,取款、存款、轉賬等是對象的行為動作,在Java語言中,每個行為動作為一個“方法成員”,有人也稱“成員方法”,簡稱“方法”。從引例中可知,一個對象的行為可用一組方法成員描述。

綜上所述,要確定一個對象,必須指明這個對象的名稱,找到所有的屬性和行為,屬性用一組數(shù)據(jù)表示,行為用一組方法表達。

2)類

引例中“銀行賬戶”用以描述所有“賬戶”這一類整體事物的共有特性,在Java語言中,把這樣一個抽象的類型概念稱為“類”?,F(xiàn)實世界中“人”、“動物”、“學生”、“飛機”、“辦公桌”等均表示一個類別,這在Java語言中都算作一個“類”。

在Java語言程序設計中,類是一個獨立的程序單位,是具有相同屬性和方法的一組對象的集合。類的概念使我們能對屬于該類的全部對象進行統(tǒng)一的描述。例如,“樹具有樹根、樹干、樹枝和樹葉,它能進行光合作用”,這個描述適合于所有的樹,從而不必對每棵具體的樹都進行一次這樣的描述。因此,描述一個類需要指明下述三個方面的內容:

(1)類標識:類的一個有別于其他類的名字。在Java語言中就是給“類”按第2章中所規(guī)定的命名規(guī)則定義名稱,這是必不可少的。

(2)屬性說明:用來描述相同對象的靜態(tài)特征。在Java語言中是聲明一組數(shù)據(jù)成員變量,用一組數(shù)據(jù)表示相同對象的狀態(tài)。

(3)方法說明:用來描述相同對象的動態(tài)特征。在Java語言中是聲明一組方法,用以改變數(shù)據(jù)成員的值,從而達到改變上述由一組數(shù)據(jù)表示的相同對象的狀態(tài)。

可用圖3-1直觀描述“類”,引例中“銀行賬戶”類描述如圖3-2所示。圖3-1類的圖形表示圖3-2“銀行賬戶”類

3.類與對象的關系

類給出了屬于該類全部對象的抽象定義,而對象則是符合這種定義的一個實體。類與對象之間的關系就如同一個模具與用這個模具鑄造出來的鑄件之間的關系一樣。也就是說,我們可以把類與對象之間的關系看成是抽象與具體的關系。在面向對象的程序設計中,對象被稱做類的一個實例(instance),而類是對象的模板(template)。類是多個實例的綜合抽象,而實例又是類的個體實物。我們用圖3-3再次表示類與對象的關系。圖3-3類與對象的實例化由于對象是類的實例,因此在定義對象之前應先定義類。在定義了類之后,才可以在類的基礎上創(chuàng)建對象,這就好比先設計樓群的圖紙,然后依據(jù)所預先設計好的圖紙建造樓房一樣?!邦悺本褪且粡埥ㄖO計的“圖紙”,而對象就是依據(jù)圖紙建造的“樓房”。3.2.1“銀行賬戶”類的聲明

依據(jù)3.1.3節(jié)有關類的分析可知,要定義一個類,必須聲明一個類名,然后定義這個類的屬性和方法。引例中“銀行賬戶”可用Java語言定義為例3-1所示的類。

【例3-1】Account.java程序。

//銀行賬戶

publicclassAccount

{

//銀行賬戶的屬性

privatedoublebalance=0; //賬戶余額3.2類的定義//向賬戶中存款,存款金額為amount

publicvoiddeposit(doubleamount)

{

balance=balance+amount;

}

//從賬戶中取款,取款金額為amount;取款成功返回true,否則返回false

publicbooleanwithdraw(doubleamount){

if(amount<=balance)

{

balance=balance-amount;

returntrue;

}

else

{

returnfalse;}

}

//查詢賬戶的當前余額

publicdoublegetBalance()

{

returnbalance;

}

}為了后續(xù)說明問題的簡明,例3-1定義的類中屬性聲明只選取了最主要的賬戶余額屬性。

例3-1用保留字public和class引出定義銀行賬戶的類名Account,?類名必須是一個有效的標識符,習慣上以大寫字母開頭。類名后以大括號括住的內容稱為類體,在類體中可聲明多個成員,這些成員分為數(shù)據(jù)成員和方法成員。數(shù)據(jù)成員用于定義類的屬性,例如balance表示賬戶的當前存款余額;方法成員用于定義類的行為,例如deposit()、withdraw()和getBalance()分別描述了賬戶的存款、取款和查詢余額行為。3.2.2定義類的一般格式

進行Java語言程序設計的過程,實際上就是定義類的過程。一個Java源程序文件往往是由許多個類組成的。從用戶的角度看,Java源程序中的類分為兩種:

(1)用戶自己定義的類。用戶按照Java的語法規(guī)則,把所研究的問題描述成Java程序中的類,以解決特定問題。進行Java語言程序設計,首先要從定義類開始。在Java程序中,用戶自己定義類的一般格式如下:

class類名

{

數(shù)據(jù)成員

成員方法

}可以看出,類的結構是由類頭部和類體兩部分組成的。類的頭部主要由關鍵字class與類名組成,類名的命名遵循Java標識符的定義規(guī)則;類體是類聲明中大括號所包括的全部內容,它又由數(shù)據(jù)成員(屬性)和成員方法(方法)兩部分組成。數(shù)據(jù)成員描述對象的屬性;成員方法刻畫對象的行為或動作,每一個成員方法確定一個功能或操作。

(2)系統(tǒng)定義的類,即Java類庫,它是系統(tǒng)定義好的類。類庫是Java語言的重要組成部分。

Java語言由語法規(guī)則和類庫兩部分組成:語法規(guī)則確定Java程序的書寫規(guī)范;類庫則提供了Java程序與運行它的系統(tǒng)軟件(Java虛擬機)之間的接口,即常說的JavaAPI(JavaApplicationProgrammingInterface)。

Java類庫是一組由它的發(fā)明者Sun公司以及其他軟件開發(fā)商編寫好的Java程序模塊,每個模塊通常對應一種特定的基本功能和任務,且這些模塊都是經(jīng)過嚴格測試的,因而也總是正確有效的。當用戶編寫的Java程序需要完成其中某一功能的時候,就可以直接利用這些現(xiàn)成的類庫,而不需要一切從頭編寫,這樣不僅可以提高編程效率,也可以保證軟件的質量。關于Java類庫的更多內容和使用將在后續(xù)章節(jié)中介紹。3.2.3數(shù)據(jù)的封裝與隱藏

1.類成員的訪問控制

在聲明一個類的成員時,可用保留字private和public控制數(shù)據(jù)成員或方法成員是否允許其他程序片段訪問。

在private后聲明的成員稱為私有成員,這些成員僅能由該類中聲明的方法成員來訪問。例如,例3-1中類Account的屬性balance被聲明為私有的,故只有在該類中聲明的deposit()、withdraw()和getBalance()等方法體中才可訪問該屬性,在其他類中聲明的方法體或在main()方法體中均禁止訪問該屬性。在public后聲明的成員稱為公有成員,這些成員是類與外部程序的接口,除該類本身聲明的方法成員可訪問這些成員外,其他類中聲明的方法成員或main()方法均可訪問這些成員。例如,例3-1中類Account的行為deposit()、withdraw()和getBalance()被聲明為公有的,因而其他程序片段都可訪問這些行為。設計類成員訪問控制的最常用策略是將所有數(shù)據(jù)成員聲明為私有的,以實現(xiàn)信息隱藏;將所有方法成員聲明為公有的,以供其他程序片段使用。這種設計模式的好處是,當一個類的屬性表示方法發(fā)生變化時,只需修改類中一些方法成員的方法體代碼,只要該類能保持所有方法成員的接口及其實現(xiàn)的功能不變,那么上述變化就不會影響到使用該類的其他程序。

2.封裝與隱藏

按上述策略設計的類實現(xiàn)了軟件工程的“封裝”與“信息隱藏”原則。封裝是指將數(shù)據(jù)及作用在這些數(shù)據(jù)上的操作組織在一起,例如,例3-1將存款余額以及作用在這一數(shù)據(jù)上的存款、取款和查詢余額等操作在邏輯上組織為一個整體。信息隱藏是指對象的某些特征只在對象內部可見,外部程序只能訪問那些允許它訪問的特征,例如,對于例3-1定義的銀行賬戶,存款余額這一數(shù)據(jù)只能由該類本身的方法成員訪問,其他程序片段無法直接讀取或修改賬戶的存款余額,而只能通過查詢余額操作獲取該數(shù)據(jù)的值,或通過存款和取款操作改變該數(shù)據(jù)的值。如果設計的類中有一個數(shù)據(jù)成員需要對外公開,就要仔細研究其他程序片段是僅僅需要讀取該數(shù)據(jù)成員的值,還是需要修改該數(shù)據(jù)成員的值。若是前者則仍應將數(shù)據(jù)成員聲明為私有的,然后提供一個返回該數(shù)據(jù)的公有方法成員,如例3-1的getBalance()方法。若是后者則有兩種處理方式:一是將數(shù)據(jù)成員聲明為公有;二是將數(shù)據(jù)成員聲明為私有并提一個公有的訪問方法和一個公有的修改方法。

返回私有數(shù)據(jù)成員的那些公有方法成員又稱getter方法,因為這些公有方法通常命名為get…()(注意對布爾類型返回值通常命名為is…());修改私有數(shù)據(jù)成員的那些公有方法成員又稱setter方法,因為這些方法通常命名為set…()。3.3.1對象的創(chuàng)建和引用

從前述對象與類的關系可知,定義好類后,就可以創(chuàng)建若干個對象,且讓對象相互協(xié)作完成指定的功能。下面使用例3-1定義的“銀行賬戶”類(Account)創(chuàng)建對象guoJing(郭敬)和對象yangGuo(楊過),實現(xiàn)引例中的存款、取款與轉賬功能。

【例3-2】Bank.java程序。3.3類?的?實?例?化//利用Account類實現(xiàn)銀行賬戶管理

publicclassBank

{

publicstaticvoidmain(Stringargs[])

{

//為郭敬開一個賬戶,存入5000元后又取出300元

AccountguoJing;//聲明一個名為guoJing的對象,此時稱為“對象引用” guoJing=newAccount();//創(chuàng)建對象,此時“對象”又稱為“對象實例”

guoJing.deposit(5000);

if(!guoJing.withdraw(300))

System.out.println("余額不足,取款失?。?);

else

System.out.println("取款成功,金額為300元!");

//為楊過開一個賬戶

AccountyangGuo=newAccount();

//從郭敬的賬戶中取出4500元存入楊過的賬戶

if(!guoJing.withdraw(4500))

System.out.println("余額不足,轉賬失敗!");

else

yangGuo.deposit(4500);

//查詢賬戶余額

System.out.println("郭敬的賬戶余額為"+guoJing.getBalance());

System.out.println("楊過的賬戶余額為"+yangGuo.getBalance());

}

}

對Bank.java程序進行以下分析。

1.聲明對象

聲明對象的語法格式如下:

類名對象名;

如上例中AccountguoJing,其中Account是例3-1已經(jīng)定義的類,guoJing為Account類的一個對象。此時,Java為對象guoJing分配一個內存單元,其中存放值為Null,如圖3-4所示。圖3-4聲明對象

2.創(chuàng)建對象

例3-2程序中,語句guoJing=newAccount();意為創(chuàng)建對象,功能有三:一是為對象guoJing分配一段新的內存空間用以存放對象的數(shù)據(jù)成員;二是給對象guoJing的數(shù)據(jù)成員變量賦一個初始值(初始化數(shù)據(jù)成員);三是將新分配存放對象數(shù)據(jù)成員的一塊內存區(qū)域的首地址存放至圖3-4所示的內存單元中,此時其中的Null變?yōu)橐粋€地址值,如圖3-5所示。圖3-5創(chuàng)建對象

3.對象實例與對象引用

圖3-5中,對象的數(shù)據(jù)成員變量blance所占有的這塊無名的內存區(qū)域,Java中稱其為對象實例,它只能通過對象名guoJing來引用;從對象的聲明可以看出,guoJing實際上可以理解為一個類型的變量名,這個類型的變量在Java中稱為對象引用。

從前述可知,對象引用在對象聲明時就產(chǎn)生了,它只占一個內存單元;而對象實例只有用new創(chuàng)建對象完成后才存在于內存中,占一塊內存區(qū)域,它只能通過對象引用來使用。由此,對象的創(chuàng)建又稱類的實例化。

4.對象中方法成員與數(shù)據(jù)成員的引用

類的定義還決定了該類所有對象實例的可用操作。例如,類Account定義了3個公有方法成員deposit()、withdraw()和getBalance(),故Account類的所有對象只能調用這3個方法。調用一個對象的方法成員時必須在方法名前加上對象名和“·”號,除此之外用法與普通方法的調用相似。調用一個對象的方法成員也是一個表達式,如果其返回結果不是void類型則還可作為子表達式參與運算,調用時實際參數(shù)必須與形式參數(shù)匹配。例3-2程序中,創(chuàng)建對象guoJing后即用表達式guoJing.deposit(5000)調用該對象的deposit()方法成員。該方法成員的方法體為

publicvoiddeposit(doubleamount)

{

balance=balance+amount;

}實際參數(shù)5000傳遞給形式參數(shù)amount后開始執(zhí)行方法體。注意,上述方法體對于對象guoJing和yangGuo而言完全相同,方法體中出現(xiàn)的名字balance引用對象的數(shù)據(jù)成員,那么執(zhí)行方法體時到底將amount累加到哪一個對象的數(shù)據(jù)成員呢?這由發(fā)出調用的對象決定,即guoJing.deposit(5000)將5000元累加到對象guoJing的余額,yangGuo.deposit(4500)將4500元累加到對象yangGuo的余額,應留意到對象guoJing和yangGuo的賬戶余額屬性存放在不同的存儲空間中,如圖3-6所示。圖3-6Account類型的對象存儲組織示意圖由于對象guoJing和yangGuo的類型均為Account,所以在Account類中定義的數(shù)據(jù)成員決定了它們的狀態(tài),即它們均有一個名為balance的域,該域的取值決定了對象的狀態(tài)。盡管對象guoJing和yangGuo的存儲結構相同,但guoJing的balance域和yangGuo的balance域是分開存儲的,所以它們的狀態(tài)很可能不同。對象yangGuo剛創(chuàng)建時余額為0,因為類Account將數(shù)據(jù)成員balance初始化為0,故每一Account類型的對象的初始余額均為0。由圖3-6可見,每一對象的數(shù)據(jù)成員占據(jù)不同內存區(qū)域,但所有對象的方法成員共享同一段程序代碼,這樣就可以節(jié)省大量存儲空間。

下列語句:

if(!guoJing.withdraw(4500))

System.out.println(“余額不足,轉賬失敗!”);

else

yangGuo.deposit(4500);從對象guoJing取出4500元后存入對象yangGuo。注意withdraw()方法作用在對象guoJing上,而deposit()方法作用在對象yangGuo上,并且當執(zhí)行if語句的else部分時,對象guoJing上的withdraw()方法肯定已成功執(zhí)行完畢。

同理,表達式guoJing.withdraw(100)首先判斷對象guoJing是否有足夠余額,如果不透支則完成取款操作。該表達式的返回值是boolean類型,故可參與“邏輯非”運算并作為if語句的條件表達式。由于大多數(shù)情況下對象屬性定義為私有數(shù)據(jù)成員,對象行為定義為公有方法成員,故訪問對象的最常見方法是調用對象的方法成員。如果一個對象的屬性被定義為公有的,則也可直接通過該對象訪問這些數(shù)據(jù)成員,調用一個對象的數(shù)據(jù)成員時必須在數(shù)據(jù)成員名前加上對象名和“.”號,除此之外其用法與普通數(shù)據(jù)的用法相同。

5.程序運行的結果

只要將例3-1程序Account.java和例3-2程序Bank.java的源代碼文件放在同一子目錄中,用java命令編譯Account.java和Bank.java后,用Java命令裝入Bank類即可運行該程序。該程序的運行輸出結果是:

取款成功,金額為300元!

郭敬的賬戶余額為200

楊過的賬戶余額為4500

至此,引例提出的問題得以解答。3.3.2對象的初始化和構造方法

一個對象的數(shù)據(jù)成員反映了該對象的內部狀態(tài),聲明一個類的數(shù)據(jù)成員時可用初始化設置數(shù)據(jù)成員的初始值,創(chuàng)建對象實例時這些初始化語句會自動執(zhí)行一次。例3-1定義的類Account中將數(shù)據(jù)成員balance初始化為0,故每一賬戶對象創(chuàng)建時的初始余額均為0。

如果對象需要更復雜的初始化操作,則可為類定義一個構造方法。構造方法是一種專門用來設置對象的初始狀態(tài)的方法成員,其方法名與類名相同且不可有返回值類型(即使void類型也不行),但允許像普通方法那樣定義一個形式參數(shù)表。用類創(chuàng)建一個對象實例時,該類的構造方法會被自動執(zhí)行一次,從而確定對象的初始狀態(tài)。如果程序不設置對象的初始狀態(tài),Java語言會按一定規(guī)則初始化對象的數(shù)據(jù)成員,例如:int類型的數(shù)據(jù)被初始化為0,float和double類型的數(shù)據(jù)均初始化為0.0,boolean類型的數(shù)據(jù)均初始化為false,引用類型均初始化為Null。

最好不要依賴這些約定,應利用構造方法明確表示出初始化對象的狀態(tài)。

例3-3和例3-4改寫了例3-1和例3-2,因為這里假設應用需求是對信用卡賬戶進行管理,而信用卡與普通銀行賬戶的最大區(qū)別是允許透支,所以例3-3和例3-4類CreditCard比例3-1中定義的類Account多引入一個表示透支限額的屬性maxOverdraft。【例3-3】CreditCard.java程序。

//信用卡賬戶

publicclassCreditCard

{

//信用卡賬戶屬性

privatedoublemaxOverdraft; //透支限額

privatedoublebalance; //存款余額

//構造方法,將透支限額maxOverdraft設置為max

publicCreditCard(doublemax){

maxOverdraft=max;

if(max>=1000)

balance=100;

else

balance=0;

}

//向賬戶中存款,存款金額為amount

publicvoiddeposit(doubleamount){

balance=balance+amount;

}

//從賬戶中取款,取款金額為amount;取款成功返回true,否則返回false

publicbooleanwithdraw(doubleamount)

{

if(balance<=amount+maxOverdraft)

{

balance=balance-amount;returntrue;

}else

returnfalse;

}

//查詢賬戶的當前余額

publicdoublegetBalance()

{

returnbalance;

}

}由于構造方法將用于創(chuàng)建對象實例,所以構造方法通常應定義為公有。

假設銀行允許每張信用卡有不同的透支限額,并且一旦開戶后禁止改變透支限額,透支限額在1000元以上的還必須在開戶時存入100元,那么在創(chuàng)建對象時應該用構造方法確定透支限額。如果將設置透支限額設計為一個普通方法成員,那么程序員在創(chuàng)建對象時有可能忘記立即調用一次該方法,并且在開戶后仍有機會改變信用卡的透支限額,所以普通方法成員并不適合處理這種在對象的整個生命期開始時僅執(zhí)行一次的行為。例3-3中,類CreditCard的構造方法名字約定為CreditCard,有一個名為max的形式參數(shù),注意在保留字public后沒有方法的返回值類型。由上述程序可見,使用構造方法確實方便了對象的初始化,并且還可在構造方法中約束初始值的合理取值范圍。

為保證構造方法僅在創(chuàng)建對象實例時調用一次,Java語言禁止程序員像調用普通方法成員那樣調用構造方法。程序員不必顯式地寫出調用構造方法的調用表達式,Java語言會在創(chuàng)建對象實例時自動調用構造方法。例3-4中的下列語句:

CreditCardguoJing=newCreditCard(1000);

CreditCardyangGuo=newCreditCard(500);創(chuàng)建了兩個對象guoJing和yangGuo,每創(chuàng)建一個對象都會自動調用一次CreditCard類的構造方法。括號中的1000和500分別是兩次調用中傳遞給形式參數(shù)max的實際參數(shù),所以對象guoJing創(chuàng)建后的初始狀態(tài)是maxOverdraft為1000、balance為100,對象yangGuo創(chuàng)建后的初始狀態(tài)是maxOverdraft為500、balance為0。【例3-4】CreditCardDemo.java程序。

//利用CreditCard類實現(xiàn)信用卡賬戶管理

publicclassCreditCardDemo

{

publicstaticvoidmain(Stringargs[])

{

//為郭敬開一個信用卡,允許最大透支限額為1000元

CreditCardguoJing=newCreditCard(1000);

//郭敬的信用卡存入500元后又取出100元

guoJing.deposit(500);

if(!guoJing.withdraw(100))

System.out.println("余額不足,取款失敗!");

//為楊過開設一個信用卡,允許最大透支額為500元

CreditCardyangGuo=newCreditCard(500);

//從郭敬的信用卡取出700元,存入楊過的信用卡

if(!guoJing.withdraw(700))

System.out.println("余額不足,轉賬失?。?);else

yangGuo.deposit(700);

//查詢郭敬和楊過的信用卡余額

System.out.println("郭敬的信用卡余額為"+guoJing.getBalance());

System.out.println("楊過的信用卡余額為"+yangGuo.getBalance());

}

}3.3.3靜態(tài)成員與static修飾符

1.類變量

如果上一小節(jié)的應用需求改為所有信用卡的透支限額是相同的,那么上述程序仍有待改進,因為按類CreditCard的上述定義,每一個信用卡對象都保存了一個名為maxOverdraft的域,這一方面浪費了存儲空間,另一方面給統(tǒng)一調整透支限額造成麻煩,并可能出現(xiàn)兩個對象的透支限額不一致的現(xiàn)象。如果將問題追溯到現(xiàn)實世界的需求分析,此時透支限額這一屬性與其說是每一信用卡個體的屬性,還不如說是信用卡整體的屬性。所以在程序建模時透支限額應是信用卡類的屬性而不是郭敬或楊過等某一個對象的屬性。像maxOverdraft這種屬性通常稱為類的屬性,也叫類變量,而像balance這種屬性則稱為對象實例的屬性。

在Java語言中,要將屬性定義為靜態(tài)的,只需在屬性定義前加上保留字static,那么該屬性即被定義為類的屬性而不是某一對象實例的屬性。在例3-5的程序中屬性maxOverdraft被定義為靜態(tài)的,因而不管程序中創(chuàng)建了多少個信用卡的對象實例,maxOverdraft屬性只會保存一份。例3-6演示了該類的用法。【例3-5】UniformCreditCard.java程序。

//采用統(tǒng)一透支限額的信用卡賬戶

publicclassUniformCreditCard

{

//聲明類屬性(類變量)

privatestaticdoublemaxOverdraft=1000; //透支限額

//聲明實例屬性

privatedoublebalance=0; //存款余額//向賬戶中存款,存款金額為amount

publicvoiddeposit(doubleamount)

{

balance=balance+amount;

}

//從賬戶中取款,取款金額為amount;取款成功返回true,否則返回false

publicbooleanwithdraw(doubleamount)

{if(amount<=balance+maxOverdraft)

{

balance=balance-amount;

returntrue;

}else

returnfalse;

}

//查詢賬戶的當前余額

publicdoublegetBalance()

{

returnbalance;

}

}我們也可為上述類定義一個構造方法,將類屬性maxOverdraft和實例屬性balance的初始化語句放在構造方法中,請讀者自己完成。

【例3-6】UniformCreditCardDemo.java程序。

//利用UniformCreditCard類實現(xiàn)信用卡賬戶管理

publicclassUniformCreditCardDemo

{

publicstaticvoidmain(Stringargs[])

{

//為郭敬開一個信用卡UniformCreditCardguoJing=newUniformCreditCard();

//郭敬的信用卡存入500元后又取出100元

guoJing.deposit(500);

if(!guoJing.withdraw(100))

System.out.println("余額不足,取款失敗!");

//為楊過開設一個信用卡

UniformCreditCardyangGuo=newUniformCreditCard();

//從郭敬的信用卡取出700元,存入楊過的信用卡

if(!guoJing.withdraw(700))

System.out.println("余額不足,轉賬失敗!");

else

yangGuo.deposit(700);

//查詢郭敬和楊過的信用卡余額

System.out.println("郭敬的信用卡余額為"+guoJing.getBalance());

System.out.println("楊過的信用卡余額為"+yangGuo.getBalance());

}

}創(chuàng)建對象實例時,即使沒有構造方法或構造方法的形式參數(shù)表為空,new和類名后的空括號也必須保留。

由于靜態(tài)數(shù)據(jù)成員由一個類的所有對象實例共享,所以此時對象guoJing和yangGuo的存儲組織如圖3-7所示。圖3-7UniformCreditCard類型的隨想存儲組織示意圖

2.類方法

不僅一個類的數(shù)據(jù)成員可定義為靜態(tài)的,一個類的方法成員也可定義為靜態(tài)的。對于普通方法成員(如Account類的deposit()、withdraw()或getBalance()方法),必須先創(chuàng)建該類的一個對象實例(如對象guoJing),然后通過該對象實例才可調用這些方法成員(如guoJing.deposit(500))。但對于靜態(tài)方法成員,無須創(chuàng)建任何對象實例,直接以類名加小數(shù)點為前綴即可調用它們。讀者可能早已注意到,所有程序的main()方法必須聲明為靜態(tài)的,因為該方法也應該不需要任何對象實例就可以執(zhí)行。

由于靜態(tài)方法成員在沒有對象實例的情況下執(zhí)行,所以在靜態(tài)方法成員的方法體中不可引用任何非靜態(tài)成員(這些非靜態(tài)成員屬于某一對象所有),在它們的方法體中只能引用靜態(tài)的數(shù)據(jù)成員或調用靜態(tài)的方法成員。例3-7中為信用卡類引入一個新方法adjustOverdraft()用于統(tǒng)一調整所有信用卡賬戶的透支限額,由于該方法不是調整某一對象實例的狀態(tài),所以應設計為靜態(tài)的方法成員,并且在其方法體中僅訪問了靜態(tài)數(shù)據(jù)成員maxOverdraft。

【例3-7】AdjustableCreditCard.java程序。//透支限額可浮動的信用卡賬戶管理

publicclassAdjustableCreditCard

{

//聲明類變量

privatestaticdoublemaxOverdraft=1000;

//透支限額//實例變量

privatedoublebalance=0;

//存款余額//將所有信用卡賬戶的透支限額設置為max

publicstaticvoidadjustOverdraft(doublemax)

{

maxOverdraft=max;

}

//向賬戶中存款,存款金額為amount

publicvoiddeposit(doubleamount){

balance=balance+amount;

}

//從賬戶中取款,取款金額為amount;取款成功返回true,否則返回false

publicbooleanwithdraw(doubleamount)

{

if(amount<=balance+maxOverdraft){

balance=balance-amount;

returntrue;

}else

returnfalse;

}

//查詢賬戶的當前余額

publicdoublegetBalance()

{returnbalance;

}

//主方法

publicstaticvoidmain(Stringargs[])

{

//為郭敬開一個信用卡

AdjustableCreditCardguoJing=newAdjustableCreditCard();

//郭敬的信用卡存入500元后又取出100元guoJing.deposit(500);

if(!guoJing.withdraw(100))

System.out.println("余額不足,取款失?。?);

//為楊過開設一個信用卡

AdjustableCreditCardyangGuo=newAdjustableCreditCard();

//重新設置所有信用卡的透支限額為1200元

AdjustableCreditCard.adjustOverdraft(1200);

//從郭敬的信用卡取出1500元,存入楊過的信用卡

if(!guoJing.withdraw(1500))System.out.println("余額不足,轉賬失??!");

else

yangGuo.deposit(1500);

//查詢郭敬和楊過的信用卡余額

System.out.println("郭敬的信用卡余額為"+guoJing.getBalance());

System.out.println("楊過的信用卡余額為"+yangGuo.getBalance());

}

}例3-7將main()方法直接放在類AdjustableCreditCard中,這與分開放置在兩個不同的類中的效果相同,只不過分為兩個文件存放時它們必須位于同一子目錄中。無論采用哪一種組織方式,用Java命令啟動時,該命令后接的參數(shù)必須是含有main()方法的類名。

思考請讀者嘗試在上述靜態(tài)方法成員adjustOverdraft()中訪問非靜態(tài)數(shù)據(jù)成員balance或調用非靜態(tài)方法成員getBalance(),看看編譯時會出現(xiàn)什么錯誤信息。3.3.4對象的參數(shù)傳遞方式

一個方法的形式參數(shù)類型既可以是本書第2章中所學的基本數(shù)據(jù)類型,也可以是由用戶自己設計的類定義的類型,亦即對象也可作為參數(shù)使用。

對象作參數(shù)與普通變量作參數(shù)的用法相似,例3-8改寫了例3-2,將其中的轉賬功能抽象為一個獨立的方法。將例3-8定義的Transfer類與例3-1定義的Account類合在一起就是一個完整的程序,用Java命令分別編譯這兩個類,然后再用Java命令裝入Transfer即可運行程序?!纠?-8】Transfer.java程序。

//利用Account類實現(xiàn)銀行賬戶管理,用方法實現(xiàn)轉賬以演示對象作為參數(shù)的用法

publicclassTransfer

{

//從賬戶source轉賬到賬戶target;轉賬成功返回true,否則返回false

publicstaticbooleantransfer(Accountsource,Accounttarget,doubleamount){

if(!source.withdraw(amount))

returnfalse;

else

{

target.deposit(amount);

returntrue;

}

}//主方法

publicstaticvoidmain(Stringargs[])

{

//為郭敬開一個賬戶

AccountguoJing=newAccount();

//郭敬的賬戶存入500后又取出100元

guoJing.deposit(500);

if(!guoJing.withdraw(100))

System.out.println("余額不足,取款失敗!");

//為楊過開一個賬戶AccountyangGuo=newAccount();

//從郭敬的賬戶中取出150元存入楊過的賬戶

if(!transfer(guoJing,yangGuo,150))

System.out.println("余額不足,轉賬失?。?);

//查詢郭敬和楊過的賬戶余額

System.out.println("郭敬的賬戶余額為"+guoJing.getBalance());

System.out.println("楊過的賬戶余額為"+yangGuo.getBalance());

}

}

思考

main()中的實際參數(shù)guoJing和yangGuo在調用轉賬方法transfer()后其狀態(tài)有無改變?請讀者自行嘗試運行上述程序。

由于轉賬涉及轉出賬戶、轉入賬戶以及轉賬金額,因此我們?yōu)榉椒╰ransfer()設計了三個形式參數(shù):轉出賬戶source和轉入賬戶target的類型均為Account,轉賬金額類型為double。在main()方法中調用transfer()方法時以對象guoJing和yangGuo為實際參數(shù),運行結果表明以對象為參數(shù)時實際參數(shù)的值(即對象的狀態(tài))會被改變,這是對象作為參數(shù)與基本數(shù)據(jù)類型的變量作為參數(shù)的主要區(qū)別。盡管Java語言僅提供了一種參數(shù)傳遞方式,即按值調用,但由于在Java語言的對象模型中所有對象名都表示對象的引用而不是對象本身,所以對象作為參數(shù)傳遞的效果與按引用調用的參數(shù)傳遞方式相同。3.4.1數(shù)值運算

由JavaAPI提供的Math類提供了常用數(shù)值運算的符號常量與方法。由該類定義的符號常量包括了高精度的自然對數(shù)底e和圓周率π,在程序中可分別用Math.E和Math.PI表示e和π。該類定義主要方法的對外接口及其功能簡述如表3-1所示。3.4使用JavaAPI表3-1Math類提供的數(shù)值運算方法3.4.2偽隨機數(shù)

在Math類中定義random()方法用于生成一個0.0~1.0之間的偽隨機數(shù),該方法被調用一次就返回一個“隨機”產(chǎn)生的數(shù)。偽隨機數(shù)的用途很多,例如,可用偽隨機數(shù)模擬游戲中的發(fā)牌或擲骰子,也可用偽隨機數(shù)生成兩個數(shù)的四則運算題目幫助小學生做練習,甚至還可用大量隨機分布的點落在一個單位正方形中與落在一個90°單位扇形中的概率粗略計算圓周率π的值。盡管Math.random()方法生成的偽隨機數(shù)位于0.0~1.0之間,但只要將得到的偽隨機數(shù)放大并轉換為整數(shù)類型,就可獲得某一個特定取值范圍的偽隨機數(shù)。例如,可采用如下語句得到一個范圍在1~m的整數(shù)類型偽隨機數(shù):

intr=1+(int)(Math.random()*m);

預定類Math提供了許多數(shù)值運算操作,這些方法成員都被定義為靜態(tài)的,所以無須創(chuàng)建任何Math類型的對象實例,直接以Math.為前綴即可調用這些方法(在JDK5.0以后,可以不加前綴Math.)。在許多小學生中流行一種名為速算24的游戲,據(jù)說該游戲對訓練兒童的算術能力與邏輯思維有很大幫助。游戲玩法是從一副沒有J、Q、K和王牌的撲克牌中隨機抽出4張牌,能最快運用加、減、乘、除四則運算算出24者為勝方,要求每一張牌有且僅有一次參與運算。

例3-9是一個供練習速算24游戲的發(fā)牌程序,利用Math.random()方法獲得一個范圍為1~10的整數(shù)類型偽隨機數(shù)。該程序將最大牌面10定義為符號常量max是為了提高程序的可擴充性,因為另一種玩法是將撲克牌中的J、Q和K分別作為11、12和13,此時只需將程序中的max設置為13即可。【例3-9】Game24.java程序。

//速算24游戲的發(fā)牌程序

publicclassGame24

{

publicstaticvoidmain(String[]args)

{

finalintmax=10;

//連發(fā)4張牌

System.out.print("請聽題:");

for(intindex=0;index<4;index++)

{

//生成一個1~max之間的偽隨機數(shù)

intcard=1+(int)(Math.random()*max);

//輸出1張牌

System.out.print(card+"");

}

System.out.println();

}

}

提示上述發(fā)牌程序在抽取1張牌時未考慮前面已被抽走的牌。對于抽取4張牌不會產(chǎn)生問題,因為速算24游戲只考慮牌的大小而不考慮花色。但如果模擬從一副牌中隨機抽取5張牌則需考慮該問題,否則可能出現(xiàn)從一副牌中抽取5張A的笑話。3.5.1使用String類型的對象

我們在第2章已知道,形如“ProgramminginJava”的常量是一個字符串類型的常量,而以下語句:

Stringname=“LiMing”;

則聲明了一個名為name的字符串變量。無論是字符串常量還是字符串變量,都是String類型的對象,因而這些對象可像普通對象一樣,通過其后接小數(shù)點和方法名的形式調用String類提供的方法。3.5字符串類String3.5.2類String的主要方法

我們經(jīng)常會比較兩個字符串是否相等,即兩個字符串中每一位置的字符是否相同,有時這種比較還可能需要忽略英文字母大小寫的差異。

此外,兩個字符串s1和s2還可比較大小,其做法是從左到右逐位比較字符串s1和s2中的字符,如果發(fā)現(xiàn)不相等立即停止比較,這時哪一個字符串中的字符大則認為該字符串大;如果其中一個字符串已經(jīng)到頭還未發(fā)現(xiàn)不相等的字符,則認為長的字符串大。根據(jù)上述規(guī)則,字符串“ABDC”比“ABCD”大,“X.1”比“AK-47”大,“Programming”比“Program”大。

String類提供的字符串比較方法如表3-2所示。表3-2字符串比較的方法

提示比較字符串s1和s2的內容是否相等的正確方法是if(s1.equals(s2))……如果你不小心采用了if(s1==s2)……則比較結果可能出乎你的意料。

比較兩個字符的大小時,Java語言依據(jù)Unicode編碼標準的次序,排序在前的字符較小。對英文字母而言,該標準的字符次序同ASCII碼;對漢字而言,該標準的字符次序同GB2312碼。

表3-3所示的方法可用于訪問字符串中某一位置的字符或判斷某一字符出現(xiàn)在字符串的什么位置。表3-3串中字符訪問的方法字符串計算下標位置時是從0開始而不是從1開始,訪問字符串中的字符時下標不可越界,否則程序會產(chǎn)生運行時異常的錯誤。由于同一字符在一個字符串可能出現(xiàn)多次,所以我們有訪問最前或最后出現(xiàn)的需要。

一個字符串中連續(xù)的一段字符序列稱為該字符串的子串,諸如會計電算化程序中的會計科目編號或進銷存管理程序中的貨品編號通常采用結構化的層次編碼方法(例如,在會計科目表中,102表示銀行存款,102001表示賬號1的存款,102002表示賬號2的存款,等等),所以應用程序經(jīng)常需要分析字符串的子串。String類提供的子串處理方法如表3-4所示。表3-4子串處理的方法兩個字符串的加法運算即為字符串的連接,該運算不滿足交換律。一個字符串也可與字符、整數(shù)、浮點數(shù)等類型的數(shù)據(jù)作加法運算,即字符串作為加法運算的左操作數(shù),字符、整數(shù)、浮點數(shù)等類型的數(shù)據(jù)作為加法運算的右操作數(shù),此時這些類型的數(shù)據(jù)會轉換為字符串類型后連接到該字符串之后。

String類提供的關于字符串處理的其他方法如表3-5所示。表3-5串處理的其他方法3.5.3使用字符串對象的例子

例3-10的程序演示了如何利用String類提供的方法對字符串常量或字符串變量進行處理。

【例3-10】StringDemo.java程序。

//演示字符串對象的用法

publicclassStringDemo

{publicstaticvoidmain(String[]args)

{

//訪問字符串長度

StringmyName="Gleeman"

intlength="張三豐".length();

System.out.println("長度1:"+myName.length()); //輸出7

System.out.println("長度2:"+length); //輸出3而不是6//比較字符串大小

Stringname1="programminginjava";

Stringname2="ProgramminginJava";

System.out.println("比較1:"+name1.equals(name2)); //輸出false

System.out.println("比較2:"+name1.equalsIgnoreCase(name2)); //輸出true

System.out.println("比較3:"+pareTo(“Program”)); //輸出正數(shù)12//訪問字符串中的字符

System.out.println("字符1:"+name1.charAt(4)); //輸出r而不是g

System.out.println("字符2:"+name1.indexOf('a')); //輸出5

System.out.println("字符3:"+name2.lastIndexOf('a')); //輸出18//訪問字符串中的子串

Stringsubname="in";

System.out.println("子串1:"+name1.substring(3,10)); //輸出grammin

System.out.println("子串2:"+"abc".concat("123")); //輸出abc123

System.out.println("子串3:"+name2.startsWith("Pro")); //輸出true

System.out.println("子串4:"+name2.endsWith("inJava")); //輸出true

System.out.println("子串5:"+name1.indexOf(subname)); //輸出8

System.out.println("子串6:"+name1.lastIndexOf(subname)); //輸出12

//字符串的其他操作

System.out.println(“小寫:”+name2.toLowerCase()); //輸出programminginjava

System.out.println(“大寫:”+name2.toUpperCase()); //輸出PROGRAMMING//INJAVA

System.out.println(“替換:”+name1.replace(‘a(chǎn)’,‘A’)); //輸出progrAmminginjAvA

}

}

用String類的length()方法計算字符串長度時,一個漢字與一個英文字母或符號的長度均為1。

【例3-11】判斷回文字符串程序Rotor.java。

回文是一種“從前向后讀”和“從后向前讀”都相同的字符串,如“rotor”是一個回文字符串。程序中使用了兩種算法來判斷回文字符串。

算法一:分別從前向后和從后向前依次獲得源串str的一個字符ch1和ch2,比較ch1和ch2,如果不相等,則str肯定不是回文字符串,yes=false,立即退出循環(huán);否則,繼續(xù)比較,直到str的所有字符全部比較完,yes的值仍為true,才能肯定str是回文字符串。算法二:將源串str反轉成temp串,再比較兩串,如果相等則是回文字符串。

程序中比較兩個字符時,使用關系運算符=?=;而比較兩個字符串,則需使用equals()方法。程序如下:

publicclassRotor

{

publicstaticvoidmain(String[]args)

{

Stringstr="rotor";

inti=0,n;

booleanyes=true;

if(args.length>0)

str=args[0];

System.out.println("str="+str);

n=str.length();

charch1,ch2; //算法一

while(yes&&(i<n/2))

{

ch1=str.charAt(i);

ch2=str.charAt(n-i-1);

System.out.println("ch1="+ch1+"ch2="+ch2);

if(ch1==ch2)

i++;

else

yes=false;

}

System.out.println("算法一:"+yes);

Stringtemp="",sub1=""; //算法二

for(i=0;i<n;i++)

{

sub1=str.substring(i,i+1);

temp=sub1+temp;

}

System.out.println("temp="+temp);

System.out.println("算法二:"+str.equals(temp));

}

}程序中方法main(String[]args)的參數(shù)稱為命令行參數(shù),是指運行時跟在文件名后輸入的多個字符串,保存在args[]數(shù)組中,其間以空格分隔。本例使用參數(shù)args[]作為輸入數(shù)據(jù),帶參數(shù)的運行命令如下:

javaRotor12345

則程序運行結果如下:

str=12345

ch1=1ch2=5

算法一:false

temp=54321

算法二:false如果沒有參數(shù),則str的值仍為“rotor”。

javaRotor

str=rotor

ch1=rch2=r

ch1=och2=o

算法一:true

temp=rotor

算法二:true

讀者可根據(jù)需要使用命令行參數(shù)args[]。3.6.1“學生成績管理”問題

本節(jié)將利用數(shù)組類型編寫一個管理學生成績的應用程序,讓計算機來管理全班同學的程序設計課程成績。我們不僅希望得到全班的最高分和最低分,而且希望將全班同學的成績從高至低排序后輸出。3.6數(shù)組3.6.2“學生成績管理”問題分析

這里假設學生成績中可能出現(xiàn)0.5分,所以采用double類型的數(shù)據(jù)表示學生成績。

顯然程序中必須記錄全班幾十位同學的成績,而不可能用幾十個double類型的變量保存這些成績,使用數(shù)組才是解決問題的正確途徑??捎靡粋€基類型為double、長度同全班人數(shù)的數(shù)組變量scores存放每一位同學的成績。程序是對現(xiàn)實世界的建模,據(jù)此可將現(xiàn)實世界中全班學生這一實體概念定義為類Students。盡管在現(xiàn)實世界中該實體有非常豐富的屬性與行為,但我們僅僅考慮我們在解決問題時關心的那部分屬性和行為。例如,全班的成績清單是我們關心的最主要屬性,該屬性可用數(shù)組變量scores定義,我們所關心的行為包括對成績的排序、統(tǒng)計、查找等。

一個Students類的對象實例對應著現(xiàn)實世界中的一個班級,由于不同班級的人數(shù)與成績都不一樣,可以將全班的成績清單設計為Students類的構造方法,在創(chuàng)建每一個班級的對象實例時確定該班級的成績清單。3.6.3知識準備——使用數(shù)組變量

在數(shù)學上常用向量表示一些相關數(shù)據(jù)組成的序列,在程序設計中與向量對應的數(shù)據(jù)類型是數(shù)組。數(shù)組是數(shù)據(jù)項的有序列表,這些數(shù)據(jù)項成為數(shù)組的元素。程序中的數(shù)組具有下列特點:

●數(shù)組的所有元素均屬于同一類型,該類型稱為數(shù)組的基類型;

●數(shù)組的元素個數(shù)一經(jīng)確定后就保持不變,稱它為數(shù)組的長度;

●數(shù)組的每一元素均能被直接訪問,用數(shù)組下標來表示數(shù)組的元素;

●數(shù)組的元素允許是數(shù)組類型,從而形成二維數(shù)組、多維數(shù)組等結構。

提示在JavaAPI提供的java.util程序包中,還為程序員預定義了許多更高級的復合數(shù)據(jù)結構,例如,向量類Vector允許長度隨元素個數(shù)的增加自動增長,并且元素類型允許為任意類型。

假設應用程序中需描述全班50位同學的總評成績,則該屬性可定義為一個名為scores的數(shù)組,如圖3-8所示。圖3-8數(shù)組scores的組織方式考慮到每位學生的成績可能含有小數(shù),故將scores的基類型設計為double,scores的長度固定為50,每一元素代表一位學生的成績。程序通過數(shù)組名scores和下標(0~49)就可直接訪問數(shù)組中的每一元素,故僅需一個數(shù)組即可描述全班50位同學的成績,而不必定義50個不同名字的屬性。

由圖3-8還可見,一個數(shù)組的所有元素在內存中連續(xù)存放,兩個相鄰元素間沒有空隙。

1.數(shù)組變量的聲明

數(shù)組是一種復合數(shù)據(jù)類型,該類型的變量有時也簡稱為數(shù)組。數(shù)組變量與其他類型的變量一樣,遵循“先聲明、后使用”的原則,并應選擇一個富有含義的標識符作為其名字。

在數(shù)據(jù)類型名X之后接上方括號得到的X[]就是一種以X為基類型的數(shù)組類型,其中X既可以是第2章所學的基本數(shù)據(jù)類型,也可以是本章所學的用戶自定義類型或數(shù)組類型。例如int[]是基類型為int的數(shù)組類型,故:

int[]scores=newint[50];聲明了一個名為scores的數(shù)組變量,該數(shù)組的基類型為int,其長度為50。我們可用這個數(shù)組存放50位學生的成績。又如:

double[]prices=newdouble[4];

聲明了一個名為prices的數(shù)組變量,該數(shù)組的基類型為double,其長度為4,可用于存放4種商品的價格。

數(shù)組的基類型還可以是程序員自己用類定義的類型,例如:

Account[]accounts=newAccount[10];聲明了一個名為accounts的數(shù)組變量,該數(shù)組的基類型為Account,其長度為10,可存放10位顧客的銀行賬戶對象。

在數(shù)組聲明中,用new初始化時的方括號不可寫成圓括號,否則會引起編譯錯誤。由于數(shù)組是元素的集合,所以習慣上采用復數(shù)形式的標識符來命名數(shù)組。

從數(shù)組定義的形式可知,數(shù)組也是一種引用類型的變量,數(shù)組名就是一個引用,而用new關鍵字創(chuàng)建數(shù)組成功后所占用的一段無名的、連續(xù)的、用來存放數(shù)組元素的內存可理解為對象。上述例子在聲明數(shù)組變量scores的同時進行了初始化,即同時創(chuàng)建一個長度為50的數(shù)組對象并讓名字scores關聯(lián)到該對象。有時數(shù)組變量的聲明與初始化也可分為兩步,例如:

int[]scores;//定義一個數(shù)組,并為scores分配一個內存單位,其值初始化為Null。

scores=newint[50];//創(chuàng)建數(shù)組,為數(shù)組分配存放50個整型量的內存空間,把每個數(shù)組元素的值初始化為0,并將這段內存的首地址存放至上述定義的引用存儲單位中,如圖3-9、圖3-10所示。圖3-9聲明數(shù)組圖3-10創(chuàng)建數(shù)組如果一個數(shù)組變量a僅被聲明但未被初始化,就不可對數(shù)組變量作各種操作(例如用a.length()訪問數(shù)組長度或用a[i]訪問數(shù)組中的任何元素),因為此時與名字a關聯(lián)的數(shù)組對象尚未創(chuàng)建。

有時我們也可在聲明數(shù)組變量時用int[]scores=null;顯式指明名字scores尚未與一個真正的對象相關聯(lián),其中保留字null表示空對象。

也可以在聲明數(shù)組的同時,用以下形式為數(shù)組賦初值。例如,

inta[]={1,2,3,4,5};

則數(shù)組的5個元素a[0]~a[4]分別得到1~5這5個值。

2.訪問

溫馨提示

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

評論

0/150

提交評論