Loading subject…
Encapsulation
The practice of putting the data describing something and the methods that act on that data inside a single class.
| Modifier | Reachable from | Used for |
|---|---|---|
| private | Inside this class only | Instance variables, helper methods |
| public | Any class | The methods other classes are meant to call |
| protected | This class and its subclasses | Members a subclass needs (B3.2, HL) |
The standard encapsulated design is private attributes with public methods, which is why nearly every instance variable you write should be private.
class Student: def __init__(self, name, age): self.__name = name # private by convention self.__age = age
# Accessor (getter) def get_name(self): return self.__name
# Mutator (setter) with validation def set_age(self, age): if age > 0: self.__age = age else: print("Age must be positive; value unchanged.")
def get_age(self): return self.__agepublic class Student { private String name; private int age;
public Student(String name, int age) { this.name = name; this.age = age; }
// Accessor (getter) public String getName() { return name; }
// Mutator (setter) with validation public void setAge(int age) { if (age > 0) { this.age = age; } }
public int getAge() { return age; }}class BankAccount: def __init__(self, initial_balance): self.__balance = 0 # private attribute if initial_balance >= 0: self.__balance = initial_balance
# Accessor: read-only view of the balance def get_balance(self): return self.__balance
# Mutator: deposits are checked before being accepted def deposit(self, amount): if amount > 0: self.__balance += amount return True return False
# Mutator: withdrawals cannot overdraw the account def withdraw(self, amount): if 0 < amount <= self.__balance: self.__balance -= amount return True return Falseacc = BankAccount(100)
acc.deposit(50) # accepted, balance 150acc.deposit(-30) # rejected, balance unchangedacc.withdraw(500) # rejected, would overdrawprint(acc.get_balance()) # 150
# Direct access is blocked by name mangling# acc.__balance = 1000000 -> creates a NEW attribute, the real balance is untouchedprint(acc.get_balance()) # still 150public class BankAccount { // Private attribute: unreachable from outside the class private double balance;
public BankAccount(double initialBalance) { if (initialBalance >= 0) { balance = initialBalance; } }
// Accessor: read-only view of the balance public double getBalance() { return balance; }
// Mutator: deposits are checked before being accepted public boolean deposit(double amount) { if (amount > 0) { balance += amount; return true; } return false; }
// Mutator: withdrawals cannot overdraw the account public boolean withdraw(double amount) { if (amount > 0 && amount <= balance) { balance -= amount; return true; } return false; }}public class Main { public static void main(String[] args) { BankAccount acc = new BankAccount(100);
acc.deposit(50); // accepted, balance 150 acc.deposit(-30); // rejected, balance unchanged acc.withdraw(500); // rejected, would overdraw System.out.println(acc.getBalance()); // 150.0
// acc.balance = 1000000; // will not compile: balance is private }}