程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Groovy >> Groovy探索之MOP 二 對類屬性的各種操作

Groovy探索之MOP 二 對類屬性的各種操作

編輯:Groovy

我們談到MOP,即“元對象協議”,就是對類或對象的各個元素,如名稱、方法、屬性等等,在運行期進行實時變化,如修改方法名、屬性名,動態增加方法、屬性等等的一類編程的統稱。

比如前面我們所談到過的“invokeMethod”和“methodMissing”兩個方法,就可以用來使得我們在運行期動態的給一個類增加方法,值得注意的是,這種增加是類級別的,即一個類所有的對象都可以增加方法。

既然說過了在運行期給一個類動態的增加方法,那麼相應的,在運行期給一個類動態的增加屬性就是我們接著要考慮的事情。

我們都知道,在Java語言中,對屬性的操作是通過屬性對應的“get”和“set”方法進行的;而在Groovy語言中,對屬性的操作則是通過Gpath進行的,這使得我們對於GroovyBean類的編程來說,不管是編寫GroovyBean類,還是訪問GroovyBean對象的屬性,都比Java語言的JavaBean來的簡單得多。

比如我們有如下的一個GroovyBean:

class Employee
{
String id

String name
}

我們現在將它初始化:

def empl1 = new Employee(id:'00001',name:'Tom')

現在我們就可以通過Gpath來訪問它的屬性了:

println empl1.name

當然,所謂Gpath訪問,即通過“.”操作符訪問,如“empl1.name”並不是直接訪問“empl1”對象的“name”屬性,而是通過“Employee”類隱含實現了的“get”和“set”方法來訪問的。明白了這個道理,我們就可以自由的給GroovyBean類或者對象添加屬性了。請先看下面的例子:

class Employee
{
String id

String name

def getAge()
{
'everyone is 24'
}
}

可以看到,我們並沒有給“Employee”類定義“age”屬性,但是我們實現了“getAge”方法,我們就可以通過Gpath來訪問“age”屬性,請看下面的代碼示例:

def empl1 = new Employee(id:'00001',name:'Tom')


println empl1.name

println empl1.age

運行結果為:

Tom

everyone is 24

當然了,我們談到了是MOP,就是要能夠在運行期改變對象屬性的方法,這當然也可以水到渠成了。請看下面的例子。

我們先將上面的“getAge”方法從“Employee”類中注銷掉:

class Employee
{
String id

String name

//  def getAge()
//  {
//     'everyone is 24'
//  }
}

然後,我們在運行期來增加“age”屬性,如下:

Employee.metaClass."getAge" = {->
"everyone is 24"
}

def empl2 = new Employee(id:'00002',name:'Mike')

println empl2.age

可以看到,我們只要給“Employee”類的“metaClass”對象增加一個“get”方法,就可以為“Employee”類增加一個屬性。上面代碼的運行結果如下:

everyone is 24

關於“metaClass”對象,在本系列的後面會有更加詳細的說明,本節就到此為止。到上面為止,我們已經談到了給一個類動態的增加屬性,想到增加屬性,馬上有會想到增加方法,在前面的部分,我們已經知道了兩個動態增加方法的方法,即“invokeMethod”和“methodMissing”方法。這兩個方法的好處是可以批量的增加一個類的方法,而不是像上面動態增加屬性那樣,一次只能增加一個。

那麼,在Groovy語言中,有沒有能夠批量增加屬性的方法呢?我們可以回答,當然有。與增加方法“invokeMethod”對應的增加屬性有兩個方法,即“getProperty”和“setProperty”。下面我們就來看看它們是如何增加類的屬性的。

class Employee
{
String id

String name

def getProperty(String property)
{
"get value from ${property}"
}

}

下面來測試該方法:

def empl3 = new Employee(id:'00003',name:'Rose')

println empl3.name

println empl3.age

運行結果為:

get value from name

get value from age

可以看到,“getProperty”方法分派了所有的“get”方法。上面的例子可能相當的沒有實用價值,下面給出一個有一點點實用價值的例子。

比如,我們有一個GroovyBean類,事先我們不能夠知道它會有多少個屬性,一切在運行期內才有答案。我們就可以做如下的一個GroovyBean類:

class Score {

def private map

def Score()
{
this.map = [:]
}

def getProperty(String property)
{
def value = map."$property"

value = value?value:''

return value
}

void setProperty(String property,Object value)
{
map."$property" = value
}


}

我們來測試上面的例子:

def score = new Score()

score.id = '01'

score.name = 'Chinese'

score.score = '100'

println "$score.name : $score.score"

運行結果為:

Chinese : 100

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved