Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

groovy protected property can't be overriden in subclass

Tags:

groovy

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,[],[]
like image 361
atian25 Avatar asked Feb 23 '23 04:02

atian25


1 Answers

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.

like image 52
ataylor Avatar answered Mar 06 '23 17:03

ataylor