Kotlin में Public Get Private Set: गलतियाँ और समाधान

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Kotlin में Public Get, Private Set: गलतियों से कैसे बचें (और अगर हो गई तो क्या करें)

\n\n

नमस्ते, दोस्त! अगर आपने कभी "Kotlin public get private set var" गूगल किया है, तो आप अकेले नहीं हैं। यह Stack Overflow पर सबसे लोकप्रिय सवालों में से एक है, और हज़ारों डेवलपर्स (मैं भी शामिल) ने अपना सिर खपाया है यह समझने में कि उनका कोड क्यों काम नहीं कर रहा।

\n\n

सोचिए, इसमें इतना मुश्किल क्या है? मैं चाहता हूँ कि प्रॉपर्टी सभी के लिए उपलब्ध हो (public get), लेकिन उसे सिर्फ क्लास ही बदल सके (private set)। Java में यह आम बात थी: private फील्ड बनाओ, getter और setter लिखो, और setter को private कर दो। Kotlin में तो यह और भी आसान होना चाहिए, लेकिन...

\n\n

स्पॉयलर: सिंटैक्स मौजूद है, लेकिन यह हमेशा आपकी उम्मीद के मुताबिक काम नहीं करता। इस आर्टिकल में हम उन टॉप गलतियों पर चर्चा करेंगे जो अनुभवी डेवलपर्स भी करते हैं, और दिखाएंगे कि उनसे कैसे बचा जाए। चलिए शुरू करते हैं!

\n\n

प्रॉपर्टी की संरचना: var, val, get और set

\n\n

पहले एक त्वरित जानकारी। Kotlin में प्रॉपर्टीज़ (properties) सिर्फ फील्ड नहीं हैं। ये पूर्ण तत्व हैं जिनमें getter और setter हो सकते हैं। यहाँ बेसिक संरचना है:

\n\n
var प्रॉपर्टी_का_नाम: प्रकार = डिफ़ॉल्ट_मान\n    get() = field\n    set(value) { field = value }
\n\n

अगर आप var का उपयोग करते हैं, तो Kotlin अपने आप getter और setter जनरेट करता है। लेकिन आप उनके व्यवहार को बदल सकते हैं। और सबसे अच्छी बात - आप उनकी विज़िबिलिटी (visibility modifiers: public, private, internal, protected) भी बदल सकते हैं।

\n\n

और यहीं से मज़ा शुरू होता है। Getter को public और setter को private बनाने के लिए, आपको यह लिखना होगा:

\n\n
var name: String = "default"\n    private set
\n\n

बस इतना ही? लगभग। लेकिन कुछ ऐसी बारीकियाँ हैं जो इस तंत्र को तोड़ देती हैं।

\n\n

गलती #1: कंस्ट्रक्टर को भूल जाना

\n\n

सबसे आम समस्या - क्लास के कंस्ट्रक्टर में public get private set var घोषित करने की कोशिश करना। उदाहरण के लिए:

\n\n
// ❌ गलती: ऐसा नहीं कर सकते\nclass User(public get private set var name: String)
\n\n

Kotlin कंपाइलेशन एरर देगा। क्यों? क्योंकि कंस्ट्रक्टर के पैरामीटर प्रॉपर्टी नहीं हैं। वे सिर्फ पैरामीटर हैं। अगर आप चाहते हैं कि प्रॉपर्टी में बदली हुई setter विज़िबिलिटी हो, तो उसे क्लास के बॉडी में घोषित करना होगा।

\n\n

सही तरीका:

\n\n
class User(name: String) {\n    var name: String = name\n        private set\n}
\n\n

या, अगर आप data class का उपयोग कर रहे हैं, तो थोड़ा घुमाव करना होगा:

\n\n
data class User(private val _name: String) {\n    var name: String = _name\n        private set\n}
\n\n

हाँ, data class आपको प्राइमरी कंस्ट्रक्टर की प्रॉपर्टीज़ के लिए सीधे setter विज़िबिलिटी बदलने की अनुमति नहीं देता। आपको backing field का उपयोग करना होगा।

\n\n

गलती #2: Backing Field में उलझन

\n\n

Backing field एक छिपा हुआ फील्ड है जो Kotlin अपने आप जनरेट करता है अगर आप getter या setter में field का उपयोग करते हैं। लेकिन अगर आप field का उपयोग किए बिना getter या setter को ओवरराइड करते हैं, तो backing field नहीं बनता।

\n\n

समस्या का उदाहरण:

\n\n
var counter: Int = 0\n    private set\n    get() = field * 2 // ❌ गलती: field परिभाषित नहीं है
\n\n

नहीं, यह कंपाइलेशन एरर नहीं है। लेकिन अगर आप यह लिखते हैं:

\n\n
var counter: Int = 0\n    private set\n    get() = 42 // ठीक है, लेकिन field का उपयोग नहीं हुआ
\n\n

इस मामले में, backing field नहीं बनेगा। और अगर आप setter में field का उपयोग करने की कोशिश करेंगे, तो एरर मिलेगा। अच्छी खबर: अगर आप private set का उपयोग करते हैं, तो backing field लगभग हमेशा अपने आप बन जाता है, क्योंकि डिफ़ॉल्ट setter field का उपयोग करता है। लेकिन अगर आप field के बिना setter को ओवरराइड करते हैं - तो आश्चर्य के लिए तैयार रहें।

\n\n

सलाह: अगर आप backing field के साथ काम करना चाहते हैं, तो हमेशा getter और setter में स्पष्ट रूप से field का उपयोग करें। और याद रखें: अगर प्रॉपर्टी में backing field नहीं है, तो आप field का उपयोग नहीं कर सकते।

ब्लॉग

पुस्तक अनुशंसाएँ