3

クロージャーは (スーパークラスを実装するのではなく) 呼び出される実際のクラスとして実行されるため、一部の変数が表示されない場合 (スーパークラスのプライベートなど) に中断するという印象があります。

例えば

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」を使用する「each」クロージャを実行するスーパー クラスの「add」メソッドを呼び出します。

私は groovy を初めて使用するので、これを行う簡単な方法が必要だと思います。そうしないと、クロージャーがスーパークラスで行われたプライベート実装のカプセル化を完全に破るように見えるためです...これは非常に一般的なニーズのようです (独自のプライベート変数を参照するスーパークラスの実装)

Groovy 2.1.3を使用しています

4

1 に答える 1