मौजूदा उत्तर केवल convenienceकहानी का आधा हिस्सा बताते हैं । कहानी का दूसरा आधा हिस्सा, जो मौजूदा उत्तरों में से कोई भी कवर नहीं करता है, डेसमंड ने टिप्पणियों में पोस्ट किए गए प्रश्न का उत्तर दिया है:
स्विफ्ट मुझे convenienceअपने इनिशियलाइज़र के सामने रखने के लिए मजबूर क्यों करेगा क्योंकि मुझे self.initइससे कॉल करने की आवश्यकता है ? `
मैंने इस उत्तर में इसे थोड़ा सा स्पर्श किया , जिसमें मैंने स्विफ्ट के कई प्रारंभिक नियमों को विवरण में शामिल किया, लेकिन मुख्य फोकस requiredशब्द पर था । लेकिन यह जवाब अभी भी कुछ ऐसा था जो इस प्रश्न और इस उत्तर के लिए प्रासंगिक है। हमें यह समझना होगा कि स्विफ्ट इनिशियलाइज़र इनहेरिटेंस कैसे काम करता है।
क्योंकि स्विफ्ट एकतरफा चर के लिए अनुमति नहीं देता है, तो आपको उस वर्ग से सभी (या किसी भी) इनिशियलाइज़र को विरासत में प्राप्त करने की गारंटी नहीं है। यदि हम अपने उपवर्ग में किसी भी प्रकार के असंगठित उदाहरण चर जोड़ते हैं, तो हमने आरंभीकरण को रोक दिया है। और जब तक हम अपने खुद के इनिशियलाइज़र नहीं जोड़ते, तब तक कंपाइलर हमारे ऊपर चिल्लाएगा।
स्पष्ट होने के लिए, एक uninitialized इंस्टेंस वैरिएबल कोई भी इंस्टेंस वैरिएबल है जिसे डिफॉल्ट वैल्यू नहीं दिया गया है (ध्यान में रखते हुए कि ऑप्शनल और इम्प्लांटली अनप्रैप्टेड ऑप्शंस अपने आप डिफॉल्ट वैल्यू मान लेते हैं nil)।
तो इस मामले में:
class Foo {
var a: Int
}
aएक असंक्रमित उदाहरण चर है। यह तब तक संकलित नहीं होगा जब तक हम aएक डिफ़ॉल्ट मूल्य नहीं देते :
class Foo {
var a: Int = 0
}
या aएक आरंभिक विधि में आरंभ करें:
class Foo {
var a: Int
init(a: Int) {
self.a = a
}
}
अब, देखते हैं कि अगर हम उपवर्ग करते हैं तो क्या होगा Foo?
class Bar: Foo {
var b: Int
init(a: Int, b: Int) {
self.b = b
super.init(a: a)
}
}
सही? हमने एक वैरिएबल जोड़ा है, और हमने एक इनिशियलाइज़र जोड़ा है bताकि एक मान सेट किया जा सके ताकि यह संकलित हो जाए। आप किस भाषा से आ रहे हैं, इस पर निर्भर करते हुए, आप उम्मीद कर सकते हैं कि आपको इनिशियलाइज़र Barविरासत में मिला है । लेकिन यह नहीं है। और यह कैसे हो सकता है? कैसे करता है पता है कि कैसे करने के लिए एक मूल्य निर्दिष्ट है कि चर जोड़ा? यह नहीं है इसलिए हम एक ऐसे इनिशियलाइज़र के साथ एक उदाहरण को इनिशियलाइज़ नहीं कर सकते हैं जो हमारे सभी मूल्यों को इनिशियलाइज़ नहीं कर सकता है।Fooinit(a: Int)Fooinit(a: Int)bBarBar
इसका किसी से क्या लेना-देना है convenience?
ठीक है, आइए आरंभिक विरासत पर नियमों को देखें :
नियम 1
यदि आपका उप-वर्ग किसी भी निर्दिष्ट इनिशियलाइज़र को परिभाषित नहीं करता है, तो यह स्वचालित रूप से अपने सभी सुपरक्लास नामित इनिशियलाइज़र को विरासत में देता है।
नियम २
यदि आपका उप-वर्ग अपने सभी सुपरक्लास नामित इनिशियलाइज़र के कार्यान्वयन को प्रदान करता है - या तो उन्हें नियम 1 के अनुसार विरासत में मिला है, या इसकी परिभाषा के भाग के रूप में एक कस्टम कार्यान्वयन प्रदान करता है - तो यह स्वचालित रूप से सभी सुपरक्लास सुविधा इनिशियलाइज़र को विरासत में मिला है।
सूचना नियम 2, जिसमें सुविधा प्रारंभकों का उल्लेख है।
इसलिए convenienceकीवर्ड जो कुछ भी करता है वह हमें इंगित करता है कि कौन से इनिशियलाइज़र को उन उपवर्गों द्वारा विरासत में मिला जा सकता है जो डिफ़ॉल्ट मानों के बिना उदाहरण चर जोड़ते हैं।
आइए इस उदाहरण को लें Base:
class Base {
let a: Int
let b: Int
init(a: Int, b: Int) {
self.a = a
self.b = b
}
convenience init() {
self.init(a: 0, b: 0)
}
convenience init(a: Int) {
self.init(a: a, b: 0)
}
convenience init(b: Int) {
self.init(a: 0, b: b)
}
}
ध्यान दें, हमारे पास तीन हैं convenience इनिशियलाइज़र हैं। इसका मतलब है कि हमारे पास तीन शुरुआती हैं जो विरासत में मिले हैं। और हमारे पास एक निर्दिष्ट इनिशियलाइज़र है (एक निर्दिष्ट इनिशियलाइज़र केवल कोई इनिशियलाइज़र है जो एक सुविधा आरम्भक नहीं है)।
हम चार अलग-अलग तरीकों से बेस क्लास के इंस्टेंस को इंस्टेंट कर सकते हैं:

तो, चलो एक उपवर्ग बनाएँ।
class NonInheritor: Base {
let c: Int
init(a: Int, b: Int, c: Int) {
self.c = c
super.init(a: a, b: b)
}
}
हमें विरासत में मिली है Base। हमने अपना खुद का इंस्टालेशन वेरिएबल जोड़ा है और हमने इसे डिफॉल्ट वैल्यू नहीं दिया है, इसलिए हमें अपने इनिशियलाइज़र को जोड़ना होगा। हमने एक जोड़ा init(a: Int, b: Int, c: Int), लेकिन यह Baseवर्ग के निर्दिष्ट इनिशियलाइज़र के हस्ताक्षर से मेल नहीं खाता init(a: Int, b: Int):। इसका मतलब है, हम किसी भी शुरुआती से विरासत में नहीं मिल रहे हैं Base:

इसलिए, अगर हमें विरासत में मिला है Base, तो क्या होगा , लेकिन हमने आगे बढ़कर एक इनिशियलाइज़र को लागू किया, जो निर्दिष्ट इनिशियलाइज़र से मेल खाता है Base?
class Inheritor: Base {
let c: Int
init(a: Int, b: Int, c: Int) {
self.c = c
super.init(a: a, b: b)
}
convenience override init(a: Int, b: Int) {
self.init(a: a, b: b, c: 0)
}
}
अब, हमने इस कक्षा में सीधे लागू किए गए दो इनिशियलाइज़र्स के अलावा, क्योंकि हमने इनिशियलाइज़र मिलान Baseक्लास के निर्दिष्ट इनिशियलाइज़र को लागू किया है, हमें Baseक्लास के सभी convenienceइनिशियलाइज़र्स विरासत में मिलते हैं :

तथ्य यह है कि मिलान हस्ताक्षर के साथ इनिशलाइज़र को चिह्नित किया जाता है, convenienceयहाँ कोई अंतर नहीं है। इसका केवल यह अर्थ है कि Inheritorकेवल एक निर्दिष्ट इनिशियलाइज़र है। इसलिए अगर हमें विरासत में मिली है Inheritor, तो हमें बस उस एक नामित इनिशियलाइज़र को लागू करना होगा, और उसके बाद हम Inheritorइनिशियलाइज़र को इनहेरिट करेंगे , जिसका अर्थ है कि हमने सभी Baseइनिशियलाइज़ इनिशियलाइज़र्स को लागू किया है और इसके convenienceइनिशियलाइज़र को इनहेरिट किया जा सकता है।