Introduction and Topic Actualization

Welcome to our next lesson! Today, we are focusing on Encapsulation, a crucial pillar of Object-Oriented Programming (OOP). We'll demystify the concept and master its implementation in Kotlin.

Encapsulation, much like a safe for valuables, ensures that our data in code is accessed and utilized appropriately.

Our exploration itinerary includes an overview of encapsulation, its implementation in Kotlin—specifically using private properties—and a hands-on tutorial on Accessors (getters and setters). Let's set forth!

A Closer Look at Encapsulation

Encapsulation wraps data (properties) and the methods manipulating that data into one coherent unit—a class in Kotlin. Central to Encapsulation is the confinement of data, which restricts outside access.

Consider your smartphone. Your interaction with it involves buttons; however, the underlying complexities are hidden. That is precisely what encapsulation accomplishes—exposing necessities while concealing complexities.

Encapsulation offers numerous advantages: it safeguards data from unwanted alteration, enhances usability by revealing only pertinent parts, and boosts modularity, thereby making your code more maintainable and adaptable.

Implementing Encapsulation in Kotlin

Encapsulation in Kotlin is achieved by controlling access to class properties, commonly by marking them as private. A private property or method can only be accessed within the class it is declared, safeguarding your class's data from unauthorized access and modification.

Consider the BankAccount class example to understand encapsulation in action:

class BankAccount {
    private var balance: Double = 0.0   // balance is private and can't be accessed directly from outside the class

    // Public method to deposit money, ensuring only valid amounts are added
    fun deposit(amount: Double) {
        if (amount > 0) {
            balance += amount
            printBalance() // Private method can be called within a public method
        }
    }

    // Public method to withdraw money, ensuring only valid amounts are subtracted
    fun withdraw(amount: Double) {
        if (amount > 0 && balance >= amount) {
            balance -= amount
            printBalance() // Private method can be called within a public method
        }
    }
    
    // Private method to print the current balance
    private fun printBalance() {
        println("Current balance: $balance")
    }
}

fun main() {
    val account = BankAccount()
    account.deposit(1000.0) // Prints "Current balance: 1000.0"
    account.withdraw(500.0) // Prints "Current balance: 500.0"
    // account.balance // Uncommenting this line will cause a compile error because balance is private
    // account.printBalance() // This line would also cause a compile error because printBalance is private
    println("Transaction completed.")
}

In the BankAccount class, the balance property is private, meaning it cannot be directly accessed or modified from outside the class. This ensures that balance can only be modified through the deposit and withdraw methods, which include checks for valid transactions. Additionally, the printBalance method is private and demonstrates that not only properties but also methods can be encapsulated within a class, further controlling access and preventing unauthorized manipulation. The main method demonstrates creating an instance of BankAccount, making deposits and withdrawals, and shows that direct access to both balance and the printBalance method is not permitted, reinforcing the concept of encapsulation.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal