第5章繼承和接口_第1頁
第5章繼承和接口_第2頁
第5章繼承和接口_第3頁
第5章繼承和接口_第4頁
第5章繼承和接口_第5頁
已閱讀5頁,還剩57頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1第5章繼承和接口本章主要講述如下內(nèi)容:繼承、覆蓋和重載抽象類和最終類

接口的定義和使用;

接口與抽象類的異同點;

內(nèi)部類;2

繼承

繼承是軟件重用的一種形式,可以提高系統(tǒng)的性能;Java不支持多繼承,但支持多接口;子類的對象也是其超類的對象,反之未必;繼承具有傳遞性。繼承語法:classclassNameextendssuperClassName{

各變量和方法的定義}

classpoint{ intx,y; point(intx,inty){ this.x=x;this.y=y;} point(){this.x=0;this.y=0;}}

classcircleextendspoint{ intradius;

circle(intr,intx,inty){ radius=r; this.x=x;

this.y=y; }}4關(guān)鍵字super構(gòu)造函數(shù)是一種特殊的方法,子類不能繼承超類的構(gòu)造函數(shù),但子類構(gòu)造函數(shù)可以通過super調(diào)用超類的構(gòu)造函數(shù)。

當創(chuàng)建子類對象時,首先執(zhí)行超類構(gòu)造函數(shù),然后執(zhí)行子類的構(gòu)造函數(shù)。例如:

classpoint{//程序4-8intx,y;point(intx,inty){

this.x=x; this.y=y; System.out.println("父類構(gòu)造函數(shù)被調(diào)用!");}}

classcircleextendspoint{intradius;circle(intr,intx,inty){

super(x,y); //必須是第一條語句

radius=r; System.out.println("子類構(gòu)造函數(shù)被調(diào)用!");}}7再次討論構(gòu)造函數(shù)

若父類沒有定義構(gòu)造函數(shù),那么對父類數(shù)據(jù)的初始化將采用系統(tǒng)缺省的構(gòu)造函數(shù);例如:

classpoint{

intx,y;}

classcircleextendspoint{intradius;circle(intr,intx,inty){ this.x=x;this.y=y;radius=r;}}8再次討論構(gòu)造函數(shù)(續(xù))若父類定義有缺省構(gòu)造函數(shù),那么子類可根據(jù)自己的需要設(shè)置自己的構(gòu)造函數(shù)。例如:

classpoint{ intx,y;

point(){ this(0,0);}

point(intx,inty){this.x=x;this.y=y;}}

classcircleextendspoint{//注意子類的構(gòu)造函數(shù) intradius; circle(intr,intx,inty){ radius=r;}}9再次討論構(gòu)造函數(shù)(續(xù))若父類定義的構(gòu)造函數(shù)都是有參的,那么子類構(gòu)造函數(shù)必須通過super調(diào)用父類構(gòu)造函數(shù),例如:classpoint{privateintx,y;

point(intx,inty){this.x=x;this.y=y;}}classcircleextendspoint{intradius;circle(intr,intx,inty){

super(x,y);

radius=r;}}10

方法的覆蓋

方法的覆蓋發(fā)生在父類和子類之間,若子類中定義的某個方法的特征,與父類中定義的某個方法的特征完全一樣,那么就說子類中的這個方法覆蓋了父類對應(yīng)的那個方法。

11

覆蓋與重載的區(qū)別

重載可以出現(xiàn)在一個類中,也可以出現(xiàn)在父類與子類的繼承關(guān)系中,并且重載方法的特征一定不完全相同。多個方法的參數(shù)或類型不同覆蓋特點:子類中的方法特征與父類定義的對應(yīng)方法的特征完全一樣?;蛘哒f子類重寫父類的方法.(方法首部完全一樣)例如:

//程序4-9classpoint{//覆蓋area() intx,y;

point(){this(0,0);} point(intx,inty){ this.x=x;this.y=y;}

doublearea(){return0;}}classcircleextendspoint{ intradius;

circle(intr,intx,inty){super(x,y);radius=r;}

doublearea(){returnMath.PI*radius*radius;}}14

方法的動態(tài)調(diào)用

Java的所有對象運行時都有一個類型標識(RTTI:Run-TimeTypeIdentification),該標識記錄了每個對象所屬于的類。Java用此標識在運行時選擇正確的方法。例如:

例子超出了范圍qt4.java//程序4-11classpoint{

intx,y;

point(){this(0,0);} point(intx,inty){this.x=x;this.y=y;}

doublearea(){return0;}}

classcircleextendspoint{

intradius; circle(intr,intx,inty){super(x,y);radius=r;}

doublearea(){//覆蓋了父類的area方法

returnMath.PI*radius*radius; }}publicclassdynamicalCall{publicstaticvoidmain(Stringargs[]){

pointp[]={newpoint(2,2),newcircle(1,1,1)};

for(inti=0;i<p.length;i++){ System.out.print(“類名:”+ p[i].getClass().getName()); System.out.print(“父類:”+ p[i].getClass().getsuperclass()); System.out.println(“面積:”+

p[i].area()); } }}17方法的動態(tài)調(diào)用小節(jié)子類對象調(diào)用方法時(1)

子類檢查是否具有同名和同參數(shù)類型的方法,若有調(diào)用該方法,否則繼續(xù)執(zhí)行。(2)

到父類中尋找同名和同參數(shù)類型的方法,若有調(diào)用該方法。若找不到,將產(chǎn)生編譯錯誤。 對象決定自己到底該調(diào)用哪個方法,取決于該對象在繼承鏈中的位置。

184.9 多態(tài)性不適合繼承鏈中的實例變量

對象.方法:根據(jù)多態(tài)性調(diào)用;對象.實例變量:根據(jù)對象的類型調(diào)用。即:多態(tài)性僅僅適用于方法的調(diào)用,而不適合實例變量。例如:方法是子類的變量是父類的classBase{ //程序4-12

intx=1;

voidprint(){ System.out.println(“當前類為”+

this.getClass().getName()); System.out.println("對象的x="+this.x); }}classDerivedextendsBase{

intx=2;

voidprint(){ System.out.println(“當前類為”+

this.getClass().getName()); System.out.println("對象的x="+this.x); }}publicclassconfusions{ publicstaticvoidmain(String[]args){ Baseobj=newDerived();

obj.print(); System.out.println("對象的x="+obj.x); }}

下面是輸出結(jié)果:當前類為Derived對象的x=2對象的x=121

staticstatic修飾變量(與C中的不同);static修飾方法(與C中的不同);

22

static變量

static變量是指這樣的成員變量:不管在程序運行中生成多少個該類的對象,它們都共享該變量。即使沒有創(chuàng)建對象,該變量仍然存在。因此,static變量又稱為類變量。定義格式為:statictypevariableName;23

static方法

static方法是類中的成員方法,它屬于整個類,即使不創(chuàng)建任何對象,也可使用靜態(tài)方法。在子類中不能覆蓋父類中定義的靜態(tài)方法。調(diào)用靜態(tài)方法格式:類名.方法名(參數(shù));靜態(tài)方法中只能出現(xiàn)靜態(tài)變量和其它靜態(tài)方法。并且還不能使用this和super。例如:p100:4.1024

關(guān)鍵字final在實例變量、局部變量和方法的形參定義之前加上final,那么這個變量值只能被引用,而不能修改。final修飾的局部變量和實例變量必須給出初值,因為它修飾的變量代表一個常量。例如:

classBase{ //程序4-16 finalintx=1; //形式1:修飾實例變量

voidprint(finalinty){ //形式2:修飾參數(shù)

//

y=0; //錯誤

System.out.println(x+y); }}

publicclassfinalVariables{ publicstaticvoidmain(String[]args){ finalintvar=100; //形式3:修飾局部變量

Baseobj=newBase();

obj.print(var); }}26

final方法

在方法定義前加上final,該方法就不能被子類覆蓋,成為終極方法;包含終極方法的類仍然可以被子類繼承,子類雖然不能覆蓋父類中的終極方法,但可以重載該方法。例如:

classBase{ finalintx=1;

finalvoidprint(inty){ //父類中的final方法

System.out.println(x+y); }}

classDerivedextendsBase{ voidprint(){ //重載了父類中的print方法

System.out.println(x); }}28

final類

在一個類定義前加上final,意味著這個類就不能被其它類繼承,成為終極類。系統(tǒng)類基本上都是final類,如String類。將class定義為final是為了杜絕繼承,類中的方法自然都變成了終極方法。例如:finalclassBase{ //聲明為final類

finalintx=1;

voidprint(finalinty){ System.out.println(x+y); }}

//錯誤:不能繼承final修飾的Base類classDerivedextendsBase{}30Static和finalStatic變量可以被隱藏(加、不加static均可)。Static方法可以被重載(加、不加static均可)。Static方法被重寫,則一定要加Static。父類的非Static方法,重寫時也一定是非Static方法。重載則沒有限制。父類的final方法不允許被重寫。父類的final方法,允許被重載(加、不加final均可)。對final變量無限制。若final前加上static后的方法,要求同static。31

組合與繼承

面向?qū)ο笾械能浖赜帽憩F(xiàn)為兩種形式:繼承和對象組合。

設(shè)計這類程序的關(guān)鍵是構(gòu)造函數(shù):子類構(gòu)造函數(shù)調(diào)用父類構(gòu)造、成員對象的初始化。例如:classdate{ //程序4-17intyear,mon,day; date(inty,intm,intd){ year=y;mon=(m>0&&m<13)?m:1; day=checkday(d);}intcheckday(intd){ intdaydisp[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; if(d>0&&d<=daydisp[mon]) returnd; if(mon==2&&d==29&&(year%400==0|| year%4==0&&year%100!=0)) returnd; return1;} Stringtostring(){returnyear+"/"+mon+"/"+day;}}classemployee{ //雇員類

longid;

datebirthday;

employee(longno,intyear,intmon,intday){ id=no;

//設(shè)置組合對象

birthday=newdate(year,mon,day); }

Stringtostring(){ returnid+","+birthday.tostring(); }}classmanagerextendsemployee{ //經(jīng)理類

doublebasePay;

manager(longno,inty,intm,intd){ super(no,y,m,d); //調(diào)用父類構(gòu)造函數(shù)

basePay=1000; }

Stringtostring(){ returnbasePay+","+super.tostring(); }}publicclasscompositionAndInherence{ publicstaticvoidmain(String[]args){ managerboss;

boss=newmanager(1001,1971,11,5); System.out.println(boss.tostring()); }}程序運行結(jié)果如下:1000.0,1001,1971/11/536

抽象類和抽象方法

抽象方法:僅有方法特征,但沒有代碼;抽象類:包含抽象方法的類。但是,不包含抽象方法的類也可以是抽象類。抽象類的作用:提供一種適當?shù)某?,子類通過繼承實現(xiàn)父類中的抽象方法。

抽象類不能用final修飾。抽象類體現(xiàn)了多態(tài)性,通過繼承可以從抽象類派生出具有相似操作的子類。例如:37//程序4-18abstractclassinstrument{abstractvoidplay(); //抽象方法 }

//wind不是抽象類classwindextendsinstrument{voidplay(){ System.out.println("windplay!");}}

//percussion也是抽象類classpercussionextendsinstrument{voidplay(){System.out.println("percussionplay!");}}//stringed也不是抽象類classstringedextendsinstrument{ voidplay(){System.out.println("stringedplay!");} }

classwoodWindextendswind{//覆蓋父類中的play方法voidplay(){System.out.println("woodWindplay!");}}

classbrassextendswind{//覆蓋了父類中的play方法voidplay(){ System.out.println("brassplay!");}}publicclassmusic{ staticvoidtuneAll(instrumente[]){ for(inti=0;i<e.length;i++)e[i].play(); } publicstaticvoidmain(String[]args){ instrumentorchestra[]=newinstrument[5]; inti=0;

orchestra[i++]=newwind(); orchestra[i++]=newpercussion(); orchestra[i++]=newstringed(); orchestra[i++]=newwoodWind(); orchestra[i++]=newbrass(); tuneAll(orchestra); }}程序運行結(jié)果:windplay!percussionplay!stringedplay!woodWindplay!brassplay!42

對象的類型轉(zhuǎn)換

類型向上轉(zhuǎn)換(upcasting);類型向下轉(zhuǎn)換(downcasting)。

43

向上類型轉(zhuǎn)換

從子類向父類轉(zhuǎn)換,在繼承圖中是向上移動,通常稱為向上類型轉(zhuǎn)換。類型向上轉(zhuǎn)換是安全的,因為這是從特殊類型到通用類型的轉(zhuǎn)換。進行向上類型轉(zhuǎn)換時,出現(xiàn)的唯一問題是可能丟失子類中定義的方法和變量。例如:

//程序4-19classpoint{ intx,y;

point(intx,inty){ this.x=x;this.y=y;} intgetX(){ returnx;}}

classcircleextendspoint{ intradius;

circle(intr,intx,inty){super(x,y); radius=r;} doublearea(){returnMath.PI*radius*radius;}}46

向下類型轉(zhuǎn)換

從父類向子類轉(zhuǎn)換,在繼承圖中是向下移動,稱為向下類型轉(zhuǎn)換。類型向下轉(zhuǎn)換是不安全的,因為這是從一般類型到特殊類型的轉(zhuǎn)換。例如:publicstaticvoidmain(String[]args){ pointp=newpoint(1,1); circlec;

if(pinstanceofcircle){//判斷能否進行類型轉(zhuǎn)換

c=(circle)p; System.out.println(c.area()); }else //出錯處理

System.out.println("cannotdownCasting");}48

接口

引入接口的原因:在程序設(shè)計中經(jīng)常遇到這樣一個問題:有些類互不相關(guān),但卻具有相似的方法。并且這些方法在各個類中的實現(xiàn)互不相同。我們不能為這些類定義一個共同的父類,但又希望在程序中體現(xiàn)出它們共同的接口。

49

接口的定義和應(yīng)用

接口是一系列常量和空方法的集合,它提供了多個類共同的方法,但不限制每個類如何實現(xiàn)這些方法。Java允許一個類同時實現(xiàn)多個接口,相當于實現(xiàn)多繼承的功能。

50

接口的定義和應(yīng)用(續(xù))聲明一個接口的語法格式:

[public]interfaceinterfaceName[extendssuper-interface-List]{

typeConstantName=value;

typeMethodName(Parameterlists);}51

接口的定義和應(yīng)用(續(xù))接口中不能聲明任何變量和構(gòu)造函數(shù)。如果一個類實現(xiàn)多個接口,應(yīng)該在接口名之間用逗號隔開。

當一個類實現(xiàn)接口時,必須實現(xiàn)接口中給出的空方法,若實現(xiàn)接口的類是一個抽象類,可以把實現(xiàn)接口的任務(wù)交給子類去實現(xiàn)。例如://程序5-1interfaceSortable{ //定義一個接口intCompare(Sortables);}

classSort{ //定義一個排序類,僅有一個靜態(tài)的方法publicstaticvoidSelectSort(Sortablea[]){ inti,j,k; Sortabletemp;

for(i=0;i<a.length-1;i++){//選擇排序 k=i; for(j=i+1;j<a.length;j++) if(a[k].Compare(a[j])<0) k=j; temp=a[i];a[i]=a[k];a[k]=temp; }}}classStudentimplementsSortable{//定義一個學(xué)生類

privateintscore; Student(intx){ score=x; }

//實現(xiàn)接口Sortable中的方法 publicintCompare(Sortables){

Studentst=(Student)s; //類型強制轉(zhuǎn)換

returnscore-st.score; }

publicStringtoString(){return"score="+score;}}classRectangleimplementsSortable{//矩形類也實現(xiàn)了接口

privateintlength,width;

Rectangle(intx,inty){length=x;width=y;}

intarea(){returnlength*wid

溫馨提示

  • 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)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論