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.
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.
Either replace the class declaration with an interface declaration, or add actual function implementations or state properties to the abstract class.
abstract class Shape { // Noncompliant, abstract class only contains abstract functions
abstract fun getPath(): Path
abstract fun getArea(): Double
abstract fun getBoundingBox(): Rectangle
}
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 {
// ...
}
}