У меня сложилось впечатление, что замыкания выполняются как вызываемый фактический класс (вместо реализующего суперкласса) и, таким образом, прерываются, когда некоторые переменные не видны (например, частные в суперклассе).
Например
package comp.ds.GenericTest2
import groovy.transform.CompileStatic
@CompileStatic
class ClosureScopeC {
private List<String> list = new ArrayList<String>()
private int accessThisPrivateVariable = 0;
void add(String a) {
list.add(a)
println("before ${accessThisPrivateVariable} ${this.class.name}")
// do something with a closure
list.each {String it ->
if (it == a) {
// accessThisPrivateVariable belongs to ClosureScopeC
accessThisPrivateVariable++
}
}
println("after ${accessThisPrivateVariable}")
}
}
// this works fine
a = new ClosureScopeC()
a.add("abc")
a.add("abc")
// child class
class ClosureScopeD extends ClosureScopeC {
void doSomething(String obj) {
this.add(obj)
}
}
b = new ClosureScopeD()
// THIS THROWS groovy.lang.MissingPropertyException: No such property: accessThisPrivateVariable for class: comp.ds.GenericTest2.ClosureScopeD
b.doSomething("abc")
Последняя строка вызывает исключение MissingPropertyException: дочерний класс вызывает метод «добавить» суперкласса, который выполняет закрытие «каждого», использующего «accessThisPrivateVariable».
Я новичок в groovy, поэтому я думаю, что должен быть простой способ сделать это, потому что в противном случае кажется, что замыкания полностью нарушают инкапсуляцию частной реализации, выполненной в суперклассе... это кажется очень распространенной потребностью ( реализация суперкласса, ссылающаяся на свои собственные частные переменные)
Я использую Groovy 2.1.3