Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Provide implementation for abstract method but restrict visibility

I have a method in an abstract class that calls an abstract method, for which the subclasses must provide the implementation.

public abstract class AClass {

    public void foo() {
        ...
        fooToImplement();
        ...
    }

    // DON'T CALL THIS METHOD, ONLY PROVIDE IMPLEMENTATION!
    protected abstract void fooToImplement();

}

I want to make sure that the subclasses don't call fooToImplement(), they should always use foo() instead. The behavior is something like a "private abstract" method, but that's not possible in Java.

Is there some alternative? Thanks!

like image 814
valcazar Avatar asked Mar 13 '23 20:03

valcazar


2 Answers

If you don't want your subclasses to be able to call this method you could use strategy: Extract the behavior of the method into an interface and pass an implementation of this interface to the object. E.g.

IStrategy {
  public void fooToImplement();
} 

AClass {
   public AClass(IStrategy impl) {...}

    public void foo() {
      ...
      strategy.fooToImplement();
      ...
    }
}

Delegation instead of inheritance. In java 8 this would be a little bit easier.

If your implementation of IStrategy would need access to the data of the object AClass, you could try to implement it as an inner class.

like image 109
morpheus05 Avatar answered Mar 18 '23 07:03

morpheus05


The method has to be visible by your subclass if you want it to be overriden. You have to use a class witch does not extends AClass as caller.

public class BClass extends ACLass {
   @Override 
   protected void fooToImplement() {
      System.out.println("override me im famous");
   }
}
public class CClass {
   private BCLass bInstance;
   public void doSomething(){
      bInstance.foo();
      // !!! NO ACCESS TO fooImplement()
   }
}
like image 41
uncleBounty Avatar answered Mar 18 '23 07:03

uncleBounty