1. 程式人生 > >JAVA——第四章——類與物件

JAVA——第四章——類與物件

接著上一篇部落格的總結,我已經學習並總結到了JAVA的類構造器,接著學習並總結。

四 . 將訊息傳給方法或構造器

引數即是將資料傳送給方法或構造器的媒介。形參是指方法宣告中的變數列表,而實參是方法呼叫時實際傳遞的值。呼叫方法時,所使用的實參與宣告中形參的型別和次序必須相匹配

(1).形參型別
方法和構造器的形參可以是任意資料型別,包括double、float、interger等基本資料型別,以及物件和陣列等引用型別。
這裡給出一個方法,他接受陣列作為實參。該方法建立新的 Polygon 物件並從 Point 物件陣列初始化該物件,假設 Point 是表示 x、y 的類:

public
Polygon polygonForm(Point[] corners){ //method body goes here }

(注意:Java 程式語言不支援向方法傳遞方法,但可以將物件傳遞給方法,然後呼叫物件的方法)

(2).任意數目的實參
可變引數構造可用於向方法傳遞任意數目的值。不清楚某種型別實參的數量是,可以使用可變引數。
要使用可變引數,要在最後一個引數型別後新增省略號(…),然後新增空格和引數名。呼叫方法時,可以攜帶任意數量的該引數,包括零個。

(3).形參名
宣告方法或構造器的形參時,要給這些形參指定名稱。在作用域內,形參名必須唯一。
形參可以與類的一個欄位同名,這種情況下,形參會覆蓋欄位,會降低程式碼的可讀性,但是我們可以用 this 關鍵字,在以後會總結到。

(4).傳遞基本資料型別實參
基本資料型別的實參通過傳值方式傳入方法。這就意味著,對引數值的改變都只能發生在方法的作用域內。方法返回時,形參失效,對形參的改變也將丟失。例子:

public class PassPrimitiveByValue{
    public static void main(String[] args) {
        int x = 3;

        passMethod(x);

        System.out.println("After invoking passMethod,x = " + x);

    }

    public
static void passMethod(int p){ p = 10; } }

程式輸出結果如下:

After invoking passMethod,x = 3

(5).傳遞引用資料型別實參
引用資料型別(物件等)也可以通過傳值方式傳入方法。這就是說,當方法返回時,輸出的引用仍會引用相同的物件。。但是,如果正確訪問物件的欄位,其值可以在方法內部改變。

4.2 物件
一個典型的 Java 程式會建立許多物件,這些物件通過呼叫方法進行互動。
這裡給出一個小 Demo ,它建立三個物件:一個 Point 物件和兩個 Rectangle 物件。

public class CreatObjectDemo{
    public static void main(String[] args) {
        //建立一個Point物件和兩個Retangle物件
        Point originOne = new Point(23,94);
        Rectangle rectOne = new Rectangle(originOne,100,200);
        Rectangle rectTwo = new Rectangle(50,100);

        System.out.println("Width of rectOne: " 
                           + rectOne.width);
        System.out.println("Height of rectOne:"
                           + rectOne.height);
        System.out.println("Area of rectOne: "
                           + rectOne.getArea());

        rectTwo.origin = originOne;
        System.out.println("X Position of rectTwo: "
                           + rectTwo.origin.x);
        System.out.println("Y Position of rectTwo: "
                           + rectTwo.origin.y);
        System.out.println("Now rectTwo has been changed.");
        rectTwo.move(40,72);
        System.out.println("X Position of rectTwo: "
                           + rectTwo.origin.x);
        System.out.println("Y Position of rectTwo: "
                           + rectTwo.origin.y);
        System.out.println(new Rectangle(100,50).getArea());
    }
}

其執行結果如下:

Width of rectOne: 100
Height of rectOne:200
Area of rectOne: 20000
X Position of rectTwo: 23
Y Position of rectTwo: 94
Now rectTwo has been changed.
X Position of rectTwo: 40
Y Position of rectTwo: 72
5000

接下來詳細總結關於物件的細節

(一).建立物件
類為物件提供了一個實現框架;可以從類建立物件。下面的語句都是建立一個物件並將其賦值給變數:

Point originOne = new Point(23,94);
Rectangle rectOne = new Rectangle(originOne,100,200);
Rectangle rectTwo = new Rectangle(50,100);

1).宣告引用物件的變數

type name;

該形式告訴編譯器可以使用 name 引用 type 型別的資料。如果宣告是豬型別變數,該宣告就會為改變過倆保留適量的記憶體空間。引用變數也可以單獨宣告,其形式為:

Point originOne;

簡單宣告引用變數沒有建立物件。若建立物件,則需使用 new 運算子。

2).例項化類
new 運算子例項化類是,會為新物件分配記憶體並返回該記憶體的引用。new 運算子也會呼叫物件的構造器。

new 運算子需要一個後置的實參以呼叫構造器。構造器的名稱是待初始化的類名。
new 運算子返回所建立物件的引用,並將該引用賦值給相應型別的變數。

3).初始化物件
Point 類的程式碼:

class Point{
    public int x;
    public int y;

    //constructor
    public Point(){}
    public Point(int startX,int startY){
        this.x = startX;
        this.y = startY; 
    }
}

Rectangle 類的程式碼:

class Rectangle{
    public int width;
    public int height;
    public Point origin;

    //constructor
    public Rectangle(){
        origin = new Point(0,0);
    }
    public Rectangle(Point p){
        origin = p;
    }
    public Rectangle(int startwidth,int startheight){
        width = startwidth;
        height = startheight;
        origin = new Point(0,0);
    }
    public Rectangle(Point startPoint,int startwidth,int startheight){
        origin = startPoint;
        width = startwidth;
        height = startheight;
    }
    public int getArea(){
        return width * height;
    }
    public void move(int changeX,int changeY){
        origin.x = changeX;
        origin.y = changeY;
    }
}

如果類有多個構造器,那他們必須有不同的方法簽名。編譯器會根據實參的數目和型別來區分構造器。
所有類都至少有一個構造器。如果類沒有顯式構造器,Java 編譯器會自動給提供一個無參構造器,這在前一篇的博文中構造器那一塊提到過,無參構造器會呼叫父類的無參構造器,如果沒有父類。會呼叫 Object 構造器,如果父類沒有構造器,即使 Object 有構造器,編譯器也會報錯。

(二).使用物件

1).引用物件的欄位
物件的欄位通過欄位名來訪問,且欄位名是唯一的。類內部只需使用簡單的欄位名即可。例如:

System.out.println("Width and height are: " 
                           + width + "," + height);

而物件外的程式碼要訪問欄位的話麼就需要使用物件的引用或 ” 表示式 + 點操作符 + 簡單的欄位名 ” 的形式 , 如:

System.out.println("Width of rectOne: " 
                           + rectOne.width);
System.out.println("Height of rectOne:"
                           + rectOne.height);

要訪問欄位,可以使用物件的引用,也可以使用返回物件型別的任意形式,例如:

System.out.println(new Rectangle(100,50).getArea());

上述例子中,建立新的 Rectangle 物件並且立即獲得它的 getArea 方法的值。本質上來說,程式並沒有儲存該物件的引用,執行完該語句後,Java 虛擬機器會釋放佔用資源並回收利用。

2).呼叫物件的方法
呼叫物件的引用可以呼叫物件的方法,只需在物件引用後新增方法的簡單名、點操作符和圓括號,並在園括號內新增傳給方法的實參列表。

int areaRectangle = new Rectangle(10050).getArea();

呼叫物件的方法和向物件傳遞資訊是一樣的。上述程式碼中,呼叫 getArea() 的物件是構造器返回的 rectangle 。

3).垃圾收集器
Java 平臺支援建立任意多物件,而且不需要銷燬他們。當 Java 執行時環境確定不再使用某些物件是,就會刪除他們。這個過程叫做垃圾收集。
物件沒有引用,會被垃圾收集。變數超出作用域,通常刪除變數中儲存的引用。也可以將該變數的值設為 null ,顯式刪除其儲存的物件引用。程式中同一物件有多個引用,垃圾收集該物件前,必須先刪除這些引用。
Java 執行時環境有一個垃圾收集器,它會週期性釋放那些沒有引用的物件所佔用的記憶體空間。垃圾收集器會在合適的時間自動完成該任務。