मुझे दोनों के बीच के अंतर या उद्देश्य को समझने में परेशानी हो रही है convenience init
।
मुझे दोनों के बीच के अंतर या उद्देश्य को समझने में परेशानी हो रही है convenience init
।
जवाबों:
मानक init
:
नामित इनिशियलाइज़र एक क्लास के लिए प्राइमरी इनिशियलाइज़र हैं। एक नामित इनिशियलाइज़र उस वर्ग द्वारा शुरू की गई सभी संपत्तियों को पूरी तरह से इनिशियलाइज़ करता है और सुपरक्लास चेन को इनिशियलाइज़ेशन प्रक्रिया जारी रखने के लिए एक उपयुक्त सुपरक्लास इनिशलाइज़र कहता है।
convenience init
:
सुविधा इनिशियलाइज़र माध्यमिक हैं, एक वर्ग के लिए इनिशियलाइज़र का समर्थन करते हैं। आप एक सुविधा इनिशियलाइज़र को एक ही वर्ग से निर्दिष्ट इनिशियलाइज़र के रूप में परिभाषित करने के लिए सुविधा इनिशियलाइज़र के रूप में परिभाषित कर सकते हैं, जिसमें कुछ इनिशियलाइज़र मापदंडों को डिफ़ॉल्ट मानों पर सेट किया गया है। आप विशिष्ट उपयोग के मामले या इनपुट मूल्य प्रकार के लिए उस वर्ग का उदाहरण बनाने के लिए एक सुविधा इनिशियलाइज़र को भी परिभाषित कर सकते हैं।
स्विफ्ट डॉक्यूमेंटेशन के अनुसार
संक्षेप में, इसका मतलब यह है कि आप एक नामित इनिशियलाइज़र को कॉल करने के लिए एक सुविधा इनिशियलाइज़र का उपयोग कर सकते हैं जो तेजी से और अधिक "सुविधाजनक" है। इसलिए सुविधा इनिशियलाइज़र self.init
के लिए super.init
आपको निर्दिष्ट इनिशियलाइज़र के ओवरराइड में देखने के बजाय इसके उपयोग की आवश्यकता होती है।
स्यूडोकोड उदाहरण:
init(param1, param2, param3, ... , paramN) {
// code
}
// can call this initializer and only enter one parameter,
// set the rest as defaults
convenience init(myParamN) {
self.init(defaultParam1, defaultParam2, defaultParam3, ... , myParamN)
}
कस्टम दृश्य बनाते समय और मुख्य रूप से चूक के साथ लंबे आरंभीकरण करने वाले ऐसे लोगों का उपयोग करता हूं। डॉक्स एक बेहतर काम करते हैं जो मैं समझा सकता हूं, उन्हें देखें!
सुविधा इनिशियलाइज़र का उपयोग तब किया जाता है जब आपके पास बहुत सारे गुणों के साथ कुछ वर्ग होता है जो इसे "दर्दनाक" के रूप में हमेशा सभी वैरिएबल्स के साथ बुद्धि को इनिशियलाइज़ करता है, इसलिए आप सुविधा इनिशियलाइज़र के साथ क्या करते हैं, यह है कि आप कुछ वैरिएबल्स को आरंभीकृत करने के लिए पास करते हैं ऑब्जेक्ट, और बाकी को एक डिफ़ॉल्ट मान के साथ असाइन करें। रे वेंडरलिच वेबसाइट पर एक बहुत अच्छा वीडियो है, यह सुनिश्चित नहीं है कि यह मुफ़्त है या नहीं क्योंकि मेरे पास एक भुगतान किया गया खाता है। यहां एक उदाहरण है जहां आप देख सकते हैं कि मेरी वस्तु को उन सभी चर के साथ आरम्भ करने के बजाय मैं इसे एक शीर्षक दे रहा हूं।
struct Scene {
var minutes = 0
}
class Movie {
var title: String
var author: String
var date: Int
var scenes: [Scene]
init(title: String, author: String, date: Int) {
self.title = title
self.author = author
self.date = date
scenes = [Scene]()
}
convenience init(title:String) {
self.init(title:title, author: "Unknown", date:2016)
}
func addPage(page: Scene) {
scenes.append(page)
}
}
var myMovie = Movie(title: "my title") // Using convenicence initializer
var otherMovie = Movie(title: "My Title", author: "My Author", date: 12) // Using a long normal initializer
यहाँ एक सरल उदाहरण है, Apple डेवलपर पोर्टल से लिया गया है ।
मूल रूप से नामित इनिशियलाइज़र है init(name: String)
, यह सुनिश्चित करता है कि सभी संग्रहित संपत्तियों को इनिशियलाइज़ किया जाए।
init()
सुविधा प्रारंभकर्ता, कोई तर्क ले, स्वत: का मान सेट name
संग्रहीत संपत्ति के लिए [Unnamed]
नामित प्रारंभकर्ता का उपयोग करके।
class Food {
let name: String
// MARK: - designated initializer
init(name: String) {
self.name = name
}
// MARK: - convenience initializer
convenience init() {
self.init(name: "[Unnamed]")
}
}
// MARK: - Examples
let food = Food(name: "Cheese") // name will be "Cheese"
let food = Food() // name will be "[Unnamed]"
यह उपयोगी है, जब आप बड़ी कक्षाओं के साथ काम कर रहे हैं, कम से कम कुछ संग्रहीत गुणों के साथ। मैं Apple डेवलपर पोर्टल पर वैकल्पिक और वंशानुक्रम के बारे में कुछ और पढ़ने की सिफारिश करूंगा ।
मेरे लिए, convenience initializers
उपयोगी हैं यदि एक वर्ग संपत्ति के लिए बस एक डिफ़ॉल्ट मान सेट करने के लिए और अधिक है।
अन्यथा, मैं बस init
परिभाषा में डिफ़ॉल्ट मान सेट करूँगा , उदाहरण के लिए:
class Animal {
var race: String // enum might be better but I am using string for simplicity
var name: String
var legCount: Int
init(race: String = "Dog", name: String, legCount: Int = 4) {
self.race = race
self.name = name
self.legCount = legCount // will be 4 by default
}
}
हालाँकि, डिफ़ॉल्ट मान सेट करने के अलावा और भी बहुत कुछ हो सकता है, और यह convenience initializers
काम में आता है:
extension Animal {
convenience init(race: String, name: String) {
var legs: Int
if race == "Dog" {
legs = 4
} else if race == "Spider" {
legs = 8
} else {
fatalError("Race \(race) needs to be implemented!!")
}
// will initialize legCount automatically with correct number of legs if race is implemented
self.init(race: race, name: name, legCount: legs)
}
}
// default init with all default values used
let myFirstDog = Animal(name: "Bello")
// convenience init for Spider as race
let mySpider = Animal(race: "Spider", name: "Itzy")
// default init with all parameters set by user
let myOctopus = Animal(race: "Octopus", name: "Octocat", legCount: 16)
// convenience init with Fatal error: Race AlienSpecies needs to be implemented!!
let myFault = Animal(race: "AlienSpecies", name: "HelloEarth")
एक सुविधा आरम्भिक को एक वर्ग विस्तार में परिभाषित किया जा सकता है । लेकिन एक मानक एक - नहीं कर सकता।
यह समझ में आता है कि यदि आपका उपयोग मामला एक इनीशियलाइज़र को उसी क्लास में एक इनिशियलाइज़र को कॉल करने के लिए है ।
खेल के मैदान में ऐसा करने की कोशिश करें
class Player {
let name: String
let level: Int
init(name: String, level: Int) {
self.name = name
self.level = level
}
init(name: String) {
self.init(name: name, level: 0) //<- Call the initializer above?
//Sorry you can't do that. How about adding a convenience keyword?
}
}
Player(name:"LoseALot")
सुविधा कीवर्ड के साथ
class Player {
let name: String
let level: Int
init(name: String, level: Int) {
self.name = name
self.level = level
}
//Add the convenience keyword
convenience init(name: String) {
self.init(name: name, level: 0) //Yes! I am now allowed to call my fellow initializer!
}
}
नोट: पूरा पाठ पढ़ें
नामित इनिशियलाइज़र एक क्लास के लिए प्राइमरी इनिशियलाइज़र हैं। एक नामित इनिशियलाइज़र उस वर्ग द्वारा शुरू की गई सभी संपत्तियों को पूरी तरह से इनिशियलाइज़ करता है और सुपरक्लास चेन तक की इनिशियलाइज़ेशन प्रक्रिया को जारी रखने के लिए एक उपयुक्त सुपरक्लास इनिशलाइज़र को कॉल करता है।
सुविधा इनिशियलाइज़र माध्यमिक हैं, एक वर्ग के लिए इनिशियलाइज़र का समर्थन करते हैं। आप एक ही वर्ग से नामित इनिशियलाइज़र को कॉल करने के लिए एक सुविधा इनिशियलाइज़र को परिभाषित कर सकते हैं क्योंकि सुविधा इनिशियलाइज़र कुछ निर्दिष्ट इनिशियलाइज़र के मापदंडों के साथ डिफ़ॉल्ट पर सेट है।
वर्गों के लिए नामित इनिशियलाइज़र उसी तरह लिखे जाते हैं जैसे कि वैल्यू टाइप्स के लिए सिंपल इनिशियलाइज़र:
init(parameters) {
statements
}
सुविधा इनिशियलाइज़र एक ही शैली में लिखे गए हैं, लेकिन init कीवर्ड से पहले रखी गई सुविधा संशोधक के साथ, एक स्थान द्वारा अलग किया गया है:
convenience init(parameters) {
statements
}
एक व्यावहारिक उदाहरण निम्नानुसार हैं:
class Food {
var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "[Unnamed]")
}
}
let namedMeat = Food(name: "Bacon")
// namedMeat's name is "Bacon”
Init (नाम: स्ट्रिंग) फूड क्लास से इनिशियलाइज़र को निर्दिष्ट इनिशियलाइज़र के रूप में प्रदान किया जाता है क्योंकि यह सुनिश्चित करता है कि नए फ़ूड इंस्टेंस के सभी संग्रहीत गुण पूरी तरह से इनिशियलाइज़ किए गए हों। खाद्य वर्ग के पास सुपरक्लास नहीं है, और इसलिए इनिट (नाम: स्ट्रिंग) इनिशियलाइज़र को इसके इनिशियलाइज़ेशन को पूरा करने के लिए सुपर.इनिट () को कॉल करने की आवश्यकता नहीं है।
“खाद्य वर्ग भी कोई तर्क के साथ, एक सुविधा इनिशियलाइज़र, इनिट () प्रदान करता है। Init () initializer एक नए भोजन के लिए एक डिफ़ॉल्ट प्लेसहोल्डर नाम प्रदान करता है जिसे फ़ूड क्लास के init (नाम: String) में एक नाम मान के साथ दर्शाया जाता है: "
“let mysteryMeat = Food()
// mysteryMeat's name is "[Unnamed]”
पदानुक्रम में दूसरा वर्ग भोजन का एक उपवर्ग है जिसे रेसिपीइन्ग्रिडिएंट कहा जाता है। पकाने की विधि में रेसिपीइन्ग्रेडिएंट क्लास मॉडल एक घटक है। यह मात्रा नामक एक Int गुण का परिचय देता है (नाम संपत्ति के अलावा यह भोजन से प्राप्त होता है) और RecipeIngredient इंस्टेंस बनाने के लिए दो इनिशियलाइज़र को परिभाषित करता है:
class RecipeIngredient: Food {
var quantity: Int
init(name: String, quantity: Int) {
self.quantity = quantity
super.init(name: name)
}
override convenience init(name: String) {
self.init(name: name, quantity: 1)
}
}
RecipeIngredient वर्ग में एक एकल निर्दिष्ट इनिशियलाइज़र, init (नाम: स्ट्रिंग, मात्रा: Int) है, जिसका उपयोग नए RecipeIngredient उदाहरण के सभी गुणों को पॉप्युलेट करने के लिए किया जा सकता है। यह इनिशलाइज़र पास की मात्रा तर्क को गुण संपत्ति में निर्दिष्ट करके शुरू होता है, जो कि RecipeIngredient द्वारा पेश की गई एकमात्र नई संपत्ति है। ऐसा करने के बाद, इनिलाइज़र खाद्य वर्ग के इनिट (नाम: स्ट्रिंग) इनिशलाइज़र को दर्शाता है।
पृष्ठ: 536 अंश से: Apple Inc. "स्विफ्ट प्रोग्रामिंग लैंग्वेज (स्विफ्ट 4)।" iBooks। https://itunes.apple.com/pk/book/the-swift-programming-language-swift-4-0-3/id881256329?mt=11
यह तब काम आता है जब आपको किसी वर्ग के लिए प्रत्येक संपत्ति को निर्दिष्ट करने की आवश्यकता नहीं होती है। इसलिए, उदाहरण के लिए, यदि मैं 100 के एचपी मूल्य को शुरू करने के साथ सभी रोमांच बनाना चाहता हूं, तो मैं इस सुविधा सुविधा का उपयोग करूंगा और बस एक नाम जोड़ूंगा । यह कोड में बहुत कटौती करने जा रहा है।
class Adventure {
// Instance Properties
var name: String
var hp: Int
let maxHealth: Int = 100
// Optionals
var specialMove: String?
init(name: String, hp: Int) {
self.name = name
self.hp = hp
}
convenience init(name: String){
self.init(name: name, hp: 100)
}
}
सभी उत्तर अच्छे लगते हैं लेकिन, इसे सरल उदाहरण से समझते हैं
class X{
var temp1
init(a: Int){
self.temp1 = a
}
अब, हम जानते हैं कि एक वर्ग दूसरे वर्ग को विरासत में दे सकता है
class Z: X{
var temp2
init(a: Int, b: Int){
self.temp2 = b
super.init(a: a)
}
अब, इस स्थिति में कक्षा Z के लिए उदाहरण बनाते समय, आपको दोनों मान 'a' और 'b' प्रदान करने होंगे।
let z = Z(a: 1, b: 2)
लेकिन, क्या होगा यदि आप केवल बी के मूल्य को पास करना चाहते हैं और बाकी को दूसरों के लिए डिफ़ॉल्ट मान लेना चाहते हैं, तो उस स्थिति में आपको अन्य मानों को एक डिफ़ॉल्ट मान को शुरू करने की आवश्यकता है। लेकिन रुको, कैसे? यू के लिए इसे केवल कक्षा में पहले ही अच्छी तरह से सेट करने की आवश्यकता है।
//This is inside the class Z, so consider it inside class Z's declaration
convenience init(b: Int){
self.init(a: 0, b: b)
}
convenience init(){
self.init(a: 0, b: 0)
}
और अब, आप चर के लिए कुछ, सभी या कोई भी मान प्रदान करने के साथ वर्ग Z के उदाहरण बना सकते हैं।
let z1 = Z(b: 2)
let z2 = Z()