How to make interfaces usable for special classes only?

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.


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.


Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *