वंशानुक्रम और बहुरूपता का व्यापक रूप से उपयोग क्यों किया जाता है?


18

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

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

लेकिन यह बतख टाइपिंग के माध्यम से प्राप्त करने के लिए बहुत सरल है, चाहे वह पायथन जैसी गतिशील भाषा में हो, या सी ++ जैसी स्थिर भाषा हो।

एक उदाहरण के रूप में, निम्नलिखित पायथन फ़ंक्शन पर विचार करें, इसके बाद इसका स्थैतिक C ++ समतुल्य है:

def foo(obj):
   obj.doSomething()

template <class Obj>
void foo(Obj& obj)
{
   obj.doSomething();
}

OOP समतुल्य कुछ निम्न जावा कोड की तरह होगा:

public void foo(DoSomethingable obj)
{
  obj.doSomething();
}

बेशक, अंतर यह है कि जावा संस्करण को काम करने से पहले एक इंटरफ़ेस या एक वंशानुक्रम पदानुक्रम के निर्माण की आवश्यकता होती है। इस प्रकार जावा संस्करण में अधिक काम शामिल है, और यह कम लचीला है। इसके अतिरिक्त, मुझे लगता है कि अधिकांश वास्तविक-विश्व विरासत पदानुक्रम कुछ अस्थिर हैं। हम सभी ने आकृतियाँ और जानवरों के वंचित उदाहरणों को देखा है, लेकिन वास्तविक दुनिया में, जैसे-जैसे व्यवसाय की आवश्यकताएं बदलती हैं और नई सुविधाएँ जुड़ती जाती हैं, आपको वास्तव में "is-a" के बीच संबंध बढ़ाने की आवश्यकता होने से पहले कोई भी काम करना मुश्किल है। उप-वर्ग, या फिर अपनी आवश्यकताओं को समायोजित करने के लिए आगे के आधार-वर्गों या इंटरफेस को शामिल करने के लिए अपने पदानुक्रम को फिर से तैयार / रीफ़्रैक्टर करें। बतख टाइपिंग के साथ, आपको कुछ भी मॉडलिंग करने की चिंता करने की ज़रूरत नहीं है - आपको बस उस कार्यक्षमता की चिंता है जो आपको चाहिए।

फिर भी, विरासत और बहुरूपता इतनी लोकप्रिय हैं कि मुझे संदेह है कि उन्हें अतिशयोक्ति और कोड के पुन: उपयोग के लिए प्रमुख रणनीति कहना अतिशयोक्ति होगी। तो विरासत और बहुरूपता इतनी बेतहाशा सफल क्यों हैं? क्या मैं कुछ गंभीर लाभों की अनदेखी कर रहा हूं, जो वंशानुक्रम / बहुरूपता पर टंकण से अधिक है?


मैं अजगर विशेषज्ञ नहीं हूं इसलिए मुझे पूछना होगा: अगर objकोई doSomethingविधि नहीं है तो क्या होगा ? क्या कोई अपवाद उठाया गया है? क्या कुछ नहीं होता है?
फ्रस्ट्रेटेडविथफॉर्म्सडिजेनर

6
@ स्वीकृत: एक बहुत स्पष्ट, विशिष्ट अपवाद उठाया जाता है।
dsimcha

11
क्या सिर्फ ग्यारह तक ले जाने वाली बहुरूपता टाइपिंग नहीं है? मेरा अनुमान है कि आप ओओपी से निराश नहीं हैं, बल्कि अपने वैधानिक रूप से अवतारों के साथ। मैं समझ सकता हूँ कि, वास्तव में, लेकिन यह ओओपी को एक बुरा विचार नहीं बनाता है।

3
सबसे पहले "बेतहाशा" को "बेतहाशा" पढ़ें ...

जवाबों:


22

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

इसके अलावा, इन स्पष्ट इंटरफेस को बतख टाइपिंग की तुलना में अधिक कुशलता से लागू किया जा सकता है। एक वर्चुअल फ़ंक्शन कॉल में सामान्य फ़ंक्शन कॉल की तुलना में मुश्किल से अधिक ओवरहेड होता है, सिवाय इसके कि यह इनलेट नहीं किया जा सकता है। बत्तख टाइपिंग में पर्याप्त ओवरहेड होता है। C ++ - स्टाइल स्ट्रक्चरल टाइपिंग (टेम्प्लेट का उपयोग करके) भारी मात्रा में ऑब्जेक्ट फ़ाइल ब्लोट उत्पन्न कर सकता है (चूंकि प्रत्येक इंस्टीट्यूशन ऑब्जेक्ट फ़ाइल स्तर पर स्वतंत्र है) और जब आप रनटाइम पर बहुरूपता की आवश्यकता नहीं करते हैं, तो काम नहीं करते हैं।

नीचे पंक्ति: मैं मानता हूं कि जावा-शैली की विरासत और बहुरूपता एक पीआईटीए हो सकती है और विकल्पों का अधिक बार उपयोग किया जाना चाहिए, लेकिन इसके फायदे अभी भी हैं।


29

विरासत और बहुरूपता व्यापक रूप से उपयोग किया जाता है क्योंकि वे काम करते हैं कुछ प्रकार की प्रोग्रामिंग समस्याओं के लिए ।

ऐसा नहीं है कि वे व्यापक रूप से स्कूलों में पढ़ाए जाते हैं, यह पीछे की ओर है: वे व्यापक रूप से स्कूलों में पढ़ाए जाते हैं क्योंकि लोगों (उर्फ बाजार) ने पाया कि उन्होंने पुराने उपकरणों की तुलना में बेहतर काम किया और इसलिए स्कूलों ने उन्हें पढ़ाना शुरू किया। [किस्सा: जब मैं पहली बार ओओपी सीख रहा था, तो एक कॉलेज ढूंढना बेहद मुश्किल था जो किसी भी ओओपी भाषा को सिखाता हो। दस साल बाद, एक कॉलेज को खोजना मुश्किल था जिसने ओओपी भाषा नहीं सिखाई थी।]

तुमने कहा था:

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

मैं कहता हूँ:

नहीं, यह नहीं है

आप जो वर्णन करते हैं वह बहुरूपता नहीं है, बल्कि विरासत है। कोई आश्चर्य नहीं कि आप OOP समस्याएँ हैं! ;-)

एक कदम पीछे हटना: बहुरूपता संदेश-गुजरने का एक लाभ है; इसका सीधा सा मतलब है कि प्रत्येक वस्तु अपने तरीके से संदेश का जवाब देने के लिए स्वतंत्र है।

तो ... बतख टाइपिंग है (या बल्कि, सक्षम बनाता है) बहुरूपता

आपके प्रश्न का सार यह प्रतीत होता है कि आप OOP को नहीं समझते हैं या आप इसे नापसंद करते हैं, लेकिन यह कि आप इंटरफेस को परिभाषित करना पसंद नहीं करते हैं । यह ठीक है, और जब तक आप सावधान हैं चीजें ठीक रहेंगी। दोष यह है कि यदि आपने कोई गलती की है - एक विधि को छोड़ दिया है, उदाहरण के लिए - आपको रन-टाइम तक पता नहीं चलेगा।

यह एक स्थिर बनाम गतिशील चीज है, जो लिस्प के रूप में पुराने रूप में चर्चा है, और ओओपी तक सीमित नहीं है।


2
के लिए "बतख टाइपिंग +1 है बहुरूपता"। बहुरूपता और वंशानुक्रम को बहुत लंबे समय तक एक साथ जकड़ा हुआ है, और सख्त स्थैतिक टाइपिंग एकमात्र वास्तविक कारण है जो उन्हें कभी भी होना था।
cHao

+1। मुझे लगता है कि स्थिर बनाम गतिशील अंतर एक साइड नोट से अधिक होना चाहिए - यह बतख टाइपिंग और जावा-शैली के बहुरूपता के बीच अंतर के मूल में है।
सावा बी।

8

मैंने वस्तुओं के बीच संबंधों के नाजुक सेट के आधार पर एक अनावश्यक प्रतिबंध लगाने के रूप में विरासत और बहुरूपता को देखना शुरू कर दिया है।

क्यों?

वंशानुक्रम (डक टाइपिंग के साथ या बिना) एक सामान्य सुविधा के पुन: उपयोग का आश्वासन देता है। यदि यह सामान्य है, तो आप आश्वस्त कर सकते हैं कि यह उपवर्गों में लगातार उपयोग किया जाता है।

बस इतना ही। कोई "अनावश्यक प्रतिबंध" नहीं है। यह एक सरलीकरण है।

बहुरूपता, इसी तरह, "बतख टाइपिंग" का मतलब है। एक ही तरीके। एक समान इंटरफ़ेस के साथ बहुत सारी कक्षाएं, फिर भी अलग-अलग कार्यान्वयन।

यह कोई प्रतिबंध नहीं है। यह एक सरलीकरण है।


7

वंशानुक्रम का दुरुपयोग किया जाता है, लेकिन इतना डकार टाइपिंग है। दोनों समस्याओं को जन्म दे सकते हैं।

मजबूत टाइपिंग के साथ आपको कई "यूनिट परीक्षण" संकलन समय पर किए जाते हैं। बतख टाइपिंग के साथ आपको अक्सर उन्हें लिखना होगा।


3
परीक्षण के बारे में आपकी टिप्पणी केवल गतिशील बतख टाइपिंग पर लागू होती है। C ++ - स्टाइल स्टैटिक डक टाइपिंग (टेम्प्लेट के साथ) आपको संकलन के समय त्रुटियां देता है। (हालांकि, दी गई सी ++ टेम्पलेट त्रुटियों को समझने के लिए बहुत कठिन है, लेकिन यह पूरी तरह से एक अलग मुद्दा है।)
Channel72

2

स्कूल में चीजें सीखने के बारे में अच्छी बात यह है कि आप करते हैं उन्हें सीखने। नहीं-तो अच्छी बात यह है कि आप उन्हें थोड़ी बहुत हठपूर्वक स्वीकार कर सकते हैं, बिना यह समझे कि वे कब उपयोगी हैं और कब नहीं।

फिर, यदि आपने इसे हठधर्मिता से सीखा है, तो आप बाद में डोग्मेटिक रूप से दूसरी दिशा में "विद्रोह" कर सकते हैं। यह भी अच्छा नहीं है।

ऐसे किसी भी विचार के साथ, यह एक व्यावहारिक दृष्टिकोण लेने के लिए सबसे अच्छा है। वे कहां फिट होते हैं और कहां नहीं, इसकी समझ विकसित करें। और उन सभी तरीकों को नजरअंदाज करें जो वे ओवरसोल्ड कर चुके हैं।


2

हाँ, स्थैतिक टाइपिंग और इंटरफेस प्रतिबंध हैं। लेकिन जब से संरचित प्रोग्रामिंग का आविष्कार किया गया था (यानी "गोटो हानिकारक माना जाता है") हमें विवश करने के बारे में है। अंकल बॉब ने अपने वीडियो ब्लॉग में इस पर एक उत्कृष्ट लिया है

अब, एक तर्क दे सकता है कि कसना बुरा है, लेकिन दूसरी ओर यह अन्यथा बहुत जटिल विषय पर आदेश, नियंत्रण और परिचितता लाता है।

(टाइप-) डायनामिक टाइपिंग शुरू करने और यहां तक ​​कि डायरेक्ट मेमोरी एक्सेस के लिए बहुत कम कॉन्सेप्ट होने की वजह से आराम मिलता है, लेकिन कई प्रोग्रामर्स के लिए इससे निपटना भी मुश्किल हो जाता है। विशेष रूप से प्रोग्रामर कंपाइलर पर भरोसा करते थे और अपने अधिकांश काम के लिए सुरक्षा टाइप करते थे।


1

वंशानुक्रम दो वर्गों के बीच बहुत मजबूत संबंध है। मुझे नहीं लगता कि जावा में कोई मजबूत है। इसलिए, आपको इसका मतलब होने पर ही इसका इस्तेमाल करना चाहिए। सार्वजनिक विरासत एक "एक-एक" संबंध है, न कि "आमतौर पर एक-एक" है। यह वास्तव में, वास्तव में वंशानुक्रम का अति प्रयोग करने में आसान है और एक गड़बड़ के साथ हवा है। कई मामलों में, वंशानुक्रम का उपयोग "है-ए" या "टेक-कार्यक्षमता-से-एक" का प्रतिनिधित्व करने के लिए किया जाता है, और यह आमतौर पर रचना द्वारा बेहतर किया जाता है।

बहुरूपता "- एक" संबंध का प्रत्यक्ष परिणाम है। यदि व्युत्पन्न बेस से विरासत में मिला है, तो प्रत्येक व्युत्पन्न "एक" बेस है, और इसलिए आप एक डिराइव्ड का उपयोग कर सकते हैं जहाँ भी आप बेस का उपयोग करेंगे। यदि यह एक विरासत पदानुक्रम में समझ में नहीं आता है, तो पदानुक्रम गलत है और शायद बहुत अधिक वंशानुक्रम चल रहा है।

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

मैं स्थैतिक टाइपिंग का वास्तविक प्रशंसक नहीं हूं (मैं इसे अक्सर समय से पहले अनुकूलन का एक रूप मानता हूं), लेकिन यह कुछ वर्गों की त्रुटियों को समाप्त करता है, और कई लोग सोचते हैं कि वे कक्षाएं समाप्त करने के लायक हैं।

अगर आपको डायनेमिक टाइपिंग पसंद है और स्टैटिक टाइपिंग और परिभाषित विरासत पदानुक्रमों की तुलना में डक टाइपिंग बेहतर है, तो यह ठीक है। हालांकि, जावा तरीके के अपने फायदे हैं।


0

मैंने देखा है कि मैं C # का जितना अधिक उपयोग करता हूं, वह उतना कम बंद होता है, मैं पारंपरिक OOP कर रहा हूं। इनहेरिटेंस आसानी से कार्यान्वयन को साझा करने का एकमात्र तरीका हुआ करता था, इसलिए मुझे लगता है कि यह अक्सर अधिक इस्तेमाल किया जाता था और गर्भाधान सीमा को बहुत दूर धकेल दिया जाता था।

जबकि आप कर सकते हैं आमतौर पर क्लोज़र का उपयोग तो अधिकांश आप विरासत के साथ क्या करेंगे, यह भी बदसूरत हो सकता है।

मूल रूप से यह एक राइट-टूल-फॉर-द-जॉब स्थिति है: पारंपरिक ओओपी वास्तव में अच्छी तरह से काम कर सकता है जब आपके पास एक मॉडल होता है जो इसे सूट करता है, और जब आप नहीं करते हैं तो क्लोजर वास्तव में अच्छी तरह से काम कर सकता है।


-1

सच्चाई कहीं न कहीं बीच में है। मुझे पसंद है कि कैसे सी # 4.0 स्टेटिकली टाइप की गई भाषा "डायनामिक" कीवर्ड द्वारा "डक टाइपिंग" का समर्थन करती है।


-1

एफपी परिप्रेक्ष्य से कारण होने पर भी विरासत, एक महान अवधारणा है; यह न केवल बहुत समय बचाता है, यह आपके कार्यक्रम में कुछ वस्तुओं के बीच संबंध को अर्थ देता है।

public class Animal {
    public virtual string Sound () {
        return "Some Sound";
    }
}

public class Dog : Animal {
    public override string Sound () {
        return "Woof";
    }
}

public class Cat : Animal {
    public override string Sound () {
        return "Mew";
    }
}

public class GoldenRetriever : Dog {

}

यहाँ वर्ग GoldenRetrieverएक ही है Soundके रूप में Dogविरासत के लिए स्वतंत्र धन्यवाद के लिए।

आपके अंतर को देखने के लिए मैं हास्केल के अपने स्तर के साथ एक ही उदाहरण लिखूंगा

data Animal = Animal | Dog | Cat | GoldenRetriever

sound :: Animal -> String
sound Animal = "Some Sound"
sound Dog = "Woof"
sound Cat = "Mew"
sound GoldenRetriever = "Woof"

यहाँ में आप निर्दिष्ट किए बच नहीं है soundके लिए GoldenRetriever। सामान्य रूप से सबसे आसान काम होगा

sound GoldenRetriever = sound Dog

लेकिन सिर्फ कल्पना करें कि आपके पास 20 कार्य हैं! यदि कोई हास्केल विशेषज्ञ है तो कृपया हमें एक आसान तरीका दिखाएं।

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


5
मैं शपथ लेता हूं, AnimalOOP का विरोधी ट्यूटोरियल है।
तेलस्टिन

@Telastyn मैंने Youtube पर डेरेक बनास से उदाहरण सीखा। महान अध्यापक। मेरी राय में इसके बारे में कल्पना करना और तर्क करना बहुत आसान है। आप एक बेहतर उदाहरण के साथ पोस्ट को संपादित करने के लिए स्वतंत्र हैं।
क्रिस्टियन गार्सिया

इससे पहले के 10 जवाबों में कुछ भी जोड़कर नहीं देखा जा सकता है
gnat

@gnat जबकि "पदार्थ" पहले से ही बाहर है, विषय के लिए एक व्यक्ति को समझ में आसान उदाहरण मिल सकता है।
क्रिस्टियन गार्सिया

2
पशु और आकार वास्तव में कई कारणों से बहुरूपता के खराब अनुप्रयोग हैं जिनकी इस साइट पर विज्ञापन nauseum पर चर्चा की गई है। मूल रूप से, एक बिल्ली "एक जानवर" अर्थहीन है, क्योंकि कोई ठोस "जानवर" नहीं है। आप वास्तव में मॉडल का क्या मतलब है व्यवहार है, पहचान नहीं। एक इंटरफ़ेस "कैनस्पीक" को परिभाषित करना जिसे एक म्याऊ या छाल के रूप में लागू किया जा सकता है, समझ में आता है। एक इंटरफ़ेस "हसारे" को परिभाषित करना जो एक वर्ग और सर्कल को लागू कर सकता है, समझ में आता है, लेकिन सामान्य आकार नहीं।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.