JAVA中的類

來源:互聯網
上載者:User
使用Java語言意味著物件導向的編程。所以,你必須要學會如何建立、引用和繼承已建立的類。
  Java的結構是基於物件導向思想的。除了那些最基本的類型如整數、單精確度浮點數之外的其它成分,均是以類的形式出現的。正是由於Java的物件導向特性,所以它能給使用者提供一種具有良好的可擴充性的編程環境,並使得程式員可以充分利用別的程式員的成果,而不必重複以前的工作。
  學習完本章後,你應該是已經可以輕鬆地建立自己的類,並能引用和繼承已有的類,這將不公使你有能力去編寫更簡捷更有效代碼,同時也是進一步學習Java所必需的。

4.1 定義類的結構

4.1.1 類的基本概念

  Java程式的基本單位是類。類的定義可以看作是建立對象的原形。你建立類之後,就可用它來建立許多你需要的對象。Java把每一個可執行檔成分都變成類,使物件導向發展到極點。
  類的基本定義成員函數如下:

    class name
   
       //Class information

  在類定義的開始與結束處必須使用花括弧。你也許想建立一個矩形類,那麼可以用如下代碼:
public class Rectangle
......
4.1.2 類的基本組成
  一個類中通常都包含資料與函數兩種類型的元素,我們一般把它叫作屬性和成員函數,在很多時候我們也把成員函數稱為方法(method)。將資料與代碼通過類緊密結合在一起,就形成了現在非常流行的封裝的概念。自然,類的定義也要包括以上兩個部分。

    class <classname>
   
       <member data declarations>
       <member function declarations>

4.1.3 類的執行個體建立

  矩形類Rectangle中,也許你想把矩形的相關資訊寫入類,如:
int width,height;
  當然你還可以寫入其它資訊,但或許長和寬對簡單的矩形來說已足夠了。現在,類的定義如下所示:
public class Retangle
int width,height;
  當你建立了自己的類之後,通常需要使用它來完成某種工作。你可以通過定義類的執行個體--對象來實現這種需求。
  new運算子可以用來建立對象,實現成員函數如下:
Rectangle myrect=new Rectangle;
  當然,此時對象myrect並沒有做任何什麼事;它只儲存了矩形的長和寬的資訊。有了對象以後,我們怎樣使用對象內部的資料呢?下面是幾個例子:
myrect.width=10;
myrect.height=20;
  同樣,類的成員函數也是用“.”運算子來被引用的。

4.2 類的成員函數的說明與使用

4.2.1 類的成員函數的說明

  成員函數相當於C或C++中的函數。你應該用如下的方式說明一個成員函數:
Type name (Parameter)
//function body
注意:每一個成員函數必須返回一個值或聲明返回為空白(void)。它傳回型別的說明告訴編譯器它將返回什麼類型的值。在某些情況下,成員函數需要表示它是否成功的完成了它的工作,此時傳回型別通常為布爾型的。參數表是用逗號分開的一組變數,它將為成員函數提供所需資訊。
  下面例子中定義了一個成員函數。通過它,你的矩形類可以計算自己的面積了:

    int getArea(int w,int h)
   
       int a;
       a=w*h;
       return a;

  當成員函數被調用時,它將返回矩形的面積值。
  另外,矩形還需要對自己進行描繪,因此它需要成員函數drawRect(),此時,你的矩形類的定義將如下所示:

    public class Rectangle
   
       int width,height;
       private int getArea(int w,int h)
      
          int a;
          a=w*h;
          return a;
      
          public void drawRect()
      
          for(int i=width;i>0;i--)
         
             System.out.print("#");
         
          System.out.print("");
          for (i=height-2;i>0;i==)
         
             System.out.print("#");
             for(int j=width-2;i>0;i--)
            
               System.out.print("");
            
             System.out.print("#");
         
          for(int i=width;i>0;i-)
         
             System.out.print("#");
         
          System.out.print("");

 

      上例中最後一個“#”號後面還有一個System.out.print("")這是由於這個成員函數在上一行沒有結束而且緩衝區沒有溢出時將不把輸出結果寫屏。若你使用print成員函數,卻沒有得到輸出,這時仔細確認一下你是否以""來結束你的輸出資料流。

4.2.2  不同類型的成員函數
      在上例的成員函式宣告中你需要注意兩點:getArea()定義為private型,drawRect()定義為public型。public型意味著任何類都可以調用它。private型,它只能被所聲明的類內部調用。這些說明類型同樣適用於資料變數。
  若有人想改變一個私人變數,通常要引用下面的成員函數:

    public void setWidth(int w)
   
        width=w;
   

      在C++中,還有一種類型被黍為protected,它意味著成員函數或資料只能被所在類和子類引用。在一些Java資料中,也對此作了說明,但實際上,在Java的1.0,1.01和1.02版本中均沒有protected的相應功能,而只是保留了該關鍵字,希望讀者注意。

4.2.3  成員函數的重載
      假如你必須在不同情況下發送不同的資訊給同一個成員函數的話,該怎麼辦呢?你可以通過對此成員函數說明多個版本(version)的方法來實現重載。重載的本質是建立了一個新的成員函數:你只需給它一個不同的參數列表(parameterlist),如下例所示:

    void get Area(int w,int h);
    void get Area(float w,float h);

  在第二種情況下,成員函數get Area()接受兩個浮點變數作為它的參數,編譯器根據調用時的不同參數來決定該調用哪一種成員函數,假如你把兩個整數提供給成員函數,你就調用第一個成員函數;假如你把兩個浮點數提供給成員函數,第二個成員函數就被調用。

4.2.4  靜態成員
      除了public、private和protected以外,你還可以把成員說明為static(靜態)。static修飾符表明一個變數或成員函數對所有類的執行個體都是相同的,你也許想使用一個所有Rectangle類都可以使用的變數,來說明該類的版本(version),假如你把它說明成一個static,那麼該變數將對該類的所有執行個體都是一樣的,如:

     static int version=1;

      靜態成員函數和靜態變數的優點就在於他們能在沒有建立類的任何一個執行個體的情況下被引用,引用時在“.”域前,可直接使用類名而無須使用對象名。例如,drawRect成員函數使用了System.out.println成員函數,但實際上你卻未曾建立一個某個System類的對象,這正是因為out是System類的一個靜態變數,所以你可以直接使用這個成員函數而無須定義一個System對象。

4.2.5  構造和析構成員函數
      類有一個特殊的成員函數叫做構造成員函數,它通常用於初始化類的資料成員。在建立對象時,會自動調用類的構造成員函數。Java中的構造成員函數必須與該類具有相同的名字,另外,構造成員函數一般都應用public類型來說明,這樣才能在程式任意的位置建立類的執行個體--對象。
  下面是一個Rectangle類的構造成員函數,它帶有兩個參數,分別表示矩形的長和寬:
      public Rectangle(int w,int h)
     
         width=w;
         height=h;
         area=getArea(w,h);

      除了構造成員函數以外,類還提供了析構成員函數,當對象被從記憶體中刪除時,該成員函數將會被自動調用。通常,在析構成員函數內,你可以填寫用來回收對象內部的動態空間的代碼。

4.3  建立Java的應用程式
4.3.1 main成員函數
      Java的普通應用程式中,必須含有一個可被外界(通常是java解譯器)所直接調用的類,我們可以把這個類稱為該應用程式的主類,而這個主類必須含有main成員函數,整個應用程式就是從這個成員函數開始執行的,這與C程式有一定的類似之處。
    main成員函數的說明如下:

    public static void main(String args[]);

4.3.2  命令列參數
      我們把main成員函數的參數args稱為命令列參數,args可以用來接收外界傳給Java應用程式的參數,下面我們舉一個例子來看看參數傳遞的具體過程:
    class doRect
   
       public static void main(String args[])
      
          int w=Integer.valueOf(args[0]).intValue();
          int h=Integer.valueOf(args[1]).intValue();
          Rectangle myrect=new Rectangle(w,h);
          myrect.drawRect();
      
    

    class Rectangle
   
       int width,height,area;
       public Rectangle(int w,int h)
      
          width=w;
          height=h;
          area=getArea(w,h);
      
       protected int getArea(int w,int h)
      
          int a;
          a=w*h;
          return a;
      
       public void drawRect()
      
          int i,j;
          for(i=width;i>0;i--)
         
           System.out.print("#");
         
          System.out.print("")
          for(i=height-2;i>0;i--)
         
            System.out.print("#");
            for(j=width-2;i>0;j--)
           
               System.out.print("");
           
            System.out.print("#");
         
          for(i=width;i>0;i--)
         
             System.out.print("#");
         
          System.out.print("");
       
    

  用Javac編譯該程式後,可以用java解譯器來執行它,具體過程如下:

    javac doRect.java
    java doRect 10 15

  注意這裡的“10 15”就是命令列參數,它將被賦給doRect的main成員函數的args變數。其中args[0]的值為“10”,args[1]的值為“15”,Integer.valueOf(Stringstring).intValue的功能是把string中的數字轉化為一個整型值。

4.4  類的集合----包
4.4.1  理解包(package)的基本概念
      一旦你建立了一個類,並想重複地使用它,那麼把它放在一個包中將是非常有效,包(package)是一組類的集合,例如,Java本身提供了許多包,如java.jo和java.lang,它們存放了一些基本類,如System和String。你可以為自己的幾個相關的類建立一個包。
      把類放入一個包內後,對包的引用可以替代對類的引用。此外,包這個概念也為使用類的資料與成員函數提供了許多方便。沒有被public、private修飾的類成員也可以被同一個包中的其它類所使用。這就使得相似的類能夠訪問彼此的資料和成員函數,而不用專門去做一些說明。
  下表5-1列出了Java內建的一些常用包:

        包名稱               包的內容描述
   
基礎語言類          為Java語言的基本結構(如字串類、數組類)
                    提供了基本的類描述
實用類              提供了一些諸如編碼、解碼、哈西表、向量、
                    堆棧之類的實用常式
I/O類               提供了標準的輸入/輸出及檔案常式

applet類            提供了與支援Java的瀏覽器進行互動的常式

另一個視窗          AWT提供了一些諸如字型、控制、按鈕、捲軸
工具集類(AWT類)     之類的圖形介面

網路類              為通過諸如telnet、ftp、www之類的協議訪問
                    網路提供了常式

                表5-1  Java基本包一覽

4.4.2  定義一個包
  你可以用下機的成員函數去說明一個包:

    package PackageName;

  比如,你可以把Rectangle類放入一個名為shapes的包中:

      package shapes

      此後,當你用javac來編譯這個檔案時,將會在當前路徑下得到一個位元組代碼檔案Rectangle.class。但你還需要將它移至java類庫所在路徑的shapes子目錄下(在此之前,你必須建立一個名為shapes的子目錄),這樣以後才能應用shapes包中的Rectangle類。當然你可以用-d選項來直接指定檔案的目的路徑,這樣就無需編譯後再移動。
  包的名稱將決定它應放的不同路徑。例如用下面的方式來構造一個包。

      package myclass.Shapes;

      歸入該包的類的位元組代碼檔案應放在java的類庫所在路徑的myclass子目錄下。現在包的相對位置已經決定了,但java類庫的路徑還是不定的。事實上,java可以有多個存放類庫的目錄,其中的預設路徑為java目錄下的lib子目錄,你可以通過使用-classpath選項來確定你當前想選擇的類庫路徑,具體成員函數可參考第三章的內容。除此之外,你還可以在CLASSPATH環境變數中設定類庫路徑。

4.4.3  引用已定義過的包    為了使用已定義過的包,你必須使用引用命令import,你可以用以下三種方式引用包中的一個類:

    1.在每一個類名前給出個包名:

     Shapes.Rectangle REET=new Shapes.Rectangle(10,20)

    2.引用類本身:

     import Shapes.Reckargle;

    3.引用整外包:

     import Shapes;

4.5  類的深入研究
4.5.1  在Java中使用繼承
      也許在物件導向的程式設計中最為強大的工具是類的繼承,類的繼承允許你在一個已經存在的類之上編寫新的程式,例如,你想建立一個可在螢幕上顯示並能填充它的矩形類,你可以從頭開始或者利用舊的矩形類,下面的部分將向你介紹如何繼承已存在的Rectangle類,而不需重寫其中的代碼。
      使用extands關鍵字讓Java程式員能夠繼承已有類的成員函數,為了告訴編譯器和解譯器你正在繼承Rectangle類,你必須引用舊的Rectangle類,並且在新類的說明中引用它:

    import Shapes.Rectangle;

    class fillRect extands Rectangle
   
       //new code here
   

      這樣,fillRect類將可以使用Rectangle類中所有已定義的資料和成員函數,如:width、height等資料和getArea等成員函數。

4.5.2  成員函數的重載
  在繼承之後有所提高,這是人類進步的一個重要方式。
      那麼,如何使fillRect類比Rectangle類有所提高呢?我們可以用如下代碼來實現一個新的drawRect成員函數,它將大大縮短代碼,並能填充矩形,而不是僅僅畫出矩形的輪廓:
    private String makeString(chr ch,int num)
   
       StringBuffer str=new StringBuffer();
       for(int i=num;i>0;i--)
      
          str.append(ch);
      
       return str.toString();
    

     public void drawRect()
    
        for(int i=height;i>0;i--)
       
           System.out.println(makeString("#",width));
       
  

      注意這裡我們使用了StringBuffer類。之所以使用StringBuffer是因為String只能產生一個靜態類型--它的大小是不能改變的,而StringBuffer能夠產生一個可變長度的字串類型。
      在這裡,drawRect成員函數被重載了,通過使用相同的成員函數名字,你可以用新的成員函數來代替舊的成員函數。不過,那些被說明為final的成員函數是不能被重載的。
      注意,你不必在新的類中包含那些與被繼承類相同的代碼,而只需要加入你想要的東西,但你必須建立一個新的構造成員函數,以區分這兩個不同的類。
  新類的全貌如下所示,你可以發現通過繼承Rectangle類,代碼變得非常簡單明了。
    class fillRect extands Rectangle
   
       public fillRect(int w,int h)
      
          supper(w,h);
      
       private String makeString(char ch,int num)
      
          StringBuffer str=new StringBuffer();
          for(int i=num;i>0;i--)
         
             str.append(ch);
         
          return str.toString();
       
        public void drawRect()
       
          for(int i=height;i>0;i--)
         
             System.out.printlm(makeString("#",width));
         
       
     

4.5.3  使用介面
      Java可以建立一種稱作介面(interface)的類,在這個類中,所有的成員函數都是抽象的,也就是說它們都只有說明沒有定義,你可以如下所示來說明一個介面。
    public interface interfaceName
        //成員函數說明
   

      介面中成員函數的預設參考型別是private,介面(interface)的內部變數是不可更改的,並且總是static和final。
      通過使用關鍵字implement,你可以在定義類時繼承一個介面。不過與extends不同的是,一個類可以同時繼承多個介面。
      使用介面的優點在何處呢?通過建立一個介面,你可以說明一整套抽象的成員函數而無須去具體實現它,所有繼承了這個介面的類,都將有著具有相同原形的成員函數。例如,你想所有的shapes都有一個draw()成員函數,你可以建立一個介面並且用Shape命名:

     public interface Shape
        void draw();

  現在,無論你何時建立一個繼承自Shape的類,都將擁有一個成員函數draw()。

4.5.4  類的轉換
  類的轉換,與不同類型的變數之間的轉換有相似之處,但並不一樣。
      我們可以把一個父類的對象轉換成一個子類對象,下面的代碼說明一個類轉換的例子,其中Y類是從X類繼承而來的:

    Yy=new Y();
    Xx;
    x=y;

  需要注意的是兩個子類之間的轉換是不可以的。

4.5.5  null,this和supper變數
  所有的類都有三種變數:null、this和supper。
  null變數不指向任何實際對象,而是指向一個Null 物件,如下例所示:

    Rectangle rect=null;

      該例產生一個矩形類的變數,但不建立一個實際的對象。另外,假如一個成員函數需要一個對象作為參數時,你同樣可以用null代替。
  this變數指向對象本身,一個類可以通過this變數來獲得一個代表它自身的物件變數。
      supper變數是一個指向類父類構造成員函數的變數,你可以通過調用它,來迅速完成對子類的構造成員函數的設計。 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.