Suggestion: final in interfaces for default implementation

I do not understand why final modifier is forbidden in interfaces provided there is default implementation

Consider example:

interface SquareAreaAbstraction {
   var width: Double
   var height: Double
   final val area: Double get() = width * height 
}

I do not want there was a way to change the logic the area is calculated in any implementation, but using final modifier in interfaces is forbidden:

image

Why not to allow this?

I suspect the reason is that you can’t do that in Java.

You can however provide an extension method on the interface if you want to make clear that is not to be overridden.

Maybe this is just me, but it feels wrong.

The whole point of having interfaces in addition to abstract classes is that interfaces are “lightweight”. Interfaces don’t hold any behavioral burden as abstract classes do. They are just a set of methods, so they are easier for multi-inheritance. They are more flexible, because they give full control to their implementations.

You can argue that final default methods does not change this, but what if I would like to log usages of area in my implementation? What about delegation? What about Proxy? What if I would like to create a RPC based on such an interface? Should we just assume that this method does not exists for such cases? Then I think it is not really a part of this interface and we should use extension function instead.

Note that default methods themselves don’t affect cases like above. We can still delegate them, use Proxy or add some logging as normal.

Having said that, I’m open to discussion. I may be biased towards existing solutions.

I assume the reason is ‘because that’s how it is in Java’. But then the question becomes: “why is it like that in Java?”. Java Architect Brian Goetz elaborates on StackOverflow.

2 Likes