B3.1.5

Explain and apply the concepts of encapsulation and information hiding in OOP

Encapsulation is the process of bundling data (attributes) and methods (behaviour) together into a single unit — a class.

4 min read854 words

What is Encapsulation?

Encapsulation is the process of bundling data (attributes) and methods (behaviour) together into a single unit — a class.

┌─────────────────────────────────────────┐
│                 BankAccount             │
├─────────────────────────────────────────┤
│  – account_number                       │
│  – name                                 │
│  – balance                              │
├─────────────────────────────────────────┤
│  + deposit()                            │
│  + withdraw()                           │
│  + get_balance()                        │
└─────────────────────────────────────────┘
         ↑ Data + Methods in ONE class

The key principle: data cannot be accessed directly from outside the class — it is protected inside.

What is Information Hiding?

Information hiding is the result achieved through encapsulation: the internal details of how an object works are hidden from the outside world.

ConceptDescription
EncapsulationThe process of bundling data + methods into a class
Information HidingThe result — data is protected and not directly accessible from outside
  • The internal representation of an object is hidden from view outside the class
  • Only a controlled interface (public methods) is exposed
  • Internal details can change without breaking code that uses the class

Encapsulation vs Information Hiding

EncapsulationInformation Hiding
NatureProcessResult
FocusBundling data + methods togetherWhat is visible vs hidden from outside
AnalogyMaking the capsuleWhat is inside the capsule
Can one exist without the other?Information hiding cannot happen without encapsulation ✅No ❌

Implementation in Python

By default, all attributes and methods in Python are public. To restrict access, use naming conventions:

ConventionMeaningVisibility
attributePublicAccessible from anywhere
_attributeProtectedIntended for internal use (soft convention)
__attributePrivateName mangling makes external access very difficult

Name mangling: Python renames __attribute to _ClassName__attribute internally, making accidental access harder.

class Example:
    def __init__(self):
        self.public    = "anyone can see"
        self._protected = "internal use only"
        self.__private  = "hidden from outside"
obj = Example()
print(obj.public)       # anyone can see     ✅
print(obj._protected)  # internal use only  ⚠️ works but not recommended
print(obj.__private)   # AttributeError      ❌
print(obj._Example__private)  # hidden from outside  ⚠️ technically works

Getters and Setters

To access or modify private attributes, you must go through controlled public methods:

Method typePurposeConvention
GetterRetrieve a value without modifying itget_attribute()
SetterModify a value with validationset_attribute(new_value)

Why use getters and setters?

  • Controls how data is accessed and modified
  • Allows validation before changing a value
  • Hides internal representation from outside code
  • Enables future changes to the class without breaking external code

Bank Account Example

class BankAccount:
    """Encapsulates a bank account with private data and controlled access."""

    def __init__(self, account_number: str, name: str, balance: float):
        self.__account_number = account_number   # Private
        self.__name           = name              # Private
        self.__balance       = 0                  # Private

        if balance > 0:                           # Validation in constructor
            self.__balance = balance

    # ── Getters ──────────────────────────────────

    def get_balance(self) -> float:               # Getter for balance
        return self.__balance

    def get_account_number(self) -> str:          # Getter for account number
        return self.__account_number

    # ── Setters ─────────────────────────────────

    def set_balance(self, new_balance: float):    # Setter for balance
        if new_balance >= 0:                      # Validation: balance cannot be negative
            self.__balance = new_balance

    def set_name(self, new_name: str):            # Setter for name
        if new_name != "":
            self.__name = new_name

    # ── Business methods ─────────────────────────

    def deposit(self, amount: float) -> bool:
        if amount > 0:
            self.__balance += amount
            return True
        return False

    def withdraw(self, amount: float) -> bool:
        # Validation: amount must be positive and within balance
        if amount > 0 and amount <= self.__balance:
            self.__balance -= amount
            return True
        return False
account = BankAccount("ACC001", "Alice", 1000.00)

print(account.get_balance())          # 1000.0

account.deposit(500)
print(account.get_balance())          # 1500.0

account.withdraw(200)
print(account.get_balance())          # 1300.0

account.set_balance(-500)             # Ignored — balance cannot be negative
print(account.get_balance())          # 1300.0  ✅

# account.__balance = 99999          # AttributeError  ❌ Direct access blocked

What Happens Without Encapsulation?

Without encapsulation, data is exposed and can be modified without any control:

# ❌ BAD — no encapsulation
class BankAccount:
    def __init__(self, balance: float):
        self.balance = balance          # Public — no protection

account = BankAccount(1000)
account.balance = -9999999              # Nothing stops this!
# ✅ GOOD — encapsulation with setter
class BankAccount:
    def __init__(self, balance: float):
        self.__balance = 0             # Private
        if balance > 0:
            self.__balance = balance

    def set_balance(self, new_balance: float):
        if new_balance >= 0:           # Validation blocks invalid values
            self.__balance = new_balance

account = BankAccount(1000)
account.set_balance(-9999999)          # Ignored — validation prevents it

Advantages of Encapsulation

AdvantageExplanation
Data protectionPrivate data cannot be changed directly — only through validated methods
Controlled modificationSetters can enforce rules (e.g., balance cannot be negative)
Reduced couplingExternal code depends only on the public interface — internal changes don’t break it
SimplicityUsers of a class only need to understand the public interface, not internal complexity
MaintainabilityChanging the internal implementation (e.g., renaming a private variable) requires changes only inside the class
ReusabilityWell-encapsulated classes can be reused in different programs without modification

Start typing to search all published objectives.