Encapsulation
Make fields private, so no one can change them directly from outside.
Provide public getter/setter methods so the value can be read/changed in a controlled way — like withdrawing cash from an ATM, not opening the vault directly.
class Account {
private double balance;
public double getBalance() { return balance; }
public void deposit(double amt) { if (amt > 0) balance += amt; }
}Agar field public ho, koi bhi bina check ke ise galat value de sakta hai (jaise balance = -500, jo real duniya mein impossible hai ek bank account ke liye). Private karke, sirf class ke apne methods (getter/setter) se access milta hai, jisme validation lagayi ja sakti hai — invalid states possible hi nahi rehte.
class Account {
private double balance;
public void deposit(double amt) {
if (amt > 0) balance += amt; // validation!
}
}Getter (getBalance()) sirf value return kare, side-effects na ho (koi cheez change na ho). Setter (setBalance()) mein validation logic rakho — invalid input par exception throw karo ya silently ignore karo (project convention ke hisaab se).
Sab fields ko blindly getter/setter dena zaroori nahi — agar koi field sirf internal use ke liye hai (kabhi bahar expose nahi hona chahiye), use bilkul private rakho, koi getter/setter mat do. "Getter/setter for everything" encapsulation ka galat use hai — isse fields effectively public hi ho jaate hain, bas thodi zyada typing ke saath.
Immutable class (jaise String) wo hai jiske objects banने ke baad change nahi ho sakte — koi bhi "modify" operation ek naya object return karta hai, original wahi rehta hai. Banane ka tarika: sab fields private aur final rakho, koi setter mat do, aur constructor mein hi sab values set kar do.
Agar field khud ek mutable object hai (jaise Date ya List), "defensive copy" banani padti hai constructor mein aur getter mein — warna koi bahar se us internal object ko change karke immutability tod sakta hai.
Immutable classes ka bada fayda: thread-safety free mein milti hai (multiple threads ek immutable object safely share kar sakte hain, kyunki koi change hi nahi kar sakta), aur HashMap keys ke liye perfect hote hain (hashCode kabhi change nahi hota).
final class Point {
private final int x, y;
Point(int x, int y) { this.x = x; this.y = y; }
int getX() { return x; } // sirf getter, koi setter nahi
Point withX(int newX) { return new Point(newX, y); } // "modify" = naya object
}Java mein ek standard naming convention hai: getters "get" se shuru (getName()), setters "set" se (setName()), boolean getters "is" se (isActive(), na ki getActive()). Ye convention frameworks (jaise Spring, Jackson JSON library) ke liye zaroori hai jo reflection se automatically fields access karte hain — agar convention follow na karo, ye tools tumhare fields ko "dhoond" hi nahi payenge.