元对象编程(Meta Object Programming)
元对象编程或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"
}
}
以下代码的输出如下所示。 请注意,即使方法显示不存在,也没有错过方法异常的错误。
Joe
1
元类(Metaclass)
此功能与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