वर्ग विस्तार बनाम वर्ग श्रेणी


82

कक्षा विस्तार @interface Class () बहुत अधिक शक्तिशाली हैं और कक्षा में चर इंजेक्ट कर सकते हैं। श्रेणियाँ @interface Class (Category)नहीं कर सकते

अन्य अंतर क्या हैं, और एक वर्ग विस्तार पर एक श्रेणी का उपयोग कब करना चाहिए?


श्रेणियां वास्तविक कोड हैं। वे जानते हैं कि आप एक वर्ग में कैसे सुविधाएँ जोड़ते हैं। एक्सटेंशन (बहुत सामान्य शब्दों में) अन्य प्रोग्रामर को गोपनीयता, आदि के बारे में कुछ विचारों को इंगित करने के लिए और अधिक सिंटैक्टिकल चीनी हैं। एक्सटेंशन में कोई कोड नहीं है और कोड नहीं हैं।
फेटी

एक्सटेंशन के रूप में वे स्विफ्ट में उपयोग किए जाते हैं, इस प्रश्न को देखें: stackoverflow.com/questions/24142829/…
सुरगछ

जवाबों:


91

मुख्य अंतर यह है कि एक विस्तार के साथ, कंपाइलर आपको अपने मुख्य के भीतर तरीकों को लागू करने की उम्मीद करेगा @implementation, जबकि एक श्रेणी के साथ आपके पास एक अलग @implementationब्लॉक है। इसलिए आपको अपने मुख्य .mफ़ाइल के शीर्ष पर एक एक्सटेंशन का उपयोग करना चाहिए (केवल एक जगह जिसे आपको ivars के बारे में परवाह करना चाहिए, संयोग से) - इसका मतलब सिर्फ इतना ही है, एक विस्तार


41
एक एक्सटेंशन निजी तरीकों के लिए सबसे अच्छा है जिसे आप अपनी .mफ़ाइल में घोषित करना चाहते हैं । मैं हर समय इसके लिए उपयोग करता हूं। जब आप अपने तरीकों को अलग-अलग वर्गों - श्रेणियों :) में समूहित करना चाहते हैं तो श्रेणियाँ अधिक उपयोगी होती हैं - या जब आप मौजूदा कक्षाओं में कोड जोड़ना चाहते हैं जो आपने नहीं बनाया था।
jtbandes

1
आप अतिरिक्त स्टोरेज को भी जोड़ सकते हैं गुण का उपयोग करके वर्ग एक्सटेंशन है।
पॉल।

23
क्लास एक्सटेंशन भी विशेष रूप से एक संपत्ति को सार्वजनिक readonlyऔर निजी रूप से अनुमति देने के लिए डिज़ाइन किए गए थे readwrite। श्रेणियों (एक जागरूक डिजाइन विकल्प) के साथ ऐसा नहीं कर सकते।
bbum

एक्सटेंशन के बजाय निजी विधियों को लागू करने के लिए Google श्रेणी का उपयोग क्यों कर रहा है? उदाहरण के लिए code.google.com/p/gdata-objectivec-client/source/browse/trunk/…
Ryan

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

29

एक वर्ग विस्तार एक श्रेणी के लिए कुछ समानता रखता है, लेकिन इसे केवल उस वर्ग में जोड़ा जा सकता है जिसके लिए आपके पास संकलन समय पर स्रोत कोड है (वर्ग विस्तार के रूप में उसी समय संकलित किया जाता है)। एक क्लास एक्सटेंशन द्वारा घोषित तरीकों को मूल वर्ग के लिए @ लागू कार्यान्वयन ब्लॉक में लागू किया जाता है, इसलिए आप उदाहरण के लिए, फ्रेमवर्क क्लास पर एक क्लास एक्सटेंशन घोषित नहीं कर सकते हैं, जैसे कि कोको या कोको टच क्लास जैसे एनएसएसटीरिंग।

वर्ग विस्तार घोषित करने का वाक्य-विन्यास किसी श्रेणी के लिए वाक्य-विन्यास के समान है, और इस तरह दिखता है:

@interface ClassName ()
@end

कोष्ठक में कोई नाम नहीं दिए जाने के कारण, क्लास एक्सटेंशन को अक्सर अनाम श्रेणियों के रूप में संदर्भित किया जाता है।

नियमित श्रेणियों के विपरीत, एक वर्ग विस्तार अपने गुणों को जोड़ सकता है और एक वर्ग के उदाहरण चर सकता है। यदि आप एक क्लास एक्सटेंशन में एक संपत्ति की घोषणा करते हैं, तो इस तरह:

@interface XYZAnimal () {
    id _someCustomInstanceVariable;
}
...
@end

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

निजी जानकारी छिपाने के लिए वर्ग एक्सटेंशन का उपयोग करें

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

एक उदाहरण के रूप में, XYZPERS वर्ग यूनीक आईडेंटिफायर नामक एक संपत्ति जोड़ सकता है, जिसे अमेरिका में एक सामाजिक सुरक्षा नंबर जैसी जानकारी का ट्रैक रखने के लिए डिज़ाइन किया गया है।

आमतौर पर असली दुनिया में किसी व्यक्ति को एक विशिष्ट पहचानकर्ता को सौंपे जाने के लिए बड़ी मात्रा में कागजी कार्रवाई की आवश्यकता होती है, इसलिए XYZPERS वर्ग इंटरफ़ेस इस संपत्ति को आसानी से घोषित कर सकता है, और कुछ तरीका प्रदान करता है जो एक पहचानकर्ता को असाइन करने का अनुरोध करता है, जैसे कि

@interface XYZPerson : NSObject
    ...
    @property (readonly) NSString *uniqueIdentifier;
    - (void)assignUniqueIdentifier;
@end

XYZPERS वर्ग के लिए आंतरिक रूप से संपत्ति को बदलने में सक्षम होने के लिए, यह वर्ग विस्तार के लिए संपत्ति को फिर से परिभाषित करने के लिए समझ में आता है जो वर्ग के लिए कार्यान्वयन फ़ाइल के शीर्ष पर परिभाषित किया गया है:

@property (readwrite) NSString *uniqueIdentifier;

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


7

श्रेणियाँ एक उद्देश्य-सी भाषा की सुविधा है जो आपको मौजूदा कक्षा में नए तरीके जोड़ने देती है। एक्सटेंशन श्रेणियों का एक विशेष मामला है जो आपको उन तरीकों को परिभाषित करते हैं जिन्हें मुख्य कार्यान्वयन ब्लॉक में लागू किया जाना चाहिए।

निजी घोषणाएं क्लास एक्सटेंशन में हो सकती हैं, जो मुख्य रूप से कुछ गुण हैं, क्योंकि हमें कॉल करने से पहले हमें कोई विधि घोषित करने की आवश्यकता नहीं है।


"जिसे मुख्य कार्यान्वयन ब्लॉक में घोषित किया जाना चाहिए।" -> कि मुख्य कार्यान्वयन ब्लॉक में "लागू किया जाना चाहिए"
Fawkes

धन्यवाद, मैंने इसे संशोधित किया है।
जूली यू

0

ios एक्सटेंशन c # के समान, java अमूर्त वर्ग या इंटरफ़ेस
ios श्रेणी, c # वर्ग एक्सटेंशन के समान है


जावा एक्सटेंशन विधियों का समर्थन नहीं करता है
someUser

माफ़ करना ! कॉपी-पेस्ट टाइपो। ios श्रेणी c # वर्ग विस्तार के अनुरूप है।
Add080bbA

क्या आप इसके बारे में एक उदाहरण जोड़ सकते हैं?
पेड्रो ट्रूजिलो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.