實驗三 面向對象的編程基礎

            開發(fā)語言及實現平臺或實驗環(huán)境

          Windows2000 XPJDK1.5以上版本與Eclipse集成開發(fā)環(huán)境

          實驗目的

          理解Java語言是如何體現面向對象編程基本思想,

          了解類的封裝方法,以及如何創(chuàng)建類和對象.

          了解成員變量和成員方法的特性。

          掌握OOP方式進行程序設計的方法

          了解類的繼承性和多態(tài)性的作用

          了解Java 中包(package)、接口(interface)的作用。

          掌握包、接口的使用方法。

          實驗任務

          編寫一個體現面向對象思想的程序。

          編寫一個創(chuàng)建對象和使用對象的方法程序。

          編寫不同成員變量修飾方法的程序。

          編寫不同成員方法修飾的程序。

          編寫體現類的繼承性(成員變量,成員方法,成員變量隱藏)的程序。

          編寫體現類多態(tài)性(成員方法重載,構造方法重載)的程序。

          了解Java 系統(tǒng)包的結構。

          掌握創(chuàng)建自定義包的方法。

          掌握使用系統(tǒng)接口的技術和創(chuàng)建自定義接口的方法。

          實驗內容或實驗步驟

          1.程序功能:通過兩個類StaticDemo、LX3_4 說明靜態(tài)變量/方法與實例變量/方法的區(qū)別。

          2.編寫類文件LX3_4.java,程序源代碼如下。

          class StaticDemo {

          static int x;

          int y;

          public static int getX() {

          return x;

          }

          public static void setX(int newX) {

          x = newX;

          }

          public int getY() {

          return y;

          }

          public void setY(int newY) {

          y = newY;

          }

          }

          public class LX3_4 {

          public static void main(String[] args) {

          System.out.println("靜態(tài)變量x="+StaticDemo.getX());

          System.out.println("實例變量y="+StaticDemo.getY()); // 非法,編譯時將出錯

          StaticDemo a= new StaticDemo();

          StaticDemo b= new StaticDemo();

          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.x="+b.getX());

          System.out.println("實例變量b.y="+b.getY());

          }

          }

          3.對上面的源程序進行編譯,會出現如圖3.4 所示的出錯提示。

          4.將源程序中的出錯語句刪除或使用解釋符//隱藏起來,例如,

          //System.out.println("實例變量y="+StaticDemo.getY());

          5.重新編譯并運行該程序,結果如圖3.5 所示。

          static 聲明的成員變量/方法被視為類的成員變量/方法,而不把它當作實例對象的成員變量/方法。換句話說,靜態(tài)變量/方法是類固有的,可以直接引用,其它成員變量/方法僅僅被聲明,生成實例對象后才存在,才可以被引用。基于這樣的事實,也把靜態(tài)變量/方法稱為類變量/方法,非靜態(tài)變量稱為實例變量/方法。

          從實驗結果可以得出以下幾點結論:

          ·類的靜態(tài)變量可以直接引用,而非靜態(tài)變量則不行。類的靜態(tài)變量相當于某些程序語言的全局變量。

          ·靜態(tài)方法只能使用靜態(tài)變量,不能使用實例變量。因為對象實例化之前,實例變量不可用。

          ·類的靜態(tài)變量只有一個版本,所有實例對象引用的都是同一個版本。

          ·對象實例化后,每個實例變量都被制作了一個副本,它們之間互不影響。

          (四) 方法中參數傳遞的練習

          在其它語言中,函數調用或過程調用時參數有傳值調用和傳地址調用之分。在Java 中,方法中的參數傳遞可以分為傳值調用或對象方法調用等方式。傳值調用即傳遞的參數是基本數據類型,調用方法時在方法中將不能改變參數的值,這意味著只能使用它們。對象調用是指先調用對象,再調用對象的方法,這種方式可以修改允許存取的成員變量。所以,如果不想改變參數的值,可以采用傳值調用的方法。如果想改變參數的值,可采用對象調用的方法,間接修改參數的值。

          1.編寫一個傳值調用的程序文件LX3_5.java。

          (1)程序功能:程序首先給整型變量x 和y 賦一個初值10,然后使用傳值調用方式調用方法ff1對x 和y 做乘方及輸出x 和y 的乘方值,最后再輸出x 和y 的乘方值。

          (2)程序源代碼如下。

          class LX3_5 {

          public static void main(String[] args) {

          int x=10, y=10;

          ff1(x, y);

          System.out.println("x="+x+", y="+y);

          }

          static void ff1(int passX, int passY) {

          passX=passX*passX;

          passY=passY*passY;

          System.out.println("passX="+passX+", passY="+passY);

          }

          }

          (3)編譯LX3_5.java,其運行結果如圖3.6 所示。

          (4)分析其運行結果

          這個程序沒有實現預期的結果,原因是ff1 方法采用了傳值調用。調用ff1 方法時,將產生兩個參數passX 和passY,x 和y 的值被傳遞給這兩個參數。盡管在方法中計算了參數的平方,但從ff1方法返回后,參數消失,此時x 和y 的值仍是初值。

          2.編寫一個調用對象方法的程序文件LX3_6.java。

          (1)程序功能:通過調用對象的方法在方法調用后修改了成員變量的值。

          (2)LX3_6.java 程序源代碼如下。

          class LX3_6 {

          public static void main(String[] args) {

          Power p=new Power();

          p.ff2(10,10);

          System.out.println("方法調用后 x="+p.x+", y="+p.y);

          }

          }

          class Power{

          int x=10, y=10;

          void ff2(int passX, int passY) {

          System.out.println("初始時 x="+x+", y="+y);

          x=passX*passX;

          y=passY*passY;

          System.out.println("方法調用中 x="+x+", y="+y);

          }

          }

          (3)編譯LX3_6.java,其運行結果如圖3.7 所示。

          (五) 類的繼承性練習

          1. 進一步理解繼承的含義

          新類可從現有的類中產生,并保留現有類的成員變量和方法并可根據需要對它們加以修改。新類還可添加新的變量和方法。這種現象就稱為類的繼承。

          當建立一個新類時,不必寫出全部成員變量和成員方法。只要簡單地聲明這個類是從一個已定義的類繼承下來的,就可以引用被繼承類的全部成員。被繼承的類稱為父類或超類(superclass),這個新類稱為子類。

          Java 提供了一個龐大的類庫讓開發(fā)人員繼承和使用。設計這些類是出于公用的目的,因此,很少有某個類恰恰滿足你的需要。你必須設計自己的能處理實際問題的類,如果你設計的這個類僅僅實現了繼承,則和父類毫無兩樣。所以,通常要對子類進行擴展,即添加新的屬性和方法。這使得子類要比父類大,但更具特殊性,代表著一組更具體的對象。繼承的意義就在于此。

          2. 創(chuàng)建公共類LX3_7_P

          (1)編寫程序文件LX3_7_P.java,源代碼如下。

          public class LX3_7_P

          {

          protected String xm; //具有保護修飾符的成員變量

          protected int xh;

          void setdata(String m,int h) //設置數據的方法

          {

          xm =m;

          xh = h;

          }

          public void print() //輸出數據的方法

          {

          System.out.println(xm+", "+xh);

          }

          }

          (2)編譯LX3_7_P.java,產生類文件LX3_7_P.class。

          3.創(chuàng)建繼承的類

          (1)程序功能:通過LX3_7_P 類產生子類LX3_8,其不僅具有父類的成員變量xm(姓名)、xh(學號),還定義了新成員變量xy(學院)、xi(系)。在程序中調用了父類的print 方法,同時可以看出子類也具有該方法。

          (2)編寫LX3_8.java 程序,源代碼如下。

          class LX3_8 extends LX3_7_P{

          protected String xy;

          protected String xi;

          public static void main(String args[])

          {

          LX3_7_P p1 = new LX3_7_P();

          p1.setdata("帥零",12321) ;

          p1.print();

          LX3_8 s1 = new LX3_8() ;

          s1.setdata("郭麗娜",12345); //調用父類的成員方法

          s1.xy="經濟管理學院"; //訪問本類的成員變量

          s1.xi="信息管理系"; //訪問本類的成員變量

          s1.print();

          System.out.print(s1.xm+", "+s1.xy+", "+s1.xi);

          }

          }

          (3)編譯并運行程序,其結果如圖3.8 所示。

          3.了解成員變量的隱藏方式

          所謂隱藏是指子類重新定義了父類中的同名變量,在子類Line 中重新定義了x 為x1,y 為y1,隱藏了父類Point 中的兩個成員變量x 和y。子類執(zhí)行自己的方法時,操作的是子類的變量,子類執(zhí)行父類的方法時,操作的是父類的變量。在子類中要特別注意成員變量的命名,防止無意中隱藏了父類的關鍵成員變量,這有可能給程序帶來麻煩。

          4.了解成員方法的覆蓋方式

          (1)方法覆蓋的定義與作用

          通過繼承子類可以繼承父類中所有可以被子類訪問的成員方法,但如果子類的方法與父類方法同名,則不能繼承,此時稱子類的方法覆蓋了父類的方法,簡稱為方法覆蓋(override)。方法覆蓋為子類提供了修改父類成員方法的能力。例如,子類可以修改層層繼承下來的Object 根類的toString 方法,讓它輸出一些更有用的信息。下面的程序顯示了在子類Circle 中添加toString 方法,用來返回圓半徑和圓面積信息。

          (2)編寫覆蓋Object 類toString 方法的程序文件LX3_9.java,源代碼如下。

          class Circle {

          private int radius;

          Circle(int r) {

          setRadius(r);

          }

          public void setRadius(int r) {

          radius=r;

          }

          public int getRadius() {

          return radius;

          }

          public double area() {

          return 3.14159*radius*radius;

          }

          public String toString() {

          return "圓半徑:"+getRadius()+" 圓面積:"+area();

          }

          }

          public class LX3_9{

          public static void main(String args[]) {

          Circle c=new Circle(10);

          System.out.println(""n"+c.toString());

          }

          }

          (3)編譯并運行程序,其結果如圖3.9 所示

          (4)程序結構分析。

          程序添加了toString 方法并修改了它的返回值。由于toString 和繼承下來的Object 類的方法名相同、返回值類型相同,因此覆蓋了超類Object 中的toString 方法。

          方法覆蓋時要特別注意:

          用來覆蓋的子類方法應和被覆蓋的父類方法保持同名、相同的返回值類型,以及相同的參數個數和參數類型。

          5.This、super 和super()的使用

          (1)程序功能:說明this、super 和super()的用法。程序首先定義Point(點)類,然后創(chuàng)建點的子類Line(線)。最后通過LX3_10 類輸出線段的長度。

          程序中通過super(a,b)調用父類Point 的構造方法為父類的x 和y 賦值。在子類Line 的setLine方法中,因為參數名和成員變量名相同,為給成員變量賦值,使用this 引用,告訴編譯器是為當前類的成員變量賦值。在length 和toString 方法中使用父類成員變量時,使用super 引用,告訴編譯器使用的是父類的成員變量。

          (2)使用this、 super 和super()的程序文件LX3_10.java,源代碼如下。

          class Point {

          protected int x, y;

          Point(int a, int b) {

          setPoint(a, b);

          }

          public void setPoint(int a, int b) {

          x=a;

          y=b;

          }

          }

          class Line extends Point {

          protected int x, y;

          Line(int a, int b) {

          super(a, b);

          setLine(a, b);

          }

          public void setLine(int x, int y) {

          this.x=x+x;

          this.y=y+y;

          }

          public double length() {

          int x1=super.x, y1=super.y, x2=this.x, y2=this.y;

          return Math.sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1));

          }

          public String toString() {

          return "直線端點:[" + super.x + "," + super.y + "] [" +

          x + "," + y + "] 直線長度:" + this.length();

          }

          }

          public class LX3_10{

          public static void main(String args[]) {

          Line line=new Line(50, 50);

          System.out.println(""n"+line.toString());

          }

          }

          (3)編譯并運行程序,結果如圖3.10 所示。

          六 類的多態(tài)性練習

          1. 理解類的多態(tài)性

          類的繼承發(fā)生在多個類之間,而類的多態(tài)只發(fā)生在同一個類上。在一個類中,可以定義多個同名的方法,只要確定它們的參數個數和類型不同。這種現象稱為類的多態(tài)。

          多態(tài)使程序簡潔,為程序員帶來很大便利。在OOP 中,當程序要實現多個相近的功能時,就給相應的方法起一個共同的名字,用不同的參數代表不同的功能。這樣,在使用方法時不論傳遞什么參數,只要能被程序識別就可以得到確定的結果。

          類的多態(tài)性體現在方法的重載(overload)上,包括成員方法和構造方法的重載。

          2. 方法的重載

          方法的重載是指對同名方法的不同使用方式。

          (1)程序功能:對不同的數進行排序輸出。在IntSort 類中定義3 個同名的方法sort,

          (2)編寫LX3_11.java 文件,源代碼如下(自己編寫程序代碼)。

          3.構造方法的重載

          構造方法的名稱和類同名,沒有返回類型。盡管構造方法看起來和一般的成員方法沒有差別,但它不是方法,也不是類的成員。因此,構造方法不能直接調用,只能由new 操作符調用。

          構造方法對于類是十分重要的,對象的初始化任務要靠構造方法來完成。

          重載構造方法的目的是提供多種初始化對象的能力,使程序員可以根據實際需要選用合適的構造方法來初始化對象。

          (1) 編寫構造方法RunDemo 的重載程序文件LX3_12,源代碼如下。

          class RunDemo {

          private String userName, password;

              RunDemo() {

          System.out.println("全部為空!");

          }

          RunDemo(String name) {

          userName=name;

          }

          RunDemo(String name, String pwd) {

          this(name);

          password=pwd;

          check();

          }

          void check() {

          String s=null;

          if (userName!=null)

          s="用戶名:"+userName;

          else

          s="用戶名不能為空!";

          if (password!="12345678")

          s=s+" 口令無效!";

          else

          s=s+" 口令:********";

          System.out.println(s);

          }

          }

          public class LX3_12 {

          public static void main(String[] args) {

          new RunDemo();

          new RunDemo("劉新宇");

          new RunDemo(null,"邵麗萍");

          new RunDemo("張馳","12345678");

          }

          }

          (2)編譯并運行程序,結果如圖3.12 所示。

          (3)三個構造方法,其中

          第一個無參構造方法RunDemo() 的實際作用是對成員變量賦缺省初值,由于userName和password都是String 類,所以它們的缺省初值為null。

          第二個構造方法RunDemo(String) 只有一個參數,用來對成員變量userName 賦初值。

          第三個構造方法RunDemo(String, String) 有兩個參數,并有更多的內容,首先調用this(name),其實際作用就是調用當前類的構造方法RunDemo(String name);然后對成員變量password 賦值;最后調用check 方法來檢查userName 和password,類似于一般程序的口令驗證。重載構造方法的執(zhí)行由對象根據實際參數的個數、類型和順序確定。

          思考

          2.程序的結構。類與對象的關系。對象創(chuàng)建、使用、銷毀的過程。

          3. 方法的參數傳遞有哪些方式?區(qū)別時什么?

          4. 說明什么是構造方法。

          5. 說明程序中有多個類時如何確定源程序文件的名稱。

          6. 說明類的繼承和多態(tài)有什么作用,在使用上應該注意什么問題。

          posted on 2010-04-15 14:36 libifeng 閱讀(1017) 評論(0)  編輯  收藏 所屬分類: Java實驗指導書

          <2010年4月>
          28293031123
          45678910
          11121314151617
          18192021222324
          2526272829301
          2345678

          導航

          統(tǒng)計

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 沈阳市| 临猗县| 江口县| 桂阳县| 海淀区| 恩施市| 涞源县| 隆安县| 兴山县| 石屏县| 永平县| 武定县| 上虞市| 四平市| 克什克腾旗| 普兰店市| 四子王旗| 兴海县| 龙门县| 天镇县| 沅江市| 新乐市| 正阳县| 奉节县| 平泉县| 宿州市| 南充市| 碌曲县| 尼勒克县| 南漳县| 仙桃市| 虞城县| 南充市| 大足县| 正安县| 神农架林区| 博兴县| 鄂伦春自治旗| 北流市| 盱眙县| 永济市|