《第4章面向?qū)ο缶幊逃嬎銠C專業(yè)課件PPT》由會員分享,可在線閱讀,更多相關(guān)《第4章面向?qū)ο缶幊逃嬎銠C專業(yè)課件PPT(39頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、1第第4章章 面向?qū)ο缶幊堂嫦驅(qū)ο缶幊? 主要任務: 理解面向?qū)ο缶幊痰幕靖拍?了解類的封裝方法 如何創(chuàng)建類和對象 了解成員變量和成員方法的特性 學習使用OOP方式進行程序設(shè)計 24.3 成員變量與封裝成員變量與封裝l成員變量描述了類和對象的狀態(tài),有時也稱為屬性、數(shù)據(jù)、域(field)。l對成員變量的操作實際上就是改變類和對象的狀態(tài),使之能滿足程序的需要。與類相似,成員變量也有很多修飾符,用來控制對成員變量的訪問,實現(xiàn)對類和對象的封裝。34.3.1成員變量的聲明成員變量的聲明l 例4.4 顯示當前日期和時間,運行結(jié)果見圖:4import java.awt.Graphics;import ja
2、va.applet.Applet;import java.util.Calendar;class Time private Calendar t; private int y, m, d, hh, mm, ss;5 Time () t=Calendar.getInstance(); y=t.get(t.YEAR); m=t.get(t.MONTH)+1; d=t.get(t.DATE); hh=t.get(t.HOUR_OF_DAY); mm=t.get(t.MINUTE); ss=t.get(t.SECOND); 6public String getDate() return y+ 年+m+
3、月+d+日; public String getTime() String s=hh+ 時+mm+分+ss+秒; return s; 7public class ShowTime extends Applet Time t=new Time(); public void paint(Graphics g) g.drawString(當前日期:+t.getDate(),50,40); g.drawString(當前時間:+t.getTime(),50,80); 84.3.2 成員變量的修飾成員變量的修飾l成員變量的聲明語句有如下格式: public private protected packa
4、ge / 訪問控制修飾符 static final transient volatile 91訪問控制權(quán)限l(1)public 公共變量 由public修飾的變量稱為公共變量,可被任何包中的任何類訪問,只有在確認任何外部訪問都不會帶來不良后果的情況下才將成員聲明為公共的。公共變量對任何類都是可見的,因此它沒有秘密可言,不具有數(shù)據(jù)保護功能。 l(2)private私有變量 由private修飾的變量稱為私有變量,只能被聲明它的類所使用,拒絕任何外部類的訪問。私有變量是不公開的,它們得到了最好的保護,這是對類進行封裝時使用的主要方法。10l(3)protected 受保護變量 由protected
5、修飾的變量稱為受保護變量,可被聲明它的類和派生的子類以及同一個包中的類訪問。 l(4)package包變量 由package修飾的變量稱為包變量,在聲明時常常省略package關(guān)鍵字,即沒有修飾符的成員被視為包成員。包成員可被聲明它的類和同一個包中的其它類(包括派生子類)所訪問,在其它包中的子類則不能訪問父類的包成員。 112static 靜態(tài)變量lstatic聲明的成員變量被視為類的成員變量,而不把它當作實例對象的成員變量。換句話說,靜態(tài)變量是類固有的,可以直接引用,其它成員變量僅僅被聲明,生成實例對象后才存在,才可以被引用?;谶@樣的事實,也把靜態(tài)變量稱為類變量,非靜態(tài)變量稱為實例變量。相
6、應地,靜態(tài)方法稱為類方法,非靜態(tài)方法稱為實例方法。 12例4.5 靜態(tài)變量的使用。class StaticDemo static int x; int y; static public int getX() return x; static public void setX(int newX) x = newX; 13 public int getY() return y; public void setY(int newY) y = newY; 14public class ShowDemo public static void main(String args) System.out.pr
7、intln(靜態(tài)變量x=+StaticDemo.getX(); System.out.println(實例變量y=+StaticDemo.getY(); / 非法,編譯時將出錯 StaticDemo a= new StaticDemo(); StaticDemo b= new StaticDemo();15 a.setX(1); a.setY(2); b.setX(3); b.setY(4); System.out.println(靜態(tài)變量a.x=+a.getX(); System.out.println(實例變量a.y=+a.getY(); System.out.println(靜態(tài)變量b.
8、x=+b.getX(); System.out.println(實例變量b.y=+b.getY(); 16對上面的源程序進行編譯會出現(xiàn)如圖所示結(jié)果,不能進行運行該程序。17 將源程序中的出錯語句刪除或使用解釋符/隱藏起來如: /System.out.println(“實例變量y=”+StaticDemo.getY(); / 非法,編譯時將出錯,再進行編譯,即可執(zhí)行該程序,結(jié)果如圖所示。18從輸出結(jié)果中可以得出以下幾點結(jié)論 :l 類的靜態(tài)變量可以直接引用,例如在程序中直接使用了StaticDemo.getX(),而非靜態(tài)變量則不行。類的靜態(tài)變量相當于某些程序語言的全局變量。l 靜態(tài)方法只能使用靜
9、態(tài)變量,不能使用實例變量。 l 類的靜態(tài)變量只有一個版本,所有實例對象引用的都是同一個版本。 l 對象實例化后,每個實例變量都被制作了一個副本,它們之間互不影響。 193final 最終變量l一旦成員變量被聲明為final,在程序運行中將不能被改變。這樣的成員變量就是一個常量。例如: final double PI=3.14159;l該語句聲明一個常量PI,如果在后面試圖重新對它賦值,將產(chǎn)生編譯錯誤。另外,常量名一般用大寫字母。常量和直接量一樣不占用內(nèi)存空間。204transient 過渡變量lJava語言目前對transient修飾符沒有明確說明,它一般用在對象序列化(object seri
10、alization)上,說明成員變量不許被序列化。5volatile 易失變量lvolatile聲明的成員變量為易失變量,用來防止編譯器對該成員進行某種優(yōu)化。這是Java語言的高級特性,僅被少數(shù)程序員使用。214.4 成員方法成員方法l對象的行為由類的方法實現(xiàn),其它對象可以調(diào)用一個對象的方法,通過消息的傳遞實現(xiàn)對該對象行為的控制。l下面討論如何通過方法影響對象的行為。224.4.1 成員方法的設(shè)計成員方法的設(shè)計l類的設(shè)計集中體現(xiàn)在成員方法的設(shè)計上。良好的設(shè)計可以使類更加強壯,功能更加完善。成員方法的設(shè)計應該從類的整體行為出發(fā),能正確響應外部消息,自然地改變對象的狀態(tài),并符合相對獨立性、結(jié)構(gòu)清晰
11、、可重用性強等編程要求。l來看下面的例子:23例4.6 方法對對象行為的影響,運行結(jié)果見圖:24import java.awt.*;import java.applet.Applet;class DrawShape private int x, y, shape; public void setPos(int xPos, int yPos) x=xPos; y=yPos; 25 public void setShape(int choice) shape=choice; public void draw(Graphics g) if (shape =1) g.drawRect(x, y, 60
12、, 60); else if (shape =2) g.drawOval(x, y, 60, 60); else g.drawString(形狀參數(shù)不對!, 20, 120); 26public class M1 extends Applet final int BOX=1, OVAL=2; DrawShape a=new DrawShape(); public void paint(Graphics g) a.setPos(40,20); a.setShape(BOX); a.draw(g); a.setPos(200,60); a.setShape(OVAL); a.draw(g); 27
13、4.4.2 成員方法的聲明與修飾成員方法的聲明與修飾l 成員方法相當于其它語言的函數(shù)或過程,是命令語句的集合。成員方法的聲明一般放在成員變量的聲明之后,聲明語句的格式和順序如下: public private protected package / 訪問控制修飾符 static final abstract native synchronized 返回值類型 方法名(參數(shù)表)throws 異常類型28不同含義的修飾符 :1final 最終方法l 方法被聲明為最終方法后,將不能被子類覆蓋,即最終方法能被子類繼承和使用但不能在子類中修改或重新定義它。這種修飾可以保護一些重要的方法不被修改,尤其是那
14、些對類的狀態(tài)和行為有關(guān)鍵性作用的方法被保護以后,可以避免未知情況的發(fā)生。l 在OOP中,子類可以把父類的方法重新定義,使之具有新功能但又和父類的方法同名、同參數(shù)、同返回值,這種情況稱為方法覆蓋(override)。292abstract 抽象方法l 一個抽象類可以含有抽象方法。所謂抽象方法是指不能實現(xiàn)的方法,因為它沒有方法體,所以抽象方法不能出現(xiàn)在非抽象類中。l 為什么要使用抽象類和抽象方法呢?一個抽象類可以定義一個統(tǒng)一的編程接口,使其子類表現(xiàn)出共同的狀態(tài)和行為,但各自的細節(jié)是不同的。子類共有的行為由抽象類中的抽象方法來約束,而子類行為的具體細節(jié)則通過抽象方法的覆蓋來實現(xiàn)。這種機制可增加編程的
15、靈活性,也是OOP繼承樹的衍生基礎(chǔ)。303native 本地方法l 用其它語言編寫的方法在Java中稱為本地方法。如果你有一個用其它語言如C+ 寫成的函數(shù),希望在Java中能利用這些資源,你可以編寫本地方法。l SDK提供了Java本地接口JNI(Java Native Interface),使得Java虛擬機能運行嵌入在Java程序中的其它語言的代碼。這些語言包括C/C+、Fortran、匯編語言等等。l 嵌入外部語言代碼出于以下幾點考慮:Java系統(tǒng)包不提供對平臺依賴性程序的支持時;想利用現(xiàn)有的其它語言資源時;出于運行速度的要求而使用其它語言開發(fā)的運行模塊。314synchronized
16、同步方法l 同步方法用于多線程編程。多線程在運行時,可能會同時存取一個數(shù)據(jù)。為避免數(shù)據(jù)的不一致性,應將方法聲明為同步方法,對數(shù)據(jù)進行加鎖,以保證線程的安全。詳細內(nèi)容請參考第8章。 5throws 異常類型l 程序在運行時可能發(fā)生異常現(xiàn)象。每一個異常都對應著一個異常類,如果希望方法忽略某種異常,可將其拋出,使程序得以繼續(xù)運行。在前面介紹的例中就使用過拋出異常throws IOException(輸入/輸出異常),有關(guān)異常處理的詳細內(nèi)容請參考第6章。326返回值類型l Java要求一個方法必須聲明它的返回值類型。如果方法沒有返回值就用關(guān)鍵字void作為返回值類型,否則應使用基本數(shù)據(jù)類型或?qū)ο箢愋驼f
17、明返回值類型,如下面的語句: public int getX(); void setXY(int x, int y); public String getName(); protected Object clone();l 其中,getX的返回值為int類型,setXY沒有返回值,getName的返回值是String類。而clone的返回值則為Object類。337方法名l 方法名可以是任何有效的方法名可以是任何有效的Java標識符。方法標識符。方法名可以和成員變量同名,也可以和成員方法名可以和成員變量同名,也可以和成員方法同名。同一個類中的方法同名現(xiàn)象在同名。同一個類中的方法同名現(xiàn)象在OOP
18、中中稱為方法重載(稱為方法重載(overload),重載使一個類),重載使一個類的多個方法享有同一個名稱,可以減輕程序的多個方法享有同一個名稱,可以減輕程序員的負擔。員的負擔。 8參數(shù)表l 方法的調(diào)用者正是通過參數(shù)表將外部消息傳方法的調(diào)用者正是通過參數(shù)表將外部消息傳遞給方法加以處理的。在參數(shù)表中要聲明參遞給方法加以處理的。在參數(shù)表中要聲明參數(shù)的類型,并用逗號分隔多個參數(shù)。數(shù)的類型,并用逗號分隔多個參數(shù)。344.4.3 方法體方法體l方法體包含在一對大括號中,即使方法體中沒有語句,一對大括號也是必不可少的。使用各種語句結(jié)構(gòu)組成方法主體,實現(xiàn)程序的功能,是設(shè)計方法體的目的。下面這段程序是一個處理格
19、式化字符串的方法: public String toString(int arr) int i, n=arr.size(); StringBuffer s=new StringBuffer();35 s.append(); for (i=0; in; i+) s.append (Integer.toString(arri); if (in-1) s.append(,); s.append(); return s.toString();364.4.4 消息傳遞消息傳遞l 一個對象和外部交換信息主要靠方法的參數(shù)來傳遞。當然,如果允許的話,外部對象也可以直接存取一個對象的成員變量。出于整體考慮,大部
20、分還是通過參數(shù)來傳遞。在Java中,可傳遞的參數(shù)包括任何數(shù)據(jù)類型,前面已經(jīng)使用了基本數(shù)據(jù)類型的參數(shù)傳遞、數(shù)組的傳遞和對象的傳遞。 l 在其它語言中,函數(shù)調(diào)用或過程調(diào)用有傳值調(diào)用和傳地址調(diào)用之分。 37例4.7 參數(shù)傳遞示例1class P1 public static void main(String args) int x=10, y=10; doPower(x, y); System.out.println(x=+x+, y=+y); static void doPower(int passX, int passY) passX=passX*passX; passY=passY*passY
21、; System.out.println(passX=+passX+, passY=+passY); 38例4.8 參數(shù)傳遞示例2 class P2 public static void main(String args) Power p=new Power(); p.doPower(10,10); System.out.println(x=+p.x+, y=+p.y); class Power int x, y; void doPower(int passX, int passY) x=passX*passX; y=passY*passY; 394.4.5 Java編程小結(jié)編程小結(jié)l 源程序的文件名和程序中定義的主類名應保持一致,包括字母大小寫的匹配。l Java嚴格區(qū)分大小寫,例如applet和Applet代表了不同的含義。l 語句以分號結(jié)束。l 程序中可加注釋,用雙斜杠“/”引導,“/* */”可包含多行注釋。l 注意設(shè)計一般類與主類,一般類可以有多個,主類只能有一個,源程序名與主類名相同。