元對象編程或MOP可以用于動(dòng)態(tài)調(diào)用方法,并且可以即時(shí)創(chuàng)建類和方法。
那么這是什么意思呢?讓我們考慮一個(gè)叫Student的類,它是一個(gè)沒有成員變量或方法的空類。假設(shè)你必須在這個(gè)類上調(diào)用以下語句。
def myStudent = new Student() myStudent.Name = ”Joe”; myStudent.Display()
現(xiàn)在在元對象編程中,即使類沒有成員變量Name或方法Display(),上面的代碼仍然可以工作。
這如何工作?那么,為了這個(gè)工作,一個(gè)人必須實(shí)現(xiàn)GroovyInterceptable接口掛鉤到Groovy的執(zhí)行過程。以下是該接口的可用方法。
Public interface GroovyInterceptable { Public object invokeMethod(String methodName, Object args) Public object getproperty(String propertyName) Public object setProperty(String propertyName, Object newValue) Public MetaClass getMetaClass() Public void setMetaClass(MetaClass metaClass) }
所以在上面的接口描述中,假設(shè)你必須實(shí)現(xiàn)invokeMethod(),它會(huì)被調(diào)用的每個(gè)方法,要么存在或不存在。
所以,讓我們看一個(gè)例子,我們?nèi)绾螢槿笔У膶傩詫?shí)現(xiàn)元對象編程。以下鍵應(yīng)該注意以下代碼。
類Student沒有定義名為Name或ID的成員變量。
類Student實(shí)現(xiàn)GroovyInterceptable接口。
有一個(gè)稱為dynamicProps的參數(shù),將用于保存即時(shí)創(chuàng)建的成員變量的值。
方法getproperty和setproperty已被實(shí)現(xiàn)以在運(yùn)行時(shí)獲取和設(shè)置類的屬性的值。
class Example { static void main(String[] args) { Student mst = new Student(); mst.Name = "Joe"; mst.ID = 1; println(mst.Name); println(mst.ID); } } class Student implements GroovyInterceptable { protected dynamicProps=[:] void setProperty(String pName,val) { dynamicProps[pName] = val } def getProperty(String pName) { dynamicProps[pName] } }
以下代碼的輸出將是 -
Joe 1
所以,讓我們看一個(gè)例子,我們?nèi)绾螢槿笔У膶傩詫?shí)現(xiàn)元對象編程。以下鍵應(yīng)該注意下面的代碼 -
類學(xué)生現(xiàn)在實(shí)現(xiàn)invokeMethod方法,它被調(diào)用,而不管該方法是否存在。
class Example { static void main(String[] args) { Student mst = new Student(); mst.Name = "Joe"; mst.ID = 1; println(mst.Name); println(mst.ID); mst.AddMarks(); } } class Student implements GroovyInterceptable { protected dynamicProps = [:] void setProperty(String pName, val) { dynamicProps[pName] = val } def getProperty(String pName) { dynamicProps[pName] } def invokeMethod(String name, Object args) { return "called invokeMethod $name $args" } }
以下代碼的輸出如下所示。請注意,即使方法Display不存在,也沒有缺少方法異常的錯(cuò)誤。
Joe 1
此功能與MetaClass實(shí)現(xiàn)相關(guān)。在默認(rèn)實(shí)現(xiàn)中,您可以訪問字段而不調(diào)用它們的getter和setter。以下示例顯示如何通過使用metaClass函數(shù),我們能夠更改類中的私有變量的值。
class Example { static void main(String[] args) { Student mst = new Student(); println mst.getName() mst.metaClass.setAttribute(mst, 'name', 'Mark') println mst.getName() } } class Student { private String name = "Joe"; public String getName() { return this.name; } }
以下代碼的輸出將是 -
Joe Mark
Groovy支持methodMissing的概念。此方法與invokeMethod的不同之處在于,它僅在失敗的方法分派的情況下被調(diào)用,當(dāng)沒有找到給定名稱和/或給定參數(shù)的方法時(shí)。以下示例顯示如何使用methodMissing。
class Example { static void main(String[] args) { Student mst = new Student(); mst.Name = "Joe"; mst.ID = 1; println(mst.Name); println(mst.ID); mst.AddMarks(); } } class Student implements GroovyInterceptable { protected dynamicProps = [:] void setProperty(String pName, val) { dynamicProps[pName] = val } def getProperty(String pName) { dynamicProps[pName] } def methodMissing(String name, def args) { println "Missing method" } }
以下代碼的輸出將是 -
Joe 1 Missing method
更多建議: