You are currently viewing Kotlin Abstract Class

Kotlin Abstract Class

An abstract class is a class that cannot be instantiated directly and is meant to be subclassed by other classes. Abstract classes are declared using the abstract keyword. They can contain both abstract and non-abstract (concrete) properties and methods. Let’s understand the concept of Abstraction.

Abstraction in Kotlin

Abstraction is one of the key principles of Object-Oriented Programming (OOP) that promotes the idea of hiding the implementation details and exposing only the essential features of an object. In Kotlin, like in many other object-oriented languages, abstraction can be achieved through the use of Abstract classes and Interfaces. Here are real-world examples illustrating abstraction:

Banking System: In a banking system, the concept of an account can be abstracted. You can have an abstract class or interface called Account with methods like deposit(), withdraw(), and getBalance(). Concrete classes like SavingsAccount and CheckingAccount can then provide specific implementations.

Abstract Class In kotlin

abstract classes can have a mix of abstract methods (methods without a body) and non-abstract methods (methods with a body). Abstract methods in an abstract class serve as a contract, and any concrete subclass must provide implementations for these abstract methods. Non-abstract methods can also be included in the abstract class, providing default behavior that can be inherited by the subclasses.

Here are some key points about abstract classes in Kotlin:

  1. Cannot be instantiated: Abstract classes cannot be instantiated directly. You cannot create objects of an abstract class.
  2. Keyword abstract: The abstract keyword is used to declare an abstract class. It indicates that the class cannot be fully instantiated and is meant to be subclassed.
  3. Abstract methods:Abstract classes can have abstract methods, which are methods without a body. Subclasses must provide concrete implementations for these abstract methods.
  4. Concrete methods: Abstract classes can also have concrete methods (methods with a body). Subclasses inherit these methods, and they can choose to override them if needed.
  5. Properties: Abstract classes can have both abstract and non-abstract properties. Abstract properties do not have an initial value and must be overridden by subclasses. non-abstract properties can have initial value in abstract class.
  6. Constructor: Abstract classes can have constructors. Subclasses must invoke the constructor of the abstract class using the super keyword.
  7. Single inheritance: Kotlin supports single-class inheritance, meaning a class can inherit from only one superclass, whether it’s abstract or not.
  8. Common structure: Abstract classes are useful for defining a common structure or base functionality shared among multiple related classes.

Here’s the syntax for declaring an abstract class in Kotlin

abstract class AbstractClassName {
    // Abstract properties
    // it can not be initialized here
    abstract val abstractProperty: DataType

    // Abstract methods
    abstract fun abstractMethod()

    // Non-abstract properties
    // it can  be initialized here
    val nonAbstractProperty: DataType = /* initialization */

    // Non-abstract methods (with a body)
    fun nonAbstractMethod() {
        // Body of the method
    }
}

In this syntax:

  • abstract class: The abstract keyword declares that this is an abstract class.
  • AbstractClassName: Replace this with the desired name of your abstract class.
  • abstractProperty: Abstract properties do not have an initial value and must be overridden by subclasses.
  • abstractMethod(): Abstract methods do not have a body and must be implemented by subclasses.
  • nonAbstractProperty: Non-abstract properties can have an initial value and do not need to be overridden.
  • nonAbstractMethod(): Non-abstract methods have a body and provide default behavior. They can be inherited by subclasses as-is or overridden.

Example of an abstract class in Kotlin:

// Abstract class definition
abstract class Animal(val name: String) {
    // Abstract property
    abstract val sound: String

    // Abstract method - it must be implemented by subclass
    abstract fun makeSound()

    // Non-abstract method // default method
    fun sleep() {
        println("$name is sleeping")
    }
}

// Concrete subclass 1
class Dog(name: String) : Animal(name) {
    override val sound: String = "Woof" // overriding abstract property

    override fun makeSound() {
        println("$name says $sound")
    }
}

// Concrete subclass 2
class Cat(name: String) : Animal(name) {
    override val sound: String = "Meow"

    override fun makeSound() {
        println("$name says $sound")
    }
}

fun main() {
    // Using the abstract class and its subclasses
    val dog = Dog("Buddy")
    val cat = Cat("Whiskers")

    dog.makeSound()
    dog.sleep()

    cat.makeSound()
    cat.sleep()
}

//Output
Buddy says Woof
Buddy is sleeping
Whiskers says Meow
Whiskers is sleeping

In this example:

  • Animal is an abstract class with an abstract property sound and an abstract method makeSound().
  • The abstract class has a non-abstract method sleep() with a default implementation.
  • Dog and Cat are concrete subclasses of the Animal abstract class. They provide specific implementations for the abstract property and method.

This example demonstrates how abstract classes can be used to define a common structure for a group of related classes while allowing each subclass to provide its own unique implementation.

what is the use of constructor in abstract class ?

The main purpose of having constructors in an abstract class is to initialize the common properties or provide a mechanism for initializing the state of its subclasses and performing any necessary setup when an instance of a concrete subclass is created..

The constructor of an abstract class can be used to ensure that certain properties are initialized before the abstract methods or non-abstract methods are called.

By having constructors in an abstract class, it can be reused initialization logic by multiple subclasses.

Here’s an example to illustrate the use of a constructor in an abstract class:

abstract class Shape(val name: String) {
    init {
        println("Initializing $name")
    }

    abstract fun calculateArea(): Double

    fun displayInfo() {
        println("$name - Area: ${calculateArea()}")
    }
}

class Circle(radius: Double) : Shape("Circle") {
    private val radius: Double = radius

    override fun calculateArea(): Double {
        return Math.PI * radius * radius
    }
}

class Square(sideLength: Double) : Shape("Square") {
    private val sideLength: Double = sideLength

    override fun calculateArea(): Double {
        return sideLength * sideLength
    }
}

fun main() {
    val circle = Circle(5.0)
    val square = Square(4.0)

    circle.displayInfo()
    square.displayInfo()
}
//Output
Initializing Circle
Initializing Square
Circle - Area: 78.53981633974483
Square - Area: 16.0
  • The Shape abstract class has a constructor that takes a name parameter. The init block in the constructor is executed when an instance of the concrete subclass is created.
  • The concrete subclasses Circle and Square provide their specific implementations for the calculateArea method.
  • When an instance of Circle or Square is created, the constructor of the abstract class (Shape) is called, and the initialization block prints a message indicating the type of shape being initialized.

Use cases of abstract classes in Android development:

  1. Activity Lifecycle: It is used to define a base activity class that encapsulates common behavior and methods related to the Activity lifecycle. Subclasses (individual activities) can then extend this abstract class to inherit and customize the common behavior.
  2. Fragment Management: It is used to create a base fragment class that includes common logic for fragment transactions, lifecycle handling, or UI interactions. Subclasses representing individual fragments can extend this abstract class to reuse common functionality.
  3. Adapter Classes: Abstract classes are useful for creating base adapter classes in Android, such as BaseAdapter or RecyclerView.Adapter. Subclasses can extend these abstract adapters to provide custom implementations for adapting data to UI elements.
  4. Permission Handling: Abstract classes can be used to create a base class for handling runtime permissions in Android. Subclasses can extend this abstract class to implement logic for requesting and handling permissions in different parts of the app.

To learn more about Kotlin abstract class, check out the official documentation at: Kotlinlang

Leave a Reply