Результат замены / переопределения беспараметрического метода, не переданного в конструктор
Я пытаюсь изменить поведение конструктора класса groovy, заменив метод в этом классе, который используется для установки свойства, но свойства не устанавливаются с ожидаемыми значениями.
class TestClass {
def noParam
def withParam
TestClass() {
noParam = noParam()
withParam = withParam('second test')
}
def noParam() {
return 'first test'
}
def withParam(param) {
return param
}
}
TestClass.metaClass.withParam = { param -> 'pass' }
TestClass.metaClass.noParam = {-> 'pass' }
def test = new TestClass()
assert test.withParam('dummy') == 'pass' //passes
assert test.withParam == 'pass' // fails
assert test.noParam() == 'pass' // passes
assert test.noParam == 'pass' // fails
1 ответ
Groovy не использует переопределения метакласса в конструкторе TestClass, когда выполняет noParam
а также withParam
методы. На самом деле, если вы введете параметр в вашем withParam
Метод 2-го утверждения также не удастся.
class TestClass {
def noParam
def withParam
TestClass() {
noParam = noParam()
withParam = withParam('second test')
println "in the constructor: noParam = $noParam, withParam = $withParam"
}
def noParam() {
return 'first test'
}
def withParam(String param) {
return param
}
}
TestClass.metaClass.withParam = { String param -> 'pass' }
TestClass.metaClass.noParam = {-> 'pass' }
def test = new TestClass()
assert test.withParam('dummy') == 'pass'
assert test.withParam == 'pass' // this fails now too!
assert test.noParam() == 'pass'
assert test.noParam == 'pass' // this fails
Вот вывод: in the constructor: noParam = first test, withParam = second test
test.withParam
а также test.noParam
на самом деле звонят test.getWithParam()
а также test.getNoParam()
- они возвращают значения свойств, установленные в конструкторе.
test.withParam('dummy')
а также test.noParam()
Вызываете ваш метод метакласса и возвращаете "pass".
Что касается того, почему groovy не использует метод метакласса в вашем конструкторе, я не уверен... Я не смог найти ничего в документации метакласса...
Может быть, вы могли бы использовать вместо этого статические методы?
class TestClass {
def noParam
def withParam
TestClass() {
noParam = TestClass.noParam()
withParam = TestClass.withParam('second test')
println "in the constructor: noParam = $noParam, withParam = $withParam"
}
static def noParam() {
return 'first test'
}
static def withParam(String param) {
return param
}
}
TestClass.metaClass.'static'.withParam = { String param -> 'pass' }
TestClass.metaClass.'static'.noParam = {-> 'pass' }
def test = new TestClass()
assert test.withParam('dummy') == 'pass'
assert test.withParam == 'pass' // passes!
assert test.noParam() == 'pass'
assert test.noParam == 'pass' // passes!
Вот вывод: in the constructor: noParam = pass, withParam = pass