Topic 5. OOP Concept
OOP is a complexity management approach, not just a vocabulary list. As a system grows, code without responsibility boundaries becomes fragile. OOP principles help isolate responsibilities, stabilize contracts, and support safer evolution.
Practical OOP perspective
Instead of asking only “what is OOP?”, ask:
- Where does state live and who can modify it?
- Which public methods define collaboration between components?
- Which implementation details can change without breaking callers?
If these answers are clear, architecture is usually healthy.
Encapsulation
Encapsulation restricts direct field access and enforces state changes through validated methods.
public class BankAccount {
private double balance;
public void deposit(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("amount must be > 0");
}
balance += amount;
}
public void withdraw(double amount) {
if (amount <= 0 || amount > balance) {
throw new IllegalArgumentException("invalid withdraw amount");
}
balance -= amount;
}
public double getBalance() {
return balance;
}
}
Benefits:
- object state cannot be corrupted by random writes,
- business rules stay centralized,
- behavior is easier to test.
Inheritance
Inheritance models is-a relationships: a child class extends shared parent behavior.
class Animal {
void speak() {
System.out.println("...");
}
}
class Dog extends Animal {
@Override
void speak() {
System.out.println("Woof");
}
}
Use when:
- hierarchy is natural and stable,
- shared contract is truly shared,
- substitution is logically valid.
Use carefully:
- if goal is only code reuse, composition (
has-a) is often more flexible.
Polymorphism
Polymorphism enables programming to interfaces while swapping implementations.
interface PaymentProcessor {
void pay(double amount);
}
class CardProcessor implements PaymentProcessor {
public void pay(double amount) {
System.out.println("Card: " + amount);
}
}
class PaymentService {
private final PaymentProcessor processor;
PaymentService(PaymentProcessor processor) {
this.processor = processor;
}
void process(double amount) {
processor.pay(amount);
}
}
Benefits:
- easier extension without rewriting service logic,
- easier mocking/testing,
- lower coupling.
Abstraction
Abstraction hides implementation complexity and exposes useful contracts.
Caller uses send(message) and does not need to know retries, serialization, networking, or logging internals.
Engineering impact:
- external code works with a clear API,
- internal implementation can evolve safely,
- each layer sees only relevant complexity.
How the four principles work together
- Encapsulation protects state.
- Abstraction stabilizes API.
- Polymorphism enables extension.
- Inheritance/composition reuses behavior.
Result: OOP gives predictable change management and better long-term maintainability.