3

Is there a way to make Java interfaces only implementable by classes of a special type?

So for instance, I have a class Foo and an interface Bar. Only subclasses of Foo should be able to implement Bar. Is this possible?

(This would be useful if subclasses of Foo are the only classes that need to implement Bar. Other classes that don't really need to implement it simply can't.)

Before you ask, I can't edit Foo to add the methods there, it's binary.

5
  • 6
    Please read What is the X Y problem? Commented Apr 19, 2016 at 17:23
  • 1
    So just to clarify, you're saying that only subclasses of Bar should implement Foo, but Bar itself does not implement it (and you don't have access to change it)?
    – Mage Xy
    Commented Apr 19, 2016 at 17:24
  • 4
    It's breaks whole concept of OOP. In this case interface should know inheritors of Foo and Foo should be abstract.
    – Sergey
    Commented Apr 19, 2016 at 17:26
  • 6
    What is the problem you're solving? There likely is a better approach to it.
    – 9000
    Commented Apr 19, 2016 at 17:29
  • I do not see how that would ever be useful. What happens when later you need to add a different implementation (Or you want to create a stub for unit testing)? You would be adding constraints to your code base for no reason.
    – Caleb
    Commented Apr 19, 2016 at 18:55

1 Answer 1

2

No, this is not possible.

There are two ways to restrict inheritance:

  • The final keyword makes a class impossible to extend. This modifier is forbidden on interfaces, and you want to inherit from it anyway.

  • Package-private visibility means only classes in the same package can inherit from the interface, but the interface itself is not accessible outside the package which makes the interface useless. I.e., you cannot hold an object of any of those subtypes in a variable of type Bar. This makes dynamic dispatch (polymorphism) impossible.

You can insert a new AbstractFooBar that looks like this:

public abstract class AbstractFooBar extends Foo implements Bar {
  // Add delegating constructors here
}

Foo only has binaries available. You cannot add Bar as an interface it implements; nor can you require its subclasses to implement Bar; nor can you restrict Bar so non-Foo-derived classes cannot inherit from it. This is the closest you can get. If nothing else, this is merely a convenience that imposes no restrictions on the use of Bar.


While this technically answers your question, you may want to take a step back and reconsider exactly what you are trying to accomplish.

Normally when I see a requirement for restricting a type hierarchy in this way it is due to trying to shoehorn inheritance where composition is more appropriate. Both techniques have their places, and it is best not to try to use one where the other is a better fit.

1
  • +1. Interfaces are the way to do OOP in Java (not classes, as is sometimes erroneously taught). One of the fundamental principles of OOP is that, if an object responds in a specific way to a certain protocol (which in Java is expressed as being an instance of an interface), it should be indistinguishable from a different object which responds the same way to the same protocol, regardless of its class. IOW: class doesn't and shouldn't matter. Classes are simply for code re-use, not for typing. Interfaces are for typing. Commented Apr 21, 2016 at 8:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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