2017-05-17 6 views
12

मैं इस हिस्से में Kotlin में इस त्रुटि हो रही है है:दुर्घटना ओवरराइड: निम्नलिखित घोषणाओं एक ही JVM हस्ताक्षर

class GitHubRepoAdapter(private val context: Context, 
    private val values: List<GithubRepo>) : ArrayAdapter<GithubRepo>(context, R.layout.list_item, 
    values) { 

निजी वैल संदर्भ: लॉग में प्रसंग

यह कहते हैं:

Error:(14, 25) Accidental override: The following declarations have the same JVM signature (getContext()Landroid/content/Context;): fun(): Context fun getContext(): Context!

मैं यह देखने में सक्षम नहीं हूं कि समस्या का कारण क्या है।

उत्तर

24

यह इसलिए होता है क्योंकि Kotlin संकलक val context अपनी कक्षा प्राथमिक निर्माता, अर्थात् एक समारोह getContext() में घोषित के लिए एक गेटर उत्पन्न करने के लिए कोशिश करता है, लेकिन आधार वर्ग ArrayAdapter<T> already has such a function

आप हल कर सकते हैं कि निम्न में से कोई एक करके:

  • अपने वर्ग 'निर्माता पैरामीटर बदले एक val होने के लिए नहीं।

    class GitHubRepoAdapter(context: Context, ... 
    

    इस मामले में, गेटर उत्पन्न नहीं किया जाएगा, और संघर्ष समाप्त हो जाएगा।

    यह आपके मामले में पसंदीदा समाधान प्रतीत होता है, क्योंकि बिना पुनर्विक्रय के, there is already a synthetic property context inferred from the Java getter

  • का प्रयोग करें @JvmName एनोटेशन, apply it to the context property getter:

    class GitHubRepoAdapter(@get:JvmName("getContext_") private val context: Context, ... 
    

    इस संकलक एक और JVM नाम (एक एनोटेशन में निर्दिष्ट) के साथ गेटर उत्पन्न कर देगा, इस प्रकार संघर्ष से बचने के लिए, लेकिन करने से उस तक पहुंचने में जावा कम अंतर्ज्ञानी (विशेष रूप से दो समान कार्य होंगे)। कोटलिन में, आप अभी भी संपत्ति का मूल नाम context के साथ उपयोग करने में सक्षम होंगे।

4

जवाब पहले से ही दिए गए के अलावा ...

  • या, आप val (या var) रख सकते लेकिन कुछ है कि सुपर के साथ भिड़ना नहीं है करने के लिए पैरामीटर का नाम बदल कक्षा घोषणा।

कक्षा घोषणा में, निर्माता घोषणाओं में पैरामीटर अक्सर पैरामीटर से अधिक होते हैं। val या var का उपयोग करके, आप वास्तव में संपत्ति सदस्यों को घोषित कर रहे हैं (केवल पैरामीटर नहीं)। और संपत्ति के सदस्यों के साथ var के मामले में स्वचालित "गेटर्स" (और "सेटर्स" आते हैं)। ओपी के मामले में स्वचालित गेटटर को getContext()कहा जाता है लेकिन बेस क्लास में पहले से ही getContext() (समान हस्ताक्षर) है।

सबसे अधिक संभावना है कि यहां पर इरादा context सुपर को पास करना था, इस मामले में, दूसरा उत्तर सबसे अच्छा काम करता है। लेकिन, जिस मामले में एक नई संपत्ति वांछित है, लेकिन नाम का चयन अलग-अलग उद्देश्य से सदस्य के साथ टकराता है, नाम बदलने का विकल्प वैकल्पिक है।

कम में, नाम बदलने के लिए लागू होता है जब आप एक नए सदस्य चर लेकिन एक सुपर वर्ग पहले से ही इसी नाम से एक अलग सदस्य को उजागर करता है चाहते हो

+0

मुझे लगता है कि यह संस्करण स्वीकार्य उत्तर के लिए वास्तव में अधिक बेहतर है। यदि मेरे सुपर क्लास में पहले से ही एक वैरिएबल के लिए एक प्रॉपर्टी/गेटर/सेटर है, तो मैं दूसरा क्यों बनाऊंगा? 'Val/var' को हटाने के लिए निश्चित रूप से जाने का सबसे आसान तरीका लगता है। – withoutclass

+0

@withoutclass - आप मेरे जवाब को गलत समझते हैं, मेरा वास्तव में कहता है कि आप वैल या var रख सकते हैं और केवल वेरिएबल का नाम बदल सकते हैं, जो उपयोगी है जब सुपर क्लास पहले से आपके द्वारा चुने गए पहले नाम का उपयोग करता है। ऐसे मामले में जहां सुपर क्लास एक संपत्ति के लिए नाम का उपयोग पूरी तरह से अलग उद्देश्य से करती है, जो आप अपने चर के लिए योजना बना रहे थे, फिर एक अलग नाम अलग-अलग नाम का उपयोग कर उपयुक्त है। मैं इसे और अधिक स्पष्ट करने के लिए अपना उत्तर अपडेट करूंगा। – Les

संबंधित मुद्दे