0

If I don't want that a method on my class can be called, I just make it private.

But if I want to allow that method to be overridden, I have to make it protected

Is it possible to have a method on an abstract class that can't be called but can be overridden? (I guess not, but is there any workaround?)

Use case:

abstract class Super {

  protected void finalize() {

  }

  public final void doThings() {
   // do stuff
   finalize();
  }
}

and whoever wanted to extend the class:

class Sub extends Super {

  @Override
  protected void finalize() {
    closeSockets();
    alertSomeone();
  }

}

But I don't want other classes calling mySub.finalize();

6
  • can't be called but can be overridden.... I dont get it, you want to override a method that you can not call??? Commented Aug 22, 2017 at 14:47
  • What would the purpose be for an overridable but not callable function? It kind of defeats the purpose. Maybe you should take a second look at your design. Commented Aug 22, 2017 at 14:47
  • 1
    OP wants a method, that is called inside the class, like a private, but also overridable... I think it is not possible, as if any class can see it to overrid, it can see it to call also... Commented Aug 22, 2017 at 14:50
  • the method would be used in the abstract class in a template pattern. Commented Aug 22, 2017 at 14:53
  • 2
    This whole thing has a bad smell...
    – Herr Derb
    Commented Aug 22, 2017 at 14:59

1 Answer 1

2

Instead of overwriting a method, the sub-class may provide the super-class with a Runnable which contains the code to be executed. You could do something like this:

public class Super {

    private final Runnable subClassCode;

    public Super(Runnable finalizeCode) {
        subClassCode = finalizeCode;
    }

    public final void doThings() {
        // do stuff
        subClassCode.run();
    }

}

public class Sub extends Super {

    public Sub() {
        super(() -> {
            // code to be executed in doThings()
        });
    }

}

You dont need to set the Runnable instance in the constructor. You may also give access to a protected setFinalizeCode(Runnable) method but that method could also be called by other classes within the same package as Super.

Not the answer you're looking for? Browse other questions tagged or ask your own question.