2017-08-20 14 views
5

के लिए क्षेत्र बनाने के लिए मेरे पास है Android पर निम्नलिखित Kotlin वर्ग:Kotlin - केवल पढ़ने के लिए बाहरी वर्गों

class ThisApplication: Application() { 

    lateinit var network: INetwork 

    override fun onCreate() { 

     super.onCreate() 

     network = Network() 
    } 
} 

अब, किसी भी बाहरी वर्ग बस करके INetwork संदर्भ प्राप्त कर सकते हैं:

application.network 

हालांकि, वह भी एक बाहरी वर्ग कि मान ओवरराइट के लिए संभव बनाता है:

application.network = myNewNetworkReference 

मैं दूसरे विकल्प से बचना चाहते हैं। दुर्भाग्य से, मैं फ़ील्ड val नहीं बना सकता क्योंकि इसकी शुरुआत onCreate कॉलबैक के अंदर होने की आवश्यकता है।

मैं भी इस तरह क्षेत्र निजी बनाने और एक समारोह के माध्यम से संपर्क में लाने, के बारे में सोचा:

private lateinit var network: INetwork 
fun getNetwork() = network 

हालांकि, जो कोई भी getNetwork (कॉल) अभी भी यह करने के लिए एक नया मान असाइन कर सकते हैं, तो जैसे:

application.getNetwork() = myNewNetworkReference 

मैं कैसे नेटवर्क क्षेत्र रीड-ओनली के लिए बाहरी वर्गों द्वारा कर सकते हैं? या इससे भी बेहतर, क्या इसे val बनाने का कोई तरीका है, भले ही मैं इसे एक कन्स्ट्रक्टर के अंदर शुरू नहीं कर सकता?

+0

यह सच नहीं है कि किसी विधि का कॉलर इस विधि के मान को फिर से सौंप सकता है। 'application.getNetwork() = myNewNetworkReference' संकलित नहीं होगा। – yole

उत्तर

3

बाहरी वर्गों से उपयोग को सीमित करने के लिए, आप accessors की दृश्यता बदल सकते।

lateinit var network: INetwork 
    private set 

या एक केवल पढ़ने के लिए आलसी संपत्ति:

:

val network: INetwork by lazy { Network() } //you can access private property here, eg. applicationContext 

कुछ गलतफहमी आप से इस कोड के बारे में कर रहे हैं अपने मामले के लिए, आप lateinit संशोधक के साथ private सेटर और public गेटर की जरूरत

private lateinit var network: INetwork 
fun getNetwork() = network 

कोटलिन पास-दर-मूल्यJava does के रूप में है। तो, application.getNetwork() = myNewNetworkReference एक वैध कथन नहीं है। हम किसी फ़ंक्शन के रिटर्न वैल्यू को मान असाइन नहीं कर सकते हैं।

2

val network: INetwork by lazy { ... } आपके परिदृश्य के लिए काम करेगा?

लैम्ब्डा अभिव्यक्ति क्षेत्र network का पहला संदर्भ के साथ बुलाया जाता है। जाहिर है, यह OnCreate विधि के प्रारंभिक स्थान को परिभाषित करने जैसा नहीं है, लेकिन यह इसे val बनाने के लिए इसे कन्स्ट्रक्टर में प्रारंभ किए बिना करने का एक तरीका है।

अन्य प्रतिनिधिमंडल विकल्प भी हैं। The Kotlin documentation चेक आउट करने लायक है।

+0

यह इस विशेष मामले के लिए काम करेगा क्योंकि नेटवर्क क्लास कोई पैरामीटर नहीं लेता है। धन्यवाद। हालांकि, मैंने थोड़ा सा उदाहरण सरल बना दिया है।मुझे क्रिएट पर भरोसा करने का एक तरीका चाहिए क्योंकि कुछ उदाहरणों के लिए मुझे पहले से शुरू किए गए कॉन्टेक्स्ट ऑब्जेक्ट की आवश्यकता होगी। उदाहरण के लिए, मैं एक SQLDatabase (यह) को तुरंत चालू कर सकता हूं और इसे अंदर की आवश्यकता है क्योंकि मैं इसे "इस" (संदर्भ) से गुजर रहा हूं। – Tiago

2

आप स्वतंत्र रूप से वास्तविक चर से getters/setters की दृश्यता को संशोधित कर सकते हैं:

lateinit var network: INetwork 
    private set 
संबंधित मुद्दे