Abstraction and encapsulation are easiest to understand in a real system. In each example below, ask two questions: what can the user do? (abstraction) and what is protected, and how? (encapsulation).
Example 1: ATM
| Concept | In the ATM |
|---|---|
| Abstraction | The user sees only: insert card, enter PIN, choose withdraw, take cash. How the bank verifies the PIN and updates the database is hidden |
| Encapsulation | The balance is private. It can only be changed through checked operations (withdraw, deposit) that enforce rules |
interface ATM { // abstraction: what the user can do
boolean login(String pin);
void withdraw(double amount);
double checkBalance();
}
class BankATM implements ATM {
private double balance = 50000; // encapsulation: hidden data
private String pin = "1234";
private boolean loggedIn = false;
public boolean login(String entered) {
loggedIn = pin.equals(entered);
return loggedIn;
}
public void withdraw(double amount) {
if (loggedIn && amount > 0 && amount <= balance) balance -= amount;
else System.out.println("Transaction rejected");
}
public double checkBalance() { return loggedIn ? balance : -1; }
}Reading the ATM code
- The
ATMinterface is the abstraction. It lists the three things a user can do, and nothing about how they are done. A different bank could write its own class that implements ATM in a completely different way, and the code that usesATMwould not change. BankATMencapsulates the data.balance,pinandloggedInare private, so no other code can read the PIN or set the balance.withdraw()enforces three rules at once: the user must be logged in, the amount must be positive, and it cannot be more than the balance. Because there is no other way to changebalance, these rules can never be bypassed.checkBalance()returns −1 if the user is not logged in, so the balance is never shown to an unauthorised user.pin.equals(entered)compares the text of the two strings. Writingpin == enteredwould compare references, and could fail even when the PIN is correct (see 3.1.3).
ATM atm = new BankATM(); // the user only sees the ATM type
atm.login("1234");
atm.withdraw(2000);
System.out.println(atm.checkBalance()); // 48000.0Example 2: Other everyday cases
| System | Abstraction (what you see) | Encapsulation (what is protected) |
|---|---|---|
| Car | Pedals, steering, gear lever | Engine state, fuel injection settings |
| Smartphone | Touch the camera icon to take a photo | Sensor and image-processing internals |
| Online shop | Add to cart, pay | Stock counts and payment records, changed only by validated methods |
| Student record system | View results | Marks can be changed only by authorised teachers through setters |
Example 3: A vending machine
Abstraction: a customer can insert money, choose an item and collect change, which gives the public methods insertMoney(double), selectItem(String code) and getChange(). The customer never sees how the machine counts coins or controls the motors.
Encapsulation: the stock of each item, the prices and the money collected are private attributes. selectItem() only gives out an item if it is in stock and enough money has been inserted, and then it reduces the stock by one. An owner might have a separate restock() method that checks a password first.
This is the same pattern every time: public methods that describe what the user can do, private data that only those methods can change, and rules checked inside the methods.
Practice exercises
- Choose a real-world system (vending machine, lift, library). List the abstraction (public operations) and the encapsulated data. Write the Java classes.
- Explain to a friend, in one paragraph and without jargon, the difference between abstraction and encapsulation using the ATM example.
End of Unit 3. Test yourself with the Unit 3 questions in the multiple-choice and structured question banks, tick the outcomes in the topic checklist, then go on to the next unit.