3

I have an interface whose implementors all require a common method internally - it is not required to be part of the public interface. Also, there are future interfaces in the pipeline that will need this functionality.

Is it good design to have this interface implement a different interface that just has this default method implemented? This way all implementors have access to the common method seamlessly. But, since there is no concept of 'private default' methods, the method is also exposed to clients, which I feel isn't right.

Is resorting to a separate concrete utils class a better means to this end? Or creating an abstract implementation of my interface with the required method and have clients extend that?

EDIT: My question is more inclined towards finding out whether an interface with only default methods is sound, design-wise? Having static methods in the interface does not seem to be in contention actually.

user3381995
  • 53
  • 1
  • 4
  • 1
    Possible duplicate of [Java 8: Interface with static methods instead of static util class](http://stackoverflow.com/questions/25098937/java-8-interface-with-static-methods-instead-of-static-util-class) – Didier L Dec 11 '15 at 12:18
  • 1
    Your feeling that this isn't right, is right. This is an abuse of what interfaces are for -- much like the "constant interface antipattern." Interfaces are for defining types. If there isn't a sensible type that you're defining, then it probably shouldn't be a interface. – Brian Goetz Dec 12 '15 at 15:59

2 Answers2

1

interface is used to segregate the users and the implementors. In your situation, i think an abstract class is more suitable.

Lamy Lau
  • 11
  • 1
  • I'd add that you may want to pull the implementation of the abstract superclass into a separate utility class if the other interfaces in the pipeline can't inherit from the same one. That is, if classes A1, A2 and A3 implement AbstractA and classes B1, B2 and B3 implement AbstractB, then since you need the internal method in both AbstractA and AbstractB, you'll have to pull it into a separate class to avoid duplication. – aro_tech Dec 11 '15 at 09:04
1

default methods are overridable methods, but your scenario describes a utility method that is intended to be neither, part of the API nor overridable. Note that since default methods can work on the instance only in terms of the public methods defined in the interface, i.e. can not access any internals, there is no difference between:

interface MyInterface {
    default ReturnType method(Parameter parameter) {
    }
}

and

interface MyInterface {
    static ReturnType method(MyInterface instance, Parameter parameter) {
    }
}

regarding what the method can do. It’s only that within the default method, you may omit the qualifying this. when invoking other interface method, whereas in the static method, using instance. is mandatory. But in either case, you may invoke all public methods of the MyInterface instance but nothing else.

But the static method is not overridable and you may move it to any other class to avoid it becoming part of MyInterface’s API. But note that there is little reason to worry about the accessibility of the utility method. Since it can’t access any internals of the implementation classes, it can’t offer anything that the callers couldn’t do otherwise. It only makes it more comfortable than re‑implementing the functionality at the caller’s site. So moving the method into another class primarily documents the intention of not being part of the MyInterface’s API. It’s no harm, if the method is public there (to support implementations in arbitrary packages).

See for example the methods in the class StreamSupport. They are there to aid implementing Streams, needed by different packages, but not part of the Stream interface API itself. The fact that the methods there are public does not create any harm, they don’t offer anything you couldn’t do yourself using the other available public APIs. But it’s convenient for implementors not needing to do it themselves.

Holger
  • 285,553
  • 42
  • 434
  • 765
  • Ok, so what I gather from your response is that it seems ok to have it as a default method in the interface or have it exposed via a separate concrete utils class - accessibility does not seem to be much of concern here as it seems to be harmless in the given context. If so, I'm leaning toward having a default method in an interface, as the common functionality in question requires the instance of the caller and keeping it in the interface aligns seamlessly with this requirement. I don't have to end up passing the instance as an argument to the static method of a separate class. – user3381995 Dec 11 '15 at 12:14
  • 1
    Don’t forget that `default` methods are overridable, that’s the biggest distraction for the API user, besides that, it’s only about whether you want the method to show up in the list of `interface` methods or not. – Holger Dec 11 '15 at 13:05