Why is this an issue?

If an abstract class does not contain properties nor actual function implementations but only abstract functions, it should be replaced with an interface. This is a good practice because an interface provides more flexibility, while an abstract class does not offer any benefit in this situation.

What is the potential impact?

Flexibility of the design

Abstract classes are limited in their inheritability compared to interfaces, while they do not offer any benefit in this situation. A class can only extend one class but can implement many interfaces. When APIs are represented by abstract classes instead of interfaces, the implementing class must have the abstract class as its one (and only) parent class. Also, it cannot implement more than one API at once.

How to fix it

Either replace the class declaration with an interface declaration, or add actual function implementations or state properties to the abstract class.

Code examples

Noncompliant code example

abstract class Shape { // Noncompliant, abstract class only contains abstract functions
    abstract fun getPath(): Path
    abstract fun getArea(): Double
    abstract fun getBoundingBox(): Rectangle
}

Compliant solution

interface Shape { // Compliant, we are using an interface here
    fun getPath(): Path
    fun getArea(): Double
    fun getBoundingBox(): Rectangle
}

// or

abstract class Shape { // Compliant, abstract class has function implementations
    abstract fun getPath(): Path
    abstract fun getArea(): Double
    fun getBoundingBox(): Rectangle {
        // ...
    }
}

Resources

Documentation

Articles & blog posts