Abstract Classes and Interfaces in Kotlin: A Complete Guide

Abstract Classes and Interfaces in Kotlin: A Complete Guide

Kotlin provides two mechanisms for defining a blueprint for classes: abstract classes and interfaces. Both abstract classes and interfaces play important roles in object-oriented programming, but they have different use cases and features.

Though in Kotlin, the difference between them is more blurry because:

  • Interfaces can have method bodies too.

  • Private functions are valid. Remember fields can not be abstract and private.

So, you may think that the abstraction provided by abstract classes and Interfaces are similar. But actually, it's not.

Abstract Classes:

  1. Definition: An abstract class is a class that cannot be instantiated on its own, but can be extended by other classes. Abstract classes can contain both abstract and non-abstract methods.

  2. Properties:

  • An abstract class can have fields and properties, both abstract and with a default implementation.

  • An abstract class can provide a common implementation that can be shared among derived classes.

  1. Use Cases:
  • An abstract class is used when you want to provide a common implementation and share state among related classes.

  • An abstract class is also used when you want to establish an inheritance hierarchy.

Example:

abstract class Shape {
    abstract val name: String
    abstract fun area(): Double
}

class Rectangle(width: Double, height: Double) : Shape() {
    override val name: String = "Rectangle"
    private val w: Double = width
    private val h: Double = height
    override fun area(): Double = w * h
}

class Circle(radius: Double) : Shape() {
    override val name: String = "Circle"
    private val r: Double = radius
    override fun area(): Double = 3.14 * r * r
}

Interfaces:

  1. Definition: An interface is a contract for a class that defines a set of abstract methods and properties. Interfaces can also contain default implementations for methods.

  2. Properties:

  • An interface can only contain abstract methods and properties, but it also supports "default implementations" for non-abstract methods.

  • An interface defines a common contract that multiple(un-related) classes can implement.

  1. Use Cases:
  • An interface is used when you want to define a common contract that multiple, potentially unrelated classes can implement.

  • An interface is also used when you want to provide a default implementation for some methods.

Example:

interface Animal {
    val name: String
    fun makeSound()
    fun sleep() {
        println("${name} is sleeping")
    }
}

class Dog : Animal {
    override val name: String = "Dog"
    override fun makeSound() {
        println("${name} barks")
    }
}

class Cat : Animal {
    override val name: String = "Cat"
    override fun makeSound() {
        println("${name} meows")
    }
}

What is the Difference?

  1. The main distinction between them lies in their intended Purpose and semantic meaning.

    • Abstract classes are used to provide a Generalization of Behavior that can be inherited by subclasses. By using an abstract class, you can ensure that all subclasses share a common structure, promoting consistency and reducing the amount of duplicate code.

      Example: Generalize the functions/fields that many types can have. Like for our Shape class. We can create it as an abstract class and generalize the behavior of a shape. Like height, breadth, area, etc. and then create particular subclasses extending that general Shape's functions and fields.(In the first code snippet) Here, we created general information that only Shapes can have.

    • Interfaces are used for the Standardization of the behavior of classes. By using interfaces, you can define a common contract that all implementing classes must follow, promoting consistency and interoperability between different parts of your code.

      Example: Creating a PLay Interface(with play() function). Here play can be anything, playing music(Music class implements PLay), playing video games(Video game class implements PLay), playing animation(Animation class implements PLay), playing outdoors(Anyy class implements PLay), etc. So things are more standardized now. Things are not general, we can play literally anything. Just implement the contract and play the Implementation provided by kotlin Interfaces or customize it for your use.

Hope, this will clear most of your doubts.

  1. Use abstract classes when you want to provide a base implementation for subclasses to build upon, and use interfaces when you want to specify a behavior that multiple classes can implement. There can be other cases too.

  2. Why Method bodies:

    In Abstract classes: Show the general behavior of the function. Like, what is the task of the function that we will expect if we are not gonna override the specific function.

    Example: We can write a print() function in our Shape abstract class and the body will just say print("Shape is printing.."). So, in the case when we are not overriding this function, then still we can use this function and print a general thing, that we can use for all our subclasses.

    In Interfaces: To provide the default output, so that our code will compile when we forgot to implement the function.
    If this thing is still confusing just remember the purpose of why we are here using the Interface.

This is a very famous Interview question also, so if I was asked to define their difference in one line, then I can say:

  1. Use abstract classes to define the TYPE and Interfaces for BEHAVIOR.

  2. Abstract classes are used to define the General purpose of things while Interface ensures to target more Standard things.

Also, give clear examples and use cases.

You can also be trapped with twisted questions like, Interfaces have method bodies, private methods, then how they distinguish! See, all these are subtle differences but the main choosing factor is YOUR use case. Either you are defining a Type or a Standard behavior.

I hope you found this helpful. If yes, then do FOLLOW me for more Android-related content.

#androidWithSagar #android #androiddevelopment #androiddev