前言
Groovy 的物件系統基本上和 Java 的物件系統大同小異,都是以類別 (class) 做為物件 (object) 的藍圖,物件做為類別的實體 (instance)。Groovy 和 Java 相異的地方在於 Groovy 加上一些語法糖,使得語法變得更簡潔。
建立類別
類別 (class) 的虛擬碼如下:
class KlassName {
// Declare some private fields
// The constructor.
public KlassName(param_a, param_b, param_c) {
// Init some fields.
}
// Declare some public methods
}
類別的目的是用來建立物件,而非物件本身,我們在撰寫類別時,其實是在撰寫帶有內部狀態的函式,這些函式藉由改變物件的屬性來改變物件的狀態。這樣講有點抽象,用實際的例子來看會比較容易了解,詳見下文。
註:和類別或物件綁在一起的函式 (function) 又稱為方法 (methods)。
實際的例子
以下用平面座標的點 (point) 為例子來看如何建立物件,這個例子只用到 getters 和 setters,算是相對單純的例子:
class Point { /* 1 */
// Some private fields. /* 2 */
private double _x /* 3 */
private double _y /* 4 */
// The constructor of Point. /* 5 */
public Point(double x, double y) { /* 6 */
setX(x) /* 7 */
setY(y) /* 8 */
} /* 9 */
// Pseudo-property getter x /* 10 */
public getX() { /* 11 */
return _x /* 12 */
} /* 13 */
// Pseudo-property setter x /* 14 */
public setX(double x) { /* 15 */
_x = x /* 16 */
} /* 17 */
// Pseudo-property getter y /* 18 */
public getY() { /* 19 */
return _y /* 20 */
} /* 21 */
// Pseudo-property setter y /* 22 */
public setY(double y) { /* 23 */
_y = y /* 24 */
} /* 25 */
} /* 26 */
類別 Point
有兩個私有屬性 _x
和 _y
,分別代表 x 軸和 y 軸上的位置。我們在第 3 行及第 4 行宣告這兩個屬性。
第 6 行到第 9 行為本類別的建構子。在建構子中,傳入參數 x
和 y
,分別用來設定物件的屬性。我們刻意呼叫兩個屬性的 setters getX
和 getY
,可以確保設定屬性的行為是一致的。
在這個類別中,只有單純的 getters 和 setters,而且 setters 沒有額外的限制。但我們不將屬性直接暴露在外,因為我們以後要修改 setters 的行為時,可確定外部程式是透過這些 setters 來存取屬性。
使用這個類別的外部程式如下:
def p = new Point(0, 0)
assert p.x == 0
assert p.y == 0
p.x = 3
p.y = 4
assert p.x == 3
assert p.y == 4
在外部程式中,我們建立物件 p
,並透過其 getters 和 setters 存取其屬性。在 Groovy 中,以 get
和 set
開頭的 method 會自動轉為 property,和 C# 的 property 有些類似,原本 Java 的物件中沒有這項特性,這是稍微較 magic 的地方。