atian25
atian25

Reputation: 4256

groovy protected property can't be overriden in subclass

subclass call parent protected method which expect return a protected override property. but return the parent's property.

//ParentClass:

package tz

import java.util.List;

class AbstractController {
    protected List keywordFilter = []
    protected String methodKey(){
        return "\t[method]parent,$keywordFilter,"+keywordFilter.toString()
    }
    def closureKey(){
        return "\t[closure]parent,$keywordFilter,"+keywordFilter.toString()
    }
}

//SubClass:

package tz

import java.util.List;

class SubController extends AbstractController{
    protected List keywordFilter = ['a']
    public SubController(){
    }

    public void test(){
        println "subCall:"+methodKey()+closureKey()
    }
    def test2 = {
        println "c,$keywordFilter,"+methodKey()+closureKey()
    }

    public static void main(String[] args) {
        def s = new SubController()
        s.test()
        s.test2()
    }
}

//Output:

subCall:[method]parent,[],[]    [closure]parent,[],[]
c,[a],  [method]parent,[],[]    [closure]parent,[],[]

Upvotes: 4

Views: 2284

Answers (1)

ataylor
ataylor

Reputation: 66069

In Java and Groovy, fields are not overriden in subclasses. The base class version is just hidden by the subclass version. You actually get two fields in the class, with the same name. The base class methods will see the base class field and subclass methods will see the subclass field.

The solution is usually to just wrap the field in a getter method. In groovy:

class AbstractController {
    protected List getKeywordFilter() { [] }
    ...
}
class SubController extends AbstractController {
    protected List getKeywordFilter() { ['a'] }
    ...
}

Following the groovy property conventions, you can still reference it as "$keywordFilter" which will automatically call the getter.

Upvotes: 8

Related Questions