版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第2章Android應用層開發(fā)語言2.1Java語言的根本語法2.2Java語言的表達式與語句2.3Java語言的類與對象2.1Java語言的根本語法
2.1.1根本數(shù)據(jù)類型
1.邏輯類型
(1)常量:true、false。
(2)變量:用關鍵字boolean來定義邏輯變量,定義時也可以賦給初值。
booleanx;
booleanok=true;2.整數(shù)類型
(1)常量:123,6000(十進制),077(八進制),0x3ABC(十六進制)。
(2)整型變量:整型變量分為以下4種。
①?int型:使用關鍵字int來定義int型整型變量,定義時也可以賦給初值。對于int型變量,內存分配給它4個字節(jié)(Byte)。int型變量的取值范圍是?-231~231-1。
intx;
inteverage=9898;②?byte型:使用關鍵字byte來定義byte型整型變量。對于byte型變量,內存分配給它1個字節(jié),占8位(bit)。byte型變量的取值范圍是-27~27-1。
③?short型:使用關鍵字short來定義short型整型變量。對于short型變量,內存分配給它2個字節(jié)。short型變量的取值范圍是?-215~215-1。
④?long型:使用關鍵字long來定義long型整型變量,對于long型變量,內存分配給它8個字節(jié)。long型變量的取值范圍是?-263~263-13.字符類型
(1)常量:Unicode表中的字符就是一個字符常量,如“A”、“?”、“9”、“好”、“き”等。Java語言還使用轉義字符常量,例如:\n表示換行;\b表示退格;\t表示水平制表。
(2)變量:字符變量使用關鍵字char來定義,例如:
charx=‘A’;對于char型變量,內存分配給它2個字節(jié),占16位,最高位不是符號位,沒有負數(shù)的char。char型變量的取值范圍是0~65536。要觀察一個字符在Unicode表中的順序位置,必須使用int型變量顯式轉換,不可使用short型變量轉換,因為char型變量的最高位不是符號位。同樣,要得到一個0~65536之間的數(shù)所代表的Unicode表中相應位置上的字符,也必須使用char型變量進行顯式轉換。4.浮點類型
浮點類型的變量分為float型和double型兩種。
(1)?float型:float型變量使用關鍵字float來定義。對于float型變量,內存分配給它4個字節(jié),其取值范圍是1038~
10-38和(-10)38~(-10)-38。例如:453.5439f,21379.987F,2e40f(2×1040,科學計數(shù)法)。(2)?double型:double型變量使用關鍵字double來定義。對于double型變量,內存分配給它8個字節(jié),其取值范圍是10-308~10308和(-10)308~(-10)-308。例如:21389.5439d(d可以省略),23189908.987,123.0,6e-140。
數(shù)據(jù)轉換涉及邏輯類型和字符類型。整數(shù)類型和浮點類型按精度從低到高排列如下:
byteshortintlongfloatdouble當把低級別變量的值賦給高級別變量時,系統(tǒng)會自動完成數(shù)據(jù)類型的轉換,例如:int型轉換成long型。當把高級別變量的值賦給低級別變量時,必須使用顯式轉換運算。顯示轉換的格式如下:
(類型名)要轉換的值2.1.2復合數(shù)據(jù)類型
1.聲明數(shù)組
聲明數(shù)組包括數(shù)組的名字、數(shù)組包含元素的數(shù)據(jù)類型。
聲明一維數(shù)組時可采用以下兩種格式:
數(shù)組元素類型數(shù)組名[];
數(shù)組元素類型[]數(shù)組名;
聲明二維數(shù)組時可采用以下兩種格式:
數(shù)組元素類型數(shù)組名[][];
數(shù)組元素類型[][]數(shù)組名;2.創(chuàng)立數(shù)組
聲明數(shù)組僅僅是給出了數(shù)組名和元素的數(shù)據(jù)類型,要想使用數(shù)組還必須為它分配內存空間,即創(chuàng)立數(shù)組。在為數(shù)組分配內存空間時必須指明數(shù)組的長度。格式如下:
數(shù)組名字=new數(shù)組元素的類型[數(shù)組元素的個數(shù)];
例如:
boy=newfloat[4];2.2Java語言的表達式與語句
Java表達式是指將運算符及操作元連接起來并符合Java語言規(guī)那么的式子。一個Java表達式必須能求值,即按照運算符的計算法那么計算出表達式的值。例如:
如果:intx=1,y=-2,n=10;
那么:表達式x+y+(--n)*(x>y&&x>0?(x+1):y)的結果是int型數(shù)據(jù),值為17。Java語句可分為以下幾類:
(1)方法調用語句:在介紹類、對象等概念的語句中,對象可以調用類中的方法產(chǎn)生行為。
(2)表達式語句:在下一個表達式的最后加上一個分號就構成了一個語句,稱為表達式語句。分號是語句中不可缺少的局部。例如:賦值語句
x=23;(3)復合語句:可以用“{”和“}”把一些語句括起來構成復合語句。一個復合語句也稱做一個代碼塊。例如:
{
z=23+x;
System.out.println(“hello”);
}(4)控制語句:包括條件分支語句、循環(huán)語句和跳轉語句。
(5)?package語句和import語句:與類、對象有關。
(6)分支語句:分為if-else語句和if-elseif-else語句。
①?if-else語句:由一個“if”、“else”和兩個復合語句按一定格式構成,格式如下:
if(表達式){
假設干語句
}else{
假設干語句
}②?if-elseif-else語句:程序有時需要根據(jù)多個條件來選擇某一操作,這時就可以使用if-elseif-else語句。if-elseif-else語句由一個“if”、假設干個“elseif”、一個“else”與假設干個復合語句按一定規(guī)那么構成。語句的格式如下:if(表達式1){
假設干語句
}elseif(表達式2){
假設干語句
}elseif(表達式n){
假設干語句
}else{
假設干語句
}(7)?switch語句:多分支開關語句,它的一般格式如下:
switch(表達式){
case常量值1:
假設干語句
break;
case常量值2:
假設干語句
break;
case常量值n:
假設干語句
break;
default:
假設干語句
}
switch語句中表達式的值必須是整型或字符型;常量值1到常量值n也必須是整型或字符型。(8)循環(huán)語句:包括while語句、do-while語句和for語句。
①while語句:while語句的一般格式如下:
while(表達式){
假設干語句
}while語句的執(zhí)行規(guī)那么如下:
(Ⅰ)計算表達式的值,如果該值是true,就執(zhí)行(Ⅱ),否那么執(zhí)行(Ⅲ)。
(Ⅱ)執(zhí)行循環(huán)體,再進行(Ⅰ)。
(Ⅲ)結束while語句的執(zhí)行。
while語句執(zhí)行的流程如圖2.1所示。圖2.1while語句執(zhí)行流程圖②?do-while語句:一般格式為
do{
假設干語句
}while(表達式);
do-while語句和while語句的區(qū)別是do-while語句中的循環(huán)體至少被執(zhí)行一次,如圖2.2所示。圖2.2do-while語句執(zhí)行流程圖③?for語句:一般格式為
for(表達式1;表達式2;表達式3){
假設干語句
}
for語句中的“表達式2”必須是一個值為boolean型數(shù)據(jù)的表達式。for語句的執(zhí)行規(guī)那么如下:
(Ⅰ)計算“表達式1”,完成必要的初始化工作。
(Ⅱ)判斷“表達式2”的值,假設“表達式2”的值為true,那么執(zhí)行(Ⅲ),否那么執(zhí)行(Ⅳ)。
(Ⅲ)執(zhí)行循環(huán)體,然后計算“表達式3”,以便改變循環(huán)條件,執(zhí)行(Ⅱ)。
(Ⅳ)結束for語句的執(zhí)行。(9)跳轉語句:由關鍵字break或continue加上分號構成的語句。例如:
break;
一般在循環(huán)語句的循環(huán)體中使用跳轉語句。在一個循環(huán)中,如果在某次循環(huán)體中執(zhí)行了break語句,那么整個循環(huán)語句結束;如果在某次循環(huán)體中執(zhí)行了continue語句,那么本次循環(huán)結束,即不再執(zhí)行本次循環(huán)中循環(huán)體中continue語句后面的語句,而轉入下一次循環(huán)。2.3Java語言的類與對象
2.3.1面向對象編程
Java語言是一種面向對象的語言,面向對象的核心思想是封裝、繼承和多態(tài)。封裝有兩層含義:一層含義是把對象的屬性和行為看成一個密不可分的整體,將這兩者“封裝”在一個不可分割的獨立單位(即對象)中;另一層含義是“信息隱蔽”,即把不需要讓外界知道的信息隱藏起來,有些對象的屬性及行為允許外界用戶知道或使用,但不允許更改,而另一些屬性或行為那么不允許外界知曉,即只允許使用對象的功能,而盡可能隱蔽對象的功能實現(xiàn)細節(jié)。所謂繼承,就是子類可以繼承父類的屬性(數(shù)據(jù))和功能(操作)。繼承是面向對象方法中的重要概念,并且是提高軟件開發(fā)效率的重要手段。
多態(tài)是指程序中允許出現(xiàn)重名現(xiàn)象。Java語言中具有操作名稱的多態(tài)以及和繼承有關的多態(tài)。2.3.2Java中的類
1.類的聲明和類體
在語法上,類由兩局部構成:類的聲明和類體。其根本格式如下:
class類名{
類體
}
其中,“class”是關鍵字,用來定義類?!癱lass類名”是類的聲明局部,類名必須是合法的Java語言標識符。兩個大括號“{”、“}”以及之間的內容稱為類體。例子:
classDog{
…
}
類的名字不能是Java語言中的關鍵字,要符合標識符規(guī)定,即名字可以由字母、下劃線、數(shù)字或美元符號組成,并且第一個字符不能是數(shù)字。但給類命名時,最好遵守以下
慣例:①如果類名使用字母,那么名字的首字母用大寫字母,例如:Hello。
②類名最好容易識別、見名知意。
③當類名由幾個單詞復合而成時,每個單詞的首字母要大寫,例如:BeijingTime、AmericanGame、HelloChina等。2.類體的構成
類體中可以有以下兩種類型的成員:
①成員變量:通過變量聲明定義的變量稱為成員變量或域,用來刻畫類創(chuàng)立的對象的屬性。
②方法:方法是類體的重要成員之一。其中的構造方法是具有特殊地位的方法,供類創(chuàng)立對象時使用,用來給出類所創(chuàng)立的對象的初始狀態(tài);另一類方法可以由類所創(chuàng)立的對象調用,對象調用這些方法來操作成員變量從而形成一定的算法,以表達出對象具有的功能。3.構造方法和對象的創(chuàng)立
類中有一局部方法稱為構造方法。類在創(chuàng)立對象時需使用構造方法為所創(chuàng)立的對象設置一個合理的初始狀態(tài)。構造方法是一種特殊的方法,它的名字必須與它所在的類的名字完全相同,并且不返回任何數(shù)據(jù)類型,即它是void型,但void必須省略不寫。4.成員變量
用關鍵字static修飾的成員變量稱為靜態(tài)變量或類變量,而沒有使用static修飾的成員變量稱為實例變量。例如:下述A類中,x是實例變量,而y是類變量。
classA{
floatx; //實例變量
staticinty; //類變量
}5.常量
如果一個成員變量修飾為final,就稱其為常量。常量的名字習慣用大寫字母,例如:
finalintMAX;
聲明常量時必須先進行初始化。對于final修飾的成員變量,對象可以使用它,但不能對它做更改操作。2.3.3方法
方法的定義包括兩局部:方法聲明和方法體。方法的一般格式如下:
方法聲明局部
{
方法體的內容
}1.方法聲明和方法體
最根本的方法聲明包括方法名和方法的返回類型,返回類型也簡稱為方法的類型。
例如:
floatarea()
{…
}
方法的名字必須符合標識符規(guī)定。在給方法命名時應遵守以下規(guī)那么:名字如果采用字母,那么首寫字母小寫;如果方法名由多個單詞組成,那么從第2個單詞開始的其他單詞的首寫字母大寫。例如:
floatgetTrangleArea();
voidsetCircleRadius(doubleradius);2.方法體的構成
方法體的內容包括變量的定義和合法的Java語句。在方法體中聲明的變量以及方法的參數(shù)稱為局部變量,局部變量僅僅在該方法內有效。方法的參數(shù)在整個方法內有效,方法內定義的局部變量從它定義的位置之后開始有效。編寫一個方法和用C語言編寫一個函數(shù)完全類似,只不過在這里稱為方法。3.實例方法與類方法
除構造方法外,其他的方法可分為實例方法或類方法。一個類中的方法可以互相調用:實例方法可以調用該類中的實例方法或類方法;類方法只能調用該類的類方法,不能調用實例方法;實例方法可以操作成員變量,無論是實例變量還是類變量;而類方法只能操作類變量,不能操作實例變量,也就是說類方法中不能有操作實例變量的語句。5.方法重載
方法重載是指一個類中可以包含多個具有相同名字的方法,但這些方法的參數(shù)必須不同,或者是參數(shù)的個數(shù)不同,或者是參數(shù)的類型不同。方法的返回類型和參數(shù)的名字不參與比較,也就是說,如果兩個方法的名字相同,即使類型不同,也必須保證參數(shù)不同。2.3.4包(package)
關鍵字包(package)可用來聲明包語句。package語句作為Java源文件的第一條語句,指明了該源文件定義的類所在的包。package語句的一般格式如下:
package包名;包名可以是一個合法的標識符,也可以是假設干個標識符加“.”分割而成的,例如:packagesunrise、package。
在編寫源文件時,除了自己編寫類外,經(jīng)常需要使用很多Java語言提供的類,這些類可能在不同的包中。1.使用類庫中的類
(1)為了能使用Java語言中的類,可以使用import語句來引入。
(2)在一個Java源程序中可以有多個import語句,它們必須寫在package語句(假設有package語句的話)和源文件中類的定義之間。
2.使用自定義包中的類
通??梢允褂胕mport語句引入自定義包中的類,例如:
importtom.jiafei.*;2.3.5Java的訪問權限
1.私有變量和私有方法
用關鍵字private修飾的成員變量和方法稱為私有變量和私有方法。對于私有成員變量或方法,只有在本類中創(chuàng)立該類的對象,這個對象才能訪問自己的私有成員變量和類中的私有方法。用某個類在另外的一個類中創(chuàng)立對象后,如果不希望該對象直接訪問自己的變量(即通過“.”運算符來操作自己的成員變量),就將該變量的訪問權限設置為private。2.共有變量和共有方法
用public修飾的成員變量和方法稱為共有變量和共有方法,例如:
classA{
publicfloatweight;//weight被修飾為public的float型變量
publicfloatf(floata,floatb){ //方法f是public方法
}
}當在任何一個類中用類A創(chuàng)立了一個對象后,該對象能訪問自己的public變量和類中的public方法。例如:
classB{
voidg(){
Aa=newA();
a.weight=23f; //合法
a.f(3,4); //合法
}
}3.友好變量和友好方法
不使用private、public、protected修飾符的成員變量和方法稱為友好變量和友好方法,例如:
classA{
floatweight; //weight是友好變量
floatf(floata,floatb){ //f是友好方法
}
}假設B與A是同一個包中的類,那么,下述B類中的a.weight、a.f(3,4)都是合法的。
classB{
voidg(){
Acat=newA();
a.weight=23f; //合法
a.f(3,4); //合法
}
}4.受保護的成員變量和方法
使用protected修飾的成員變量和方法稱為受保護的成員變量和受保護的方法,例如:
classA{
protectedfloatweight;//weight被修飾為protected變量。
protectedfloatf(floata,floatb){ //f是protected方法
}
}假設B與A是同一個包中的類,那么,B類中的a.weight、a.f(3,4)都是合法的,例如:
classB{
voidg(){
Toma=newTom();
a.weight=23f;//合法
a.f(3,4);//合法
}
}5.public類與友好類
聲明類時,如果在關鍵字class前加上public關鍵字,就稱這個類是一個public類,但不能用protected和private修飾類,例如:
publicclassA{…}
可以在任何另外一個類中,使用public類創(chuàng)立對象。另外一個類使用友好類創(chuàng)立對象時,要保證它們在同一個包中,例如:
classA{
}2.3.6繼承、內部類和接口
1.繼承與多態(tài)
關鍵字extends用來聲明一個類是另外一個類的子類,格式如下:
class子類名extends父類名
{
}當使用子類的構造方法創(chuàng)立一個子類的對象時,子類的構造方法總是先調用父類的某個構造方法,如果子類的構造方法沒有指明使用父類中的哪個構造方法,子類就調用父類中不帶參數(shù)的構造方法??梢赃@樣來理解子類創(chuàng)立的對象:
(1)將子類中聲明的成員變量作為子類對象的成員變量,就是說子類未繼承的父類成員變量不作為子類對象的成員變量使用。(2)為父類的成員變量均分配了內存空間,但只將其中一局部(繼承的那局部)作為子類對象的成員變量。盡管給父類的私有成員變量分配了內存空間,但它不作為子類的成員變量,即父類的私有成員變量不歸子類管理。方法的繼承性與成員變量相同。另外,假設子類和父類不在同一包中,盡管給父類的友好成員分配了內存空間,但它也不作為子類的成員。子類對象內存示意圖如圖2.3所示。圖2.3子類對象內存示意圖和繼承有關的多態(tài)性是指父類的某個方法被其子類重寫時,可以產(chǎn)生自己的功能行為,即同一個操作被不同類型對象調用時可能產(chǎn)生不同的行為。例如,狗和貓都具有哺乳類的功能:“叫”,當狗“叫”時產(chǎn)生的聲音是“汪汪”,而貓“叫”時產(chǎn)生的聲音是“喵喵”,這就是“叫”的多態(tài)。2.內部類
內部類是指在一個外部類的內部再定義一個類。內部類作為外部類的一個成員,依附于外部類而存在。內部類為靜態(tài)時,可用protected和private修飾(而外部類只能使用public和缺省的包訪問權限)。內部類主要有以下幾類:成員內部類、局部內部類、靜態(tài)內部類、匿名內部類。(1)成員內部類。成員內部類作為外部類的一個成員存在,與外部類的屬性、方法并列,例如:
PublicclassOuter{
Privatestaticinti=1;
Privateintj=10;
privateintk=20;
publicstaticvoidouter_f1(){
}
publicvoidouter_f2(){
}//成員內部類中,不能定義靜態(tài)成員
//成員內部類中,可以訪問外部類的所有成員
classInner{
//staticintinner_i=100;//內部類中不允許定義靜態(tài)變量
intj=100;//內部類和外部類的實例變量可以共存
intinner_i=1;
voidinner_f1(){
(i);//在內部類中,直接用變量名訪問內部類自己的變量
(j);
//在內部類中,也可以用this.變量名訪問內部類自己的變量
(this.j);
/*在內部類中,用外部類名.this.變量名訪問外部類中與內部類同名的實例變量*/
();
/*如果內部類中沒有與外部類同名的變量,那么可以直接用變量名訪問外部類變量*/(k);
outer_f1();
outer_f2();
}
}
//外部類的非靜態(tài)方法訪問成員內部類
publicvoidouter_f3(){
Innerinner=newInner();
inner.inner_f1();
}//外部類的靜態(tài)方法訪問成員內部類,與在外部類外部訪問成員內部類一樣
publicstaticvoidouter_f4(){
//step1:建立外部類對象
Outerout=newOuter();
//step2:根據(jù)外部類對象建立內部類對象
Innerinner=out.newInner();
//step3:訪問內部類的方法
inner.inner_f1();}
publicstaticvoidmain(String[]args){
//outer_f4();//該語句的輸出結果和下面三條語句的輸出結果一樣
/*如果要直接創(chuàng)立內部類的對象,不能想當然地認為只需加上外圍類Outer的名字,就可以按照通常的樣子生成內部類的對象,而是必須使用此外圍類的一個對象來創(chuàng)立其內部類的一個對象*/
//Outer.Inneroutin=out.newInner()/*因此,除非你已經(jīng)有了外圍類的一個對象,否那么不可能生成內部類的對象。因為此內部類的對象會悄悄地鏈接到創(chuàng)立它的外圍類的對象。如果使用的是靜態(tài)的內部類,那就不需要對其外圍類對象的引用*/
Outerout=newOuter();
Outer.Inneroutin=out.newInner();
outin.inner_f1();
}
}(2)局部內部類。在方法中定義的內部類稱為局部內部類。與局部變量類似,局部內部類不能有訪問說明符,因為它不是外部類的一局部,但是它可以訪問當前代碼塊內的常量,以及此外部類所有的成員,例如:publicclassOuter{
privateints=100;
privateintout_i=1;
publicvoidf(finalintk){
finalints=200;
inti=1;
finalintj=10;
//定義在方法內部classInner{
ints=300; //可以定義與外部類同名的變量
//staticintm=20; //不可以定義靜態(tài)變量
Inner(intk){
inner_f(k);
}
intinner_i=100;
voidinner_f(intk){
/*如果內部類沒有與外部類同名的變量,那么在內部類中可以直接訪問外部類的實例變量*/System.out.println(out_i);
/*可以訪問外部類的局部變量(即方法內的變量),但是變量必須是final的(j);*/
//(i);
//如果內部類中有與外部類同名的變量,那么直接用變量名訪問的是內部類的變量
(s);
//用this.變量名訪問的也是內部類變量
(this.s);//用外部類名.this.內部類變量名訪問的是外部類變量
();
}
}
newInner(k);
}
publicstaticvoidmain(String[]args){
//訪問局部內部類必須先有外部類對象
Outerout=newOuter();
out.f(3);
}
}(3)靜態(tài)內部類(嵌套類)。如果內部類對象與其外部類對象無聯(lián)系,那么可以將該內部類聲明為static,通常稱為嵌套類(NestedClass)。想要理解static應用于內部類時的含義,必須牢記普通的內部類對象隱含地保存了一個引用,指向創(chuàng)立它的外圍類對象。然而,當內部類是static的時,就不是這樣。嵌套類的意義如下:①創(chuàng)立嵌套類的對象時并不需要其外部類的對象。
②不能從嵌套類的對象中訪問非靜態(tài)的外部類對象。
上述兩種內部類與變量類似,所以可以參照參考變量使用。靜態(tài)內部類的例子如下:
publicclassOuter{
privatestaticinti=1;
privateintj=10;
publicstaticvoidouter_f1(){
}
Publicvoidouter_f2(){
}//靜態(tài)內部類可以用public、protected及private修飾
//靜態(tài)內部類中可以定義靜態(tài)或非靜態(tài)的成員
staticclassInner{
staticintinner_i=100;
intinner_j=200;
staticvoidinner_f1(){
//靜態(tài)內部類只能訪問外部類的靜態(tài)成員(包括靜態(tài)變量和靜態(tài)方法)
System.out.println(“Outer.i”+i);
outer_f1();}
voidinner_f2(){
//靜態(tài)內部類不能訪問外部類的非靜態(tài)成員(包括非靜態(tài)變量和非靜態(tài)方法)
//(“Outer.i”+j);
//outer_f2();
}
}
publicvoidouter_f3(){
//外部類訪問內部類的靜態(tài)成員:內部類.靜態(tài)成員(Inner.inner_i);Inner.inner_f1();
//外部類訪問內部類的非靜態(tài)成員:實例化內部類即可
Innerinner=newInner();
inner.inner_f2();
}
publicstaticvoidmain(String[]args){
newOuter().outer_f3();
}
}生成一個靜態(tài)內部類時不需要外部類成員,這是靜態(tài)內部類和成員內部類的區(qū)別。靜態(tài)內部類的對象可以直接生成(Outer.Innerin=newOuter.Inner();),而不需要通過外部類對象來生成。這樣實際上使靜態(tài)內部類成為了一個頂級類(正常情況下,不能在接口內部放置任何代碼,但嵌套類可以作為接口的一局部。因為它是static的,只需將嵌套類置于接口的命名空間內即可,這并不違反接口的規(guī)那么)。(4)匿名內部類。簡單地說,匿名內部類就是沒有名字的內部類。滿足以下條件時,使用匿名內部類是比較適宜的:
①只用到類的一個實例。
②類在定義后馬上用到。
③類非常小(SUN推薦在4行代碼以下)。
④給類命名并不會使代碼更容易被理解。在使用匿名內部類時,應遵循以下幾個原那么:
①匿名內部類不能有構造方法。
②匿名內部類不能定義任何靜態(tài)成員、方法和類。
③匿名內部類不能是public、protected、private及static的。
④只能創(chuàng)立匿名內部類的一個實例。下面舉一個匿名內部類的例子:
//在方法中返回一個匿名內部類
publicclassParcel6{
publicContentscont(){
returnnewContents(){
privateinti=11;
publicintvalue(){
returni;
}}; //這里需要一個分號
}
publicstaticvoidmain(String[]args){
Parcel6p=newParcel6();
Contentsc=p.cont();
}
}
cont()方法將下面兩個動作合并在一起:返回值的生成,表示這個返回值的類的定義。進一步說,這個類是匿名的,它沒有名字,是正要創(chuàng)立的一個Contents對象:
returnnewContents();
但是,在語句結束的分號之前,如果插入一個類的定義:
returnnewContents(){
privateinti=11;
publicintvalue(){
returni;
}
};匿名內部類的語法是下面例子的簡略形式:
classMyContentsimplementsContents{
privateinti=11;
publicintvalue(){
returni;
}
}
returnnewMyContents();下面的代碼展示了如何為基類生成一個有參數(shù)的構造器:
publicclassParcel7{
publicWrappingwrap(intx){//根本構造調用函數(shù)
returnnewWrapping(x){//傳遞構造參數(shù)
publicintvalue(){
returnsuper.value()*47;
}
};}
publicstaticvoidmain(String[]args){
Parcel7p=newParcel7();
Wrappingw=p.wrap(10);
}
}
可以看出,只需簡單地傳遞適宜的參數(shù)給基類的構造器即可,這里是將x傳遞給newWrapping(x)。匿名內部類末尾的分號,并不是用來標記此內部類結束(C++?中是這種情況)。實際上,它標記的是表達式的結束,只不過這個表達式正巧包含了內部類罷了。因此,這里與別處使用的分號是一致的。
如果在匿名類中定義成員變量,那么同樣能夠對其執(zhí)行初始化操作。例如:
publicclassParcel8{
//Argumentmustbefinaltouseinside
//anonymousinnerclass
publicDestinationdest(finalStringdest){
returnnewDestination(){
privateStringlabel=dest;
publicStringreadLabel(){
returnlabel;}
}
}
publicstaticvoidmain(String[]args){
Parcel8p=newParcel8();
Destinationd=p.dest(“Tanzania”);
}
}
如果一個匿名內部類要使用一個在其外部定義的對象,那么編譯器會要求其參數(shù)引用是final型的,就像dest()中的參數(shù),否那么,會得到一個編譯器錯誤信息。如果想做一些類似構造器的行為,通過實例初始化,就能夠實現(xiàn)為匿名內部類“制作”一個構造器的效果。例如:
abstractclassBase{
publicBase(inti){
(“Baseconstructor,i=”+i);
}
publicabstractvoidf();
}ublicclassAnonymousConstructor{
publicstaticBasegetBase(inti){
returnnewBase(i){
{
(“Insideinstanceinitializer”);
}
publicvoidf(){
(“Inanonymousf()”);
}
}
}publicstaticvoidmain(String[]args){
Basebase=getBase(47);
base.f();
}
}
在此例中,不要求變量i一定是final的。因為i被傳遞給匿名類的基類的構造器,它并不會在匿名類內部被直接使用。下例是帶實例初始化的“parcel”形式。注意dest()的參數(shù)必須是final的,因為它們是在匿名類內被使用的。
publicclassParcel9{
publicDestinationdest(finalStringdest,finalfloatprice){
returnnewDestination(){
privateintcost;
//Instanceinitializationforeachobject{
cost=Math.round(price);
if(cost>100)
System.out.println(“Overbudget!”);
}
privateStringlabel=dest;
publicStringreadLabel(){
returnlabel;
}
};}
publicstaticvoidmain(String[]args){
Parcel9p=newParcel9();
Destinationd=p.dest(“Tanzania”,101.395F);
}
}
在實例初始化的局部,可以看到有一段代碼,那原本是不能作為成員變量初始化的一局部而執(zhí)行的(即if語句)。所以對于匿名類而言,實例初始化的實際效果就是構造器。例如:
classMNA{
privatevoidf(){}
classA{
privatevoidg(){}
publicclassB{
voidh(){
g();
f();
}
}
}
}publicclassMultiNestingAccess{
publicstaticvoidmain(String[]args){
MNAmna=newMNA();
MNA.Amnaa=mna.newA();
MNA.A.Bmnaab=mnaa.newB();
mnaab.h();
}
}可以看到在中,不需要任何條件(即使它們被定義為private)就能調用方法g()和f()。這個例子同時展示了如何從不同的類里創(chuàng)立多層嵌套的內部類對象的根本語法。“.new”語法能產(chǎn)生正確的作用域,所以不必在調用構造器時限定類名。如果已創(chuàng)立了一個內部類,在繼承其外圍類并重新定義此內部類時,“重載”內部類就好似它是外圍類的一個方法,其實并不起什么作用。例如:
classEgg{
privateYolky;
protectedclassYolk{
publicYolk(){
(“Egg.Yolk()”);
}
}publicEgg(){
(“NewEgg()”);
y=newYolk();
}
}
publicclassBigEggextendsEgg{
publicclassYolk{
publicYolk(){
(“BigEgg.Yolk()”);
}
}缺省的構造器是編譯器自動生成的,這里是調用基類的缺省構造器。讀者可能認為既然創(chuàng)立了BigEgg的對象,那么所使用的應該是被“重載”過的Yolk,但可以從輸出中看到實際情況并不是這樣的。明確地繼承某個內部類也是可以的:
classEgg2{
protectedclassYolk{
publicYolk(){
(“Egg2.Yolk()”);
}publicvoidf(){
(“Egg2.Yolk.f()”);
}
}
privateYolky=newYolk();
publicEgg2(){
(“NewEgg2()”);
}
publicvoidinsertYolk(Yolkyy){
y=yy;
}publicvoidg(){
y.f();
}
}
publicclassBigEgg2extendsEgg2{
publicclassYolkextendsEgg2.Yolk{
publicYolk(){
(“BigEgg2.Yolk()”);
}publicvoidf(){
(“BigEgg2.Yolk.f()”);
}
}
publicBigEgg2(){
insertYolk(newYolk());
}
publicstaticvoidmain(String[]args){
Egg2e2=newBigEgg2();
e2.g();
}
} 輸出結果如下:
Egg2.Yolk()
NewEgg2()
Egg2.Yolk()
BigEgg2.Yolk()
BigEgg2.Yolk.f()
現(xiàn)在BigEgg2.Yolk通過extendsEgg2.Yolk明確地繼承了此內部類,并且重載了其中的方法。Egg2的insertYolk()方法使得BigEgg2將它自己的Yolk對象向上轉型,然后傳遞給引用y,所以當g()調用y.f()時,
重載后的新版f()被執(zhí)行。第二次調用Egg2.Yolk()是BigEgg2.Yolk的構造器調用了其基類的構造器??梢钥吹?/p>
在調用g()時,新版的f()被調用。classWithInner{
classInner{
Inner(){
(“thisisaconstructorinWithInner.Inner”);
}
}
}
publicclassInheritInnerextendsWithInner.Inner{//!InheritInner(){}//Won‘tcompile
InheritInner(WithInnerwi){
wi.super();
(“thisisaconstructorinInheritInner”);
}
publicstaticvoidmain(String[]args){
WithInnerwi=newWithInner();
InheritInnerii=newInheritInner(wi);
}
}輸出結果如下:
thisisaconstructorinWithInner.Inner
thisisaconstructorinInheritInner
可以看到,InheritInner只繼承內部類,而不是外部類。但是,當要生成一個構造器時,缺省的構造器并不算好,而且不能只傳遞一個指向外圍類對象的引用。必須在構造器內使用如下語法:
enclosingClassReference.super();
這樣才提供了必要的引用,然后程序才能編譯通過。3.接口
Java語言支持繼承,但不支持多重繼承,即一個類只能有一個父類。單繼承使得程序更加容易維護和健壯,多重繼承使得編程更加靈活,但卻增加了子類的負擔,使用不當會引起混亂。綜合上述問題,Java語言設計了接口(Interface),接口可以增加很多類都需要的功能,一個類可以實現(xiàn)多個接口,不同的類也可以使用相同的接口。接口通常是單方法接口,例如:
publicinterfaceActionlistener{
publicabstractvoidactionPerformed(ActionEventevent);
}
由此可見,只有重寫接口這個唯一方法,才能在事件監(jiān)聽器列表里進行注冊(參數(shù)為Actionlistener類型)。接口可分為標識接口和常量接口兩種。
(1)標識接口。標識接口就是沒有任何方法和屬性的接口。標識接口不對實現(xiàn)它的類有任何語意上的要求,它僅僅說明了實現(xiàn)它的類屬于一個特定的類型(傳遞)。不推薦過多地使用標識接口。
(2)常量接口。Java用語言中的接口來聲明一些常量,然后由實現(xiàn)該接口的類使用這些常量。定義一個或多個類實現(xiàn)某個接口時,用implements關鍵字代替extends關鍵字。例如:
①創(chuàng)立一個名為vacationInterface.java的文件,并定義vacationInterface接口。
packagevacationInterface;
publicinterfacevacationInterface{
publicvoidgetVaction();
}②創(chuàng)立一個名為TestInterface.java的文件,并實現(xiàn)vacationInterface接口
。
importvacationInterface.vacationInterface;
//人事部類,實現(xiàn)vacationInterface接口
classpersonnelimplementsvacationInterface{
//部門名稱屬性
privateStringpersonnelName;
//無參數(shù)構造方法
publicfinancial(){
}//帶參數(shù)構造方法
publicfinancial(StringfinancialName){
this.financialName=financialName;
}
//實現(xiàn)vacationInterface接口中的getVaction()放假方法,金融部放假兩天
publicvoidgetVaction(){
(financialName+“放假兩天!”);
}
}//測試類
publicclassTestInterface{
溫馨提示
- 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
提交評論