Abstract Classes vs Interfaces in Kotlin: Understanding the Key Differences and When to Use Them

Abstract Classes vs Interfaces in Simple Terms

In Kotlin, abstract classes and interfaces are tools used to define shared behaviors for multiple classes. While they have similarities, they serve slightly different purposes and are used in different scenarios.


1. What is an Abstract Class?

  • An abstract class is like a blueprint. It can have both:
    • Abstract methods: These are methods without a body (no implementation) that subclasses must implement.
    • Concrete methods: These are methods with a body (already implemented) that can be inherited by subclasses.

Key Points:

  • You cannot instantiate an abstract class (you can’t create objects from it directly).
  • An abstract class can have:
    • Properties (with or without values).
    • Methods (abstract or implemented).
    • Constructors.
  • Use abstract keyword for both the class and its methods.

Example:

abstract class Animal(val name: String) {
abstract fun makeSound() // Abstract method
fun eat() { // Concrete method
println("$name is eating")
}
}

class Dog(name: String) : Animal(name) {
override fun makeSound() {
println("$name says Woof!")
}
}

fun main() {
val dog = Dog("Buddy")
dog.makeSound() // Output: Buddy says Woof!
dog.eat() // Output: Buddy is eating
}

2. What is an Interface?

  • An interface is a collection of methods (and properties) that a class can implement. It defines what a class must do but not how it does it.
  • Starting from Kotlin 1.2, interfaces can also have default implementations for methods, but they cannot store state (i.e., no fields with values).

Key Points:

  • A class can implement multiple interfaces (but can inherit only one abstract class).
  • Interfaces do not have constructors.

Example:

interface Flyable {
fun fly() // Abstract method
fun takeOff() { // Default implementation
println("Taking off!")
}
}

class Bird : Flyable {
override fun fly() {
println("The bird is flying")
}
}

fun main() {
val bird = Bird()
bird.takeOff() // Output: Taking off!
bird.fly() // Output: The bird is flying
}

Key Differences:

FeatureAbstract ClassInterface
PurposeTo share code and structure between related classes.To define a contract for unrelated classes.
Multiple InheritanceA class can inherit only one abstract class.A class can implement multiple interfaces.
StateCan have state (fields with values).Cannot have state (fields must be abstract).
ConstructorsCan have constructors.Cannot have constructors.
MethodsCan have both abstract and concrete methods.Can have abstract methods and default methods.
PropertiesCan have concrete properties (with values).Properties are abstract by default (no backing field).

When to Use Abstract Classes

  1. Use an abstract class when:
    • You want to share code and state among related classes.
    • You need a base class with a constructor.
    • Your classes are tightly related (e.g., Animal -> Dog, Cat).
  2. Abstract classes are suitable for hierarchies where you want a base class to enforce structure but also provide some functionality.

When to Use Interfaces

  1. Use an interface when:
    • You want to define a contract that can be implemented by multiple unrelated classes.
    • You need to achieve multiple inheritance.
    • You want to share behavior without enforcing a class hierarchy.
  2. Interfaces are ideal for defining capabilities or roles (e.g., Flyable, Swimmable, Drivable).

Combining Both

Kotlin allows classes to inherit from an abstract class and implement multiple interfaces.

Example:

abstract class Animal(val name: String) {
abstract fun makeSound()
}

interface Flyable {
fun fly()
}

class Bird(name: String) : Animal(name), Flyable {
override fun makeSound() {
println("$name chirps")
}

override fun fly() {
println("$name is flying")
}
}

fun main() {
val bird = Bird("Sparrow")
bird.makeSound() // Output: Sparrow chirps
bird.fly() // Output: Sparrow is flying
}

Quick Summary

  • Abstract Class: Use when you need a base class for related objects with shared code and state.
  • Interface: Use when you need to define a set of behaviors that can be implemented by unrelated classes or need multiple inheritance.

Happy Koding!! 😊

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *