Groovy 元對象編程

2023-01-31 10:29 更新

元對象編程或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 
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)