Designed by katemangostar / Freepik

“What is the difference between abstract class and interface?” — this is one of the most popular questions during programmer recruiting process. Popular answers are:

An interface cannot hold state

Classes can have actual functions

We can implement multiple interfaces and only one class

I will show that those answers are not really true. Interfaces can have properties and can hold state, but not using fields. They can have functions with actual bodies, as long as they are not final. True significant differences between abstract classes and interfaces are:

Interfaces cannot have fields

We can extend only one class, and implement multiple interfaces

Classes have constructors

So, let’s talk about myths:

Interfaces can have functions

In Kotlin interfaces can have functions with default bodies:

In these bodies, we can use the reference to the class using this :

Those functions cannot be final and they can always be overridden. This is a difference between interface and abstract class where we can make function final. When we override those functions, we can still use default body using super :

Interfaces can have properties

Property in Kotlin represents an abstraction of getter ( val ) or getter and setter ( var ). By default, they have fields used under the hood. This is why this class:

Compiles to the code similar to this one:

Although properties do not need to have field under the hood. For instance, in the following code fullName is just a getter calculated every time on demand:

Properties are just accessors (getters and setters), and so they can be present on interfaces as long as they do not have any actual values:

Those properties can have default bodies as well:

Interfaces formally can have state

It is a bit of a hacking and generally a bad practice, but I just want to show that it is possible to hold state in an interface. We just need to use default bodies to store it. Where can we store it? There are some options and none of them is good. They will all be badly managed and not cleaned properly by the garbage collector. Choosing lesser evil, I decided to store it in a companion object property:

Notice that this way to store in memory is different than when we use fields:

It is not properly managed by Garbage Collector

Properties are associated with equal classes, not with the same classes (this could be improved if we would use reference)

This solution is counterintuitive and should not be used in the real project unless you know really well what you do and what are the consequences! Although it is good to know that it is possible, and it shows us that interfaces can hold state. It doesn’t mean that you should correct when someone says that they cannot. It is hard and unintuitive to make them hold state properly, so colloquially we say that they cannot. Let’s keep it this way ;)

Differences

Abstract classes can have everything that interfaces can, and additionally, they can have fields and constructors. Therefore we can properly hold state in abstract classes:

Functions and properties with default bodies not only can be final but also they are final by default. We can also have a constructor and so pass values to this abstract class:

When we have a primary constructor, we can have init blocks:

On the other side, when we use them, we can implement multiple interfaces and extend only a single class. We always have to call a constructor of the superclass.

This is an important advantage of interfaces over classes. In this article, I showed how it can be used in the pattern called traits or mixins: