जवाबों:
एकाधिक वंशानुक्रम (एमआई के रूप में संक्षिप्त) बदबू आती है , जिसका अर्थ है कि आमतौर पर , यह खराब कारणों के लिए किया गया था, और यह अनुचर के चेहरे में वापस आ जाएगा।
यह विरासत के लिए सच है, और इसलिए, यह कई विरासत के लिए और भी अधिक सच है।
क्या आपकी वस्तु को वास्तव में दूसरे से विरासत में प्राप्त करने की आवश्यकता है? A Car
को किसी Engine
कार्य से विरासत की आवश्यकता नहीं है , न ही a से Wheel
। A Car
की Engine
चार और एक है Wheel
।
यदि आप रचना के बजाय इन समस्याओं को हल करने के लिए कई विरासत का उपयोग करते हैं, तो आपने कुछ गलत किया है।
आमतौर पर, आपके पास एक वर्ग होता है A
, B
और फिर C
दोनों को विरासत में मिलता है A
। और (मुझे मत पूछो क्यों) किसी ने फिर फैसला किया कि D
दोनों से विरासत में मिला होगा B
और C
।
मैंने 8 बार आठ साल में इस तरह की समस्या का सामना किया है, और यह देखने के लिए बहुत खुश है:
D
दोनों से विरासत में नहीं मिला होना चाहिए B
और C
), क्योंकि यह खराब आर्किटेक्चर था (वास्तव में, C
इसका अस्तित्व ही नहीं होना चाहिए था ...)A
अपने पोते के वर्ग में मौजूद दो बार था D
, और इस तरह, एक माता पिता क्षेत्र को अद्यतन करने के A::field
लिए या तो मतलब यह दो बार अद्यतन करने (के माध्यम से B::field
और C::field
), या कुछ चुपचाप गलत और दुर्घटना जाना है, बाद में (नए सूचक में B::field
और हटाएं C::field
...)C ++ में कीवर्ड वर्चुअल का उपयोग करके वंशानुक्रम को अर्हता प्राप्त करने के लिए ऊपर वर्णित दोहरे लेआउट से बचा जाता है यदि आप ऐसा नहीं चाहते हैं, लेकिन वैसे भी, मेरे अनुभव में, आप शायद कुछ गलत कर रहे हैं ...
ऑब्जेक्ट पदानुक्रम में, आपको पदानुक्रम को ट्री के रूप में रखने की कोशिश करनी चाहिए (एक नोड में एक माता-पिता हैं), ग्राफ़ के रूप में नहीं।
C ++ में डायमंड ऑफ ड्रेड के साथ वास्तविक समस्या ( डिजाइन ध्वनि है - क्या आपके कोड की समीक्षा की गई है! ), यह है कि आपको एक विकल्प बनाने की आवश्यकता है :
A
लिए आपके लेआउट में दो बार मौजूद होना वांछनीय है , और इसका क्या मतलब है? यदि हाँ, तो हर तरह से इसे दो बार विरासत में मिला है।यह विकल्प समस्या के लिए अंतर्निहित है, और सी ++ में, अन्य भाषाओं के विपरीत, आप वास्तव में इसे हठधर्मिता के बिना अपने डिजाइन को भाषा के स्तर पर मजबूर कर सकते हैं।
लेकिन सभी शक्तियों की तरह, उस शक्ति के साथ जिम्मेदारी आती है: क्या आपके डिजाइन की समीक्षा की गई है।
शून्य या एक ठोस वर्गों की कई विरासत, और शून्य या अधिक इंटरफेस आमतौर पर ठीक है, क्योंकि आप ऊपर वर्णित भय के डायमंड का सामना नहीं करेंगे। वास्तव में, यह जावा में चीजों को कैसे किया जाता है।
आमतौर पर, जब आपका मतलब होता है जब C से विरासत में मिलता है A
और B
यह है कि उपयोगकर्ता इसका उपयोग कर सकते हैं C
जैसे कि यह एक था A
, और / या जैसे कि यह एक था B
।
C ++ में, एक इंटरफ़ेस एक सार वर्ग है जिसमें है:
शून्य से एक वास्तविक वस्तु की कई विरासत, और शून्य या अधिक इंटरफेस को "बदबूदार" नहीं माना जाता है (कम से कम, बहुत अधिक नहीं)।
सबसे पहले, एनवीआई पैटर्न का उपयोग एक इंटरफ़ेस का उत्पादन करने के लिए किया जा सकता है, क्योंकि वास्तविक मानदंड में कोई राज्य नहीं है (अर्थात कोई सदस्य चर नहीं है, सिवाय this
)। आपका सार इंटरफ़ेस का बिंदु एक अनुबंध प्रकाशित करना है ("आप मुझे इस तरह से कॉल कर सकते हैं, और इस तरह से"), अधिक कुछ नहीं, कुछ भी कम नहीं। केवल अमूर्त आभासी विधि होने की सीमा एक डिज़ाइन पसंद होनी चाहिए, एक बाध्यता नहीं।
दूसरा, C ++ में, यह वस्तुतः अमूर्त इंटरफेस से विरासत में मिलता है, (अतिरिक्त लागत / अप्रत्यक्ष के साथ भी)। यदि आप नहीं करते हैं, और इंटरफ़ेस वंशानुक्रम आपकी पदानुक्रम में कई बार दिखाई देता है, तो आपके पास अस्पष्टताएँ होंगी।
तीसरा, वस्तु उन्मुखीकरण महान है, लेकिन यह नहीं है केवल सच्चाई का पता वहाँ टीएम में सी ++। सही उपकरणों का उपयोग करें, और हमेशा याद रखें कि आपके पास C ++ में अन्य प्रतिमान हैं जो विभिन्न प्रकार के समाधान पेश करते हैं।
कभी कभी हाँ।
आमतौर पर, अपने C
वर्ग से इनहेरिट है A
और B
, और A
और B
कर रहे हैं दो असंबंधित वस्तुओं (यानी इसी पदानुक्रम नहीं, आम, अलग अवधारणाओं, आदि में कुछ भी नहीं)।
उदाहरण के लिए, आपके पास Nodes
X, Y, Z निर्देशांक की एक प्रणाली हो सकती है , जो बहुत सारे ज्यामितीय गणना करने में सक्षम है (शायद एक बिंदु, ज्यामितीय वस्तुओं का हिस्सा) और प्रत्येक नोड एक स्वचालित एजेंट है, जो अन्य एजेंटों के साथ संवाद करने में सक्षम है।
शायद आपके पास पहले से ही दो पुस्तकालयों तक पहुंच है, प्रत्येक अपने स्वयं के नामस्थान (नामस्थान का उपयोग करने का एक और कारण ... लेकिन आप नामस्थान का उपयोग करते हैं, क्या आप नहीं?), एक जा रहा है geo
और दूसरा?ai
तो तुम own::Node
दोनों से ai::Agent
और अपने खुद के व्युत्पन्न है geo::Point
।
यह वह क्षण है जब आपको खुद से पूछना चाहिए कि क्या आपको इसके बजाय रचना का उपयोग नहीं करना चाहिए। यदि own::Node
वास्तव में दोनों एक ai::Agent
और एक है geo::Point
, तो रचना नहीं करेगी।
फिर आपको own::Node
3 डी स्थान में उनकी स्थिति के अनुसार अन्य एजेंटों के साथ संवाद करने के लिए, कई विरासत की आवश्यकता होगी ।
(आप कि ध्यान दें जाएगा ai::Agent
और geo::Point
पूरी तरह से, पूरी तरह से, पूरी तरह से संबंधित नहीं हैं ... यह काफी एकाधिक वंशानुक्रम के खतरे को कम करता है)
अन्य मामले हैं:
this
)कभी-कभी आप रचना का उपयोग कर सकते हैं, और कभी-कभी एमआई बेहतर होता है। मुद्दा यह है: आपके पास एक विकल्प है। यह जिम्मेदारी से करें (और आपके कोड की समीक्षा की जाए)।
ज्यादातर समय, मेरे अनुभव में, नहीं। एमआई सही उपकरण नहीं है, भले ही यह काम करने लगता है, क्योंकि इसका उपयोग आलसी द्वारा ढेर सुविधाओं के साथ मिलकर परिणामों को साकार किए बिना किया जा सकता है (जैसे कि Car
दोनों को एक Engine
और एक बनाकर Wheel
)।
लेकिन कभी-कभी, हाँ। और उस समय, एमआई से बेहतर कुछ भी काम नहीं करेगा।
लेकिन क्योंकि MI बदबूदार है, कोड की समीक्षा में अपनी वास्तुकला का बचाव करने के लिए तैयार रहें (और इसका बचाव करना अच्छी बात है, क्योंकि यदि आप इसका बचाव करने में सक्षम नहीं हैं, तो आपको ऐसा नहीं करना चाहिए)।
बज़्ने स्ट्रॉस्ट्रप के साथ एक साक्षात्कार से :
लोग काफी सही ढंग से कहते हैं कि आपको कई विरासतों की आवश्यकता नहीं है, क्योंकि कुछ भी आप कई विरासतों के साथ कर सकते हैं जो आप एकल विरासत के साथ भी कर सकते हैं। आप सिर्फ मेरे द्वारा उल्लेखित प्रतिनिधि ट्रिक का उपयोग करते हैं। इसके अलावा, आपको किसी भी तरह की विरासत की आवश्यकता नहीं है, क्योंकि आप एकल विरासत के साथ जो कुछ भी करते हैं वह आप वर्ग के माध्यम से अग्रेषित करके विरासत के बिना भी कर सकते हैं। वास्तव में, आपको किसी भी वर्ग की आवश्यकता नहीं है, क्योंकि आप यह सभी बिंदुओं और डेटा संरचनाओं के साथ कर सकते हैं। लेकिन आप ऐसा क्यों करना चाहेंगे? भाषा सुविधाओं का उपयोग करना कब सुविधाजनक है? आप वर्कअराउंड कब पसंद करेंगे? मैंने ऐसे मामले देखे हैं जहाँ कई उत्तराधिकार उपयोगी हैं, और मैंने ऐसे मामले भी देखे हैं जहाँ कई जटिल बहु विरासतें उपयोगी हैं। आम तौर पर, मैं वर्कअराउंड करने के लिए भाषा द्वारा दी जाने वाली सुविधाओं का उपयोग करना पसंद करता हूं
const
- मुझे क्लूनी वर्कआर्ड (आमतौर पर इंटरफेस और रचना का उपयोग करके) लिखना पड़ता है जब एक वर्ग को वास्तव में परस्पर-और अपरिवर्तनीय होने की आवश्यकता होती है। हालाँकि, मैंने कभी भी एक से अधिक उत्तराधिकार प्राप्त करने से नहीं चूके हैं, और मुझे कभी नहीं लगा कि इस सुविधा की कमी के कारण मुझे वर्कअराउंड लिखना पड़ा। यही अंतर है। हर मामले में मैंने कभी देखा है, एमआई का उपयोग नहीं करना बेहतर डिजाइन विकल्प है, न कि वर्कअराउंड।
इससे बचने का कोई कारण नहीं है और यह स्थितियों में बहुत उपयोगी हो सकता है। हालांकि आपको संभावित मुद्दों के बारे में पता होना चाहिए।
मौत का सबसे बड़ा हीरा:
class GrandParent;
class Parent1 : public GrandParent;
class Parent2 : public GrandParent;
class Child : public Parent1, public Parent2;
अब आपके पास बाल के भीतर ग्रैंडपैरेंट की दो "प्रतियां" हैं।
C ++ ने इसके बारे में सोचा है और आपको मुद्दों के इर्द-गिर्द आने के लिए आभासी विरासत करने की सुविधा देता है।
class GrandParent;
class Parent1 : public virtual GrandParent;
class Parent2 : public virtual GrandParent;
class Child : public Parent1, public Parent2;
हमेशा अपने डिज़ाइन की समीक्षा करें, सुनिश्चित करें कि आप डेटा पुन: उपयोग पर सहेजने के लिए वंशानुक्रम का उपयोग नहीं कर रहे हैं। यदि आप रचना के साथ एक ही चीज़ का प्रतिनिधित्व कर सकते हैं (और आमतौर पर आप कर सकते हैं) तो यह एक बेहतर दृष्टिकोण है।
GrandParent
हैं Child
। एमआई का डर है, क्योंकि लोगों को लगता है कि वे भाषा के नियमों को नहीं समझ सकते हैं। लेकिन जो कोई भी इन सरल नियमों को प्राप्त नहीं कर सकता है वह एक गैर तुच्छ कार्यक्रम नहीं लिख सकता है।
देखें: एकाधिक वंशानुक्रम ।
एकाधिक विरासत को आलोचना मिली है और इस तरह, कई भाषाओं में लागू नहीं किया गया है। आलोचनाओं में शामिल हैं:
- जटिलता बढ़ गई
- शब्दार्थ अस्पष्टता को अक्सर हीरे की समस्या के रूप में संक्षेपित किया जाता है ।
- एक ही वर्ग से कई बार स्पष्ट रूप से विरासत में नहीं मिल रहा है
- वंशानुक्रम बदलने का क्रम वर्ग शब्दार्थ।
C ++ / Java स्टाइल कंस्ट्रक्टर्स वाली भाषाओं में मल्टीपल इनहेरिटेंस, कंस्ट्रक्टर्स और कंस्ट्रक्टर चाइनिंग की विरासत की समस्या को बढ़ाता है, जिससे इन भाषाओं में रखरखाव और एक्स्टेंसिबिलिटी की समस्या पैदा होती है। बहुत अलग-अलग निर्माण विधियों के साथ वंशानुगत रिश्तों में ऑब्जेक्ट्स को निर्माण प्रतिमान के तहत लागू करना कठिन है।
COM और जावा इंटरफ़ेस जैसे इंटरफ़ेस (शुद्ध सार वर्ग) का उपयोग करने के लिए इसे हल करने का आधुनिक तरीका।
मैं इसके स्थान पर अन्य काम कर सकता हूं?
हाँ तुम कर सकते हो। मैं GoF से चोरी करने जा रहा हूं ।
सार्वजनिक विरासत एक आईएस-ए संबंध है, और कभी-कभी एक वर्ग कई अलग-अलग वर्गों का एक प्रकार होगा, और कभी-कभी यह प्रतिबिंबित करना महत्वपूर्ण होता है।
"मिक्सिन्स" कभी-कभी उपयोगी भी होते हैं। वे आम तौर पर छोटे वर्ग हैं, आमतौर पर कुछ भी विरासत में नहीं मिलता है, उपयोगी कार्यक्षमता प्रदान करता है।
जब तक वंशानुगत पदानुक्रम काफी उथला है (जैसा कि यह लगभग हमेशा होना चाहिए), और अच्छी तरह से प्रबंधित किया जाता है, तो आपको खतरनाक हीरे की विरासत प्राप्त होने की संभावना नहीं है। हीरा सभी भाषाओं के साथ कोई समस्या नहीं है जो कई उत्तराधिकार का उपयोग करता है, लेकिन C ++ का उपचार अक्सर अजीब होता है और कभी-कभी अजीब होता है।
जब मैं उन मामलों में भाग लेता हूं, जहां कई विरासत बहुत आसान हैं, तो वे वास्तव में काफी दुर्लभ हैं। यह संभावना है क्योंकि मैं अन्य डिजाइन विधियों का उपयोग करना पसंद करता हूं जब मुझे वास्तव में कई विरासत की आवश्यकता नहीं होती है। मैं भ्रामक भाषा निर्माणों से बचना पसंद करता हूं, और विरासत के मामलों का निर्माण करना आसान है जहां आपको मैनुअल पढ़ने के लिए वास्तव में अच्छी तरह से पता लगाना है कि क्या चल रहा है।
आपको एकाधिक उत्तराधिकार से "बचना" नहीं चाहिए, लेकिन आपको ऐसी समस्याओं के बारे में पता होना चाहिए जो 'हीरा समस्या' ( http://en.wikipedia.org/wiki/Diamond_problem ) के रूप में उत्पन्न हो सकती हैं और देखभाल के साथ आपको दी गई शक्ति का इलाज कर सकती हैं , जैसा कि आपको सभी शक्तियों के साथ होना चाहिए।
थोड़ा सार होने के जोखिम पर, मुझे श्रेणी सिद्धांत के फ्रेम के भीतर विरासत के बारे में सोचने के लिए रोशन लगता है।
यदि हम विरासत के संबंधों को निरूपित करते हुए हमारे सभी वर्गों और उनके बीच के तीरों के बारे में सोचते हैं, तो ऐसा कुछ है
A --> B
इसका मतलब है कि से class B
प्राप्त होता है class A
। ध्यान दें, दिया गया
A --> B, B --> C
हम कहते हैं कि C, B से व्युत्पन्न है जो A से प्राप्त होता है, इसलिए C को A से व्युत्पन्न भी कहा जाता है
A --> C
इसके अलावा, हम कहते हैं कि प्रत्येक वर्ग के लिए A
जो तुच्छ A
रूप से प्राप्त होता है A
, इस प्रकार हमारा उत्तराधिकार मॉडल एक श्रेणी की परिभाषा को पूरा करता है। अधिक पारंपरिक भाषा में, हमारे पास एक वर्ग है Class
जिसमें सभी वर्ग और आकारिकी वस्तुओं के साथ विरासत संबंध हैं।
यह थोड़ा सा सेटअप है, लेकिन इसके साथ आइए एक नजर डालते हैं हमारे डायमंड ऑफ डूम पर:
C --> D
^ ^
| |
A --> B
यह एक छायादार आरेख है, लेकिन यह करूँगा। इसलिए , और , D
सभी से विरासत में मिला है । इसके अलावा, और ओपी के प्रश्न को संबोधित करने के करीब पहुंचना भी किसी भी सुपरक्लास से विरासत में मिला है । हम एक चित्र बना सकते हैंA
B
C
D
A
C --> D --> R
^ ^
| |
A --> B
^
|
Q
अब, समस्याओं की मौत डायमंड के साथ जुड़े यहाँ जब कर रहे हैं C
और B
साझा कुछ संपत्ति / विधि के नाम और चीजें अस्पष्ट मिलता है, हालाँकि, यदि हम किसी साझा व्यवहार को आगे A
बढ़ाते हैं तो अस्पष्टता गायब हो जाती है।
स्पष्ट शब्दों में कहें, हम चाहते हैं A
, B
और C
ऐसा होना चाहिए कि अगर B
और उसके बाद C
से विरासत में उपवर्ग के रूप में फिर से लिखा जा सके । यह एक पुशआउट नामक कुछ बनाता है ।Q
A
Q
A
पुलबैकD
नामक एक सममित निर्माण भी है । यह अनिवार्य रूप से सबसे सामान्य उपयोगी वर्ग है जिसे आप निर्माण कर सकते हैं जो दोनों से विरासत में मिला है और । यही है, अगर आपके पास कोई अन्य वर्ग है, जो बहुतायत से विरासत में मिला है , और फिर एक ऐसा वर्ग है जहां उपवर्ग के रूप में फिर से लिखा जा सकता है ।B
C
R
B
C
D
R
D
यह सुनिश्चित करना कि हीरे की आपकी युक्तियां पुलबैक और पुशआउट हैं, हमें नाम-क्लैशिंग या रखरखाव के मुद्दों को संभालने का एक अच्छा तरीका प्रदान करती हैं जो अन्यथा उत्पन्न हो सकती हैं।
नोट पारसेबल के उत्तर से यह प्रेरित है क्योंकि उनकी सलाह ऊपर दिए गए मॉडल द्वारा दी गई है कि हम पूरी श्रेणी के सभी संभावित वर्गों में काम करते हैं।
मैं उनके तर्क को कुछ सामान्य करना चाहता था, जिससे पता चलता है कि कई विरासत वाले रिश्ते कितने शक्तिशाली और गैर-समस्याग्रस्त हो सकते हैं।
टीएल; डॉ । एक श्रेणी के रूप में अपने कार्यक्रम में निहित संबंधों के बारे में सोचो। तब आप डायमंड की कयामत की समस्याओं को बहु-विरासत वाले वर्गों को पुशआउट और सममित रूप से बनाकर, एक सामान्य अभिभावक वर्ग बना सकते हैं, जो एक पुलबैक है।
हम एफिल का उपयोग करते हैं। हमारे पास उत्कृष्ट एमआई है। कोई चिंता नहीं। कोई बात नहीं। आसानी से प्रबंधित। एमआई का उपयोग करने के लिए समय नहीं है। हालांकि, यह लोगों की तुलना में अधिक उपयोगी है क्योंकि वे जानते हैं: ए) एक खतरनाक भाषा में जो इसे अच्छी तरह से प्रबंधित नहीं करता है -ओआर-बी) इस बात से संतुष्ट हैं कि उन्होंने सालों और वर्षों तक एमआई के आसपास कैसे काम किया है -ओआर-सी) अन्य कारण ( सूची के लिए बहुत सारे मैं काफी यकीन है - ऊपर जवाब देखें)।
हमारे लिए, एफिल का उपयोग करते हुए, एमआई कुछ और के रूप में प्राकृतिक है और टूलबॉक्स में एक और ठीक उपकरण है। सच कहूँ, हम काफी असंबद्ध हैं कि कोई और एफिल का उपयोग नहीं कर रहा है। कोई चिंता नहीं। हम खुश हैं कि हमारे पास क्या है और आपको एक नज़र रखने के लिए आमंत्रित करते हैं।
जब आप देख रहे हों: शून्य-सुरक्षा और नल पॉइंटर डेरेफेरेंसिंग के उन्मूलन पर विशेष ध्यान दें। जब हम एमआई के चारों ओर नृत्य कर रहे हैं, तो आपके संकेत खो रहे हैं! :-)
प्रत्येक प्रोग्रामिंग भाषा में पेशेवरों और विपक्षों के साथ ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग का थोड़ा अलग उपचार होता है। C ++ का संस्करण प्रदर्शन पर जोर देता है और इसका नकारात्मक पक्ष यह है कि यह अमान्य कोड लिखना मुश्किल है - और यह कई उत्तराधिकार का सच है। एक परिणाम के रूप में वहाँ इस सुविधा से दूर प्रोग्रामर चलाने की प्रवृत्ति है।
अन्य लोगों ने इस सवाल को संबोधित किया है कि बहु विरासत क्या अच्छा नहीं है। लेकिन हमने बहुत कम टिप्पणियां देखी हैं, जो कम-से-कम इसका मतलब है कि इससे बचने का कारण यह है कि यह सुरक्षित नहीं है। खैर, हाँ और नहीं।
जैसा कि सी ++ में अक्सर सच होता है, यदि आप एक बुनियादी दिशानिर्देश का पालन करते हैं तो आप इसे लगातार "अपने कंधे पर देखने" के बिना सुरक्षित रूप से उपयोग कर सकते हैं। मुख्य विचार यह है कि आप एक विशेष प्रकार की वर्ग परिभाषा को "मिक्स-इन" कहते हैं; वर्ग एक मिक्स-इन है यदि इसके सभी सदस्य कार्य आभासी (या शुद्ध आभासी) हैं। फिर आपको एक ही मुख्य वर्ग से और जितनी भी "मिक्स-इन" पसंद की अनुमति दी जाती है - लेकिन आपको "वर्चुअल" कीवर्ड के साथ मिक्सिट विरासत में प्राप्त करना चाहिए। जैसे
class CounterMixin {
int count;
public:
CounterMixin() : count( 0 ) {}
virtual ~CounterMixin() {}
virtual void increment() { count += 1; }
virtual int getCount() { return count; }
};
class Foo : public Bar, virtual public CounterMixin { ..... };
मेरा सुझाव यह है कि यदि आप एक क्लास को मिक्स-इन क्लास के रूप में उपयोग करने का इरादा रखते हैं, तो आप किसी नामकरण सम्मलेन को भी अपना सकते हैं, जिससे किसी को भी कोड पढ़ने में आसानी हो, यह देखने के लिए कि क्या हो रहा है और यह सत्यापित करने के लिए कि आप मूल दिशानिर्देश के नियमों से खेल रहे हैं । और आप पाएंगे कि यह बेहतर काम करता है अगर आपके मिक्स-इन में डिफ़ॉल्ट कंस्ट्रक्टर भी हैं, जिस तरह से वर्चुअल बेस क्लास काम करते हैं। और सभी विध्वंसक को भी आभासी बनाना याद रखें।
ध्यान दें कि यहां "मिक्स-इन" शब्द का उपयोग पैरामीटराइज्ड टेम्प्लेट क्लास ( अच्छी व्याख्या के लिए इस लिंक को देखें ) के समान नहीं है, लेकिन मुझे लगता है कि यह शब्दावली का उचित उपयोग है।
अब मैं यह धारणा नहीं देना चाहता कि सुरक्षित रूप से एकाधिक विरासत का उपयोग करने का यही एकमात्र तरीका है। यह सिर्फ एक ही तरीका है जो जांचना काफी आसान है।
आपको इसका उपयोग सावधानी से करना चाहिए, कुछ मामले हैं, जैसे डायमंड प्रॉब्लम , जब चीजें जटिल हो सकती हैं।
(स्रोत: learncpp.com )
Printer
भी नहीं होना चाहिए PoweredDevice
। A Printer
मुद्रण के लिए है, न कि बिजली प्रबंधन के लिए। किसी विशेष प्रिंटर के कार्यान्वयन के लिए कुछ बिजली प्रबंधन करना पड़ सकता है, लेकिन इन बिजली प्रबंधन आदेशों को सीधे प्रिंटर के उपयोगकर्ताओं के सामने उजागर नहीं किया जाना चाहिए। मैं इस पदानुक्रम के किसी भी वास्तविक विश्व उपयोग की कल्पना नहीं कर सकता।
इनहेरिटेंस के उपयोग और दुरुपयोग।
लेख विरासत को समझाने का एक बड़ा काम करता है, और यह खतरे हैं।
हीरे के पैटर्न से परे, कई उत्तराधिकार वस्तु मॉडल को समझने में कठिन बनाते हैं, जिससे रखरखाव लागत बढ़ जाती है।
रचना आंतरिक रूप से समझने, समझने और समझाने में आसान है। यह कोड लिखने के लिए थकाऊ हो सकता है, लेकिन एक अच्छा आईडीई (यह कुछ साल रहा है जब मैंने विजुअल स्टूडियो के साथ काम किया है, लेकिन निश्चित रूप से जावा आईडीई सभी के पास महान रचना शॉर्टकट स्वचालित उपकरण हैं) आपको उस बाधा से उबरना चाहिए।
इसके अलावा, रखरखाव के संदर्भ में, "हीरे की समस्या" गैर-शाब्दिक विरासत उदाहरणों में भी सामने आती है। उदाहरण के लिए, यदि आपके पास ए और बी है और आपकी कक्षा सी उन दोनों को बढ़ाती है, और ए के पास एक 'मेक जाइसिस' विधि है जो संतरे का रस बनाती है और आप विस्तार करते हैं कि संतरे का रस चूने के साथ बनाने के लिए: डिजाइनर के लिए क्या होता है ' बी 'एक' मेक ज्यूस 'पद्धति को जोड़ता है जो विद्युत प्रवाह उत्पन्न करता है? 'ए' और 'बी' अभी संगत "माता-पिता" हो सकते हैं , लेकिन इसका मतलब यह नहीं है कि वे हमेशा रहेंगे!
कुल मिलाकर, विरासत और विशेष रूप से कई विरासत से बचने के लिए झुकाव की अधिकतम ध्वनि है। सभी अधिकतम के रूप में, अपवाद हैं, लेकिन आपको यह सुनिश्चित करने की आवश्यकता है कि आपके द्वारा कोड किए गए किसी भी अपवाद को इंगित करने वाला एक चमकता हुआ हरा नीयन चिह्न है (और अपने मस्तिष्क को प्रशिक्षित करें ताकि किसी भी समय आप ऐसे विरासत के पेड़ देखें जो आप अपने स्वयं के चमकते हरे नीयन में आकर्षित करते हैं संकेत), और यह सुनिश्चित करने के लिए कि आप यह जांच करते हैं कि यह सब हर एक बार एक समय में हो जाता है।
what happens when the designer for 'B' adds a 'makeJuice' method which generates and electrical current?
उह, आपको पाठ्यक्रम की एक जटिल त्रुटि मिलती है (यदि उपयोग अस्पष्ट है)।
ठोस वस्तुओं के एमआई के साथ प्रमुख मुद्दा यह है कि शायद ही कभी आपके पास एक वस्तु है जो वैध रूप से "ए ए और बी होना चाहिए", इसलिए यह शायद ही कभी तार्किक आधार पर सही समाधान है। अधिक बार, आपके पास एक ऑब्जेक्ट सी है जो "सी एक ए या बी" के रूप में कार्य कर सकता है, जिसे आप इंटरफ़ेस विरासत और संरचना के माध्यम से प्राप्त कर सकते हैं। लेकिन कोई गलती न करें- कई इंटरफेस की विरासत अभी भी एमआई है, बस इसका एक सबसेट।
विशेष रूप से C ++ के लिए, सुविधा की प्रमुख कमजोरी कई वंशानुक्रम का वास्तविक उदाहरण नहीं है, लेकिन कुछ निर्माणों से यह अनुमति देता है कि वे लगभग हमेशा विकृत होते हैं। उदाहरण के लिए, एक ही वस्तु की कई प्रतियों को विरासत में देना जैसे:
class B : public A, public A {};
परिभाषा द्वारा विकृत है। अंग्रेजी में अनुवादित यह "बी एक ए और एक ए" है। तो, मानव भाषा में भी एक गंभीर अस्पष्टता है। क्या आपका मतलब है "B में 2 As हैं" या सिर्फ "B एक A" है। इस तरह के पैथोलॉजिकल कोड की अनुमति देने, और इसे एक उदाहरण के रूप में बदतर बनाने के बाद, C ++ को कोई एहसान नहीं हुआ जब यह उत्तराधिकारी भाषाओं में फीचर रखने के लिए एक मामला बनाने की बात आई।
आप वरीयता के लिए रचना का उपयोग कर सकते हैं।
सामान्य भावना यह है कि रचना बेहतर है, और यह बहुत अच्छी तरह से चर्चा की गई है।
The general feeling is that composition is better, and it's very well discussed.
इसका मतलब यह नहीं है कि रचना बेहतर है।
इसमें प्रति वर्ग 4/8 बाइट्स शामिल हैं। (प्रति वर्ग एक सूचक)।
यह कभी भी चिंता का विषय नहीं हो सकता है, लेकिन अगर एक दिन आपके पास एक माइक्रो डेटा संरचना होती है जो कि अरबों समय का होता है तो यह होगा।