Groovy - 元物件程式設計



元物件程式設計或 MOP 可用於動態呼叫方法,以及動態建立類和方法。

那麼這意味著什麼呢?讓我們考慮一個名為 Student 的類,它是一個沒有任何成員變數或方法的空類。假設您必須對這個類呼叫以下語句。

Def myStudent = new Student() 
myStudent.Name = ”Joe”; 
myStudent.Display()

現在在元物件程式設計中,即使該類沒有 Name 成員變數或 Display() 方法,上述程式碼仍然可以工作。

這怎麼可能呢?為了實現這一點,必須實現 GroovyInterceptable 介面以掛接到 Groovy 的執行過程中。以下是此介面提供的方法。

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) 
}

因此,在上述介面描述中,假設您必須實現 invokeMethod(),它將被呼叫用於每個存在或不存在的方法。

缺少屬性

那麼讓我們來看一個如何為缺少的屬性實現元物件程式設計的示例。以下程式碼需要注意以下關鍵事項。

  • Student 類沒有定義名為 Name 或 ID 的成員變數。

  • Student 類實現了 GroovyInterceptable 介面。

  • 有一個名為 dynamicProps 的引數,它將用於儲存動態建立的成員變數的值。

  • 已實現 getproperty 和 setproperty 方法以在執行時獲取和設定類屬性的值。

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

缺少方法

那麼讓我們來看一個如何為缺少的屬性實現元物件程式設計的示例。以下程式碼需要注意以下關鍵事項:

  • Student 類現在實現了 invokeMethod 方法,無論方法是否存在都會呼叫該方法。

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 方法不存在,也沒有缺少方法異常錯誤。

Joe 
1 

元類

此功能與 MetaClass 實現相關。在預設實現中,您可以訪問欄位而無需呼叫它們的 getter 和 setter。以下示例展示瞭如何透過使用 metaClass 函式來更改類中私有變數的值。

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 的區別在於,它僅在方法排程失敗時呼叫,即當找不到給定名稱和/或給定引數的方法時。以下示例展示瞭如何使用 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 
廣告

© . All rights reserved.