मान लीजिए आप निम्नलिखित स्थितिपायथन में विरासत का क्या मतलब है?
#include <iostream>
class Animal {
public:
virtual void speak() = 0;
};
class Dog : public Animal {
void speak() { std::cout << "woff!" <<std::endl; }
};
class Cat : public Animal {
void speak() { std::cout << "meow!" <<std::endl; }
};
void makeSpeak(Animal &a) {
a.speak();
}
int main() {
Dog d;
Cat c;
makeSpeak(d);
makeSpeak(c);
}
आप देख सकते हैं है, makeSpeak एक नियमित है कि एक सामान्य पशु वस्तु को स्वीकार करता है। इस मामले में, पशु जावा इंटरफेस के समान ही है, क्योंकि इसमें केवल शुद्ध वर्चुअल विधि है। मेकस्पीक पशु की प्रकृति को नहीं जानता है जो इसे पारित किया जाता है। यह सिर्फ सिग्नल को "बोलता है" भेजता है और कॉल करने के लिए किस विधि का ख्याल रखने के लिए देर से बाध्यकारी छोड़ देता है: या तो बिल्ली :: बोलें() या कुत्ता :: बोलें()। इसका मतलब यह है कि, जहां तक मेकस्पीक का संबंध है, ज्ञान का वास्तव में पारित होने का ज्ञान अप्रासंगिक है।
लेकिन पायथन के बारे में क्या? चलिए पाइथन में एक ही मामले के लिए कोड देखते हैं। कृपया ध्यान दें कि मैं एक पल के लिए सी करने के लिए संभव के रूप में समान होने की कोशिश ++ मामला:
class Animal(object):
def speak(self):
raise NotImplementedError()
class Dog(Animal):
def speak(self):
print "woff!"
class Cat(Animal):
def speak(self):
print "meow"
def makeSpeak(a):
a.speak()
d=Dog()
c=Cat()
makeSpeak(d)
makeSpeak(c)
अब, इस उदाहरण में आप एक ही रणनीति को देखते हैं। आप कुत्तों और बिल्लियों दोनों जानवरों की पदानुक्रमिक अवधारणा का लाभ उठाने के लिए विरासत का उपयोग करते हैं। लेकिन पायथन में, इस पदानुक्रम की कोई आवश्यकता नहीं है। यह समान रूप से अच्छी तरह से काम करता है
class Dog:
def speak(self):
print "woff!"
class Cat:
def speak(self):
print "meow"
def makeSpeak(a):
a.speak()
d=Dog()
c=Cat()
makeSpeak(d)
makeSpeak(c)
पायथन में आप किसी भी वस्तु को "बोलने" संकेत भेज सकते हैं। यदि वस्तु इसके साथ सौदा करने में सक्षम है, तो इसे निष्पादित किया जाएगा, अन्यथा यह एक अपवाद उठाएगा। मान लीजिए कि आप दोनों कोडों में एक क्लास एयरप्लेन जोड़ते हैं, और स्पीक बनाने के लिए एक एयरप्लेन ऑब्जेक्ट सबमिट करते हैं। सी ++ मामले में, यह संकलित नहीं होगा, क्योंकि विमान पशु का व्युत्पन्न वर्ग नहीं है। पायथन मामले में, यह रनटाइम पर एक अपवाद उठाएगा, जो एक अपेक्षित व्यवहार भी हो सकता है।
दूसरी ओर, मान लीजिए कि आप विधि विधि() के साथ एक MouthOfTruth क्लास जोड़ते हैं। सी ++ मामले में, आपको या तो अपने पदानुक्रम को दोबारा बदलना होगा, या आपको मुथऑफट्रूथ ऑब्जेक्ट्स को स्वीकार करने के लिए एक अलग मेक स्पीक विधि को परिभाषित करना होगा, या जावा में आप व्यवहार को कैनस्पीकआईफेस में निकाल सकते हैं और प्रत्येक के लिए इंटरफेस को कार्यान्वित कर सकते हैं। कई समाधान हैं ...
मैं यह इंगित करना चाहता हूं कि मुझे पाइथन में विरासत का उपयोग करने के लिए एक कारण नहीं मिला है (ढांचे और अपवादों के पेड़ों के अलावा, लेकिन मुझे लगता है कि वैकल्पिक रणनीतियों मौजूद)। आपको polymorphically प्रदर्शन करने के लिए एक बेस व्युत्पन्न पदानुक्रम को लागू करने की आवश्यकता नहीं है। यदि आप कार्यान्वयन का पुन: उपयोग करने के लिए विरासत का उपयोग करना चाहते हैं, तो आप इसे अतिरिक्त लाभ के साथ रोकथाम और प्रतिनिधिमंडल के माध्यम से पूरा कर सकते हैं, जिसे आप रनटाइम पर बदल सकते हैं, और आप स्पष्ट रूप से अनचाहे साइड इफेक्ट्स के जोखिम के बिना निहित इंटरफ़ेस को परिभाषित करते हैं।
तो अंत में, प्रश्न खड़ा है: पायथन में विरासत का बिंदु क्या है?
संपादित करें: बहुत ही रोचक उत्तरों के लिए धन्यवाद। दरअसल आप इसे कोड पुन: उपयोग के लिए उपयोग कर सकते हैं, लेकिन कार्यान्वयन का पुन: उपयोग करते समय मैं हमेशा सावधान रहता हूं। आम तौर पर, मैं बहुत उथले विरासत पेड़ या कोई पेड़ नहीं करता हूं, और यदि कोई कार्यक्षमता आम है तो मैं इसे एक सामान्य मॉड्यूल दिनचर्या के रूप में पुनः प्रतिक्रिया देता हूं और फिर इसे प्रत्येक ऑब्जेक्ट से कॉल करता हूं। मुझे परिवर्तन का एक बिंदु होने का लाभ दिखाई देता है (उदाहरण के लिए, कुत्ते, बिल्ली, मूस और अन्य में जोड़ने के बजाय, मैं सिर्फ पशु में जोड़ता हूं, जो विरासत का मूल लाभ है), लेकिन आप इसे प्राप्त कर सकते हैं एक प्रतिनिधिमंडल श्रृंखला (उदाहरण के लिए एक ला जावास्क्रिप्ट)। मैं दावा नहीं कर रहा हूं कि यह बेहतर है, हालांकि, एक और तरीका है।
मुझे इस संबंध में a similar post भी मिला।
-1: "आप एक प्रतिनिधिमंडल श्रृंखला के साथ इसे प्राप्त कर सकते हैं"। सच है, लेकिन विरासत से कहीं ज्यादा दर्दनाक है। आप किसी भी वर्ग परिभाषाओं का उपयोग किए बिना इसे प्राप्त कर सकते हैं, केवल जटिल शुद्ध कार्यों के बहुत सारे। आप एक ही चीज़ को एक दर्जन तरीकों से प्राप्त कर सकते हैं, विरासत से कम सरल। –
वास्तव में मैंने कहा "मैं दावा नहीं कर रहा हूं कि यह बेहतर है;)" –
"मुझे अभी तक पाइथन में विरासत का उपयोग करने का एक कारण नहीं मिला है" ... यकीन है कि "मेरा समाधान बेहतर है"। –