Encapsulation
Fields को private बनाओ, ताकि कोई बाहर से सीधा change ना कर सके।
public getter/setter methods दो जिससे controlled तरीक़े से value पढ़ी/बदली जा सके — जैसे ATM से पैसा निकालना, सीधा locker खोल कर नहीं।
class Account {
private double balance;
public double getBalance() { return balance; }
public void deposit(double amt) { if (amt > 0) balance += amt; }
}- Fields को private रखो
- getter/setter से controlled access
- ग़लत change होने से बचाता है
अगर field public हो, कोई भी बिना check किए इसे ग़लत value दे सकता है (जैसे balance = -500, जो real दुनिया में impossible है एक bank account के लिए)। Private करके, सिर्फ़ class के अपने methods (getter/setter) से access मिलता है, जिसमें validation लगाई जा सकती है — invalid states possible ही नहीं रहते।
class Account {
private double balance;
public void deposit(double amt) {
if (amt > 0) balance += amt; // validation!
}
}Getter (getBalance()) सिर्फ़ value return करे, side-effects ना हों (कोई चीज़ change ना हो)। Setter (setBalance()) में validation logic रखो — invalid input पर exception throw करो या silently ignore करो (project convention के हिसाब से)।
सब fields को blindly getter/setter देना ज़रूरी नहीं — अगर कोई field सिर्फ़ internal use के लिए है (कभी बाहर expose नहीं होना चाहिए), उसे बिल्कुल private रखो, कोई getter/setter मत दो। "Getter/setter for everything" encapsulation का ग़लत use है — इससे fields effectively public ही हो जाते हैं, बस थोड़ी ज़्यादा typing के साथ।
Immutable class (जैसे String) वो है जिसके objects बनने के बाद change नहीं हो सकते — कोई भी "modify" operation एक नया object return करता है, original वही रहता है। बनाने का तरीक़ा: सब fields private और final रखो, कोई setter मत दो, और constructor में ही सब values set कर दो।
अगर field ख़ुद एक mutable object है (जैसे Date या List), "defensive copy" बनानी पड़ती है constructor में और getter में — वरना कोई बाहर से उस internal object को change करके immutability तोड़ सकता है।
Immutable classes का बड़ा फ़ायदा: thread-safety free में मिलती है (multiple threads एक immutable object safely share कर सकते हैं, क्योंकि कोई change ही नहीं कर सकता), और HashMap keys के लिए perfect होते हैं (hashCode कभी change नहीं होता)।
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 में एक standard naming convention है: getters "get" से शुरू (getName()), setters "set" से (setName()), boolean getters "is" से (isActive(), ना कि getActive())। ये convention frameworks (जैसे Spring, Jackson JSON library) के लिए ज़रूरी है जो reflection से automatically fields access करते हैं — अगर convention follow ना करो, ये tools तुम्हारे fields को "ढूँढ" ही नहीं पाएंगे।