Question

Is there a possibility to have some default behaviour defined for a method in a subclass, without having to call super?

E.g: Suppose we want to set a boolean value in the superclass and you want to hide this from the subclass, is there a way to hide the modification of the boolean value? Suppose that we have the following base class BaseTest

public class BaseTest {
    private boolean mIsInitialized = false;

    public BaseTest() {
    }

    public void initialize() {
        mIsInitialized = true;
    }
}

and its subclass Test:

public class Test extends BaseTest {
    public Test() {
    }

    public void initialize() {
    }
}

I would like for the call to Test.initialize() to set the mIsInitialized value to true without having to call super.initialize(). I would equally like to avoid to define an abstract function in the superclass. Is this even possible?

Was it helpful?

Solution 2

@rgettman et al. are calling for using the Template pattern. Therein you make explicit the fact that subclasses may "hook in" to the superclass's action through specific overridable methods that are not initialize, which seems to go against the spirit of your question.

You can also use an aspect-oriented framework like AspectJ to have all kinds of invisible behaviors attached to method calls.

OTHER TIPS

It is possible to do this, but not by overriding initialize. In the BaseTest class, mark initialize as final so it cannot be overridden. In initialize, call another method to do any subclass initialization.

public final void initialize() {
    mIsInitialized = true;
    initializeFurther();
}

You said no abstract methods. But, initializeFurther can just be made empty.

protected void initializeFurther() {}

Then, the subclass Test just needs to override initializeFurther.

public class Test extends BaseTest {
    @Override
    protected void initializeFurther() {
       // Initialize Test here.
    }
}

The base class's initialize method is guaranteed to set mIsInitialized to true, and Test can implement initializeFurther however it wants, without calling super.initialize(). Test can't stop the superclass BaseTest from doing its initialization.

When initialize is called on any BaseTest instance, the initialize logic will always run.

If you prevent Test from overriding BaseTest's initialize(), you can call BaseTest's initialize() directly. Here's some test code:

public class BaseTest {
   private boolean mIsInitialized = false;

   public BaseTest() {
   }

   public void initialize() {
    mIsInitialized = true;
    System.out.println(mIsInitialized);
   }

   public static void main(String[] args){
    Test test = new Test();
    test.initialize();

   }

}


class Test extends BaseTest {
   public Test() {
   }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top