inheritance सकत क्या एक तेज उप-वर्ग*हमेशा*को super.init को कॉल करना पड़ता है)




बिना नंबर दिखाए कर सकते हैं कॉल, स्क्रीन पर आएगा unknown नंबर (4)

अगर मेरे पास एक तेज उप-वर्ग है जो:

  1. self का उपयोग करने की आवश्यकता नहीं है
  2. self पर किसी भी संपत्ति का उपयोग करने की आवश्यकता नहीं है

क्या मुझे अभी भी उप-वर्ग की init() विधि में super.init() को कॉल super.init() ?

* नोट: यह एक अलग सवाल है, जो कि पूछा गया है और उत्तर में 1 और 2 में सूचीबद्ध विनिर्देशों के कारण SO पर यहां उत्तर दिया गया है।


मुझे लगता है कि आपको सुपर कॉल करने की ज़रूरत नहीं है मैंने स्थिति का अनुकरण करने की कोशिश की:

class Animal {
}

class Parrot: Animal {

    override init() {
        // Some code (super not called)
    }
}

हालांकि, मैं हमेशा असली ऐप में super.init को कॉल करने की सलाह देता हूं, जैसे आप उद्देश्य-सी में करने के लिए उपयोग करते हैं


डॉक्स से:

नामित प्रारंभिकियों को अपने तत्काल सुपरक्लास से नामित प्रारंभिक कॉल करना चाहिए।

इसके अलावा, स्वचालित प्रारंभिक विरासत के बारे में:

यह मानते हुए कि आप किसी उप-वर्ग में पेश किसी भी नए गुणों के लिए डिफ़ॉल्ट मान प्रदान करते हैं, तो निम्न दो नियम लागू होते हैं:

नियम 1 यदि आपका उपवर्ग किसी भी नामित प्रारंभिकता को परिभाषित नहीं करता है, तो यह स्वचालित रूप से अपने सभी सुपरक्लास नामित प्रारंभिकताओं को प्राप्त करता है।

नियम 2 यदि आपका उपवर्ग अपने सभी सुपरक्लास नामित प्रारंभिकों के कार्यान्वयन को प्रदान करता है - या तो नियम 1 के अनुसार उन्हें विरासत में लेकर या इसके परिभाषा के अनुसार एक कस्टम कार्यान्वयन प्रदान करके - तो यह स्वचालित रूप से सभी सुपरक्लूस सुविधा प्रारंभिकताएं प्राप्त करता है

ये नियम लागू होते हैं, भले ही आपका उप-वर्ग आगे सुविधा प्रारंभकर्ता जोड़ता हो।

तो आपके प्रश्न का उत्तर निम्नानुसार है:

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

इसके अलावा, जिस तरह से शुरुआती चीजों का निर्माण किया गया था, वह 2-चरण की प्रक्रिया में है। पहले चरण में, यह उप-वर्गों से सुपर क्लासेस की तरफ से शुरू होता है, किसी भी पैरामीटर के लिए डिफ़ॉल्ट मान निर्दिष्ट करता है। दूसरे चरण में, प्रक्रिया पीछे की तरफ चलती है, सुपर-क्लासेस से शुरू होती है और आपके उपवर्ग के साथ समाप्त होती है, जहां पैरामीटर का अनुकूलन किया जाता है और ओवरराइड किया जाता है।

इसका मतलब यह है कि आपको प्रत्येक init() में पहले सबसे पहले अपने चर को सेट करना होगा, और फिर आप super.init() को कॉल करने के लिए स्वतंत्र हैं या कस्टम कोड चला सकते हैं। तो जैसा कि आपने ऊपर पूछा, यदि आप सुपर की शुरुआत को चलाने के लिए चाहते हैं, तो 'शुरुआत' को अपने चर बनाने के बाद ही समझें:

class a {
    var name: String

    init() {
        name = "james"
        println("a")
    }
}

class b: a {
    let title: String

    override init() {
        title = "supervisor"
        super.init()
        self.name = "john"
        println("b")
    }
}

let x = b()

यह प्रिंट होगा, फिर बी।


नहीं, आपको नहीं करना है

मान लें कि आपके पास निम्नलिखित कक्षाएं हैं।

class a {
    let name: String

    init() {
        name = "james"
    }
}

class b: a {
    let title: String

    override init() {
        title = "supervisor"
    }
}

अगर आप एक वेरिएबल को इन्स्तांत करते हैं तो

let myVar = b()

फिर,

  • b में override init() बुलाया जाएगा
  • तो एक init() में कहा जाएगा

भले ही आपने स्पष्ट रूप से super.init() नहीं बुलाया

यह तेज स्विट-यूज़र की ईमेल सूची पर क्रिस लाटेनर द्वारा पुष्टि की गई है। यह जब आपके सुपर क्लास में शून्य-तर्क init के साथ एक नामित प्रारंभिक है यही कारण है कि जब आपको एनएसओबीजेक्स से निकलने के लिए सुपरइनिट () कॉल करना पड़ता है।

* Wingzero की टिप्पणी के लिए नीचे दिए गए धन्यवाद


हां, नामित आरम्भिकारी को प्रतिनिधि देना होगा, इसलिए इसे super.init () को कॉल करना होगा। यदि आप लाइन नहीं लिखते हैं, तो संकलक यह आपके लिए करेगा।

तो आपको स्पष्ट रूप से super.init(...) लिखना नहीं है, लेकिन उपवर्ग को करना है, यहां तक ​​कि पर्दा के पीछे भी।

लेकिन याद रखना, पहले चरण में आपको उपवर्ग में गुण सेट करना होगा, फिर super.init () को बुलाया जाना चाहिए। दूसरे चरण में आप सभी वंशानुगत गुणों को बदल सकते हैं। मुझे लगता है कि super.init() चरण 1 और चरण 2 के बीच एक आदर्श विभाजक है

डॉक्स से:

सुरक्षा जांच 2

किसी निर्दिष्ट आरंभिक को एक विरासत में आने वाली संपत्ति के लिए एक मूल्य निर्दिष्ट करने से पहले एक सुपरक्लास प्रारंभकर्ता को सौंपना चाहिए । यदि ऐसा नहीं होता है, तो नामित प्रारंभिक नियत किए गए नए मान को अपने स्वयं के प्रारंभिक भाग के रूप में सुपर क्लास द्वारा अधिलेखित किया जाएगा





swift