0

Occasionally, I want to write an interface that provides some complex method, and I want to make that a default method that uses some protected helper methods.

The objective is such that I can later on change the logic in the complex method and have the changes apply to all implementations of the interface, some of which may not be mine.

But there's no such thing as protected interface methods in Java, so the code I end up writing looks like this:

public interface SomeInterface {
    /** Don't override this, override a() and b() instead */
    /* final */ default void doSomething() {
        // complex code involving a() and b()
    }

    /** Don't call this directly, use doSomething() instead */
    /* protected */ void a();

    /** Don't call this directly, use doSomething() instead */
    /* protected */ void b();
}

I also can't use an abstract class since Java doesn't support multiple inheritance. Is there any workaround to this problem?

  • What you are trying to do here leads to the classic anti-pattern of the fragile base class problem. Avoid the idea of doSomething being tied to abstract protected methods as you weaken encapsulation (you make the internal workings of doSomething part of its public specification and you couple that base class to all future sub classes. And trying to achieve this with comments in an interface just makes things worse. I'm not sure what Java's equivalent of C#'s Action is, but you can easily achieve what you want with the interface defining void doSomething(Action a, Action b) – David Arno Jun 11 at 9:44
0

An abstract class and template pattern should be used to do this.

You mentioned that there will be a multiple-inheritance problem in your design. But is there anything stopping you follow the principle, "Inherit the most important class and delegate the rest" to solve this? Just delegate the task to another abstract class that does things you mentioned in "SomeInterface" and use it. Then the problem should be solved.

1

I think the problem is your outlook on component-based design, not the lack of a design pattern to support this outlook.

The purpose of a Java interface is to define the programmer's interface to the components that implement it. The user of your object will only have access to public members of the object, so making something non-public in an interface runs contrary to what the interface is intended to be used for.

You shouldn't need or even want to force class-specific decisions from the interface. When you're designing an interface you shouldn't be considering implementation details at all. Those decisions belong in the implementing classes, and different classes may then implement the same interface differently. This is also why you don't specify fields in an interface: that's an implementation detail.

Defining how to use the component is the job of the interface. How to implement the component is up to the concrete class.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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