JAVA程序設(shè)計(jì)技能教程第6章_第1頁
JAVA程序設(shè)計(jì)技能教程第6章_第2頁
JAVA程序設(shè)計(jì)技能教程第6章_第3頁
JAVA程序設(shè)計(jì)技能教程第6章_第4頁
JAVA程序設(shè)計(jì)技能教程第6章_第5頁
已閱讀5頁,還剩62頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第6章類的繼承與多態(tài)

任務(wù)一:掌握類的繼承

任務(wù)三:掌握接口的使用

任務(wù)二:掌握類的多態(tài)

任務(wù)四:掌握包的使用

任務(wù)五:實(shí)訓(xùn)六繼承與多態(tài)編程實(shí)訓(xùn)

6.1任務(wù)一掌握類的繼承

繼承:子類擁有父類的屬性和方法我們通過一個(gè)實(shí)際應(yīng)用問題來引出類的繼承這個(gè)問題的講解。6.1.1繼承的基本概念

【例6-1】定義一個(gè)普通人的類和學(xué)生類。publicclassPerson{ publicStringname; publicintage; publicStringgetInfo(){...}}publicclassStudent{ publicStringname;publicintage; publicStringschool; publicStringgetInfo(){...} publicStringstudy(){...}}Student類中包含了Person類的所有屬性和方法。針對這種情況,Java引入了繼承這個(gè)概念,只要表明類Student繼承了類Person的所有屬性和方法,就不用在類Student中重復(fù)書寫類Person中的代碼了,更確切的說就是簡化了類的定義。我們通過extends關(guān)鍵字來表明類Student具有類Person的說有屬性和方法上面的兩個(gè)類可以簡寫成下面的代碼:【例6-2】簡寫的學(xué)生類。publicclassPerson{ publicStringname; publicintage; publicStringgetInfo(){...}}publicclassStudentextendsPerson{ publicStringschool; publicStringstudy(){...}}在類的繼承中有這樣一些細(xì)節(jié)問題:1.通過繼承可以簡化類的定義,可以實(shí)現(xiàn)代碼重用,在上面的例子中我們重用了基類的屬性和方法。2.Java只支持單繼承,不允許多重繼承。也就是說,在Java中一個(gè)子類只能有一個(gè)父類,不允許一個(gè)類直接繼承多個(gè)父類,但一個(gè)類可以被多個(gè)類繼承。3.Java中可以有多層繼承。即一個(gè)類可以繼承為某一個(gè)類的子類。如類Y繼承了類X,類Z又可以繼承類Y,那么類Z也間接繼承了類X。這種應(yīng)用如下所示:classX{}classYextendsX{}classZextendsY{}4.子類繼承父類所有的成員變量和成員方法,但不繼承父類的構(gòu)造方法。在子類的構(gòu)造方法中可以使用super(參數(shù)列表)調(diào)用父類的構(gòu)造方法。如:publicclassStudentextendsPerson{ publicStudent(Stringname,intage,Stringschool){ super(name,age); this.school=school; }}5.如果子類的構(gòu)造方法中沒有顯示的調(diào)用父類的構(gòu)造方法,也沒有使用this關(guān)鍵字調(diào)用重載其他的構(gòu)造方法,則在產(chǎn)生之類的實(shí)例對象時(shí),系統(tǒng)默認(rèn)調(diào)用父類無參數(shù)的構(gòu)造方法,也就是說在下面的的類B中定義的構(gòu)造發(fā)昂法中,寫不寫super()語句效果是一樣的。publicclassBPersonA{ publicB(){ super();//有沒有這一句,效果都是一樣的

}}}publicclassStudentextendsPerson{ publicvoidstudy(){ System.out.println("學(xué)習(xí)中..."); } publicstaticvoidmain(String[]args){ Personp=newPerson(); ="張三"; p.age=35; p.getInfo(); Students=newStudent(); ="李四"; s.age=18; s.getInfo(); s.study(); }}6.1.2繼承的實(shí)現(xiàn)對象中的成員變量的初始化過程是按照下述步驟進(jìn)行的:1.分配成員變量的存儲(chǔ)空間并進(jìn)行默認(rèn)的初始化,就是用new關(guān)鍵字產(chǎn)生對象后,對類中的成員變量進(jìn)行初始化賦值。2.綁定構(gòu)造方法參數(shù),就是newPerson(實(shí)際參數(shù)列表)中所傳遞的參數(shù)賦值給構(gòu)造方法中的形式參數(shù)變量。3.如果有this()調(diào)用則調(diào)用相應(yīng)得重載構(gòu)造方法(被調(diào)用的重載構(gòu)造方法又從步驟(2)開始執(zhí)行這些流程),被調(diào)用的重載構(gòu)造方法執(zhí)行流程結(jié)束后,回到當(dāng)前構(gòu)造方法當(dāng)前構(gòu)造方法直接跳到步驟(6)執(zhí)行。4.顯式或隱式追溯調(diào)用父類的構(gòu)造方法(一直到Object類為止,Object是所有Java類的最頂層父類),父類的構(gòu)造方法又從步驟(2)開始對父類執(zhí)行這些流程,父類的構(gòu)造方法執(zhí)行流程結(jié)束后,回到當(dāng)前的構(gòu)造方法,當(dāng)前的構(gòu)造方法繼續(xù)執(zhí)行。5.進(jìn)行實(shí)例變量的顯示初始化操作,也就是執(zhí)行在定義成員變量是就對其進(jìn)行賦值的語句,如:publicclassStudentextendsPerson{ Stringschool="HRBJZ"http://顯式初始化

...}將HRBJZ賦值給school成員變量6.執(zhí)行當(dāng)前構(gòu)造方法中方法體中的程序代碼,如:publicclassStudentextendsPerson{ publicStudent(Stringname,intage,Stringschool){ super(name,age); this.school=school; }}6.1.3super與this的使用

1.this:使用在一個(gè)成員函數(shù)的內(nèi)部,指向當(dāng)前對象

【例6-4】使用this變量訪問對象的成員變量。classPerson{

Stringname;

intage;

voidPerson(Stringname,intage){

=name;

this.age=age;

}

}this用來訪問本類的成員變量和成員方法的引用格式如下:(1)this.成員變量(2)this.成員方法([參數(shù)列表])一般情況下,在以下幾種情況下需要使用到this:1.通過this調(diào)用另一個(gè)構(gòu)造方法,用法是this(參數(shù)列表),這個(gè)僅僅在類的構(gòu)造方法中,別的地方不能這么用。2.函數(shù)參數(shù)或是函數(shù)中的局部變量和成員變量同名的情況下,成員變量被屏蔽,此時(shí)要訪問成員變量則需要用“this.成員變量名”的方式來引用成員變量。3.在函數(shù)中,需要引用該函所屬類的當(dāng)前對象時(shí)候,直接用this。this還有一個(gè)用法,就是構(gòu)造函數(shù)的第一個(gè)語句,它的形式是this(參數(shù)表),這個(gè)構(gòu)造函數(shù)就會(huì)調(diào)用同一個(gè)類的另一個(gè)相對的構(gòu)造函數(shù)。【例6-5】this的另一用法。

classUserInfo{

publicUserInfo(Stringname){

this(name,aNewSerialNumber);

}

publicUserinfo(Stringname,intnumber){

userName=name;

userNumber=number;

}}2.super引用super是用在子類中,目的是訪問直接父類(即類之上最近的超類)中被屏蔽的成員。【例6-6】super的用法示例classPerson{

publicintnumber;

privateStringname;

privateintage;protectedvoidsetName(Stringname){

=name;

}

protectedvoidsetAge(intage){

this.age=age;

}protectedvoidprint(){System.out.println("姓名:"+name+",年齡:"+age);}

}publicclassDemoSuperextendsPerson{

publicvoidprint(){System.out.println("DemoSuper:");super.print();}publicstaticvoidmain(String[]args){DemoSupertest=newDemoSuper();test.setName("張三");test.setAge(20);test.print();}【例6-7】在對象初始化的時(shí)候自動(dòng)調(diào)用this和super:classPerson{

publicstaticvoidprint(Strings){System.out.println(s);

}Person(){print("APerson.");}Person(Stringname){print("Apersonnameis:"+name);}}publicclassChineseextendsPerson{Chinese(){super();

//調(diào)用父類構(gòu)造函數(shù)(1)print("Achinese.");//(4)}Chinese(Stringname){super(name);//調(diào)用父類具有相同形參的構(gòu)造函數(shù)(2)print("hisnameis:"+name);}Chinese(Stringname,intage){this(name);//調(diào)用當(dāng)前具有相同形參的構(gòu)造函數(shù)(3)print("hisageis:"+age);}publicstaticvoidmain(String[]args){Chinesepeople=newChinese();people=newChinese("張三");people=newChinese("張三",20);}}

綜上所述,super用來訪問父類的成員變量和成員方法的引用格式有以下幾種:(1)super.成員變量(2)super.(參數(shù)列表)(3)super.成員方法([參數(shù)列表])針對super的引用方式,下面總結(jié)一下super的用法:第一,在子類構(gòu)造方法中要調(diào)用父類的構(gòu)造方法,用“super(參數(shù)列表)”的方式調(diào)用,參數(shù)不是必須的。同時(shí)還要注意的一點(diǎn)是:“super(參數(shù)列表)”這條語句只能用在子類構(gòu)造方法體中的第一行。第二,當(dāng)子類方法中的局部變量或者子類的成員變量與父類成員變量同名時(shí),也就是子類局部變量覆蓋父類成員變量時(shí),用“super.成員變量名”來引用父類成員變量。當(dāng)然,如果父類的成員變量沒有被覆蓋,也可以用“super.成員變量名”來引用父類成員變量,不過這是不必要的。第三,當(dāng)子類的成員方法覆蓋了父類的成員方法時(shí),也就是子類和父類有完全相同的方法定義(但方法體可以不同),此時(shí),用“super.方法名(參數(shù)列表)”的方式訪問父類的方法。6.1.4final類和final方法1.final標(biāo)記的類不能被繼承。2.final標(biāo)記的方法不能被子類重寫。3.final標(biāo)記的變量(成員變量和局部變量)成為常量,只能賦值一次。如:finalintY=2;Y=3;//出錯(cuò)4.final標(biāo)記的成員變量必須在聲明的同時(shí)顯式賦值,或在該類的構(gòu)造方法中顯式賦值,然后才能使用,如:classTest{ finalintX=5;}或者:classTest{ finaintX; Test(){ X=3; }}5.方法中定義的內(nèi)置類只能訪問該方法內(nèi)的final類型的局部變量,用final定義的局部變量相當(dāng)于是一個(gè)常量,它的生命周期超出方法運(yùn)行的生命周期。6.將一個(gè)形式參數(shù)定義成final也是可以的,這就限定了我們在方法中修改形式參數(shù)的值。7.final標(biāo)記的變量(成員變量或局部變量)通常我們稱為常量,只能賦值一次,但這個(gè)“常量”也只能在這個(gè)類的內(nèi)部使用,不能在類的外部直接使用。但當(dāng)我們用publicstaticfinal共同標(biāo)記常量時(shí),這個(gè)常量就成為了全局常量,而且這樣定義的常量只能在定義時(shí)賦值,即使在構(gòu)造函數(shù)里面也不能對其進(jìn)行賦值,如:classPerson{

publicstaticfinalStringname="張三";

......

}

6.2任務(wù)二掌握類的多態(tài)

在Java中我們通過方法的重載和方法的覆蓋(重寫)來實(shí)現(xiàn)了多態(tài)性,下面本節(jié)我們通過介紹方法的重載和覆蓋來給大家介紹Java是如何實(shí)現(xiàn)多態(tài)的。6.2.2方法的重載

1.成員函數(shù)的重載

【例6-8】方法重載的例子://方法的重載.classOverloadDemo{//不含參數(shù)

voidtest(){ System.out.println("Noparameters"); }//含有一個(gè)整型參數(shù). voidtest(inta){ System.out.println("a:"+a); }//含有兩個(gè)整型參數(shù)

voidtest(inta,intb){ System.out.println("aandb:"+a+""+b); }//含有一個(gè)雙精度型參數(shù)

doubletest(doublea){ System.out.println("doublea:"+a); returna*a;}}publicclassOverload{ publicstaticvoidmain(Stringargs[]){ OverloadDemoob=newOverloadDemo(); doubleresult;//調(diào)用各種類型的參數(shù)test(){

ob.test(); ob.test(10); ob.test(10,20);

result=ob.test(123.25); System.out.println("Resultofob.test(123.25):"+result); }2.構(gòu)造函數(shù)重載除了重載正常的方法外,構(gòu)造函數(shù)也能夠重載。實(shí)際上,對于大多數(shù)你創(chuàng)建的現(xiàn)實(shí)的類,重載構(gòu)造函數(shù)是很常見的,并不是什么特例。為了理解為什么會(huì)這樣,我們給出一個(gè)Box類的例子:【例6-10】Box類重載的例子。

classBox{ doublewidth; doubleheight; doubledepth;//該類的構(gòu)造函數(shù)

Box(doublew,doubleh,doubled){ width=w; height=h; depth=d; }//返回體積

doubulevolume(){ returnwidth*height*depth; }}下面程序是Box的一個(gè)改進(jìn)版本,它就是運(yùn)用對Box構(gòu)造函數(shù)的重載來解決這些問題的:classBox{ doublewidth;doubleheight;doubledepth; //包含所有參數(shù)

Box(doublew,doubleh,doubled){ width=w;height=h;depth=d; }//沒有參數(shù)的特殊盒子

Box(){ width=-1;height=-1;depth=-1;//用-1表示未初始化的盒子 }//立方體盒子。只有一個(gè)參數(shù)

Box(doublelen){ width=height=depth=len; }//返回體積

doublevolume(){ returnwidth*height*depth; }}publicclassOverloadCons{publicstaticvoidmain(Stringargs[]){ //創(chuàng)建給出不同參數(shù)個(gè)數(shù)的盒子

Boxmybox1=newBox(10,20,15); Boxmybox2=newBox(); Boxmycube=newBox(7); doublevol; vol=mybox1.volume(); System.out.println("Volumeofmybox1is"+vol); vol=mybox2.volume(); System.out.println("Volumeofmybox2is"+vol); vol=mycube.volume(); System.out.println("Volumeofmycubeis"+vol); }}6.2.3方法的覆蓋1.方法覆蓋在子類中根據(jù)需要對父類中繼承來的方法進(jìn)行改造——方法的覆蓋(也叫重寫)。覆蓋方法必須和被覆蓋的方法具有相同的方法名稱、參數(shù)列表和返回值類型。【例6-11】修改后的Student類和Person類重寫了getInfo()方法:

classPerson{ publicStringname; publicintage; publicPerson(Stringname,intage) { =name; this.age=age; } publicPerson(){} publicvoidgetInfo() { System.out.println(name); System.out.println(age); }}publicclassStudentextendsPerson{ publicStringschool; publicvoidstudy(){ System.out.println("學(xué)習(xí)中..."); } publicvoidgetInfo() { super.getInfo(); System.out.println(school); }

publicstaticvoidmain(String[]args){ Personp=newPerson(); ="張三"; p.age=35; p.getInfo(); Students=newStudent(); ="李四"; s.age=18; s.school="哈爾濱金融高等專科學(xué)校"; s.getInfo(); s.study(); }}(1)子類型轉(zhuǎn)換成父類【例6-12】子類型B轉(zhuǎn)換成父類A。classA{ publicvoidfunc1(){ System.out.println("Afunctioniscalling"); } publicvoidfunc2(){ func1(); }

}classBextendsA{ publicvoidfunc1(){ System.out.println("Bfunctioniscalling"); } publicvoidfunc3(){ System.out.println("Bfunc3iscalling"); }}2.父類對象與子類對象之間的轉(zhuǎn)換publicclassc{ publicstaticvoidmain(String[]args){ Bb=newB(); Aa=b; callA(a); callA(newB()); } publicstaticvoidcallA(Aa){ a.func1(); a.func2(); }}(2)父類轉(zhuǎn)換成子類【例6-13】父類型轉(zhuǎn)換成子類。publicstaticvoidCallA(Aa){ Bb=(B)a; b.func1(); b.func2(); b.func3();}(3)instanceof操作符可以用instanceof判斷是否一個(gè)類實(shí)現(xiàn)了某個(gè)接口,也可以用它對一個(gè)實(shí)例對象是否屬于一個(gè)類。instanceof語法格式為:對象instanceof類(或接口)它的返回值是布爾型的,或?yàn)閠rue,或者為false【例6-14】instanceof操作符的使用。publicstaticvoidCallA(Aa){ if(ainstanceofB){ Bb=(B)a; b.func1(); b.func2(); b.func3(); } else{ a.func1(); a.func2(); } }6.3任務(wù)三掌握接口的使用6.3.1抽象類和抽象方法

Java中可以定義一些不含方法體的方法,它的方法體的事項(xiàng)交給該類的子類根據(jù)自己的情況去實(shí)現(xiàn),這樣的方法就是抽象方法,包含抽象方法的類就叫抽象類.

一個(gè)抽象類中可以有一個(gè)或多個(gè)抽象方法。抽象類定義規(guī)則:1.抽象類必須用abstract關(guān)鍵字來修飾;抽象方法也必須用abstract來修飾。2.抽象類不能被實(shí)例化,也就是不能用new關(guān)鍵字去產(chǎn)生對象。3.抽象方法只需要聲明,不需要去實(shí)現(xiàn)。4.含有抽象方法的類不許被聲明為抽象類,抽象類的子類也必須覆蓋收有抽象方法后才能被實(shí)例化,否則這個(gè)子類還是一個(gè)抽象類。抽象方法的寫法abstract返回值類型抽象方法(參數(shù)列表)例:abstractclassA{ abstractintxx(intx,inty);}含有抽象方法的類肯定是抽象類,抽象類中的某個(gè)方法不一定是抽象的。6.3.2接口的聲明如果一個(gè)抽象類中的所有方法都是抽象的,就可以將這個(gè)類用另外一種方式來定義,也就是接口定義。接口是抽象方法和常量值的定義的集合。例:publicinterfaceRunner{ intID=1001; voidrun();}6.3.3接口的使用我們可以定義一個(gè)新的接口用extends關(guān)鍵字去繼承已有的接口;也可以定義一個(gè)類,用implements關(guān)鍵字去實(shí)現(xiàn)一個(gè)接口中的所有方法;還可以定義一個(gè)抽象類,用implements關(guān)鍵字去實(shí)現(xiàn)一個(gè)接口中定義的部分方法。【例6-15】接口和抽象類的定義和使用。interfaceAnimalextendsRunner{ voidbreathe();}classFishimplementsAnimal{ publicvoidrun(){ System.out.println("fishisswimming..."); } publicvoidbreathe(){ System.out.println("fishisbubbling..."); }}abstractclassLandAniamalimplementsAnimal{ publicvoidbreathe(){ System.out.println("LandAnimalisbreaching..."); }}6.4任務(wù)四掌握包的使用6.4.1包的概念包是java語言提供的組織類和接口的工具,即包是一組相關(guān)類和接口的集合。包的定義(四步)

1、創(chuàng)建一個(gè)文件夾,文件夾名與包名相同。

2、構(gòu)建包:package包名;//必須是第一條語句//

類的定義;//存盤時(shí)以類名保存為.java文件//3、對保存的文件進(jìn)行編譯,產(chǎn)生.class文件。

4、將.class文件放入第一步建立的與包名同名的文件夾中。該文件夾即是包。注意:包名全部用小寫字母。【例6-16】包的定義。packageedu.hrbjzpublicclassTestpackage{ publicstaticvoidmain(String[]args) { newTest().print; }}classTest{ publicvoidprint(){ System.out.println("Teachinghowtousingpackage!"); }}6.4.2包的使用【例6-16】包的使用。packageedu.hrbjzpublicclassTestpackage{ publicstaticvoidmain(String[]args) { newTest().print;//標(biāo)記

}}程序清單2:Test.javapackageedu.hrbjz.example;classTest{ publicvoidprint(){ System.out.println("Teachinghowtousingpackage!"); }}6.4.3常用系統(tǒng)包1.java.lang包:java的核心類庫,包含了運(yùn)行java程序必不可少的系統(tǒng)類,如基本數(shù)據(jù)類型、基本數(shù)學(xué)函數(shù)、字符串處理、線程、異常處理類等,系統(tǒng)缺省加載這個(gè)包。這里需要補(bǔ)充說明的的是這個(gè)java.lang包從java1.2版本以后對于其中的類,不需要實(shí)用import語句來做導(dǎo)入了,如我們前面經(jīng)常使用的System類。2.java.io包:java語言的標(biāo)準(zhǔn)輸入/輸出類庫,如基本輸入/輸出流、文件輸入/輸出、過濾輸入/輸出流等等。3.java.util包:包含如處理時(shí)間的date類,處理變成數(shù)組的Vector類,以及stack和HashTable類。4.java.util.zip包:實(shí)現(xiàn)文件壓縮功能。5.java.lang.reflect包:提供用于反射對象的工具。6.java.awt.image包:處理和操縱來自于網(wǎng)上的圖片的java工具類庫。7.java.wat.peer包:很少在程序中直接用到,使得同一個(gè)java程序在不同的軟硬件平臺(tái)上運(yùn)行。8.包:實(shí)現(xiàn)網(wǎng)絡(luò)功能的類庫有Socket類、ServerSocket類9.ava.awt.event包:GUI事件處理包。10.java.sql包:實(shí)現(xiàn)JDBC的類庫。11.java.awt.datatransfer包:處理數(shù)據(jù)傳輸?shù)墓ぞ哳悾糍N板,字符串發(fā)送器等。12.java.awt包:構(gòu)建圖形用戶界面(GUI)的類庫,低級(jí)繪圖操作Graphics類,圖形界面組件和布局管理如Checkbox類、Container類、LayoutManger接口等,以及界面用戶交互控制和事件響應(yīng),如Event類。6.5任務(wù)五實(shí)訓(xùn)六

繼承與多態(tài)編程實(shí)訓(xùn)

1.創(chuàng)建一個(gè)項(xiàng)目,在項(xiàng)目中創(chuàng)建Subroutine類和兩個(gè)內(nèi)部類,分別為Parent和SubParent。這三個(gè)類的繼承關(guān)系是

Subroutine類繼承SubParent類,

SubParent類繼承Parent類。分別在這三個(gè)類的構(gòu)造方法中輸出構(gòu)造方法名稱,然后創(chuàng)建Subroutine類的實(shí)例對象,繼承機(jī)制將使該類的父類對象自動(dòng)初始化。classParent{//父類

Parent(){ System.out.println("調(diào)用

溫馨提示

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

評(píng)論

0/150

提交評(píng)論