Published on

OOP Mastery: Abstraction in Kotlin

Authors

OOP Mastery is a series of self-study articles on Object-Oriented Programming with the Kotlin language, compiled at DanTech0xFF. The purpose of this series of articles is to provide a comprehensive view of Object Orientation in the Kotlin language. This will be a solid foundation for future Programmers if you delve into Android, Mobile Cross Platform, or Backend Java.

  • Part 1: OOP Mastery: Class Types, Interface in Kotlin
  • Part 2: OOP Mastery: Encapsulation in Kotlin
  • Part 3: OOP Mastery: Inheritance in Kotlin
  • Part 4: OOP Mastery: Polymorphism in Kotlin
  • Part 5: OOP Mastery: Abstraction in Kotlin

In this article, we will analyze the Abstraction aspect of OOP in the Kotlin programming language.

Reminding Abstraction

Abstraction – an interesting feature in the approach of object-oriented programming.

Abstraction is demonstrated through the fact that when designing software features, Programmers will focus on designing the workflow of behaviors (behaviour / method) and then divide them into Classes without going into specific details. Classes designed at this stage are called Abstract Classes, or may also be called Interfaces in some cases.

Abstraction in Kotlin

The polymorphism of OOP in Kotlin is expressed through Interface and Abstract Class. I mentioned it in the article on Polymorphism in Kotlin.

Kotlin provides Interface and Abstract class solutions so that Programmers can define empty interfaces during the design process before going into implementation.

interface MyInterface {
    val name: String // Kotlin's interface can contain member variable
    fun myFunction() {
    // Kotlin's interface can contain pre-defined functions
        println("Hello from MyInterface")
    }
    // Kotlin's interface can contain undefined functions
    fun myEmptyFunction()
}

abstract class MyAbstractClass {
    open val name: String = "Name"
    abstract val age: Int
    abstract fun myFunction()
    open fun myOpenFunction() {
        println("Hello from myEmptyFunction")
    }
    fun myNormalFunction() {
        println("Hello from myNormalFunction")
    }
}

How to declare Interface and Abstract class in Kotlin

Benefits of leveraging Abstraction in Kotlin

Mastering abstraction and leveraging it during software development is a mandatory requirement for Programmers.

The purpose of abstraction is to help logical flows be easily extended and easily implemented during software development. This is tightly reflected in the principles of SOLID Principles

Real-world example: Designing a solution for storing and reading music files for the Spotify application. Encryption is required to ensure data security.

In this case, we have not yet found a specific solution for which encryption algorithm to use; if we continue to search for an encryption algorithm, the development will continue to be stalled. The solution at this time is Abstraction.

  • Step 1, design a common Interface for encrypting and decrypting music files
interface ICrypto {
  fun encrypt(arr: ByteArray): ByteArray
  fun decrypt(arr: ByteArray): ByteArray
}
  • Step 2, implement a simple solution and integrate it into the source code
class DummyCrypto : ICrypto {
  fun encrypt(arr: ByteArray): ByteArray {
    return arr
  }
  fun encrypt(arr: ByteArray): ByteArray {
    return arr
  }
}
  • Step 3, develop encryption and decryption methods
class CryptoSolution1 : ICrypto {
    fun encrypt(arr: ByteArray): ByteArray {
      // implement logic for the Solution1
    }
    fun encrypt(arr: ByteArray): ByteArray {
      // implement logic for the Solution1
    }
}

class CryptoSolution2 : ICrypto {
    fun encrypt(arr: ByteArray): ByteArray {
      // implement logic for the Solution 2
    }
    fun encrypt(arr: ByteArray): ByteArray {
      // implement logic for the Solution 2
    }
}
  • Step 4, Test them
class CryptoSolution1Test {
  // write unit test for CryptoSolution1
}
class CryptoSolution2Test {
  // write unit test for CryptoSolution2
}
  • Step 5, Release the product

You can see that thanks to polymorphism, we can easily replace DummyCrypto with CryptoSolution1 or CryptoSolution2. This is the strength of polymorphism. In addition, throughout the development process, the Solutions are independent of each other, so testing becomes easier, which makes the feature highly reliable when released.

So I have fully shared the 4 properties of Object-Oriented Programming in Kotlin. I hope you can learn something interesting from this series of articles.

Good luck!