




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第3章JAVA面向?qū)ο缶幊堂嫦驅(qū)ο蟮某绦蛟O(shè)計 類與對象 構(gòu)造方法 方法重載
static關(guān)鍵字
this關(guān)鍵字
instanceof關(guān)鍵字類的繼承與多態(tài) 繼承 成員訪問
super
何時調(diào)用構(gòu)造方法本章內(nèi)容: 初始化順序 父類的靜態(tài)方法
java.lang.Object類
final
多態(tài)抽象類、接口與內(nèi)部類
抽象類 接口 用接口實現(xiàn)多重繼承 向上及向下轉(zhuǎn)型 內(nèi)部類 嵌套類和匿名類面向?qū)ο蟮某绦蛟O(shè)計1、封裝2、繼承3、多態(tài)類聲明由四部分組成:類修飾符、類關(guān)鍵字class、聲明父類、實現(xiàn)接口,其一般形式如下:[public][abstract|final]class類名[extends父類名][implements接口列表]{……}3.1類與對象(1)類修飾符
public:這個public關(guān)鍵字聲明了類可以在其他類中使用。缺省時,該類只能被同一個包中的其他類使用。
abstract:聲明這個類為抽象類,即這個類不能被實例化。
final:聲明該類不能被繼承,即不能有子類。也就是說,不能用它通過擴展的辦法來創(chuàng)建新類。(2)類的關(guān)鍵字class
在類聲明中,class是聲明類的關(guān)鍵字,表示類聲明的開始,類聲明后面跟著類名,按習(xí)慣類名要用大寫字母開頭,并且類名不能用阿拉伯?dāng)?shù)字開頭。給類名命名時,最好取一個容易識別且有意義的名字,避免A、B、C之類的類名。
類成員的四種訪問權(quán)限:1、公有public2、受保護protected3、默認4、私有private類的訪問權(quán)限:只有如下兩種:公有public及默認,除此之外,沒有其它的修飾符。構(gòu)造方法特點如下:1、無返回值2、方法名與類名相同3、訪問權(quán)限不能為私有4、可重載5、調(diào)用時,根據(jù)參數(shù)自動選擇相應(yīng)的構(gòu)造方法。創(chuàng)建對象與定義構(gòu)造函數(shù)1.創(chuàng)建對象定義類的最終目的是使用對象。創(chuàng)建對象的一般格式:
類名新建對象名=new構(gòu)造函數(shù)();創(chuàng)建對象與聲明基本數(shù)據(jù)類型的變量類似,首先說明新建對象所屬的類名,然后說明新建對象的名字,new是為新建對象開辟內(nèi)存空間的運算符。像聲明變量需要為變量開辟內(nèi)存空間保存數(shù)據(jù)一樣,創(chuàng)建對象也需要為對象開辟內(nèi)存空間保存域和方法。與變量相比,對象占用的內(nèi)存空間要大得多,對象是以類為模板創(chuàng)建的具體實例。2.構(gòu)造函數(shù)(構(gòu)造方法)創(chuàng)建對象與聲明變量的不同點:創(chuàng)建對象的同時將調(diào)用這個對象的構(gòu)造函數(shù)完成對象的初始化。聲明變量時可以用賦值語句為它賦初值,而一個對象可能包括若干個域,需要若干個賦值語句,把若干個賦初值的語句組合成一個方法在創(chuàng)建對象時一次性同時執(zhí)行,這個方法就是構(gòu)造函數(shù)。構(gòu)造函數(shù)是與類同名的方法,創(chuàng)建對象的語句用new運算符開辟了新建對象的內(nèi)存空間之后,將調(diào)用構(gòu)造函數(shù)初始化這個新建對象。構(gòu)造函數(shù)是類的特殊方法,主要體現(xiàn)在以下的幾個方面:(1)構(gòu)造函數(shù)的方法名與類名相同。(2)沒有返回類型。(3)作用:完成對類對象的初始化工作。(4)一般不能由編程人員顯式直接調(diào)用。(5)在創(chuàng)建一個類的新對象的同時,系統(tǒng)會自動調(diào)用該類的構(gòu)造函數(shù)為新對象初始化。import
java.io.*;public
class
StuInfo{public
static
void
main(String[]args){Studentst1=newStudent();//st1.setName("衛(wèi)洪春");st1.setStuNum(2010090423);System.out.println(st1.toString());}}classStudent{//屬性Stringname;int
StuNum;Stringcourse[];intgrade[];//方法Student(){name="無名";StuNum=-8;inti=0;course=newString[3];grade=new
int[3];course[0]="語文";course[1]="數(shù)學(xué)";course[2]="英語";for(i=0;i<3;i++)grade[i]=0;}public
int
getGrade(String
str){if(str.equals(course[0]))returngrade[0];else
if(str.equals(course[1])){returngrade[1];}else
if(str.equals(course[2])){returngrade[2];}else{System.out.println("沒有課程<"+str+">!");return-1;}}publicStringgetName(){returnname;}public
int
getStuNum(){return
StuNum;}public
void
setGrade(int
grd,String
str){if(str.equals(course[0]))grade[0]=grd;else
if(str.equals(course[1])){grade[1]=grd;}else
if(str.equals(course[2])){grade[2]=grd;}else{System.out.println("沒有課程<"+str+">!");}}public
void
setName(Stringname){this.name=name;}public
void
setStuNum(int
stuNum){StuNum=stuNum;}publicStringtoString(){Stringtemp_String="";temp_String+="姓名:";temp_String+=this.name;temp_String+="\n學(xué)號:";temp_String+=this.StuNum;temp_String+="\n\n各科成績?nèi)缦拢?;return
temp_String;}}import
java.io.*;public
class
testMyJava{public
static
void
main(String[]args){Personp=newPerson(35,true);System.out.println(p.showInfo());}}classPerson{public
int
ageI;public
boolean
genderB;public
Person(intage,booleangender){this.ageI=age;this.genderB=gender;}public
int
getAgeI(){return
ageI;}public
boolean
isGenderB(){return
genderB;}public
void
setAgeI(int
ageI){this.ageI=ageI;}public
void
setGenderB(boolean
genderB){this.genderB=genderB;}StringshowInfo(){StringtempString="";tempString+=ageI;tempString+="歲";if(this.genderB==true)tempString+="男";else
tempString+="女";return
tempString;}}基本類型默認值booleanfalsecharnullbyte(byte)0short(short)0int
0long0lfloat0.0fdouble0.0dJava類的某個成員為基本數(shù)據(jù)類型時,或沒有初始化,則它們的默認值如右表:注意:只有當(dāng)變量作為一個類的成員使用時,java才確保給定其默認值,但一般還是顯示給出其默認值較好。類的修飾符Java程序在定義類時,除了使用class關(guān)鍵字標識之外,還可以在class之前增加若干類的修飾符來修飾限定所定義的類的特性。兩種類的修飾符:訪問控制符和非訪問控制符。有些類的修飾符也可以用來修飾類中的域或方法,非訪問控制有:abstract、final抽象類(abstract)抽象類:用abstract修飾符修飾的類。抽象類是沒有具體對象的概念類。抽象類是它的所有子類的公共屬性的集合。使用抽象類的優(yōu)點是可充分利用這些公共屬性來提高開發(fā)和維護程序的效率。最終類(final)如果一個類被final修飾符所修飾和限定,則該類不能有子類。被定義為final的類通常是有固定作用、用來完成某種標準功能的類。如Java系統(tǒng)定義的、用來實現(xiàn)網(wǎng)絡(luò)功能的InetAddress、Socket等類都是final類。在Java程序中,當(dāng)通過類名引用一個類或其對象時,實際真正引用的既可能是這個類或其對象本身,也可能是這個類的某個子類及子類的對象,具有一定的不確定性。將一個類定義為final則可以將它的內(nèi)容、屬性和功能固定下來,與它的類名形成穩(wěn)定的映射關(guān)系,從而保證引用這個類時所實現(xiàn)的功能的正確無誤。注意:abstract和final不能同時修飾一個類。因為abstract類自身沒有具體對象,需要派生出子類后再創(chuàng)建子類的對象;而final類不可能有子類,這樣abstractfinal類就就沒有意義。但abstract和final可以分別與其他修飾符合用。例如一個類可以是publicabstract的,或者是publicfinal的。public是訪問控制符,當(dāng)一個以上的修飾符修飾類或類中的域、方法時,這些修飾符之間以空格分開,寫在class關(guān)鍵字之前,修飾符之間的先后排列次序?qū)︻惖男再|(zhì)沒有影響。類訪問權(quán)限修飾符
------public(公共的)用public關(guān)鍵字修飾的一個類,表明該類可以被任何其它類使用。如果一個類沒有public修飾符,則這個類只能在它所包含的包中訪問。一個Java源文件包含幾個類定義時,只能有一個public類,文件名與public類名完全一致(包括大小寫也必須一致)。域域是類和對象的靜態(tài)屬性,可以是基本數(shù)據(jù)類型的變量,或其他類(系統(tǒng)類或用戶自定義類)的對象。定義域的操作就是說明變量或創(chuàng)建對象的操作。與類相似,域也可以擁有若干修飾符,包括訪問控制符和非訪問控制符。非訪問控制符有靜態(tài)、最終及易失。1.靜態(tài)域(static)用static修飾符修飾的域是僅屬于類的靜態(tài)域。靜態(tài)域的本質(zhì):它們是類的域,不屬于任何一個類的具體對象。它不是保存在某個對象的內(nèi)存空間中,而是保存在類的內(nèi)存區(qū)域的公共存儲單元。即,對于該類的任何一個具體對象,靜態(tài)域是一個公共的存儲單元,任何一個類的對象訪問它時,取到的都是相同的數(shù)值;任何一個類的對象去修改它時,都是在對同一個內(nèi)存單元進行操作。2.靜態(tài)初始化器靜態(tài)初始化器是由關(guān)鍵字static引導(dǎo)的一對大括號括起的語句組。作用類似于類的構(gòu)造函數(shù),用來完成初始化工作,但靜態(tài)初始化器與構(gòu)造函數(shù)根本不同點的原因在于:(1)構(gòu)造函數(shù)是對新創(chuàng)建的對象初始化,而靜態(tài)初始化器是對類自身進行初始化。(2)構(gòu)造函數(shù)是在用new產(chǎn)生新對象時由系統(tǒng)自動執(zhí)行,而靜態(tài)初始化器則是在它所屬的類加載入內(nèi)存時由系統(tǒng)調(diào)用執(zhí)行。(3)不同于構(gòu)造函數(shù),靜態(tài)初始化器不是方法,沒有方法名、返回值和參數(shù)列表。classPhoneCard200{ staticlongnextCardNumber; longcardNumber;
intpassword; doublebalance;
static {
nextCardNumber=2001800001; } PhoneCard200() {
cardNumber=nextCardNumber++; }}例:使用靜態(tài)初始化器,在加載類時初始化類的靜態(tài)域。3.最終域(final)final修飾符:修飾常量。一個類的域若被聲明為final,則其取值在程序的整個執(zhí)行過程中都不會改變。例如PhoneCard200類中的接入號碼,對于200電話卡是固定的字符串″200″,根據(jù)問題的實際情況,這個數(shù)據(jù)不需要也不應(yīng)該被改變,故把它定義為最終域。
staticfinalStringconnectNumber=″200″;用final修飾符說明常量時,需要注意:(1)需要說明常量的數(shù)據(jù)類型。(2)需要同時指出常量的具體取值。(3)因為所有類對象的常量成員,其數(shù)值都固定一致,為了節(jié)省空間,常量通常聲明為static。
4.易失域(volatile)如果一個域被volatile修飾符所修飾,說明這個域可能同時被幾個線程所控制和修改,即這個域不僅僅被當(dāng)前程序所掌握,在運行過程中可能存在其他未知的程序操作來影響和改變該域的取值。通常,volatile用來修飾接受外部輸入的域。如表示當(dāng)前時間的變量將由系統(tǒng)的后臺線程隨時修改,以保證程序中取到的總是最新的當(dāng)前的系統(tǒng)時間,所以可以把它定義為易失域。方法方法是類的動態(tài)屬性,標志了類所具有的功能和操作,用來把類和對象的數(shù)據(jù)封裝在一起。Java的方法,由方法頭和方法體組成,其一般格式如下: 修飾符1修飾符2……返回值類型方法名(形參列表)throw[異常列表]
{
方法體各語句;
}形參列表的格式為: 形參類型1形參名1,形參類型2形參名2……小括號是方法的標志,程序使用方法名來調(diào)用方法,形式參數(shù)是方法從調(diào)用它的環(huán)境輸入的數(shù)據(jù),返回值是方法在操作完成后返還給調(diào)用它的環(huán)境的數(shù)據(jù)。定義方法的目的是定義具有相對獨立和常用功能的模塊,使程序結(jié)構(gòu)清晰,也利于模塊在不同場合的重復(fù)利用。例如例3-5,把求完全數(shù)功能的程序?qū)懗煞椒╥sPerfect(),并在主類的main()方法中調(diào)用。例3-5PerfectNum.javapublicclassPerfectNum{publicstaticvoidmain(String
args[]){
intcount=1;
for(inti=1;i<1000;i++){
if(isPerfect(i)){
System.out.print(i+String.valueOf(′\t′));count++;}if(count%3==0)
System.out.println();}}
staticboolean
isPerfect(intx){
inty=0;
for(inti=1;i<x;i++)
if(x%i==0)y+=i;
if(y==x)returntrue;elsereturnfalse;}}
方法的調(diào)用通常稱做給對象發(fā)送消息方法的修飾符分為:訪問控制符和非訪問控制符兩大類,常用的非訪問控制符把方法分成若干種。方法的非訪問控制符有:抽象、靜態(tài)、最終、本地、同步等方法1.抽象方法(abstract)abstract修飾的抽象方法僅有方法頭,而沒有具體的方法體和操作實現(xiàn)的方法。如圖形類的求面積方法如下
abstractdoublegetArea();abstract方法只有方法頭的聲明,用一個分號來代替方法體的定義。抽象方法方法體的實現(xiàn),是留到其子類中去完成。各子類在繼承了父類的抽象方法之后,再分別用不同的語句和方法體來重新定義它,形成若干個名字相同,返回值相同,參數(shù)列表也相同,目的一致但是具體實現(xiàn)有一定差別的方法。抽象方法的目的:使某個類的所有子類對外都有相同名字,是一個統(tǒng)一的接口。其實,為抽象方法書寫方法體沒有意義,因為abstract方法所依附的abstract類沒有自己的對象,只有它的子類才存在具體的對象,而它的不同子類對這個abstract方法有互不相同的實現(xiàn)方法,除了參數(shù)列表和返回值之外,沒有其他的公共點。故把abstract方法作為一個共同的接口,表明當(dāng)前抽象類的所有子類都使用這個接口來完成某個的功能。定義abstract方法的優(yōu)點:可以隱藏具體的細節(jié)信息,使調(diào)用該方法的程序不必過分關(guān)注類及其子類內(nèi)部的具體狀況。特別:所有的抽象方法,都必須存在于抽象類之中。一個非抽象類中出現(xiàn)抽象方法是非法的。一個抽象類的子類如果不是抽象類,則它必須為父類中的所有抽象方法書寫方法體。抽象類不一定只能擁有抽象方法,它可以包含非抽象的方法。例3-6:把電話卡類定義為抽象類,派生出IC卡和200卡兩個子類分別為performDial()方法書寫方法體。例TestAbstract.java
publicclassTestAbstract{publicstaticvoidmain(String
args[]){PhoneCard200my200=newPhoneCard200(50.0);
IC_Card
myIC=newIC_Card(50.0);System.out.println("200卡可以撥打 "+my200.TimeLeft()+"次電話。");
System.out.println("IC
卡可以撥打 "+myIC.TimeLeft()+"次電話。");}}abstractclassPhoneCard{ doublebalance; abstractvoidperformDial(); doubleTimeLeft(){doublecurrent=balance;
inttimes=0;do{
performDial();times++;}while(balance>=0);balance=current;returntimes-1;}}classPhoneCard200extendsPhoneCard{staticlongnextCardNumber;staticfinalStringconnectNumber="200";staticdoubleadditoryFee;longcardNumber;
intpassword;
booleanconnected;static{
nextCardNumber=2001800001;
additoryFee=0.1;}PhoneCard200(doubleib){
cardNumber=nextCardNumber++; balance=ib; } voidperformDial() { balance-=0.5+additoryFee; } } classIC_CardextendsPhoneCard {
IC_Card(double
ib) { balance=ib; }voidperformDial() { balance-=0.9; } }2.靜態(tài)方法(static)用static修飾符修飾的方法,是屬于整個類的類方法;而不用static修飾符限定的方法,是屬于某個具體類對象或?qū)嵗姆椒?。聲明一個方法為static的意義:(1)調(diào)用該方法時,應(yīng)使用類名做前綴,而不是某一具體的對象名;(2)非static的方法是屬于某個對象的方法,在這個對象創(chuàng)建時,對象的方法在內(nèi)存中擁有自己專用的代碼段;static方法屬于整個類,它在內(nèi)存中的代碼段將隨著類的定義而分配和裝載,不被任何一個對象專有;(3)static方法只能處理static域。3.最終方法(final)final修飾符所修飾的類方法,不能被當(dāng)前類的子類重新定義的方法。在面向?qū)ο蟮某绦蛟O(shè)計中,子類可以把從父類那里繼承來的某個方法改寫并重新定義,形成同父類方法同名,解決的問題也相似,但具體實現(xiàn)和功能卻不盡一致的新的類方法,這個過程稱為覆蓋。如果類的某個方法被final修飾符所限定,則該類的子類就不能再重新定義與此方法同名的自己的方法,而僅能使用從父類繼承來的方法。這樣,就固定了這個方法所對應(yīng)的具體操作,可以防止子類對父類關(guān)鍵方法的重定義,保證了程序的安全性和正確性。注意:所有已被private修飾符限定為私有的方法,以及所有包含在final類中的方法,都被缺省地認為是final。這些方法要么不可能被子類所繼承,要么根本沒有子類,所以都不可能被覆蓋,自然都是最終的方法。4.本地方法(native)native修飾符一般用來聲明用其他語言書寫方法體并具體實現(xiàn)方法功能的特殊的方法,包括C、C++、匯編、FORTRAN等。由于native的方法的方法體使用其他語言在程序外部寫成,所以所有的native方法都沒有方法體,而用一個分號代替。用其他語言編寫的模塊作為類方法,其目的是:利用已經(jīng)存在的程序功能模塊、避免重復(fù)工作。由于Java是解釋型的語言,它的運行速度比較慢。在未經(jīng)任何優(yōu)化處理時,Java程序的運行速度幾乎是C程序的1/20~1/15。所以,當(dāng)在某些實時性比較強或執(zhí)行效率要求比較高的場合,僅使用Java程序不能滿足需要時,就可利用native方法來求助于其他運行速度較高的語言。注意:由于native方法對應(yīng)其他語言書寫的模塊是以非Java字節(jié)碼的二進制代碼形式嵌入Java程序的,而這種二進制代碼通常只能運行在編譯生成它的平臺之上,所以整個Java程序的跨平臺性能將受到限制或破壞,除非保證native方法引入的代碼也是跨不同平臺的5.同步方法(synchronized)如果synchronized修飾的方法是一個類的方法(即static的方法),則在被調(diào)用執(zhí)行前,將把系統(tǒng)類Class中對應(yīng)當(dāng)前類的對象加鎖。如果synchronized修飾的是一個對象的方法(未用static修飾的方法),則這個方法在被調(diào)用執(zhí)行前,將把當(dāng)前對象加鎖。synchronized修飾符主要用于多線程共存的程序中的協(xié)調(diào)和同步。訪問控制符訪問控制符:一組限定類、域或方法是否可以被程序中的其他部分訪問和調(diào)用的修飾符。類及其屬性和方法的訪問控制符規(guī)定了程序的哪些其他部分可以訪問和調(diào)用它們,哪些不可以。這里的其他部分是指程序里這個類之外的其他類,無論修飾符如何定義,一個類總能夠訪問和調(diào)用它自己的域和方法,但是這個類之外的其他部分能否訪問這個域或方法,要考察該域和方法以及它所屬的類的訪問控制符。類的訪問控制符只有public。域和方法的訪問控制符有三個:public、private、protected。另外還有一種沒有定義專門的訪問控制符的缺省情況。1.公共訪問控制符public類的訪問控制符只有一個:public(公共)。一個類被聲明為公共類,則它可被所有其他類所訪問和引用。訪問和引用是指這個類作為整體是可見和可使用的,程序的其他部分可以創(chuàng)建這個類的對象、訪問這個類內(nèi)部可見的成員變量和調(diào)用它的可見的方法。Java的類是通過包來組織的,包是類的一種松散的集合。處于同一個包中的類可以不需任何說明而方便地互相訪問和引用,而對于在不同包中的類,一般說來,它們相互之間是不可見的,也不可能互相引用。當(dāng)一個類被聲明為public時,它就具有了被其他包中的類訪問的可能性,只要其他包中的類在程序中使用import語句引入public類,就可訪問和引用這個類。一個類作為整體對程序的其他部分可見,并不能代表類內(nèi)的所有域和方法也同時對程序的其他部分可見,類的域和方法能否為所有其他類所訪問,還要看這些域和方法自己的訪問控制符。如果這些域和方法自己的訪問控制符也被聲明為public,那么程序中的所有其他部分都可訪問它們。類中被設(shè)定為public的方法是這個類對外的接口部分,程序的其他部分通過調(diào)用它們達到與當(dāng)前類交換信息、傳遞消息甚至影響當(dāng)前類的作用,從而避免程序的其他部分直接去操作類內(nèi)的數(shù)據(jù)。如果一個類中定義了常用的操作,希望能作為公共工具供其他的類和程序使用,則應(yīng)該把類本身和這些方法都定義成public,例如Java類庫中的公共類和它們的公共方法。特別:Java程序的主類都必須是public類。用public修飾的類的域稱為公共域。如果公共域?qū)儆谝粋€公共類,則它可以被所有的其他類所引用。public修飾符會造成安全性和數(shù)據(jù)封裝性下降,一般應(yīng)減少public域的使用。2.缺省訪問控制符(也叫包訪問性)若一個類沒有訪問控制符,則它具有缺省的訪問控制性。缺省的訪問控制權(quán)規(guī)定該類只能被同一個包中的類訪問和引用。類內(nèi)的域和方法如果沒有訪問控制符來限定,也說明它們具有包訪問性,可以被同一個包中的其他類所訪問和調(diào)用。定義在同一個程序中的所有類屬于一個包。3.私有訪問控制符(private)用private修飾的域或方法只能被該類本身所訪問和修改。private修飾符用來聲明類的私有成員,它提供了最高的保護級別。4.保護訪問控制符protected用protected修飾的成員變量可以被三種類所引用:該類自身、與它在同一個包中的其他類、在其他包中的該類的子類。(同包及子類可訪問).protected修飾符的主要作用是:允許其他包中的它的子類來訪問父類的特定屬性。importjava.applet.Applet;importjava.awt.*;publicclassAccessControlextendsApplet//定義主類,在瀏覽器中顯示信息{
ClassBeAccessedc=newClassBeAccessed();//創(chuàng)建被訪問使用類的對象(區(qū)域D)
subClasssc=newsubClass();//創(chuàng)建被訪問類子類的對象(區(qū)域C)
PackageClass
ic=newPackageClass();//創(chuàng)建被訪問類同一包中類的對象(區(qū)域B)publicvoidpaint(Graphicsg)//顯示可訪問信息{
g.drawString("SelfAccessible:",10,20);//類可以訪問自己的所有屬性和方法
g.drawString(c.toString(),20,35);
g.drawString("SubAccessible:",10,55);//子類可以直接訪問父類的哪些屬性
g.drawString(sc.AccessDirectly(),20,70);
g.drawString("PackageAccessible:",10,90);//同包中的類可以訪問哪些屬性
g.drawString(ic.AccessDirectly(),20,105);
g.drawString("Accessusingpublicmethod:",10,125);//通過調(diào)用被訪問類的
g.drawString(sc.AccessCls(),20,140);//公共方法來訪問它的
g.drawString(ic.AccessCls(),20,155);//所有性質(zhì)的屬性
}}classClassBeAccessed
//被訪問類是非公共類,同一包中的其他類都可創(chuàng)建其對象{publicStringm_PublicProperty;//公共屬性
Stringm_FriendlyProperty;//缺省屬性(又稱為友元)protectedStringm_ProtectedProperty;//保護屬性
privateStringm_PrivateProperty;//私有屬性
ClassBeAccessed()//構(gòu)造函數(shù),為各屬性賦初值
{
m_PublicProperty=newString("Public");
m_FriendlyProperty=newString("Friendly");
m_ProtectedProperty=newString("Protected");
m_PrivateProperty=newString("Private");}例AccessControl.javapublicStringtoString()//公共方法,連接各屬性的字符串并顯示
{
return(m_PublicProperty+";"+m_FriendlyProperty+";"+m_ProtectedProperty+";"+m_PrivateProperty+";");}}classsubClassextendsClassBeAccessed//被訪問類的子類{
ClassBeAccessedc=newClassBeAccessed();//創(chuàng)建被訪問類的對象
StringAccessDirectly()//直接調(diào)用被訪問類的屬性,可調(diào)用的有:
{
return(c.m_PublicProperty+";"http://公共屬性
+c.m_FriendlyProperty+";"http://缺省屬性
+c.m_ProtectedProperty+";");//保護屬性
}StringAccessCls()//通過調(diào)用被訪問類的公共方法,可以調(diào)用它的各種性質(zhì)的屬性
{
return(c.toString());}}classPackageClass//與被訪問類在同一個包中的類
{
ClassBeAccessedc=newClassBeAccessed();//創(chuàng)建被訪問類的對象
StringAccessDirectly()//直接調(diào)用被訪問類的屬性,可調(diào)用的有:
{
return(c.m_PublicProperty+";"http://公共屬性
+c.m_FriendlyProperty+";"http://缺省屬性
+c.m_ProtectedProperty+";");//保護屬性
}StringAccessCls(){
return(c.toString());//通過調(diào)用被訪問類的公共方法,可以調(diào)用它的各種性質(zhì)的屬性}}運行結(jié)果大多數(shù)情況下,修飾符可混合使用。例如類的三個修飾符public,final和abstract之間并不互斥,一個公共類可以是抽象的:publicabstractclasstransportmeans…一個公共類也可以是final的,例如:
publicfinalclassSocket……但有些修飾符不能同時使用,例如final與abstract。下面是一些修飾符混用時需要注意的問題。(1)abstract不能與final并列修飾同一個類。(2)abstract不能與private,static,final或native并列修飾同一個方法。(3)abstract類中不能有private的成員(包括屬性和方法)。(4)abstract方法必須在abstract類中。(5)static方法中不能處理非static的屬性。為什么不能在abstract方法前加static呢?
在沒有實例化類的情況下(不討論abstract類不能實例化),加了static后可以直接通過Class.method()來調(diào)用該方法,這個方法都沒方法體,調(diào)用這樣的方法沒有實際的意義。(編程語言就是為了解決生活中的問題,而這個問題在生活中是沒有意義的那編程語言也不會去實現(xiàn)它,如:一臺電視機上有一個電源按鈕(方法),而這個按鈕按下卻沒有任何作用,你說這樣的按鈕有實際的意義嗎?)
static是靜態(tài),就是在編譯時已經(jīng)確定的東西,當(dāng)然不能是抽象(動態(tài))的,那是運行時才能確定的東西。static和dynamic是反義詞
而abstract是為了實現(xiàn)dynamic。所以static和abstract是不能共存的。static變量前可以有private修飾,表示這個變量可以在類的靜態(tài)代碼塊中,或者類的其他靜態(tài)成員方法中使用(當(dāng)然也可以在非靜態(tài)成員方法中使用--廢話),但是不能在其他類中通過類名來直接引用,這一點很重要。實際上你需要搞明白,private是訪問權(quán)限限定,static表示不要實例化就可以使用。static前面加上其它訪問權(quán)限關(guān)鍵字的效果也以此類推。
繼承和多態(tài):繼承是面向?qū)ο蟪绦蛟O(shè)計方法中的一種重要手段,通過繼承可以更有效地組織程序結(jié)構(gòu),明確類間關(guān)系,并充分利用已有的類來完成更復(fù)雜、深入的開發(fā)。多態(tài):提高類的抽象度和封閉性,統(tǒng)一一個或多個相關(guān)類對外的接口。繼承:一個類獲取另一個類中所有非私有的數(shù)據(jù)和操作的定義,并將它們作為自己的部分或全部成分。被繼承的類稱為父類或超類,繼承了父類或超類的所有數(shù)據(jù)和操作的類稱為子類。繼承一個父類可以擁有多個子類,這時父類就是所有子類的公共域和公共方法的集合,每一個子類則是父類的特殊化,是對公共域和方法在功能、內(nèi)涵方面的擴展和延伸。現(xiàn)仍以電話卡為例,下圖列舉了各種電話卡類的層次結(jié)構(gòu)、域和方法。各種電話卡類及其間的繼承關(guān)系import
java.io.*;import
java.util.*;abstract
class
PhoneCard{
doublebalance;
abstract
boolean
performDial();
double
getBalance(){
returnbalance;}}
abstract
class
None_Number_PhoneCard
extends
PhoneCard{StringphoneSetType;StringgetSetType(){
return
phoneSetType;}}
abstract
class
Number_PhoneCard
extends
PhoneCard{
long
cardNumber;
intpassword;StringconnectNumber;
booleanconnected;
boolean
performConnection(long
cn,int
pw){
if(cn==cardNumber&&pw==password){connected=true;
return
true;}
else
return
false;}}
class
magCard
extends
None_Number_PhoneCard{StringusefulArea;
boolean
performDial(){
if(balance>0.9){balance-=0.9;
return
true;}
else
return
false;}}class
IC_Card
extends
None_Number_PhoneCard{
boolean
performDial(){
if(balance>0.5){balance-=0.9;
return
true;}
else
return
false;}}class
IP_Card
extends
Number_PhoneCard{DateexpireDate;
boolean
performDial(){
if(balance>0.3&&expireDate.after(newDate())){balance-=0.3;
return
true;}
else
return
false;}}
classD200_Cardextends
Number_PhoneCard{
double
additoryFee;
boolean
performDial(){
if(balance>(0.5+additoryFee)){balance-=(0.5+additoryFee);
return
true;}
else
return
false;}}各種電話卡類及其間的繼承關(guān)系面向?qū)ο蟮睦^承關(guān)系符合人們的思維模式。電話卡分為無卡號、有卡號兩大類,無卡號的電話卡可以細分為磁卡、IC卡等,有卡號的電話卡可分為IP電話卡和200電話卡等。電話卡類是所有其他類的父類,是所有電話卡的公共屬性的集合,包括卡中剩余金額等靜態(tài)的數(shù)據(jù)屬性,撥打電話、查詢余額等動態(tài)的行為屬性。將電話卡具體化,分別派生出兩個子類:無卡號電話卡和有卡號電話卡。這兩個子類繼承了父類電話卡的所有屬性(包括域與方法),即它們也擁有剩余金額、撥打電話、查詢余額等數(shù)據(jù)和操作,但它們定義了適用于本類特殊需要的特殊屬性,如,對于所有的有卡號電話卡,應(yīng)該有卡號、密碼、接入號碼等域和登錄交換機的行為,這些屬性對無卡號電話卡是不適合的。從有卡號電話卡到IP電話卡和200電話卡的繼承遵循完全相同的原則。繼承的主要優(yōu)點:使程序結(jié)構(gòu)清晰,降低編碼和維護的工作量。在繼承特性中,有單重繼承和多重繼承。單重繼承:任何一個類都只有一個父類多重繼承:一個類有一個及以上的父類,它的靜態(tài)的數(shù)據(jù)屬性和操作從所有這些父類中繼承。單重繼承的結(jié)構(gòu)比較簡單,容易控制;但多重繼承的結(jié)構(gòu)是復(fù)雜的網(wǎng)狀,設(shè)計、實現(xiàn)都比較復(fù)雜。但在實際問題中,它們的內(nèi)部結(jié)構(gòu)多為復(fù)雜的網(wǎng)狀,用多重繼承的程序來模擬比較自然,而單重繼承的程序要解決這些問題,則需要其他的一些輔助措施。C++是開發(fā)人員熟悉的支持多重繼承的面向?qū)ο蟮木幊陶Z言,而Java語言僅支持單重繼承??傊?,在面向?qū)ο蟮某绦蛟O(shè)計中,采用繼承的機制來組織、設(shè)計系統(tǒng)中的類,可以提高程序的抽象程度,使之更接近于人類的思維方式,同時也可以提高程序開發(fā)效率,降低維護工作量。3.2Java的繼承(extends
)3.2.1派生子類Java中的繼承:通過extends關(guān)鍵字實現(xiàn),在定義類時使用extends關(guān)鍵字指明新定義類的父類,就在兩個類之間建立了繼承關(guān)系。新定義的類稱為子類,它可以從父類那里繼承所有非private的屬性和方法作為自己的成員。import
java.io.*;import
java.util.*;public
class
StuInfo{public
static
void
main(String
args[]){D200_Cardmy200=newD200_Card();my200.balance=50.0;
System.out.println("父類被隱藏的金額為:"+my200.getBalance());if(my200.performDial())
System.out.println("子類的剩余金額為:"+my200.balance);}}abstract
class
PhoneCard{doublebalance;
abstract
boolean
performDial();
double
getBalance(){returnbalance;}}abstract
class
Number_PhoneCard
extends
PhoneCard{
long
cardNumber;
intpassword;StringconnectNumber;booleanconnected;
boolean
performConnection(long
cn,int
pw){
if(cn==cardNumber&&pw==password){connected=true;
return
true;}
else
return
false;}}classD200_Cardextends
Number_PhoneCard{
double
additoryFee;
doublebalance;
boolean
performDial(){
if(balance>(0.5+additoryFee)){balance-=(0.5+additoryFee);
return
true;}
else
return
false;}}例實現(xiàn)電話卡類的繼承結(jié)構(gòu)。上例定義了PhoneCard,None-Number-PhoneCard,Number-PhoneCard,magCard,IC-Card,IP-Card,D200-Card共七個類,其中None-Number-PhoneCard類和Number-PhoneCard類是PhoneCard類派生出的子類;magCard類和IC-Card類是None-Number-PhoneCard類派生出的子類;IP-Card類和D200-Card類是Number-PhoneCard類派生出的子類。
上例的程序中只在PhoneCard類中定義了域balance,但是在magCard類、IC-Card類、IP-Card類、D200-Card類中中都使用了balance域,它們自身并未定義balance域,使用的balance都是從父類PhoneCard那里繼承來的。PhoneCard類定義了抽象方法performDial(),它的兩個子類也是抽象類,可以不實現(xiàn)這個抽象方法,分別派生出來的4個電話卡類不是抽象類,故而分別定義了針對自己具體情況的performDial()方法。例如磁卡電話通話時沒有優(yōu)惠時段,平均話費較高;200卡的話費較低,但是有額外的附加費;IP卡的話費最低。在IP_Card類中用了java.util包中的Java系統(tǒng)類Date,每個Date類的對象代表一個具體的日期。newDate()創(chuàng)建包含當(dāng)前日期的Date類的對象,after()方法是Date類的方法,在失效日期比當(dāng)前日期晚時,expireDate.after(newDate())返回true,否則返回false。3.2.2域的繼承與隱藏1.域的繼承子類可繼承父類的所有非私有域。父類的所有非私有域?qū)嶋H是各子類都擁有的域的集合。子類從父類繼承域而不是把父類域的定義部分復(fù)制一遍,這就減少程序維護的工作量。2.域的隱藏域的隱藏:子類重新定義一個與從父類那里繼承來的域變量完全相同的變量。隱藏是指子類擁有了兩個相同名字的變量,一個繼承自父類,另一個由自己定義;當(dāng)子類執(zhí)行繼承自父類的操作時,處理的是繼承自父類的變量,而當(dāng)子類執(zhí)行它自己定義的方法時,所操作的變量是它自己定義的變量,而把繼承自父類的變量“隱藏”起來。例UsedHiddenField.javaimport
java.io.*;import
java.util.*;public
class
StuInfo{public
static
void
main(String
args[]){D200_Cardmy200=newD200_Card();my200.balance=50.0;
System.out.println("父類被隱藏的金額為:"+my200.getBalance());if(my200.performDial())
System.out.println("子類的剩余金額為:"+my200.balance);}}abstract
class
PhoneCard{doublebalance;
abstract
boolean
performDial();
double
getBalance(){
returnbalance;}}abstract
class
Number_PhoneCard
extends
PhoneCard{
long
cardNumber;
intpassword;StringconnectNumber;booleanconnected;
boolean
performConnection(long
cn,int
pw){
if(cn==cardNumber&&pw==password){connected=true;
return
true;}
else
return
false;}}classD200_Cardextends
Number_PhoneCard{
double
additoryFee;
doublebalance;
boolean
performDial(){
if(balance>(0.5+additoryFee)){balance-=(0.5+additoryFee);
return
true;}
else
return
false;}}運行結(jié)果注意:子類隱藏父類的域只是使之不可見,父類的同名域在子類對象中仍然擁有自己的獨立的內(nèi)存空間3.2.3方法的繼承與隱藏1.方法的繼承父類的非私有方法也可以被子類繼承。如上例調(diào)用的my200對象的getBalance()方法就繼承自父類PhoneCard類。2.方法的覆蓋如同域變量的隱藏,子類也可重新定義與父類同名的方法,實現(xiàn)對父類方法的覆蓋(Override)。方法的覆蓋與域的隱藏的不同之處在于:子類隱藏父類的域只是使之不可見,父類的同名域在子類對象中仍然占有自己的獨立的內(nèi)存空間;而子類方法對父類同名方法的覆蓋將清除父類方法占用的內(nèi)存,從而使父類方法在子類對象中不復(fù)存在。運行結(jié)果例UsedOverload.javaimport
java.io.*;import
java.util.*;public
class
StuInfo{public
static
void
main(String
args[]){D200_Cardmy200=newD200_Card();my200.balance=50.0;
System.out.println("父類被隱藏的金額為:"+my200.getBalance());
if(my200.performDial())
System.out.println("子類的剩余金額為:"+my200.balance);}}abstract
class
PhoneCard{
doublebalance;
abstract
boolean
performDial();
double
getBalance(){
returnbalance;}}abstract
class
Number_PhoneCard
extends
PhoneCard{
long
cardNumber;intpassword;StringconnectNumber;
booleanconnected;
boolean
performConnection(long
cn,int
pw){
if(cn==cardNumber&&pw==password){connected=true;
return
true;}
else
return
false;}}classD200_Cardextends
Number_PhoneCard{
double
additoryFee;
doublebalance;
boolean
performDial(){
if(balance>(0.5+additoryFee)){balance-=(0.5+additoryFee);
return
true;}
else
return
false;}
double
getBalance(){returnbalance;}}3.2.4this與superthis和super:用來指代父類對象和子類對象的關(guān)鍵字。Java系統(tǒng)默認,每個類都缺省地具有null,this和super三個域,所以在任意類中都可以不加說明而直接使用它們。null代表“空”值。當(dāng)定義一個對象但沒為其開辟內(nèi)存單元時可指定這個對象為null。this和super兩個域與繼承有密切關(guān)系。1.thisthis:表示當(dāng)前對象本身,即當(dāng)前對象的引用。對象的引用是對象的別名,通過引用可以順利地訪問到對象,包括訪問、修改對象的域、調(diào)用對象的方法。對象的引用與內(nèi)存地址無關(guān),它僅僅是對象的另一個名字。一個對象可以有若干個引用,this只是其中之一。利用this可以調(diào)用當(dāng)前對象的方法或使用當(dāng)前對象的域。例如,在D200-Card類中的getBalance()方法需要訪問同一個對象的域balance,可以利用this寫成:
doublegetBalance(){ returnthis.balance; }表示返回當(dāng)前同一個對象的balance域,在這種情況下this也可以不加。this通常用來把當(dāng)前對象的引用作為參數(shù)傳遞給其他的對象或方法。例:getDouble.java
importjava.applet.*;importjava.awt.*;importjava.awt.event.*;publicclassgetDoubleextendsAppletimplements ActionListener{Labelprompt;
TextFieldinput;doubled=0.0;publicvoidinit(){prompt=newLabel(″請輸入一個浮點數(shù):″); input=newTextField(10);
add(prompt);
add(input);
input.addActionListener(this);}publicvoidpaint(Graphicsg){
g.drawString(″你輸入了數(shù)據(jù):″+d,10,50);}publicvoidactionPerformed(ActionEvente){d=Double.valueOf(input.getText()).doubleValue();repaint();}}上例中,調(diào)用的addActionListener()方法是系統(tǒng)類TextField的方法,調(diào)用這個方法要求提供一個實現(xiàn)了ActionListener接口的對象作為實際參數(shù)。定義的用戶類getDouble利用implements關(guān)鍵字實現(xiàn)了ActionListener接口,并使用this將當(dāng)前getDouble類的對象指定為調(diào)用addActionListener()方法的實際參數(shù)。2.superSuper:代表當(dāng)前對象的直接父類對象,是當(dāng)前對象的直接父類對象的引用。直接父類是相對于當(dāng)前對象的其他“祖先”類而言。例如,設(shè)類A派生出子類B,B類派生出子類C,則B是C的直接父類,而A是C的祖先類。super代表的就是直接父類。
例TestSuper.javapublicclassTestfSupper{ publicstaticvoidmain(String
args[]) { D200_Cardmy200=newD200_Card(); my200.balance=50.0;
System.out.println("父類被隱藏的金額為: "+my200.getBalance()); if(my200.performDial())
System.out.println("子類的剩余金額為: "+my200.balance); }}abstract
class
PhoneCard{
doublebalance;abstract
boolean
performDial();double
getBalance(){returnbalance;}}abstract
class
Number_PhoneCard
extends
PhoneCard{
long
cardNumber;intpassword;StringconnectNumber;
booleanconnected;
boolean
performConnection(long
cn,int
pw){
if(cn==cardNumber&&pw==password){connected=true;
return
true;}
else
return
false;}}
classD200_Cardextends
Number_PhoneCard{
double
additoryFee;
doublebalance;
boolean
performDial(){
if(balance>(0.5+additoryFee)){
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 透析患者常見并發(fā)癥及護理
- 垃圾處理與可持續(xù)發(fā)展的關(guān)系
- 豐田汽車生產(chǎn)流程
- 銀行關(guān)于LPR培訓(xùn)
- 金融投資風(fēng)險與收益分配協(xié)議
- 酒類行業(yè)私人藏酒協(xié)議
- 房地產(chǎn)經(jīng)紀行業(yè)現(xiàn)狀與發(fā)展趨勢分析
- 脊柱外科出院流程護理
- 溫室節(jié)能遮蔭保溫幕相關(guān)行業(yè)投資規(guī)劃報告范本
- 移動應(yīng)用開發(fā)服務(wù)合同
- 蘇教版六年級下冊數(shù)學(xué)第三單元第1課《解決問題的策略(1)》課件(公開課)
- EOS-60D-說明手冊課件
- 企業(yè)經(jīng)營管理診斷方案
- 年度球迷活動策劃方案
- 壓瘡上報登記表
- 2021年無人機駕駛員考試題庫及答案(完整版)
- 城軌車輛常見制動系統(tǒng)-EP09制動系統(tǒng)
- 同位素水文學(xué)研究綜述
- 【公開課】第1章發(fā)酵工程單元復(fù)習(xí)教學(xué)設(shè)計高二下學(xué)期生物人教版選擇性必修3
- 植筋施工施工方案
- 骨關(guān)節(jié)科臨床診療指南及技術(shù)操作規(guī)范
評論
0/150
提交評論