Мета-объектное программирование или 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 не определена переменная-член с именем или идентификатором.
-
Класс Student реализует интерфейс GroovyInterceptable.
-
Существует параметр с именем dynamicProps, который будет использоваться для хранения значений переменных-членов, которые создаются на лету.
-
Методы getproperty и setproperty были реализованы для получения и установки значений свойств класса во время выполнения.
В классе Student не определена переменная-член с именем или идентификатором.
Класс 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, который вызывается независимо от того, существует метод или нет.
Класс 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. В реализации по умолчанию вы можете получить доступ к полям, не вызывая их методы получения и установки. В следующем примере показано, как с помощью функции 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 поддерживает концепцию метода Missing. Этот метод отличается от 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" } }
Вывод следующего кода будет: