रचना का जिक्र सिर्फ बहुरूपता के बारे में नहीं है। यद्यपि यह इसका हिस्सा है, और आप सही हैं (कम से कम नाममात्र की भाषाओं में) जो लोग वास्तव में इसका मतलब है "रचना और इंटरफ़ेस कार्यान्वयन का संयोजन पसंद करते हैं।" लेकिन, रचना को पसंद करने के कारण (कई परिस्थितियों में) गहरा हैं।
बहुरूपता एक बात है कई तरीकों का व्यवहार करना। इसलिए, जेनेरिक / टेम्प्लेट एक "बहुरूपी" विशेषता हैं, जहाँ तक वे एक ही कोड को अपने व्यवहार को विभिन्न प्रकारों के लिए अलग-अलग करने की अनुमति देते हैं। वास्तव में, इस प्रकार का बहुरूपता वास्तव में सबसे अच्छा व्यवहार है और आमतौर पर पैरामीट्रिक बहुरूपता के रूप में संदर्भित किया जाता है क्योंकि भिन्नता को एक पैरामीटर द्वारा परिभाषित किया गया है।
कई भाषाएं "ओवरलोडिंग" या तदर्थ बहुरूपता नामक बहुरूपता का एक रूप प्रदान करती हैं जहां एक ही नाम के साथ कई प्रक्रियाएं एक तदर्थ तरीके से परिभाषित की जाती हैं, और जहां एक भाषा (शायद सबसे विशिष्ट) द्वारा चुना जाता है। यह बहुरूपता का कम से कम अच्छी तरह से व्यवहार किया गया है, क्योंकि विकसित सम्मेलन को छोड़कर दो प्रक्रियाओं के व्यवहार को कुछ भी नहीं जोड़ता है।
एक तीसरे प्रकार का बहुरूपता उप-प्रकार बहुरूपता है । यहां एक दिए गए प्रकार पर परिभाषित एक प्रक्रिया, उस प्रकार के "उपप्रकार" के पूरे परिवार पर भी काम कर सकती है। जब आप एक इंटरफ़ेस लागू करते हैं या एक वर्ग का विस्तार करते हैं तो आप आमतौर पर एक उपप्रकार बनाने के लिए अपने इरादे की घोषणा कर रहे होते हैं। सही उपप्रकार Liskov के प्रतिस्थापन सिद्धांत द्वारा नियंत्रित होते हैं, जो कहता है कि यदि आप एक सुपरटेप में सभी वस्तुओं के बारे में कुछ साबित कर सकते हैं, तो आप इसे सबटाइप में सभी उदाहरणों के बारे में साबित कर सकते हैं। हालांकि, जीवन खतरनाक हो जाता है, क्योंकि सी ++ और जावा जैसी भाषाओं में, लोग आम तौर पर बिना लाइसेंस के होते हैं, और अक्सर उन वर्गों के बारे में अनिर्धारित धारणाएं होती हैं जो उनके उपवर्गों के बारे में सच हो सकती हैं या नहीं। यही है, कोड के रूप में लिखा है कि अगर यह वास्तव में है की तुलना में अधिक साबित होता है, जो मुद्दों की एक पूरी मेजबान पैदा करता है जब आप लापरवाही से सबटाइप करते हैं।
विरासत वास्तव में बहुरूपता से स्वतंत्र है। कुछ चीज़ "T" को देखते हुए, जिसका खुद के लिए एक संदर्भ है, वंशानुक्रम तब होता है जब आप "T" के स्थान पर "T" के संदर्भ में "S" के संदर्भ में स्वयं से एक नई चीज़ बनाते हैं। यह परिभाषा जानबूझकर अस्पष्ट है, क्योंकि वंशानुक्रम कई स्थितियों में हो सकता है, लेकिन सबसे आम एक ऐसी वस्तु को उपवर्गित कर रहा है, जिसमें this
पॉइंटर के साथ वर्चुअल फ़ंक्शन द्वारा बुलाया सूचक को प्रतिस्थापित करने का प्रभाव this
होता है।
वंशानुक्रम एक खतरनाक चीज है जैसे कि सभी बहुत शक्तिशाली चीजें विरासत में कहर ढाती हैं। उदाहरण के लिए, मान लें कि जब आप किसी वर्ग से विरासत में लेते हैं तो एक विधि को ओवरराइड करते हैं: यह तब तक अच्छा और अच्छा होता है जब तक कि उस वर्ग की कोई अन्य विधि आपको एक निश्चित तरीके का व्यवहार करने के लिए विरासत में नहीं मिल जाती है, आखिरकार यह है कि मूल वर्ग के लेखक ने इसे कैसे बनाया है। । जब तक वे ओवरराइड करने के लिए डिज़ाइन नहीं किए जाते हैं, तब तक आप अपने तरीकों में से किसी अन्य तरीके से निजी या गैर-आभासी (फाइनल) घोषित करके सभी तरीकों से आंशिक रूप से रक्षा कर सकते हैं । हालांकि यह हमेशा काफी अच्छा नहीं है। कभी-कभी आप ऐसा कुछ देख सकते हैं (छद्म जावा में, C ++ और C # उपयोगकर्ताओं के लिए उम्मीद के मुताबिक)
interface UsefulThingsInterface {
void doThings();
void doMoreThings();
}
...
class WayOfDoingUsefulThings implements UsefulThingsInterface{
private foo stuff;
public final int getStuff();
void doThings(){
//modifies stuff, such that ...
...
}
...
void doMoreThings(){
//ignores stuff
...
}
}
आपको लगता है कि यह प्यारा है, और आपके पास "चीजें" करने का अपना तरीका है, लेकिन आप "अधिकता" करने की क्षमता हासिल करने के लिए विरासत का उपयोग करते हैं,
class MyUsefulThings extends WayOfDoingUsefulThings{
void doThings {
//my way
}
}
और सब ठीक है और अच्छा है। WayOfDoingUsefulThings
इस तरह से डिज़ाइन किया गया था कि एक विधि को प्रतिस्थापित करने से किसी अन्य के शब्दार्थ में बदलाव नहीं होता है ... प्रतीक्षा के अलावा, नहीं, यह नहीं था। यह जैसा दिखता था, वैसा ही हुआ, लेकिन doThings
बदले हुए परिवर्तनशील अवस्था को बदल दिया। इसलिए, भले ही इसने किसी भी ओवरराइड-सक्षम फ़ंक्शन को कॉल न किया हो,
void dealWithStuff(WayOfDoingUsefulThings bar){
bar.doThings()
use(bar.getStuff());
}
जब आप इसे पास करते हैं तो अब यह उम्मीद से अलग कुछ करता है MyUsefulThings
। इससे भी बुरा यह है कि आप यह भी नहीं जानते होंगे कि WayOfDoingUsefulThings
वे वादे किए गए थे। हो सकता है कि dealWithStuff
के रूप में ही पुस्तकालय से आता है WayOfDoingUsefulThings
और getStuff()
यहां तक कि पुस्तकालय द्वारा निर्यात नहीं कर रहा है (के बारे में सोच दोस्त कक्षाएं C ++ में)। इससे भी बदतर अभी भी, आप इसे साकार करने के बिना भाषा के स्थिर चेकों को हरा दिया है: dealWithStuff
एक ले लिया WayOfDoingUsefulThings
सिर्फ यकीन है कि यह एक के लिए होता है बनाने के लिए getStuff()
समारोह है कि एक निश्चित तरीके से व्यवहार किया।
रचना का उपयोग करना
class MyUsefulThings implements UsefulThingsInterface{
private way = new WayOfDoingUsefulThings()
void doThings() {
//my way
}
void doMoreThings() {
this.way.doMoreThings();
}
}
स्थिर प्रकार की सुरक्षा वापस लाता है। सामान्य रचना में उपप्रकार को लागू करते समय वंशानुक्रम की तुलना में उपयोग करना और सुरक्षित करना अधिक आसान होता है। यह आपको अंतिम विधियों को भी ओवरराइड करने देता है, जिसका अर्थ है कि आपको समय के विशाल बहुमत को छोड़कर सभी चीजों को अंतिम / गैर-आभासी घोषित करने के लिए स्वतंत्र महसूस करना चाहिए ।
एक बेहतर विश्व भाषाओं में स्वचालित रूप से एक delegation
कीवर्ड के साथ बॉयलरप्लेट डाला जाएगा । अधिकांश नहीं, इसलिए एक नकारात्मक पक्ष बड़ी कक्षाएं हैं। यद्यपि, आप अपने आईडीई को आपके लिए प्रतिनिधि प्रतिनिधि लिखने के लिए प्राप्त कर सकते हैं।
अब, जीवन केवल बहुरूपता के बारे में नहीं है। आपको हर समय सबटाइप करने की आवश्यकता नहीं हो सकती है। बहुरूपता का लक्ष्य आमतौर पर कोड का पुन: उपयोग होता है लेकिन यह उस लक्ष्य को प्राप्त करने का एकमात्र तरीका नहीं है। अक्सर समय, कार्यक्षमता को प्रबंधित करने के तरीके के रूप में, उप-प्रकार के बहुरूपता के बिना रचना का उपयोग करना समझ में आता है।
इसके अलावा, व्यवहार विरासत में इसके उपयोग हैं। यह कंप्यूटर विज्ञान के सबसे शक्तिशाली विचारों में से एक है। इसका यही कारण है कि, ज्यादातर समय, OOP अनुप्रयोगों को केवल इंटरफ़ेस वंशानुक्रम और रचनाओं का उपयोग करके लिखा जा सकता है। दो सिद्धांतों
- इसके लिए प्रतिबंध विरासत या डिजाइन
- रचना को प्राथमिकता दें
ऊपर दिए गए कारणों के लिए एक अच्छा मार्गदर्शक हैं, और किसी भी पर्याप्त लागत को लाइक नहीं करते हैं।