inheritance c
उदाहरणों के साथ C ++ में विरासत का महत्व:
वंशानुक्रम वस्तु-उन्मुख प्रोग्रामिंग की सबसे महत्वपूर्ण विशेषताओं में से एक है।
वंशानुक्रम वह तकनीक है जिसके द्वारा एक वर्ग दूसरे वर्ग के गुणों और विधियों को प्राप्त करता है। इस तरह हम उस कोड का पुनः उपयोग कर सकते हैं जो पहले से लिखा और सत्यापित है। किसी अन्य वर्ग के गुणों को प्राप्त करने वाले वर्ग को उपवर्ग या व्युत्पन्न वर्ग या बाल वर्ग कहा जाता है।
जिस वर्ग के गुणों का अधिग्रहण किया जाता है उसे बेस क्लास या पैरेंट क्लास या सुपरक्लास कहा जाता है। जब एक वर्ग दूसरे वर्ग को अधिग्रहित या विरासत में देता है, तो व्युत्पन्न वर्ग के लिए आधार वर्ग के सभी गुण और तरीके उपलब्ध होते हैं, ताकि हम इस कोड का पुन: उपयोग कर सकें।
=> स्क्रैच से C ++ जानने के लिए यहाँ जाएँ।
जावा में बाइनरी सर्च ट्री प्रोग्राम
आप क्या सीखेंगे:
- हमें वंशानुक्रम की आवश्यकता क्यों है?
- विरासत के मोड
- इनहेरिटेंस में कंस्ट्रक्टर्स / डिस्ट्रक्टर्स का क्रम
- वंशानुक्रम के प्रकार
- टेम्प्लेट इनहेरिटेंस
- रचना
- हमें रचना और विरासत के बीच कैसे निर्णय लेना चाहिए?
- निष्कर्ष
- अनुशंसित पाठ
हमें वंशानुक्रम की आवश्यकता क्यों है?
कार, बस, जीप, आदि जैसे वाहनों के एक समूह पर विचार करें। इनमें से प्रत्येक वाहन में गुण और विधियाँ होंगी जैसा कि नीचे दिए गए चित्र में दिखाया गया है।
यदि हमें उपरोक्त वाहनों के लिए अलग-अलग वर्गों को लागू करने की आवश्यकता है, तो हम देख सकते हैं कि सभी तीन वर्गों में, हमें एक ही कोड लिखना होगा, क्योंकि तीनों प्रकार के वाहन कमोबेश समान गुणों का प्रदर्शन करते हैं। यह हमारे कार्यक्रम को अक्षम और बोझिल बना देगा क्योंकि इसमें बहुत सारे डुप्लिकेट कोड होंगे।
ऊपर की तरह एक डुप्लिकेट कोड लिखने के बजाय, हम कोड को डुप्लिकेट करने से रोकने के लिए विरासत की सुविधा को लागू कर सकते हैं और कोड का एक टुकड़ा भी लिख सकते हैं और इसे तीनों वर्गों में उपयोग कर सकते हैं। यह नीचे के रूप में सचित्र रूप से दर्शाया गया है।
उपरोक्त आंकड़े में, हमने एक बेस क्लास 'वाहन' को परिभाषित किया है और इस वर्ग से कार, बस और जीप को निकाला है। सामान्य विधियां और गुण अब वाहन वर्ग का एक हिस्सा हैं। जैसा कि अन्य वर्ग वाहन वर्ग से प्राप्त होते हैं, सभी वर्ग इन विधियों और गुणों को प्राप्त करते हैं।
इसलिए, हमें केवल एक बार और तीनों वर्गों में समान कोड लिखने की जरूरत है; कार, बस और जीप इसका अधिग्रहण करेगी।
इस प्रकार, मुख्य लाभ, हमें मौजूदा वर्गों को विरासत में मिलता है या विरासत तंत्र को डिजाइन करना कोड की पुन: प्रयोज्य है।
आगे पढ़ना = >> जावा इनहेरिटेंस ट्यूटोरियल
एक वर्ग विरासत में मिलने वाला सामान्य प्रारूप है:
class derived_classname: access_specifier base_classname { };
यहाँ ' der_classname 'व्युत्पन्न वर्ग का नाम है,' access_specifier 'एक्सेस मोड यानी सार्वजनिक, संरक्षित या निजी, जिसमें व्युत्पन्न वर्ग को बेस क्लास और' वारिस 'करना होता है der_classname 'बेस क्लास का नाम है जिसमें से व्युत्पन्न वर्ग विरासत में मिला है।
विरासत के मोड
विरासत के उपरोक्त घोषणा में दिखाए गए 'access_specifier' में नीचे दिखाए अनुसार उनके मान हो सकते हैं।
जब हम क्लास को इनहेरिट करते हैं, तो access_specifier के आधार पर, हमारे पास विरासत के विभिन्न तरीके हैं जो नीचे सूचीबद्ध हैं।
सार्वजनिक विरासत
सामान्य वाक्यविन्यास
class sub_class : public parent_class
जब सार्वजनिक पहुंच विनिर्देश निर्दिष्ट किया जाता है, तो आधार वर्ग के सार्वजनिक सदस्यों को सार्वजनिक रूप से विरासत में मिला है जबकि संरक्षित सदस्यों को संरक्षित किया जाता है। निजी सदस्य निजी रहते हैं। यह वंशानुक्रम की सबसे लोकप्रिय विधा है।
प्राइवेट इनहेरिटेंस
सामान्य सिंटेक्स
class sub_class : parent_class
निजी विरासत में कुछ भी विरासत में नहीं मिलता है। जब निजी एक्सेस स्पेसियर का उपयोग किया जाता है, तो बेस क्लास के सार्वजनिक और संरक्षित सदस्य भी निजी हो जाते हैं।
संरक्षित वंशानुक्रम
सामान्य सिंटेक्स
class sub_class:protected parent_class
जब संरक्षित एक्सेस स्पेसियर का उपयोग किया जाता है, तो बेस क्लास के सार्वजनिक और संरक्षित सदस्य व्युत्पन्न वर्ग में संरक्षित सदस्य बन जाते हैं।
ध्यान दें कि जब हम बेस क्लास के लिए निजी एक्सेस स्पेसियर का उपयोग करते हैं, तो बेस क्लास के किसी भी सदस्य को विरासत में नहीं मिलता है। वे सभी व्युत्पन्न वर्ग में निजी हो जाते हैं।
नीचे दिए गए सभी पहुँच मोडों की सारणीबद्ध प्रतिनिधित्व और वंशानुक्रम के लिए उनकी व्याख्या है।
व्युत्पन्न वर्ग -> आधार वर्ग | निजी | जनता | संरक्षित |
---|---|---|---|
निजी | विरासत में नहीं मिली | इनहेरिट नहीं किया गया | इनहेरिट नहीं किया गया |
जनता | निजी | जनता | संरक्षित |
संरक्षित | निजी | संरक्षित | संरक्षित |
इनहेरिटेंस में कंस्ट्रक्टर्स / डिस्ट्रक्टर्स का क्रम
जब कक्षाएं विरासत में मिलती हैं, तो निर्माणकर्ताओं को उसी क्रम में बुलाया जाता है जैसे कक्षाएं विरासत में मिली हैं। यदि हमारे पास एक बेस क्लास है और एक व्युत्पन्न वर्ग है जो इस बेस क्लास को विरासत में मिला है, तो बेस क्लास कंस्ट्रक्टर (चाहे डिफॉल्ट या पैरामीटराइज्ड हो) को पहले व्युत्पन्न क्लास कंस्ट्रक्टर कहा जाएगा।
निम्नलिखित कार्यक्रम उत्तराधिकार में निर्माणकर्ताओं के आदेश को प्रदर्शित करता है। हमारे पास एक बेस क्लास 'बेस' है जिसमें एक डिफॉल्ट कंस्ट्रक्टर और एक पैरामीटरेड कंस्ट्रक्टर है। हम इसे 'व्युत्पन्न' नाम से एक वर्ग प्राप्त करते हैं, जिसमें एक डिफ़ॉल्ट और दूसरा पैरामीटर निर्मित निर्माता भी है।
इस कार्यक्रम का आउटपुट उस क्रम को दर्शाता है जिसमें निर्माणकर्ताओं को बुलाया जाता है।
#include using namespace std; //order of execution of constructors in inheritance class Base { int x; public: // default constructor Base() { cout आउटपुट:
बेस क्लास डिफॉल्ट कंस्ट्रक्टर
बेस क्लास डिफॉल्ट कंस्ट्रक्टर
व्युत्पन्न वर्ग डिफ़ॉल्ट निर्माता
बेस क्लास पैरामीटरेड कंस्ट्रक्टर
व्युत्पन्न वर्ग पैरामीटर निर्मित निर्माता
हम देखते हैं कि बेस क्लास ऑब्जेक्ट बनाने के बाद हम डिफॉल्ट कंस्ट्रक्टर के साथ व्युत्पन्न क्लास ऑब्जेक्ट बनाते हैं। जब यह ऑब्जेक्ट बनाया जाता है, तो पहले बेस क्लास डिफ़ॉल्ट कंस्ट्रक्टर को बुलाया जाता है और फिर व्युत्पन्न क्लास कंस्ट्रक्टर को निष्पादित किया जाता है।
इसी प्रकार, जब व्युत्पन्न वर्ग वस्तु को पैरामीटर किए गए कंस्ट्रक्टर के उपयोग से बनाया जाता है, तो बेस क्लास के पैरामीटर वाले कंस्ट्रक्टर को पहले कहा जाता है और फिर व्युत्पन्न क्लास कंस्ट्रक्टर को कहा जाता है।
ध्यान दें कि यदि आधार वर्ग में कोई पैरामीटर निर्मित कंस्ट्रक्टर नहीं था, तो पैरामीटर व्युत्पन्न वर्ग ऑब्जेक्ट के निर्माण के लिए भी डिफॉल्ट कंस्ट्रक्टर को बुलाया जाएगा।
लेकिन यह सवाल बना हुआ है कि व्युत्पन्न वर्ग वस्तुओं का निर्माण करते समय बेस क्लास कंस्ट्रक्टर को क्यों कहा जाता है?
हम जानते हैं कि एक निर्माणकर्ता का उपयोग कक्षा की वस्तुओं को बनाने के लिए किया जाता है और वर्ग के सदस्यों को आरंभ करने के लिए भी किया जाता है। जब व्युत्पन्न वर्ग वस्तु बनाई जाती है, तो इसके निर्माता का केवल व्युत्पन्न वर्ग सदस्यों पर नियंत्रण होता है।
हालाँकि, व्युत्पन्न वर्ग भी आधार वर्ग के सदस्यों को विरासत में मिला है। यदि केवल व्युत्पन्न वर्ग के निर्माता को बुलाया गया था, तो व्युत्पन्न वर्ग द्वारा विरासत में प्राप्त आधार वर्ग के सदस्यों को ठीक से प्रारंभ नहीं किया जाएगा।
नतीजतन, पूरी वस्तु कुशलता से नहीं बनाई जाएगी। यही कारण है कि जब एक व्युत्पन्न वर्ग वस्तु बनाई जाती है, तो सभी बेस क्लास बिल्डरों को पहले कहा जाता है।
वंशानुक्रम के प्रकार
जिस तरह से वर्ग व्युत्पन्न किया गया है या एक वर्ग के आधार वर्ग कितने हैं, इस पर निर्भर करते हुए, हमारे पास निम्न प्रकार की विरासत है जैसा कि नीचे दिए गए चित्र में दर्शाया गया है।

हम अपने अगले ट्यूटोरियल में 'इनहेरिटेंस के प्रकार' पर इन प्रकारों में से प्रत्येक का पता लगाएंगे।
टेम्प्लेट इनहेरिटेंस
जब हमारे कार्यान्वयन में टेम्प्लेट शामिल होते हैं, तो हमें टेम्प्लेट कक्षाओं से इनहेरिट या व्युत्पन्न करने की आवश्यकता होती है, और हम टेम्प्लेट इनहेरिटेंस का उपयोग करते हैं।
टेम्प्लेट का उपयोग करके विरासत को बेहतर ढंग से समझने के लिए आइए हम सीधे एक प्रोग्रामिंग उदाहरण पर जाएं।
#include using namespace std; //template inhertance templateclass basecls_Template { public: T value; basecls_Template(T value) { this->value = value; } void displayVal() { cout << value << endl; } }; //derived class inherits basecls_Template class derivedcls_Child : public basecls_Template { public: derivedcls_Child(/* no parameters */): basecls_Template( 0 ){ // default char is NULL; } derivedcls_Child(char c): basecls_Template( c ) { ; } void displayVal_drvd() { displayVal(); } }; int main() { basecls_Template obj( 100 ); derivedcls_Child obj1( 'A' ); cout<<'basecls_Template obj = '; obj.displayVal(); // should print '100' cout< आउटपुट:
basecls_Template obj = 100
dercls_Child obj1 (basecls_Template = A से विरासत में मिला है
उपरोक्त कार्यक्रम में, हमारे पास basecls_Template नाम का एक टेम्पलेट है जो बेस क्लास के लिए क्लास टेम्पलेट को परिभाषित करता है। अगला, हम एक वर्ग व्युत्पन्न_ परिभाषित करते हैं जो हम एक टेम्पलेट वर्ग से प्राप्त करना चाहते हैं।
लेकिन ध्यान दें कि वर्ग basecls_Template केवल एक प्रकार है और एक वर्ग नहीं है। इसलिए, हम इस टेम्पलेट से वर्ग dercls_Child प्राप्त नहीं कर सकते।
ps4 के साथ संगत आभासी वास्तविकता हेडसेट
इसलिए यदि हम बच्चे को कक्षा के रूप में घोषित करते हैं:
class derivedcls_Child : public basecls_Template
इसके परिणामस्वरूप त्रुटि होगी। Basecls_Template होने का कारण डेटा प्रकार है और वर्ग नहीं है। इस प्रकार basecls_Template के सदस्यों को विरासत में देने के लिए, इससे पहले कि हम इसे प्राप्त कर लें, हमें पहले इसे तत्काल भेज देना चाहिए।
इसलिए उपरोक्त कथन, वर्ग dercls_Child: सार्वजनिक basecls_Template ठीक काम करता है।
इस कथन में, हमने टेम्प्लेट basecls_Template को एक वर्ण श्रेणी के टेम्पलेट में त्वरित किया है। एक बार जब हम इस तात्कालिक टेम्पलेट वर्ग का उपयोग करते हैं, तो इसके बाद की अन्य चीजें जो वस्तुओं को बनाना और उपयोग करना पसंद करती हैं वे सामान्य विरासत के साथ काम करती हैं।
रचना
अब तक हमने विरासत के सभी रिश्तों के बारे में देखा है। इनहेरिटेंस मूल रूप से उस तरह के रिश्तों को दर्शाता है जिसमें रिश्ते एक हिस्से को इंगित करते हैं। उदाहरण के लिए, सांप एक तरह का सरीसृप है। हम यह भी कह सकते हैं कि सरीसृप पशु वर्ग का एक हिस्सा है।
निष्कर्ष में, वंशानुक्रम इंगित करता है 'एक है' ऐसे रिश्ते जिनमें हम कह सकते हैं कि व्युत्पन्न वर्ग आधार वर्ग का एक हिस्सा है।
हम समग्र रूप से रिश्तों का प्रतिनिधित्व भी कर सकते हैं। उदाहरण के लिए, अगर हम कहते हैं कि वेतन वर्ग कर्मचारी वर्ग का एक हिस्सा है, तो हम इसका ठीक से प्रतिनिधित्व नहीं कर रहे हैं। हम जानते हैं कि कर्मचारियों का वेतन है। इस प्रकार यह कहना अधिक सुविधाजनक है कि 'कर्मचारी के पास वेतन है'।
इसी तरह, यदि हम उदाहरण के रूप में वाहन वर्ग लेते हैं, तो हम कह सकते हैं कि वाहन में इंजन है या वाहन में चेसिस है। इस प्रकार ये सभी रिश्ते चित्रित करते हैं 'एक' ऐसे रिश्ते जो किसी अन्य वर्ग में निहित एक पूरी वस्तु का प्रतिनिधित्व करते हैं। इसे इस रूप में परिभाषित किया गया है रचना ।
रचना द्वारा दर्शाए गए रिश्ते एक-दूसरे पर निर्भर होते हैं। उदाहरण के लिए, एक वाहन के बिना चेसिस मौजूद नहीं हो सकता। इसी तरह, एक कर्मचारी के बिना वेतन मौजूद नहीं हो सकता।
हम चित्र को नीचे दिखाए अनुसार रचना का प्रतिनिधित्व कर सकते हैं:

रचना को कन्टेनमेंट भी कहा जाता है। उपरोक्त प्रतिनिधित्व में, हमने एक मूल वर्ग दिखाया है। विरासत के विपरीत, हम मूल वर्ग के अंदर एक बाल वर्ग वस्तु शामिल करते हैं। यह समास या रचना है।
जावा बनाम सी ++ सिंटैक्स
इसे समझने के लिए एक प्रोग्रामिंग उदाहरण लेते हैं।
#include using namespace std; //Composition example //Child class - address class Address { public: string houseNo, building, street, city, state; //Initialise the address object Address(string houseNo,string building,string street, string city, string state) { this->houseNo = houseNo; this->building = building; this->street = street; this->city = city; this->state = state; } }; //Parent class - Employee class Employee { private: Address* address; //composition->Employee has an address public: int empId; string empName; Employee(int empId, string empName, Address* address) { this->empId = empId; this->empName = empName; this->address = address; } void display() { cout< आउटपुट:
10001 वेद
A-101 सिल्वर स्प्रिंग्स औंध पुणे महाराष्ट्र
इस उदाहरण में, हमारे पास एक अभिभावक वर्ग कर्मचारी और एक बच्चा वर्ग पता है। मूल वर्ग कर्मचारी के अंदर, हमने पता वर्ग के लिए एक सूचक घोषित किया है और कर्मचारी निर्माणकर्ता में इस ऑब्जेक्ट को इनिशियलाइज़ भी करता है। इस प्रकार हम उस संबंध को दर्शाते हैं कि कर्मचारी का एक पता है जो रचना है।
हमें रचना और विरासत के बीच कैसे निर्णय लेना चाहिए?
रचना और विरासत दोनों वर्गों के बीच संबंधों को दर्शाते हैं। जबकि विरासत में 'आईएस-ए' संबंध दर्शाया गया है, रचना 'एचएएस-ए' संबंध को दर्शाती है।
अब प्रश्न यह है कि हमें विरासत का उपयोग कब करना चाहिए और हमें रचना का उपयोग कब करना चाहिए? वास्तव में, हम सटीक स्थितियों पर निर्णय नहीं ले सकते हैं जब हमें उनमें से किसी एक का उपयोग करना चाहिए। ऐसा इसलिए है क्योंकि प्रत्येक के अपने फायदे और नुकसान हैं।
दोनों कोड पुन: प्रयोज्य को बढ़ावा देते हैं। इनहेरिटेंस कोड को भारी बना सकता है क्योंकि समाधान जटिल हो जाता है, लेकिन साथ ही यह हमें मौजूदा कोड का विस्तार करने की भी अनुमति देता है। इस प्रकार, हमें विरासत का उपयोग तब करना चाहिए जब हमारी आवश्यकता नए वर्ग के अंदर किसी अन्य वर्ग के गुणों और पद्धति को संशोधित करने और उपयोग करने की हो।
दूसरे शब्दों में, जब हम अधिक गुण जोड़ना चाहते हैं और मौजूदा वर्ग का विस्तार करना चाहते हैं। दूसरी ओर, जब हम किसी अन्य वर्ग के गुणों और व्यवहार को संशोधित नहीं करना चाहते हैं, लेकिन बस कक्षा के अंदर इसका उपयोग करते हैं, हम रचना के लिए जाते हैं।
इस प्रकार सबसे अच्छा निर्णय यह है कि क्या विशेष परिस्थिति के लिए दोनों तकनीकों के पेशेवरों और विपक्षों को तौलकर रचना या वंशानुक्रम का उपयोग किया जाना है या नहीं।
निष्कर्ष
इस प्रकार, हम विरासत पर अपने विषय के अंत में आ गए हैं। हमने विरासत के विभिन्न तरीकों को देखा है। हमने विरासत के प्रकार भी देखे हैं, जिसे हम अपने अगले ट्यूटोरियल में देखेंगे। हमने निर्माणकर्ताओं के आदेश के बारे में सीखा जो विरासत के मामले में निष्पादित किया जाता है।
हमने टेम्प्लेट और विरासत के बारे में भी अध्ययन किया। इससे पहले कि हम इसका उपयोग इनहेरिटेंस में कर सकें, हमें एक टेम्प्लेट की आवश्यकता है क्योंकि टेम्प्लेट स्वयं एक डेटा प्रकार है और हम डेटा प्रकार से इनहेरिट नहीं कर सकते।
रचना एक अन्य प्रकार का वर्ग संबंध है और हमें पहले सटीक स्थिति को जानना होगा और उसके बाद ही हम यह तय कर सकते हैं कि रचना या वंशानुक्रम का उपयोग करना है या नहीं।
हमारे आगामी ट्यूटोरियल में, हम विरासत के प्रकारों के बारे में अधिक देखेंगे।
=> यहाँ सरल सी ++ प्रशिक्षण श्रृंखला देखें।
अनुशंसित पाठ
- C ++ में इनहेरिटेंस के प्रकार
- C ++ में रनटाइम पॉलिमोर्फिज्म
- मित्र कार्य C ++ में
- एक वेब पेज पर ड्रॉपडाउन तत्वों को संभालने के लिए सेलेनियम चयन कक्षा का उपयोग - सेलेनियम ट्यूटोरियल # 13
- C ++ में क्लास और ऑब्जेक्ट
- C ++ में Static
- यूनिक्स पाइप्स ट्यूटोरियल: यूनिक्स प्रोग्रामिंग में पाइप्स
- उदाहरण के साथ जावा इंटरफेस और एब्सट्रैक्ट क्लास ट्यूटोरियल