Introduction

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 Scala.

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

This guide covers an overview of encapsulation, its implementation in Scala, specifically using private properties, and a detailed rundown on Scala's unique approach to Accessors (getters and setters). Onward, let's dive in!

A Closer Look at Encapsulation

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

When you use your smartphone, you interact with apps and functions without directly accessing the internal storage or battery management system, ensuring the internal state is protected and managed through controlled interfaces.

Encapsulation offers valuable advantages: it safeguards data from unwanted alteration, enhances usability by revealing only pertinent aspects, and bolsters modularity, making your code more maintainable and adaptable.

Implementing Encapsulation in Scala

In Scala, encapsulation is implemented primarily by controlling access to class properties using the private keyword. A private property can only be accessed within either the class they're defined in or the package they belong to, protecting your data from unauthorized access or modification.

To achieve exclusive intra-class access, Scala uses private[this]. Let's illustrate with a BankAccount class example:

class BankAccount:
  private[this] var balance: Double = 0.0 

  // Public method to deposit money, ensuring only valid amounts are added
  def deposit(amount: Double): Unit =
    if amount > 0 then
      balance += amount
      printBalance()
  
  // Public method to withdraw money, ensuring only valid amounts are subtracted
  def withdraw(amount: Double): Unit =
    if amount > 0 && balance >= amount then
      balance -= amount
      printBalance()
  
  // Private method to print the current balance
  private def printBalance(): Unit =
    println(s"Current balance: $balance")

@main def run: Unit =
  val account = new BankAccount()
  account.deposit(1000.0) // Prints "Current balance: 1000.0"
  account.withdraw(500.0) // Prints "Current balance: 500.0"
  // Uncommenting the below lines would cause a compile error
  // account.balance 
  // account.printBalance() 
  println("Transaction completed.")

The BankAccount class's balance property is private[this], allowing it to be only accessed within the class. It ensures balance can only be manipulated through the deposit and withdraw methods, preserving data integrity. Additionally, the printBalance method, also private, demonstrates methods encapsulation within a class, further controlling access.

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