- Groovy 教程
- Groovy - 首页
- Groovy - 概述
- Groovy - 环境
- Groovy - 基本语法
- Groovy - 数据类型
- Groovy - 变量
- Groovy - 运算符
- Groovy - 循环
- Groovy - 决策
- Groovy - 方法
- Groovy - 文件 I/O
- Groovy - 可选
- Groovy - 数字
- Groovy - 字符串
- Groovy - 范围
- Groovy - 列表
- Groovy - 映射
- Groovy - 日期和时间
- Groovy - 正则表达式
- Groovy - 异常处理
- Groovy - 面向对象
- Groovy - 泛型
- Groovy - 特性
- Groovy - 闭包
- Groovy - 注解
- Groovy - XML
- Groovy - JMX
- Groovy - JSON
- Groovy - DSL
- Groovy - 数据库
- Groovy - 构建器
- Groovy - 命令行
- Groovy - 单元测试
- Groovy - 模板引擎
- Groovy - 元对象编程
- Groovy 有用资源
- Groovy - 快速指南
- Groovy - 有用资源
- Groovy - 讨论
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