Encapsulation
Let's start with something concrete. Imagine a BankAccount. In the real world, a bank account isn't just a number written on paper β it's a thing that has information and can do things. OOP lets us model it exactly that way.
The account has a balance field. That balance needs to be readable β you need to know your balance. But does any code anywhere in the system have the right to directly change it? What if someone writes account.balance = -9999 by accident? There's nothing stopping it. That's the problem Encapsulation solves.
The Problem β Unprotected State
Instead of letting code set balance directly, you provide a deposit(amount) method. Inside that method, you write if-conditions before the field is ever modified. If the check fails, the method prints a message and returns early β balance is never touched.
To force everything through the method, mark the field private. Now account.balance = -9999 won't even compile. The method is the only door in. That is Encapsulation. But to enforce that, you need the language's help. That's what access modifiers are for.
Think of your bank as a building with different rooms. Not every room is open to everyone β who's allowed in depends on which door they're standing at.
In code, every field and method you write is one of those rooms. An access modifier is the keyword that decides who gets a key.
Start with private for everything. Only upgrade to protected when a subclass genuinely needs it, or public when something is intentionally part of the external interface. The tighter the access, the less that can go wrong.
Try It β Broken Bank vs Safe Bank
Both accounts start at $500. On the left, balance is public β type anything and it is accepted without question. On the right, balance is private β every input goes through the validation checks above. Try -999, 0, abc, 200000 on both sides.
The Pattern in Code
private locks the field. Public methods are the only doors. Validation lives inside each method β written once, always enforced.
The One-Line Takeaway
Make fields private. Make methods the only door. Write validation inside once β it's always enforced.