版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
Java程序設(shè)計案例教程
主編魏衍君
興趣是最好的老師知識有限創(chuàng)意無限歡迎大家學(xué)習(xí)Java程序設(shè)計案例教程
項目5面向?qū)ο蟮某绦蛟O(shè)計基礎(chǔ)5.1【任務(wù)9】設(shè)計學(xué)生類Students5.2【任務(wù)10】設(shè)計本科生類和研究生類
5.3【任務(wù)11】設(shè)計抽象類Book5.1【任務(wù)9】設(shè)計學(xué)生類Students
任務(wù)描述:
編寫一個程序StudentsDemo,設(shè)計一個學(xué)生類,其屬性有姓名、年齡、學(xué)位,其方法有各種屬性的get和set方法,還要有相關(guān)數(shù)據(jù)的輸出方法,并創(chuàng)建一個學(xué)生類的對象。通過該任務(wù)的學(xué)習(xí),可以初步了解類和對象的基本概念,掌握和創(chuàng)建使用類生成對象的方法以及面向?qū)ο蟮木幊趟枷牒皖惖姆庋b特性。
設(shè)計過程:
(1)在“記事本”中輸入如下程序:
classStudents{//下面是Students類的成員變量和方法
publicStringname;
publicintage;
publicStringdegree;
publicStudents(Stringname1,intage1,Stringdegree1)//構(gòu)造方法用于初始化類
{name=name1;age=age1;degree=degree1;this.getName();this.getAge();this.getDegree();}publicvoidsetName(Stringn){name=n;}//設(shè)置學(xué)生姓名publicvoidsetAge(inta){age=a;}//設(shè)置學(xué)生年齡
publicvoidsetDegree(Stringd){degree=d;}//設(shè)置學(xué)生的學(xué)位
publicStringgetName(){returnname;}//獲取學(xué)生姓名
publicintgetAge(){returnage;}//獲取學(xué)生成績
publicStringgetDegree(){returndegree;}//獲取學(xué)生學(xué)位publicvoidshow(){System.out.println("學(xué)生的姓名是:"+name);System.out.println("學(xué)生的年齡是:"+age);System.out.println("學(xué)生的學(xué)位是:"+degree+"\\n");}}publicclassStudentsDemo{publicstaticvoidmain(Stringargs[]){Studentss1=newStudents("張三",20,"大專");System.out.println("修改前張三個人信息:");s1.show();s1.setAge(28);s1.setDegree("博士");System.out.println("修改后張三個人信息:");s1.show();}}
(2)將文件保存在“D:\\myprogram”文件夾中,文件名為StudentsDemo.java。
(3)在“命令提示符”窗口內(nèi)的“D:\\myprogram”提示符下,輸入“javacStudentsDemo.java”命令,然后在新的命令行中,輸入“javaStudentsDemo”命令,運行字節(jié)碼程序,輸出程序的運行結(jié)果,如圖5-1-1所示。圖5-1-1
程序StudentsDemo的運行結(jié)果
相關(guān)知識
5.1.1類
類是對一個或幾個相似對象的描述,它把不同對象具有的共性抽象出來,定義為某類對象共有的變量和方法,從而使程序員實現(xiàn)代碼的復(fù)用,所以說,類是同一類對象的原型。創(chuàng)建一個類,相當(dāng)于構(gòu)造一個新的數(shù)據(jù)類型,而實例化一個類就得到一個對象。Java為我們提供了大量的類庫,如果從已知類庫入手來構(gòu)造自己的程序,不僅能有效地簡化程序設(shè)計,而且能很好地學(xué)習(xí)面向?qū)ο蟪绦蛟O(shè)計方法。
類的聲明
類聲明包括關(guān)鍵字class﹑類名及類的屬性。類名必須是合法的標(biāo)識符,類的屬性為一些可選的關(guān)鍵字。其聲明格式如下:
[public|private|friendly|protected][abstract]
[final]classclassName[extendssuperclassName][implementsinterfaceNameList]
{…}
其中,第一項屬于訪問控制字符,它不僅針對于類,類的變量、方法的訪問也有該項的限制,我們后面作專門的介紹。其他的修飾符說明如下:
abstract:聲明該類不能被實例化。
final:聲明該類不能被繼承,即沒有子類。
classclassName:關(guān)鍵字class告訴編譯器表示類的聲明以及類名是className。
extendssuperclassName:extends語句擴展superclassName為該類的父類。
implementsinterfaceNameList:聲明類可實現(xiàn)一個或多個接口,可以使用關(guān)鍵字implements并且在其后面給出由類實現(xiàn)的多個接口名字列表,各接口之間以逗號分隔。
類的實體
實體是類的主要部分,包括變量的說明及該類所支持的方法,我們習(xí)慣稱之為成員變量和成員方法。需要注意的是,除了實體中定義的變量與方法外,該類還繼承了其父類的變量與方法。當(dāng)然,對父類變量和方法的訪問要受到訪問控制條件的限制。實體說明的格式為:
classclassName{
variableDeclaration
methodDeclaration
}
1.變量
Java中變量的說明可以分為兩種:類成員變量的說明和方法變量的說明。其變量聲明格式為:
[public|protected|private][static][final]typevariableName
上述聲明格式中,第一項指的是訪問控制格式(后面介紹),另外的幾項說明如下:
static:成員控制修飾符,說明該類型的變量為靜態(tài)變量,或者稱之為類變量。說明靜態(tài)變量類型后,則該類的所有實例對象都可以對其共享,而且訪問靜態(tài)變量無須事先初始化它所在的類。
final:常量聲明修飾符,與C/類似,用該符號聲明后,在程序的運行過程中不能再改變它的值。實際使用中,final往往與static結(jié)合在一起使用。比如:
finalintINDEX=1000;
staticfinalintLOOP=10;
總之,從變量定義的不同位置及所使用的限定詞來看,變量可以分為三類:實例變量、局部變量和靜態(tài)變量。
(1)實例變量。如果在類的方法代碼段之外聲明且沒有限定詞static,則為實例變量。從它的定義我們可以看出,實例變量與類緊密相關(guān),如果一個類有多個實例對象,那么每個實例對象都有自己的實例變量,之間并不影響。
(2)局部變量。如果在類的方法體之中聲明,則為局部變量,這有點與C語言函數(shù)中定義的局部變量相似。由于局部變量是在方法體內(nèi)所定義,因而只能在本方法中使用,無所謂訪問控制,也不能用static修飾符加以說明。另外,需要注意的是,局部變量使用前必須初始化,這也是它與實例變量及后面要介紹的靜態(tài)變量之間的不同之處。局部變量可以與實例變量同名而相互不影響。
(3)靜態(tài)變量。如果將一個實例變量聲明為static,則為靜態(tài)變量,或稱之為類變量。靜態(tài)變量在類聲明后就可以直接引用,但實例變量則不能,必須在實例化對象后才可以使用。
下面我們對實例變量與類變量加以詳細(xì)說明,以加深讀者的理解。比如可以如下來聲明一個成員變量:
classMyClass{
publicfloatvariable1;
publicstaticintvariable2;
}
該例中聲明了一個實例變量variable1和一個類變量variable2。今后當(dāng)創(chuàng)建類的實例的時候,系統(tǒng)就會為該實例創(chuàng)建一個類實例的副本,但系統(tǒng)為每個類分配類變量僅僅只有一次,而不管類創(chuàng)建的實例有多少。當(dāng)?shù)谝淮握{(diào)用類的時候,系統(tǒng)為類變量分配內(nèi)存。所有的實例共享了類的類變量的相同副本。在程序中可通過一個實例或者類本身來訪問類變量。例如:
…
MyClassA=newMyClass();
MyClassB=newMyClass();
A.variable1=100;
A.variable2=200;
B.variable1=300;
B.varable2=400;System.out.println("A.variable1="+A.variable1);System.out.println("A.variable2="+A.variable2);System.out.println("B.variable1="+B.variable1);System.out.println("B.variable2="+B.variable2);
…
當(dāng)從類實例化新對象的時候,就得到了類實例變量的一個副本。這些副本跟新對象是聯(lián)系在一起的。因此每實例化一個新MyClass對象的時候,就得到了一個和MyClass對象有聯(lián)系的variable1的新副本。當(dāng)一個成員變量用關(guān)鍵字static指定為類變量之后,其第一次調(diào)用的時候,系統(tǒng)就會為它創(chuàng)建一個副本,之后,類的所有實例均共享了該類變量的相同副本。所以上述程序段的輸出結(jié)果為:
A.variable1=100
A.variable2=400
B.variable1=300
B.variable2=400
2.方法
Java程序通過方法完成對類和對象屬性的操作。方法定義了在類成員變量上的一系列操作,它只能在類的內(nèi)部聲明并加以實現(xiàn),其他的對象通過調(diào)用對象的方法得到該對象的服務(wù)。方法的定義包含了兩部分內(nèi)容:方法聲明和方法體。
(1)方法聲明。方法聲明的一般格式如下:
[public|protected|private][static][final]
[abstract]
returnTypemethodName([paramList])[throwsexceptionList]
{…}
在方法聲明中應(yīng)包括方法名、方法的返回值類型、方法的修飾詞、參數(shù)的數(shù)目和類型及方法可能產(chǎn)生的例外。從其聲明格式中可以發(fā)現(xiàn),不一定要全部顯示并指明所有的信息,方法最基本的聲明格式為:
returnTypemethodName()
{…}
一般聲明格式中的第一項是訪問控制屬性,后面會有介紹。對其他幾個修飾詞說明如下:
static:說明該方法為靜態(tài)方法。與變量的定義類似,靜態(tài)方法也稱作類方法,與之對應(yīng),其他的方法就稱之為實例方法。靜態(tài)方法屬于類,所以只要對類作了聲明,就可以調(diào)用該類的類方法,即使用時無須類的初始化。當(dāng)然,實例方法只能在類的實例或子類的實例中調(diào)用。類方法只能操作類變量而不能訪問定義在類中的實例變量,這是實際使用過程中經(jīng)常出錯的地方。例如:classA{intx;staticpublicintx(){returnx;}staticpublicvoidsetX(intnewX){x=newX();}}
…AmyX=newA();AanotherX=newA();myX.setX(1);anotherX.x=2;System.out.println("myX.x="+myX.x());System.out.println("anotherX.x="+anotherX.x());…
當(dāng)編譯的時候,編譯器會給出以下的錯誤信息:
A.Java:4:Can’tmakeastaticreferncetononstaticvariablexinclassA.returnx;^
出現(xiàn)這個錯誤的原因是類方法不能訪問實例變量。
實例成員和類成員之間不同點是類成員可以在類本身中訪問,而不必實例化一個類來訪問類成員。
下面再對上面的代碼進行修改:
…
A.setX(1);System.out.println(″A.x=″+A.x());…
這里我們不用實例化類對象myX和anotherX就可以直接從類A中設(shè)置x并輸出。這樣同樣可以得到類變量x的值。
abstract:說明一個方法是抽象方法,即該方法只有方法說明而沒有方法體。抽象方法的實現(xiàn)須由該方法所在類的子類來實現(xiàn)。如果一個類包含一個或多個抽象方法,則該類必須為抽象類。抽象類不能被實例化。例如:classShape{abstractvoiddraw();}
該例中的說明方法draw()為抽象方法。
final:final方法類似于常量的定義,它說明了一個方法為終極方法,即它不能被子類重載。說明為final的方法往往與關(guān)鍵字private一起使用,避免出錯。例如:
…
privatefinalmeth_final()
{…}Java
針對任何一個方法,返回類型是必需的,如果方法沒有返回值,則返回類型為void。否則返回類型可以是各種數(shù)據(jù)類型,如int、float、String等。對于有返回值的方法,其方法體中至少有一條return語句,形式為:
return(表達式)
當(dāng)調(diào)用該方法時,方法的返回值即為此表達式的值。
(2)方法重載。Java中方法的重載指的是多個方法共用一個名字(這樣可實現(xiàn)對象的多態(tài)),同時,不同的方法要么參數(shù)個數(shù)不相同,要么參數(shù)類型不同。Java提供的標(biāo)準(zhǔn)類中包含了許多構(gòu)造函數(shù),并且每個構(gòu)造函數(shù)允許調(diào)用者為新對象的不同實例變量提供不同的初始數(shù)值。比如,Java.awt.Rectangle就有三個構(gòu)造函數(shù):
Rectangle(){};
Rectangle(intwidth,intheight){};
Rectangle(intx,inty,intwidth,intheight){};
當(dāng)傳遞不同的參數(shù)時,構(gòu)造出來的對象的實例具有不同的屬性。
(3)參數(shù)傳遞。在調(diào)用一個帶有形式參數(shù)的方法時,必須為方法提供實際參數(shù),完成實際參數(shù)與形式參數(shù)的結(jié)合,稱為參數(shù)傳遞,然后用實際參數(shù)執(zhí)行所調(diào)用的方法體。在Java中參數(shù)的傳遞是以傳值的方式進行,即將實際參數(shù)的值傳遞給形式參數(shù),而不是將實際參數(shù)的地址傳遞給形式參數(shù)。由于被調(diào)用方法沒有訪問實際參數(shù),因而在改變形式參數(shù)值時,并沒有改變實際參數(shù)的值?!纠?-1】參數(shù)傳遞舉例。publicclassExa1{staticvoidsum(Stringx,Stringy){Stringtemp;System.out.println(″形參改變之前″);System.out.println(″x=″+x+″″+″y=″+y);temp=x;x=y;y=temp;System.out.println(″形參改變之后″);System.out.println(″x=″+x+″″+″y=″+y);}publicstaticvoidmain(Stringargs[]){Stringa=″10″,b=″20″;System.out.println(″方法調(diào)用之前″);System.out.println(″a=″+a+″″+″b=″+b);Sum(″10″,″20″);System.out.println(″方法調(diào)用之后″);System.out.println(″a=″+a+″″+″b=″+b);}}運行結(jié)果:方法調(diào)用之前a=10b=20形參改變之前x=10y=20形參改變之后x=20y=10方法調(diào)用之后a=10b=20
【程序解析】
通過程序的運行結(jié)果可以看出:實際參數(shù)即a、b的值不受形式參數(shù)x、y的值的影響,即使形式參數(shù)的值改變了,實際參數(shù)的值也不會改變。
(4)構(gòu)造方法。構(gòu)造方法用來初始化新創(chuàng)建的對象。類可以包含一個或者多個構(gòu)造方法,不同的構(gòu)造方法根據(jù)參數(shù)的不同來決定要初始化的新對象的狀態(tài)。所有的Java類都有構(gòu)造方法,它用來對新的對象進行初始化。構(gòu)造方法與類的名字是相同的。比如Stack類的構(gòu)造方法的名字為Stack,而Rectangle類的構(gòu)造方法的名字為Rectangle,Thread類的構(gòu)造方法的名字為Thread。下面給出Stack類的構(gòu)造方法:
publicStack(){items=newVector(10);}
Java支持對構(gòu)造方法的重載,這樣一個類就可以有多個構(gòu)造方法,所有的構(gòu)造方法的名字是相同的,只是所帶參數(shù)的個數(shù)和類型相異而已。下面是類Stack的另一個構(gòu)造方法,這個構(gòu)造方法根據(jù)它的參數(shù)來初始化對象的大小。publicStack(intinitialSize){items=newVector(initialSize);}
從上面可以看出,兩個構(gòu)造方法都有相同的名字,但是它們有不同的參數(shù)列表。編譯器會根據(jù)參數(shù)列表的數(shù)目以及類型來區(qū)分這些構(gòu)造方法。所以,當(dāng)創(chuàng)建對象的時候,要根據(jù)它的參數(shù)是否與初始化的新對象相匹配來選擇構(gòu)造方法。根據(jù)傳遞給構(gòu)造方法參數(shù)的數(shù)目和類型,編譯器可以決定要使用哪個構(gòu)造方法。如對于下面的代碼,編譯器就可以知道應(yīng)該使用單一的整型參數(shù)來初始化對象:
newStack(10);
與此相同,當(dāng)給出下面代碼的時候,編譯器選擇沒有參數(shù)的構(gòu)造方法或者缺省的構(gòu)造方法進行初始化:
newStack();
另外,如果生成的類不為它提供構(gòu)造方法,系統(tǒng)會自動提供缺省的構(gòu)造方法。這個缺省的構(gòu)造方法不會完成任何事情。下例給出類AnimationThread的構(gòu)造方法,在其初始化過程中設(shè)置了一些缺省的數(shù)值,比如幀速度、圖片的數(shù)目等。classAnimationThreadextendsThread{intframesPerSecond;intnumImages;Image[]images;AnimationThread(intfps,intnum){super("AnimationThread");this.framesPerSecond=fps;this.numImages=num;this.images=newImage[numImages];for(inti=0;i<=numImages;i++){…}
}…}
從該例來看,構(gòu)造方法的實體跟一般方法的實體是相似的,均包含局部變量聲明、循環(huán)以及其他的語句。該例的構(gòu)造方法中出現(xiàn)了以下一條語句:
super(″AnimationThread″);
與關(guān)鍵字this相似(this表示當(dāng)前對象),關(guān)鍵字super表示當(dāng)前對象的父對象,所以使用super可以引用父類被隱藏的變量和方法。本例中調(diào)用了父類Thread的構(gòu)造方法。使用中須注意的是,父類的構(gòu)造方法必須是子類構(gòu)造方法的第一條語句,因為對象必須首先執(zhí)行高層次的初始化。構(gòu)造方法說明中只能帶訪問控制修飾符,即只能使用public、protected及private中的任一個。
(5)變量和方法的訪問控制。前面多次提到過對類、變量及方法的訪問控制屬性,比如有private、friendly、protected及public。Java中最低級的訪問控制范圍是類的級別,分為四種:同一個類、同一個包、不同包的子類及不同包的非子類。
類的訪問控制權(quán)限只能為public和friendly,變量和方法的訪問控制可以為上面四種中的任何一種。關(guān)于訪問控制權(quán)限修飾符的作用,在5.1.3節(jié)進行詳細(xì)介紹。
5.1.2對象
本項目開始的時候就討論過類與對象的關(guān)系,大家知道,類是一個抽象的概念,而對象是實實在在存在的東西,是一個具體的概念,所以對象的使用就是某個類的實例化操作。與此對應(yīng),本節(jié)分兩部分來介紹對象:對象的創(chuàng)建及對象的使用。
對象的創(chuàng)建
Java中創(chuàng)建新的對象必須使用new語句,其一般格式為:
classNameobjectName=new
className(parameterList);
此表達式隱含了三個部分,即:對象說明、實例化和初始化。
對象說明:上面的聲明格式中,classNameobjectName是對象的說明;className是某個類名,用來說明對象所屬的類;objectName為對象名。例如:
IntegeriVariable;
該語句說明iVariable為Integer類型。
實例化:new是Java實例化對象的運算符。使用命令new可以創(chuàng)建新的對象并且為對象分配內(nèi)存空間。一旦初始化,所有的實例變量也將被初始化,即算術(shù)類型初始化為0,布爾邏輯型初始化為false,復(fù)合類型初始化為null。例如:
IntegeriVariable=newInteger(100);
此句實現(xiàn)將Integer類型的對象iVariable初始值設(shè)為100的功能。
初始化:new運算符后緊跟著一個構(gòu)造方法的調(diào)用。前面介紹過,Java中的構(gòu)造方法可以重構(gòu),因而通過給出不同的參數(shù)類型或個數(shù)就可以進行不同初始化工作。如例5-2,類Rectangle定義了一個矩形類,它有多個不同的構(gòu)造方法,可以通過調(diào)用不同的構(gòu)造方法來進行初始化。【例5-2】對象的初始化舉例。importjava.util.*;importjavax.swing.*;importjava.awt.*;publicclassRectangle{publicintwidth=0;publicintheight=0;publicPointorigin;
publicstaticvoidmain(Stringargs[]){
Pointp=newPoint(20,20);
Rectangler1=newRectangle();
Rectangler2=newRectangle(p,80,40);
System.out.println("TheareaofRectangleis:"+r1.area());
System.out.println("TheareaofRectangleis:"+r2.area());
}publicRectangle(){origin=newPoint(0,0);}publicRectangle(Pointp){origin=p;}publicRectangle(intw,inth){this(newPoint(0,0),w,h);}publicRectangle(Pointp,intw,inth){origin=p;width=w;height=h;}publicvoidmove(intx,inty){origin.x=x;origin.y=y;}publicintarea(){returnwidth*height;}}classPoint{publicintx=0;publicinty=0;publicPoint(intx,inty){this.x=x;this.y=y;}}
該例中,我們定義了兩個類Rectangle、Point,并調(diào)用了類Rectangle中的area()方法來求矩形的面積。方法Rectangle()不帶參數(shù),因而只是初始化原點坐標(biāo)為(0,0),矩形的長、寬均為0;方法Rectangle(p,80,40)不僅初始化原點由類型Point()指定,同時還限定矩形的長、寬分別為80,40。
對象的使用
前面花了很大的篇幅介紹類,其目的就是為了掌握如何使用它。類是通過實例化為對象來使用的,而對象的使用是通過引用對象變量或調(diào)用對象的方法來實現(xiàn)的。與相類似,對象變量和方法是通過運算符“.”來實現(xiàn)的。1.變量的引用對象變量引用的一般格式為objectName.variableName;例如:classexample{intx;}examplea=newexample();a.x=100;
變量的引用在Java中還有一種很特殊的情況,即可以使用表達式指定變量所在的對象,例如:
intz=newexample().x;
這個語句創(chuàng)建了一個新的example對象,并且得到了它的成員變量x。需要注意的是,在這條語句被執(zhí)行后,程序不再保留對象expmple的引用。這樣,對象example就被取消引用,因而通過上述語句并不能達到初始化對象的目的。
2.對象方法的引用
與對象變量一樣,對象方法的引用的一般格式為:
objectName.methodName([argumentList]);
例如在例5-2中調(diào)用對象Rectangle中的area()方法計算矩形的面積:System.out.println(“TheareaofRectangle1is:”+r1.area());System.out.println(“TheareaofRectangle1is:”+r2.area());
雖然通過直接引用對象變量可以改變對象的屬性,但是它沒有任何意義(比如,在例5-2中,使用Rectangle類的構(gòu)造方法,可以創(chuàng)建不同的矩形,如果設(shè)置其高為height、寬width是負(fù)值,程序并不認(rèn)為其非法)。所以,較好的做法是:不直接對變量進行操作,而由類提供一些方法,對變量的引用可以通過這些方法來進行,以確保給定變量的數(shù)值是有意義的。這樣一來,Rectangle類將提供setWidth、setHeight、getWidth以及getHeight方法來設(shè)置或者獲得寬度和高度。設(shè)置變量的方法將在調(diào)用者試圖將width和height設(shè)置為負(fù)數(shù)的時候給出一個錯誤提示。這樣能夠更好地體現(xiàn)數(shù)據(jù)的封裝和隱蔽。例如,加上上述的幾個方法后,例5-2變?yōu)閜ublicclassRectangle{……publicvoidsetWidth(intwidth){if(width<0)System.out.println(″illegalnumber!″);elsethis.width=width;}publicvoidsetHeight(intheight){……}publicintgetWidth(){returnwidth;}publicintgetHeight(){returnheight;}publicvoidmove(intx,inty){origin.x=x;origin.y=y;}publicintarea(){
returnwidth*height;
}}
5.1.3類的封裝
Java是一個面向?qū)ο蟮某绦蛟O(shè)計語言,面向?qū)ο缶幊痰幕締卧穷?。我們說類是對對象的一個抽象,同時類也為對象進行了封裝。所謂封裝也就是說類的設(shè)計者只是為使用者提供類對象可以訪問的部分(包含類的成員變量和方法),而對于類中其他成員變量和方法隱藏起來,用戶不能訪問。這種數(shù)據(jù)隱藏機制和封裝機制為程序的編制和系統(tǒng)的維護提供了方便,我們不必知道程序?qū)崿F(xiàn)的細(xì)節(jié),而只要知道類可以訪問的部分,排除錯誤更為方便。
所謂封裝,指以下幾個方面:
(1)在類的定義中設(shè)置對對象中的成員變量和方法進行訪問的權(quán)限。
(2)提供一個統(tǒng)一供其他類引用的方法。
(3)其他對象不能直接修改本對象所擁有的屬性和方法。
隱藏和封裝機制是面向?qū)ο蟪绦蛟O(shè)計的特性,那么如何進行數(shù)據(jù)的隱藏和封裝呢?Java為對象變量提供4種訪問權(quán)限:public、protected、private和friendly。
對象的可見性和作用域
對于類而言,它有成員變量和方法。對于類中的成員變量,它是屬于整個類的,在創(chuàng)建對象時,自動在內(nèi)存區(qū)域分配一塊空間作為對象的屬性出現(xiàn)。同樣,類的方法中也有變量,這些變量的運行范圍只是在方法體內(nèi),如果出了方法體,那么這些變量就不起作用。
屬于類中的成員變量或方法是否就可以被其他類訪問呢?前面給出的例子中為類、方法和成員變量的定義中常常要用到“public”這個關(guān)鍵字,它的意思是允許其他類對其所定義的類、方法和成員變量進行訪問,如果不想讓其他類對其進行訪問,或者是只允許類中的方法來訪問當(dāng)前類的成員變量和方法,那么就可使用private來定義。
這里就涉及方法和成員變量的生存期問題,也就是說這些變量在程序中的哪些區(qū)域有定義。
【例5-3】引用私有方法和修改私有成員變量。
classdef{
privateintx,y,z=0;//定義私有變量
privatevoidmethod1(){//定義私有方法
intx=3,y=4,z;
z=x*y;
System.out.println(″z=″+z);
}publicvoidshow(){System.out.println(″z=″+z);
}}publicclassChange1{publicstaticvoidmain(Stringargs[]){defss=newdef();ss.method1();//直接引用私有方法出現(xiàn)錯誤ss.z=12;//直接修改私有變量是不允許的ss.show();}}程序編譯結(jié)果:>JavacChange1.javaChange1.java:15:method1()hasprivateaccessindefss.method1();//直接調(diào)用私有方法出現(xiàn)錯誤^Chnage1.java:16:zhasprivateaccessindefss.z=12;//直接修改私有變量是不允許的^
2個錯誤
【程序解析】程序要直接修改私有變量是不允許的,只有類本身和方法可以對私有變量進行訪問,這也就是我們常說的,數(shù)據(jù)封裝后,類外的方法是不能訪問私有變量的,達到數(shù)據(jù)安全的目的。
【例5-4】修改例5-3,使其能夠引用方法并修改成員變量。
classdef{
privateintx,y,z=0;
publicvoidmethod1(){
intx=3,y=4,z;
z=x*y;
System.out.println(″z=″+z);
}publicvoidshow(){System.out.println(″z=″+z);}}publicclassChange2{publicstaticvoidmain(Stringargs[]){intz=20;defss=newdef();ss.method1();//引用ss對象的method1()方法ss.show();}}程序運行結(jié)果:z=12z=0
【程序解析】程序中將method1()方法的訪問權(quán)限由private改為public,然后引用method1()方法,通過method1()方法對def類中的私有成員變量z進行訪問。
通過這個例子可以看出,對于類中的成員變量和方法,如果允許其他類對其進行訪問,可以將其訪問權(quán)限設(shè)置為public;如果要防止其他類對其進行訪問,可以盡量設(shè)置為private。
下面分別講述訪問權(quán)限修飾符的作用。
public
public顧名思義是公開的、公眾的,也就是說如果一個類被修飾為public,那么這個類就是公共類。公共類不但可供它所在包中的其他類使用,也可供其他包中的類使用,在程序中可以用import語句引入其他包中的public類。那些被public定義的類中成員變量或方法可以供其他類進行訪問,這些類、方法和成員變量可以用來供其他類訪問。
在Java中,一個程序文件只能定義一個public類,其他類可以是沒有修飾的類。
【例5-5】使用import引入已經(jīng)定義的、屬性為public的Account類,引用其方法。
publicclassAccount{//定義公共類Account
Stringname;
Stringaddress;
publicdoublebalance;//定義該成員變量是公共的
publicvoiddisplay(){//定義公共方法display
System.out.println(″name:″);System.out.print(name);System.out.println(″Address:″);System.out.print(address);System.out.println(″balance:″);System.out.print(balance);}}
定義了公共類Account以及公共成員變量balance和方法display(),將此文件保存為Account.java。
引入Account類并引用Account類定義的方法
importAccount;//引入公共類Account
publicclassUseraccount{
publicstaticvoidmain(Stringargs[]){
Accountmyaccount=newAccount();//成績類對象myaccount
=″張三″;
myaccount.address=″鄭州市黃河路19號″;
myaccount.balance=123.40;//引用myaccount對象的balance成員變量
myaccount.display();//引用display()方法,顯示輸入內(nèi)容
}
}
程序運行結(jié)果:
name:張三
address:鄭州市黃河路19號
balance:123.4
private
如果不想讓其他類進行訪問,采取什么方法呢?就是對其設(shè)置private訪問權(quán)限。
【例5-6】定義Scope類的私有方法,使用類外的方法來引用此私有方法,查看程序運行情況。
classScope{
privateintx=10;
Scope(){
intx=1000;
}privatevoida(){//設(shè)置為私有方法
intx=200;
x*=4;
System.out.println(″Aofamethodis″+x);}privatevoidb(){//設(shè)置為私有方法
x*=2;
System.out.println(″Bofamethodis″+x);}}publicclassSamp2{
publicstaticvoidmain(Stringargs[]){
intx=100;
System.out.println(″xofmainmethodis″+x);Scopeb1=newScope();b1.a();b1.b();System.out.println(″xofmainmethodis″+x);}}程序編譯結(jié)果:>javacSamp2.java
Samp2.java:22:a()hasprivateaccessinScope
b1.a();
^
Samp2.java:23:b()hasprivateaccessinScope
b1.b();
^
2個錯誤
【程序解析】在這里對Scope類的a()方法和b()方法設(shè)置為私有屬性,所以不能對其方法進行訪問,而如果要訪問,只能通過類本身所定義的方法。
例如修改Scope類中定義的構(gòu)造方法,在構(gòu)造方法中引用方法a()和方法b(),修改程序如下:
classScope{
privateintx=10;
Scope(){
intx=1000;
a();//調(diào)用a()方法
b();//調(diào)用b()方法}privatevoida(){//設(shè)置為私有方法
intx=200;
x*=4;
System.out.println(″Aofamethodis″+x);}
privatevoidb(){//設(shè)置為私有方法
x*=2;
System.out.println(″Bofamethodis″+x);
}
}
【程序解析】當(dāng)創(chuàng)建對象時,系統(tǒng)自動引用構(gòu)造方法,而在構(gòu)造方法中添加調(diào)用a()和b()方法,這樣就可以使用類中的方法來訪問類中的私有成員變量和方法。
protected
使用protected定義的成員變量或方法具有二重性,類本身、子類或包中的方法可以訪問它們,而對于其他類沒有訪問權(quán)限。
【例5-7】定義類的protected方法,通過創(chuàng)建對象來引用此方法。
classMax
{
privateintx,y;//定義私有變量
protectedintplay(ints,intt)//定義protected方法{intm;x=s;y=t;m=(x>y)?x/y:y/x;returnm;}}publicclassGetNum{publicstaticvoidmain(Stringargs[]){
intresult;
Maxss=newMax();
result=ss.play(5,45);
System.out.println(″result=″+result);
}}
程序運行結(jié)果:
result=9
【程序解析】對play()方法設(shè)置的protected屬性在程序引用中可以像使用public修飾的權(quán)限方法一樣來引用。
friendly
如果在通常條件下,成員變量或方法名前都沒有設(shè)定如public、private等訪問權(quán)限關(guān)鍵字,則通常稱此成員變量或方法為friendly,這意味著這些成員變量或方法對于包內(nèi)的所有類而言它們是可以訪問的,但對于包外的類,則不能對它們進行訪問。
【例5-8】使用方法的默認(rèn)訪問權(quán)限來引用此方法。publicclassX1{X1(){//X1類構(gòu)造器System.out.println(″Thisisaconstruct″);}voiddoing(){System.out.println(″Couldyoutellme″);}}//將此文件保存為X1.javaimportX1;//引用X1類publicclassX2{staticvoidstore(){System.out.println(″Thisisastoreprocessing″);}publicstaticvoidmain(Stringargs[]){X1y=newX1();y.doing();store();}}程序運行結(jié)果:ThisisaconstructCouldyoutellmeThisisastoreprocessing
【程序解析】類X1與類X2在編譯后系統(tǒng)自動將它們放在一個包內(nèi)。對于X1類中的doing()方法而言,如果不進行訪問權(quán)限設(shè)定,則通過“importX1”方法引入,使得X1類對象y可以調(diào)用doing()方法,即“y.doing();”。但是如果在X1類中對doing()方法強加private訪問權(quán)限(如:privatevoiddoing();),則當(dāng)使用y對象調(diào)用doing()方法時,編譯會出現(xiàn)錯誤提示信息。
任務(wù)進階
【進階任務(wù)19】創(chuàng)建并應(yīng)用People類
設(shè)計過程:
(1)在“記事本”中輸入如下程序:
classPeople
{
floatheight,weight;
Stringhead,ear,hand,foot,mouth;
voidspeak(Strings)
{
System.out.println(s);}}publicclassPeopleDemo{publicstaticvoidmain(Stringargs[]){Peoplezhubajie,sunwukong;//聲明對象zhubajie=newPeople();//為對象分配內(nèi)存sunwukong=newPeople();zhubajie.height=1.80f;//對象給自己的變量賦值zhubajie.head="大頭";zhubajie.ear="一雙大耳朵";sunwukong.height=1.62f;//對象給自己的變量賦值sunwukong.weight=1000f;sunwukong.head="金發(fā)飄飄";System.out.println("zhubajie的身高:"+zhubajie.height);System.out.println("zhubajie的頭:"+zhubajie.head);System.out.println("sunwukong的重量:"+sunwukong.weight);System.out.println("sunwukong的頭:"+sunwukong.head);zhubajie.speak("俺老豬我想娶媳婦");//對象調(diào)用方法System.out.println("zhubajie現(xiàn)在的頭:"+zhubajie.head);sunwukong.speak("老孫我重1000斤,我想騙八戒背我");//對象調(diào)用方法System.out.println("sunwukong現(xiàn)在的頭:"+sunwukong.head);}}
(2)將文件保存在“D:\\myprogram”文件夾中,文件名為PeopleDemo.java。
(3)在“命令提示符”窗口內(nèi)的“D:\\myprogram”提示符下,輸入“javacPeopleDemo.java”命令,然后在新的命令行中,輸入“javaPeopleDemo”命令,運行字節(jié)碼程序,輸出程序的運行結(jié)果,如圖5-1-2所示。圖5-1-2
程序PeopleDemo的運行結(jié)果【進階任務(wù)20】創(chuàng)建并應(yīng)用梯形類設(shè)計過程:(1)在“記事本”中輸入如下程序:classLader//梯形類{floatShangDi,Gao;staticfloatXiaDi;Lader(floatx,floaty,floath)//構(gòu)造函數(shù){ShangDi=x;XiaDi=y;Gao=h;}floatGetXiaDi(){returnXiaDi;}//獲取下底voidSetXiaDi(floatb){XiaDi=b;}//修改下底floatGetShangDi(){returnShangDi;}//獲取上底voidSetShangDi(floatb){ShangDi=b;}//設(shè)置上底floatGetGao(){returnGao;}//獲取高voidSetGao(floatb){Gao=b;}//修改高publicfloatarea(){//求梯形的面積floatresult;result=(ShangDi+XiaDi)Gao/2;returnresult;}}publicclassLaderDemo{publicstaticvoidmain(Stringargs[]){//分別創(chuàng)建2個梯形類的對象laderOne和laderTwoLaderladerOne=newLader(3.0f,10.0f,20),laderTwo=newLader(2.0f,3.0f,10);laderOne.SetXiaDi(100);//通過對象操作類變量
System.out.println("laderOne的XiaDi:"+laderOne.GetXiaDi());
System.out.println("laderTwo的XiaDi:"+laderTwo.GetXiaDi());
laderOne.Gao=30;laderTwo.SetXiaDi(60);
System.out.println("laderOne的ShangDi:"+laderOne.GetShangDi());
System.out.println("laderOne的XiaDi:"+laderOne.GetXiaDi());
System.out.println("laderOne的Gao:"+laderOne.GetGao());
System.out.println("laderOne的面積:"+laderOne.area());
System.out.println("laderTwo的ShangDi:"+laderTwo.GetShangDi());
System.out.println("laderTwo的XiaDi:"+laderTwo.GetXiaDi());
System.out.println("laderTwo的Gao:"+laderTwo.GetGao());
System.out.println("laderTwo的面積:"+laderTwo.area());}}
(2)將文件保存在“D:\\myprogram”文件夾中,文件名為LaderDemo.java。
(3)在“命令提示符”窗口內(nèi)的“D:\\myprogram”提示符下,輸入“javacLaderDemo.java”命令,然后在新的命令行中,輸入“javaLaderDemo”命令,運行字節(jié)碼程序,輸出程序的運行結(jié)果,如圖5-1-3所示。圖5-1-3
程序LaderDemo的運行結(jié)果第三章624三、分支程序與循環(huán)程序設(shè)計休息一下,鞏固所學(xué)的知識5.2【任務(wù)10】設(shè)計本科生類和研究生類
任務(wù)描述:
編寫一個程序UseStudents,設(shè)計本科生類(Undergraduate)和研究生類(Graduate),兩個類都由學(xué)生類派生。在本科生類中增加屬性:選修專業(yè)(Specialty),在研究生類中增加屬性:研究方向(Studydirection)。并分別創(chuàng)建這幾個類的對象。通過該任務(wù)的學(xué)習(xí),可以初步了解類的繼承和多態(tài)的基本概念,并掌握類的繼承和類的多態(tài)的使用方法。
設(shè)計過程:
(1)在“記事本”中輸入如下程序:
classStudents{//下面是Students類的成員變量和方法
publicStringname;publicintage;publicStringdegree;publicStudents(Stringname1,intage1,Stringdegree1)//構(gòu)造方法用于初始化類{name=name1;age=age1;degree=degree1;}publicvoidsetName(Stringn){name=n;}//設(shè)置學(xué)生姓名publicvoidsetAge(inta){age=a;}//設(shè)置學(xué)生年齡
publicvoidsetDegree(Stringd){degree=d;}//設(shè)置學(xué)生的學(xué)位
publicStringgetName(){returnname;}//獲取學(xué)生姓名
publicintgetAge(){returnage;}//獲取學(xué)生成績
publicStringgetDegree(){returndegree;}//獲取學(xué)生學(xué)位
publicvoidshow()
{System.out.println("學(xué)生的姓名是:"+name);System.out.println("學(xué)生的年齡是:"+age);System.out.println("學(xué)生的學(xué)位是:"+degree+"\\n");}}classUndergraduateextendsStudents{
//下面是Undergraduate類的成員變量和方法,是Students父類的一個子類
publicStringSpecialty;//選修專業(yè)
publicUndergraduate(Stringname1,intage1,Stringdegree1,StringSpecialty1)
{//構(gòu)造方法用于初始化類
super(name1,age1,degree1);
Specialty=Specialty1;
}
publicvoidsetSpecialty(Strings){Specialty=s;}//設(shè)置學(xué)生的選修專業(yè)
publicStringgetSpecialty(){returnSpecialty;}//獲取選修專業(yè)
publicvoidshow()
{System.out.println("學(xué)生的姓名是:"+name);System.out.println("學(xué)生的年齡是:"+age);System.out.println("學(xué)生的學(xué)位是:"+degree);System.out.println("學(xué)生的選修專業(yè)是:"+Specialty+"\\n");}}
classGraduateextendsStudents{
//下面是Graduate類的成員變量和方法,是Students父類的一個子類
publicStringStudydirection;//研究方向
publicGraduate(Stringname1,intage1,Stringdegree1,StringStudydirection1)
{//構(gòu)造方法用于初始化類
super(name1,age1,degree1);
Studydirection=Studydirection1;
}
publicvoidsetStudydirection(Strings){Studydirection=s;}//設(shè)置學(xué)生的研究方向
publicStringgetStudydirection(){returnStudydirection;}//獲取研究方向
publicvoidshow()
{
System.out.println("學(xué)生的姓名是:"+name);
System.out.println("學(xué)生的年齡是:"+age);
System.out.println("學(xué)生的學(xué)位是:"+degree);
System.out.println("學(xué)生的研究方向是:"+Studydirection+"\\n");}}
publicclassUseStudents{
publicstaticvoidmain(Stringargs[]){
Studentss1=newStudents("張三",18,"大專");
Undergraduates2=newUndergraduate("李四",20,"本科","學(xué)士");
Graduates3=newGraduate("王五",28,"碩士","Java程序設(shè)計");
s1.show();
s2.show();
s3.show();}}
(2)將文件保存在“D:\\myprogram”文件夾中,文件名為UseStudents.java。
(3)在“命令提示符”窗口內(nèi)的“D:\\myprogram”提示符下,輸入“javacUseStudents.java”命令,然后在新的命令行中,輸入“javaUseStudents”命令,運行字節(jié)碼程序,輸出程序的運行結(jié)果,如圖5-2-1所示。圖5-2-1
程序UseStudents的運行結(jié)果
相關(guān)知識
5.2.1類的繼承
繼承是面向?qū)ο蟪绦蛟O(shè)計的一個重要特征,它是通過繼承原有類的基礎(chǔ),派生出新類,進而開發(fā)出更為復(fù)雜的數(shù)據(jù)類型。新開發(fā)的對象既有新定義的行為特征,又包含有原有類定義的行為特征。
繼承的概念
溫馨提示
- 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)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 醫(yī)院水電修維合同(2篇)
- 提升學(xué)習(xí)興趣的班級文化建設(shè)計劃
- 供熱應(yīng)急預(yù)案范本
- 基于shell編程的課程設(shè)計
- 生產(chǎn)仿真課課程設(shè)計
- 民族學(xué)課程設(shè)計表
- 滑油管系課程設(shè)計
- 構(gòu)音跟的課程設(shè)計
- 甲烷臥式儲罐課程設(shè)計
- 四年級語文下冊 第11課《白樺》同步訓(xùn)練題(含答案)(部編版)
- 吉林長春市普通高中2025屆高三數(shù)學(xué)第一學(xué)期期末達標(biāo)測試試題含解析
- 期中測試卷(1-4單元) (試題)-2024-2025學(xué)年四年級上冊數(shù)學(xué)人教版
- 城市軌道交通列車自動控制系統(tǒng)維護 課件 2.8 車載應(yīng)答器天線維護檢修
- 時代樂章第一課城市名片 課件 2024-2025學(xué)年人教版(2024)初中美術(shù)七年級上冊
- 2024人教版道德與法治四年級上冊第三單元:信息萬花筒大單元整體教學(xué)設(shè)計
- 第十五屆全國電力行業(yè)職業(yè)技能競賽(碳排放管理員)考試題庫(含答案)
- 飛瓜數(shù)據(jù)-2024上半年抖音內(nèi)容與電商數(shù)據(jù)報告-2024-WN8
- 產(chǎn)品oem合同書范本
- 【課件】Unit+4+My+Favourite+Subject大單元教學(xué)說課課件人教版(2024)七年級英語上冊
- 2024年秋季學(xué)期新滬粵版八年級上冊物理課件 第3章 光和眼睛第4節(jié) 光的折射規(guī)律
- 餐廳服務(wù)員四級理論考核試題
評論
0/150
提交評論