Turning abstract class without fields to interface (Java, Sonar rule s1610)

Viewed 921

I refer to this rule:

With Java 8's "default method" feature, any abstract class without direct or inherited field should be converted into an interface.

  • In my perception default + private methods in Java8+ interfaces is a pure compromise JDK designers took in order to solve a dilemma they faced: they had to introduce new methods (for ex. Map interface) without breaking old code that used those interfaces (backward compatibility).
  • In practice JDK designers introduced implementation inheritance in places where interface inheritance existed, so potentially they increased coupling and brittleness of our existing and future code.
  • In my perception introduced implementation inheritance now diminishes cool nature of interfaces - the multiple inheritance.
  • I understand why "abstract classes without fields" is mentioned in Sonar rule. By this the authors of the rule do lessen brittleness (but don't eliminate the fact of implementation inheritance). Compare to problems of Scala traits that do permit fields (new Java interfaces look more and more like Scala's traits) - Scala lang designers tried to solve those problems with things like trait linearization, lazy vals, etc.
  • I'm avoiding arguments like "it is in JDK so it is a pattern", let us speak more at the conceptual level here.
  • Question: Could anyone explain me why Sonar promotes this, IMHO, flawed rule? What do we gain by such a rule? What benefit/use case am I missing here?

Thanks.

1 Answers

I don't necessarily agree with the rule, but I see where it's coming from.

The thing is that you don't really lose anything in this case. The only time you'd run into problems with regard to multiple inheritance would be if you implemented several interfaces containing methods with the same signature and different implementations.

However, this is forbidden by Java (you'd need to provide your own implementation of that method), so there is no danger in doing so.

In general, interfaces are more versatile than classes, so it makes sense to use them if possible.

As a counter point, the interface default feature was introduced to allow adding methods to existing interfaces without breaking existing code, but that's not the case here.

Related