प्रोटोटाइपिक विरासत, शास्त्रीय विरासत से व्यावहारिक रूप से कैसे भिन्न है?


27

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

हालाँकि, मैं यह नहीं समझ सकता कि व्यावहारिक उपयोग के बिंदु से उनका अंतर क्या है? दूसरे शब्दों में, जब आप एक बेस क्लास (प्रोटोटाइप) को परिभाषित करते हैं और फिर इसमें से कुछ उपवर्गों को प्राप्त करते हैं, तो आप दोनों के पास आपके बेस क्लास के फंक्शंस तक पहुंच होती है, और आप व्युत्पन्न वर्गों पर कार्यों को बढ़ा सकते हैं। यदि हम समझते हैं कि मैंने जो कहा था वह विरासत का इच्छित परिणाम है, तो अगर हम प्रोटोटाइप या क्लासिक संस्करण का उपयोग कर रहे हैं तो हमें क्यों परवाह करनी चाहिए?

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

जवाबों:


6

जेएस ओ ओ के बारे में हालिया ब्लॉग पोस्ट

मेरा मानना ​​है कि आपकी तुलना जावास्क्रिप्ट में शास्त्रीय OO अनुकरण और शास्त्रीय OO है और निश्चित रूप से आप कोई अंतर नहीं देख सकते हैं।

अस्वीकरण: "प्रोटोटाइप ओओ" के साथ "जावास्क्रिप्ट में ओओ" के सभी संदर्भों को बदलें। मैं स्वयं या किसी अन्य कार्यान्वयन की बारीकियों को नहीं जानता।

हालांकि प्रोटोटाइप ओओ अलग है। प्रोटोटाइप के साथ आपके पास केवल ऑब्जेक्ट होते हैं और आप केवल ऑब्जेक्ट को अन्य ऑब्जेक्ट प्रोटोटाइप चेन में इंजेक्ट कर सकते हैं। जब भी आप किसी ऑब्जेक्ट को किसी ऑब्जेक्ट पर एक्सेस करते हैं, तो आप उस ऑब्जेक्ट और किसी भी ऑब्जेक्ट को प्रोटोटाइप चेन में खोजते हैं।

प्रोटोटाइप ओओ के लिए एनकैप्सुलेशन की कोई धारणा नहीं है। एनकैप्सुलेशन गुंजाइश, क्लोजर और प्रथम श्रेणी के कार्यों की एक विशेषता है लेकिन इसका प्रोटोटाइप ओओ से कोई लेना-देना नहीं है। विरासत की भी कोई धारणा नहीं है, जिसे लोग "विरासत" कहते हैं, वह वास्तव में सिर्फ बहुरूपता है।

हालांकि इसमें बहुरूपता है।

उदाहरण के लिए

var Dog = {
  walk: function() { console.log("walks"); }
}

var d = Object.create(Dog);
d.walk();

स्पष्ट रूप dसे विधि तक पहुंच है Dog.walkऔर यह बहुरूपता प्रदर्शित करता है।

तो वास्तव में एक बड़ा अंतर है । आपको केवल बहुरूपता है।

हालांकि, जैसा कि आप उल्लेख करते हैं, यदि आप ऐसा करना चाहते हैं (मुझे पता नहीं है कि आप क्यों करेंगे) तो आप जावास्क्रिप्ट में शास्त्रीय OO का अनुकरण कर सकते हैं और इनका उपयोग (प्रतिबंधित) इनकैप्सुलेशन और इनहेरिटेंस तक कर सकते हैं।


1
@ रैयॉन, गूगल प्रोटोटाइपिक विरासत के लिए और आप देखेंगे कि प्रोटोटाइप विरासत में आता है। याहू से भी!
सईद नेमाटी

@ सईद विरासत एक अस्पष्ट शब्द है और आमतौर पर इसका दुरुपयोग किया जाता है। वे "विरासत" I लेबल "बहुरूपता" के साथ क्या मतलब है। परिभाषाएँ बहुत अस्पष्ट हैं।
रेयनोस

नहीं @ रेयॉन, मेरा मतलब था कि प्रोटोटाइप शब्द सही शब्द है, प्रोटोटाइप नहीं । मैं विरासत के बारे में बात नहीं करता था :)
सईद नेमाटी

1
@Saeed कि उन टाइपो में से एक मेरा दिमाग अभी खाली है। मैं उस पर ध्यान नहीं देता
रेयानोस

1
हम्म .. शब्दावली। Ick। मैं उस तरह से कॉल करूंगा कि जावास्क्रिप्ट ऑब्जेक्ट्स उनके प्रोटोटाइप "डेलिगेशन" से संबंधित हैं। बहुरूपता मुझे एक निम्न-स्तर की चिंता प्रतीत होती है, इस तथ्य के आधार पर कि एक दिया गया नाम अलग-अलग वस्तुओं के लिए अलग-अलग कोड को इंगित कर सकता है।
शॉन मैकमिलन

15

शास्त्रीय विरासत में मूल राज्य से, किसी भी राज्य के बिना व्यवहार विरासत में मिला है। यह उस क्षण व्यवहार को विरासत में प्राप्त करता है जब वस्तु को त्वरित किया जाता है।

प्रोटोोटाइपल इनहेरिटेंस को मूल वस्तु से व्यवहार और अवस्था विरासत में मिलती है। यह उस समय व्यवहार और स्थिति को विरासत में प्राप्त करता है जिसे वस्तु कहा जाता है। जब रन-टाइम पर पैरेंट ऑब्जेक्ट बदलता है, तो चाइल्ड ऑब्जेक्ट्स की स्थिति और व्यवहार प्रभावित होते हैं।

प्रोटोटाइप इनहेरिटेंस का "लाभ" यह है कि आप अपनी सभी वस्तुओं को त्वरित करने के बाद राज्य और व्यवहार को "पैच" कर सकते हैं। उदाहरण के लिए, एक्सटी जेएस फ्रेमवर्क में "ओवरराइड्स" लोड करने के लिए आम है जो फ्रेमवर्क के कोर घटकों को फ्रेमवर्क के तुरंत बाद लोड किया जाता है।


4
व्यवहार में, यदि आप राज्य की विरासत प्राप्त कर रहे हैं, तो आप खुद को चोट की दुनिया के लिए स्थापित कर रहे हैं। यदि वह किसी अन्य वस्तु पर रहता है, तो अंतर्निहित अवस्था साझा हो जाएगी।
शॉन मैकमिलन

1
मेरे साथ ऐसा होता है कि जावास्क्रिप्ट में वास्तव में राज्य से अलग व्यवहार की कोई अवधारणा नहीं है। कंस्ट्रक्टर फ़ंक्शन के अलावा सभी व्यवहार को किसी भी अन्य राज्य की तरह ही पोस्ट-ऑब्जेक्ट-निर्माण को संशोधित / संशोधित किया जा सकता है।
जोएरी सेब्रेट्स

तो पायथन में शास्त्रीय विरासत नहीं है? अगर मेरे पास है class C(object): def m(self, x): return x*2और फिर instance = C()जब मैं दौड़ता instance.m(3)हूं तो मुझे मिलता है 6। लेकिन अगर मैं तब बदल Cजाता C.m = lambda s, x: x*xहूं और मैं दौड़ता instance.m(3)हूं तो मुझे मिलता है 9। वही जाता है अगर मैं एक बना देता हूं class D(C)और एक विधि को बदल देता हूं Cतो Dपरिवर्तित विधि प्राप्त करने के किसी भी उदाहरण को भी। क्या मुझे गलतफहमी है या इसका मतलब यह है कि आपकी परिभाषा के अनुसार पायथन में शास्त्रीय विरासत नहीं है?
mVChr

@ एमवीसीएचआर: आप अभी भी व्यवहार विरासत में प्राप्त कर रहे हैं और उस मामले में राज्य नहीं कर रहे हैं, जो शास्त्रीय विरासत की ओर इशारा करता है, लेकिन यह "जिस क्षण वस्तु को त्वरित किया जाता है, उस व्यवहार की मेरी परिभाषा के साथ एक मुद्दे को इंगित करता है"। मुझे यकीन नहीं है कि परिभाषा को कैसे ठीक किया जाए।
जोएरी सेब्रेचट्स

9

पहला: अधिकांश समय, आप वस्तुओं का उपयोग कर रहे होंगे, उन्हें परिभाषित नहीं कर रहे होंगे, और वस्तुओं का उपयोग करना दोनों प्रतिमानों के तहत समान है।

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

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

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

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


हाँ, सबसे अच्छा जवाब IMO!
आइवर

0

जावास्क्रिप्ट में प्रोटोटाइप इनहेरिटेंस इन महत्वपूर्ण तरीकों से कक्षाओं से अलग है:

कंस्ट्रक्टर बस ऐसे कार्य हैं जिन्हें आप बिना बुलाए कर सकते हैं new:

function Circle (r, x, y) { 
  //stuff here
}
Var c = new Circle();
Circle.call(c, x, y, z); //This works and you can do it over and over again.

कोई भी निजी चर या विधियां नहीं हैं, सबसे अच्छा आप यह कर सकते हैं:

function Circle (r, x, y) {
  var color = 'red';
  function drawCircle () {
    //some code here with x, y and r
  }
  drawCircle();
  this.setX = function (x_) {
    x = x_;
    drawCircle();
  }

}
Circle.prototype.getX = function () {
   //Can't access x!
}

पिछले उदाहरण में आप वर्ग को सार्थक रूप से विस्तारित नहीं कर सकते हैं यदि आप नकली निजी चर और विधियों का सहारा लेते हैं और इसके अलावा आपके द्वारा घोषित किए गए किसी भी सार्वजनिक तरीके को हर बार एक नया उदाहरण बनाया जाता है।


आप "क्लास" को सार्थक रूप से बढ़ा सकते हैं। तुम सिर्फ स्थानीय चर उपयोग नहीं कर सकते color, r, x, yऔर drawCircleइस बात का शाब्दिक गुंजाइश के लिए बाध्य कर रहे हैंCircle
Raynos

यह सच है, आप कर सकते हैं, लेकिन आप इसे 'सार्वजनिक' तरीकों का एक गुच्छा बनाए बिना नहीं कर सकते हैं जो संदर्भ में हर बार जब आप एक उदाहरण बनाते हैं तो जोड़े जाते हैं।
ब्योर्न

यह एक बहुत ही अजीब पैटर्न है जिसका आप उपयोग कर रहे हैं। Circle.call()एक निर्माता के रूप में? ऐसा लगता है कि आप "कार्यात्मक वस्तुओं" (एक मिथ्या नाम ...) का वर्णन करने की कोशिश कर रहे हैं
शॉन मैकमिलन

यह ऐसा कुछ नहीं है जो मैं कभी करूंगा, मैं सिर्फ इतना कह रहा हूं कि कंस्ट्रक्टर को बार-बार जावास्क्रिप्ट के साथ कॉल करना संभव है, लेकिन पारंपरिक कक्षाओं वाली भाषाओं में नहीं।
ब्योर्न

1
लेकिन ये अंतर 'महत्वपूर्ण' कैसे हैं? मैं एक फ़ंक्शन को कॉल करके ऑब्जेक्ट का निर्माण नहीं देखता, 'नए' का उपयोग नहीं करता, 'महत्वपूर्ण' के रूप में, बस एक छोटे से वाक्यविन्यास अंतर। इसी तरह, निजी चर न होना, मूल रूप से अलग नहीं है, बस एक छोटा सा अंतर है। साथ ही, आप जिस तरह का वर्णन करते हैं, वैसा ही (कुछ वैसा ही) निजी चर भी हो सकता है।
रोएल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.