निम्नलिखित कोड में मैं क्लास इंस्टेंस का संदर्भ सेट करना चाहता हूं ताकि स्थिर कार्य इसका संदर्भ वापस कर सकें:

open class TestRunner {

    init {
        instance = this
    }

    companion object {
        private lateinit var instance: TestRunner

        fun addTestSetups(vararg testSetups: () -> TestSetup): TestRunner {
           for (setup in testSetups) {
              testsSetups.add(setup)
           }

           return instance
        }
    }
}

लेकिन instance = this सेटिंग की अनुमति नहीं है। कक्षा को सिंगलटन के रूप में रखते हुए मैं किसी फ़ंक्शन से कक्षा का उदाहरण कैसे वापस कर सकता हूं?

0
Johann 7 पद 2019, 13:15
साथी वस्तु से init ब्लॉक निकालें। इस ब्लॉक में, this साथी वस्तु है, जो एक टेस्टरनर नहीं है, बल्कि एक टेस्टरनर है। साथी (जैसा कि त्रुटि संदेश बताता है)
 – 
JB Nizet
7 पद 2019, 13:17
क्षमा करें, मैंने उस कोड को पहले हटाए बिना चिपका दिया। मैंने वास्तव में इसे हटा दिया था। मैंने उपरोक्त कोड को सही किया है, लेकिन सवाल वही रहता है।
 – 
Johann
7 पद 2019, 13:19
यह कोड ठीक संकलित करता है (अपरिभाषित चर और कक्षाओं को छोड़कर)। आप क्या कर रहे हैं, आप क्या होने की उम्मीद करते हैं, इसके बजाय क्या होता है? सटीक होना। आपको प्राप्त होने वाला कोई भी पूर्ण और सटीक त्रुटि संदेश शामिल करें।
 – 
JB Nizet
7 पद 2019, 13:21
AddTestSetups फ़ंक्शन में, यह TestRunner देता है। मैं कार्यों की श्रृंखला की अनुमति देने के लिए ऐसा करता हूं। लेकिन काम करने के लिए जंजीर के लिए, मुझे कक्षा के उदाहरण के संदर्भ की आवश्यकता है। तो "उदाहरण" चर को सेट करने की आवश्यकता है।
 – 
Johann
7 पद 2019, 13:24
इंस्टेंस सेट करना = यह इस की अनुमति है। तो आपका सवाल क्या है? प्रासंगिक कोड पोस्ट करें। बताएं कि आप क्या कर रहे हैं, आप क्या होने की उम्मीद करते हैं, इसके बजाय क्या होता है? सटीक होना। आपको प्राप्त होने वाला कोई भी पूर्ण और सटीक त्रुटि संदेश शामिल करें।
 – 
JB Nizet
7 पद 2019, 13:26

3 जवाब

यह काम करने लगता है। कक्षा के संदर्भ में एक चर रखने के बजाय, कक्षा के नाम का संदर्भ देना पर्याप्त है। हालांकि, कार्यों से वर्ग का एक उदाहरण वापस करने के लिए, वापसी प्रकार सहयोगी होना चाहिए:

open class TestRunner {
    companion object {
        fun addTestSetups(vararg testSetups: () -> TestSetup): Companion {
           for (setup in testSetups) {
              testsSetups.add(setup)
           }

           return TestRunner
        }
    }
}

यह एक सच्चा सिंगलटन नहीं है क्योंकि यदि आप ऐसा करते हैं तो भी आप एक नया उदाहरण बना सकते हैं:

val testRunner = TestRunner()

हालाँकि, यदि आप कभी भी एक उदाहरण नहीं बनाते हैं, लेकिन केवल कार्यों को स्थिर रूप से संदर्भित करते हैं, तो यह एक सिंगलटन की तरह व्यवहार करता है और साथी वस्तु के अंदर किसी भी निजी चर की स्थिति अभी भी बनी रहेगी।

अपडेट करें:

मैं एंड्रॉइड डेवलपर साइट पर इस कोड में आया था जो एक वर्ग का एक उदाहरण दिखाता है जो सिंगलटन के रूप में स्थापित है:

class StockLiveData(symbol: String) : LiveData<BigDecimal>() {
    private val stockManager: StockManager = StockManager(symbol)

    private val listener = { price: BigDecimal ->
        value = price
    }

    override fun onActive() {
        stockManager.requestPriceUpdates(listener)
    }

    override fun onInactive() {
        stockManager.removeUpdates(listener)
    }

    companion object {
        private lateinit var sInstance: StockLiveData

        @MainThread
        fun get(symbol: String): StockLiveData {
            sInstance = if (::sInstance.isInitialized) sInstance else StockLiveData(symbol)
            return sInstance
        }
    }
}

लेकिन यह इंगित किया जाना चाहिए कि इस उदाहरण के लिए ऐसे कार्यों की आवश्यकता होती है जिन्हें पहले एक उदाहरण वापस करने की आवश्यकता होती है, यह जांचने के लिए कि क्या आवृत्ति चर सेट है और यदि नहीं, तो एक नया उदाहरण बनाएं। मुझे यकीन नहीं है कि उस फ़ंक्शन को कॉल करने के बाद से आपके पास पहले से ही एक उदाहरण है। तो परेशान क्यों एक नया उदाहरण बनाते हैं? कोई मतलब नहीं लगता।

0
Johann 7 पद 2019, 17:02
आपके शीर्ष उदाहरण में, यदि आप TestRunner को उपवर्गित करते हैं, तो आप साथी ऑब्जेक्ट के कार्यों को इनहेरिट नहीं कर सकते। सहयोगी वस्तुएं बाहरी वर्ग परिभाषा का हिस्सा नहीं हैं। वे केवल सिंगलटन हैं जिन्हें आसानी से उस बाहरी वर्ग के नाम से संदर्भित किया जा सकता है।
 – 
Tenfour04
7 पद 2019, 19:26

कोटलिन में object सिंगलटन है, न कि इसके भीतर परिभाषित वर्ग। एक साथी वस्तु में आपको उस बाहरी वर्ग के नाम से कॉल करने की अनुमति देने की अतिरिक्त सुविधा होती है। लेकिन यह अन्यथा इसके साथ कोई पदानुक्रम साझा नहीं करता है।

अपनी कक्षा को उपवर्गीय बनाने के लिए, आप सहयोगी वस्तु में कार्यों को परिभाषित नहीं कर सकते। लेकिन आप क्लास को एब्सट्रैक्ट बना सकते हैं, इसलिए इसे तब तक इंस्टेंट नहीं किया जा सकता जब तक कि सबक्लास न हो जाए। फिर अपने साथी वस्तु को अमूर्त वर्ग का विस्तार करें ताकि उसके पास वे सभी कार्य उपलब्ध हों।

abstract class TestRunner{
    open fun addTestSetups(vararg testSetups: () -> TestSetup): TestRunner{
        //...
        return this
    }

    companion object: TestRunner()
}

उपयोग:

TestRunner.addTestSetups(someTestSetup)

ध्यान दें कि आपका सिंगलटन TestRunner का उदाहरण नहीं है। यह TestRunner के उपवर्ग का सिंगलटन उदाहरण है। लेकिन चूंकि आप कोई अतिरिक्त फ़ंक्शन परिभाषित नहीं करते हैं और कुछ भी ओवरराइड नहीं करते हैं, यह बिल्कुल टेस्टरनर की तरह व्यवहार करता है।

यदि आप एक उपवर्ग चाहते हैं:

abstract class ExtendedTestRunner: TestRunner() {

    fun someOtherFunction() {}

    companion object: ExtendedTestRunner()
}

साथियों को उपवर्गित नहीं किया जा रहा है, लेकिन उनके अमूर्त माता-पिता हो सकते हैं।

0
Tenfour04 7 पद 2019, 19:30

अगर मैं आपको सही समझता हूं, तो आपको ऐसा कुछ चाहिए:

abstract class TestRunner {
    companion object : TestRunner()
}
0
Bananon 7 पद 2019, 13:47
नहीं। सार वर्गों का कोई कार्यान्वयन नहीं है। मैं सिर्फ कार्यों में कक्षा के उदाहरण का संदर्भ वापस करना चाहता था। नीचे मेरा समाधान देखें।
 – 
Johann
7 पद 2019, 14:22