क्लास इनहेरिटेंस OOP (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) की एक मौलिक विशेषता है जो आपको किसी भी क्लास का अधिक विशिष्ट और विशेष संस्करण बनाने में मदद करती है।
यहां एक उदाहरण है:
Food -> Fruit -> Orange
इन क्लासेस के बीच एक संबंध है!
हम कह सकते हैं कि एक संतरा एक फल है, लेकिन फल भी भोजन हैं।
पेरेंट क्लास (जिसे सुपर क्लास या बेस क्लास भी कहा जाता है) हमेशा सबक्लासेस से अधिक सामान्य होती है।
Fruit (अधिक सामान्य) Orange (अधिक विशिष्ट) की पेरेंट क्लास है।
रूबी में यह इस तरह दिखता है:
class Food end class Fruit < Food end class Orange < Fruit end
इनहेरिटेंस के निहितार्थों में से एक रूबी में यह है कि Food पर परिभाषित हर मेथड और हर कॉन्स्टेंट Fruit पर उपलब्ध होगा, और Orange पर भी।
मेथड्स बेस क्लास से नीचे पास होते हैं, लेकिन दूसरी तरफ नहीं।
इनहेरिटेंस का उद्देश्य क्या है?
आप सोच सकते हैं कि ऑब्जेक्ट हायरार्की बनाना आपके कोड के लिए किसी प्रकार का "फील गुड" संगठन प्रदान करता है, लेकिन इसमें इससे कहीं अधिक है।
इनहेरिटेंस का उपयोग पेरेंट क्लास का एक अलग संस्करण बनाने के लिए किया जाता है जो किसी विशेष उद्देश्य के लिए उपयुक्त है। शायद इसे कुछ अतिरिक्त फीचर्स या मेथड्स की आवश्यकता है जो पेरेंट क्लास में समझ में नहीं आएंगे।
यहां एक उदाहरण है:
सभी फलों का एक रंग, वजन और नाम होता है।
कुछ फलों में विशेष विशेषताएं हो सकती हैं जो अन्य फलों के साथ साझा नहीं की जाती हैं, इसलिए आप एक नई क्लास बनाते हैं जो सभी फलों की विशेषताओं (रंग, वजन, आदि) को इनहेरिट करती है और फिर विशेष विशेषता जोड़ती है।
यही मेरा मतलब है विशेषज्ञता से।
एक और उदाहरण:
आपके पास एक क्लास है जो डेटाबेस में लिखती है, लेकिन आप क्लास का दूसरा संस्करण चाहते हैं (शायद डिबगिंग उद्देश्यों के लिए) जो सभी डेटाबेस ऑपरेशन्स को लॉग करता है।
इस मामले में, आप डेकोरेटर पैटर्न चाहते हैं।
आप इस लेख पर विस्तृत व्याख्या पढ़ सकते हैं, लेकिन मूल विचार यह है कि आप दूसरी क्लास को रैप करने के लिए इनहेरिटेंस का उपयोग करते हैं और फिर इसमें कुछ नया जोड़ते हैं।
मूल को बदले बिना!
वास्तविक दुनिया में इनहेरिटेंस
ठीक है।
हमने इनहेरिटेंस के बारे में सीखा, लेकिन क्या आप जानते हैं कि आप रूबी डेवलपर के रूप में हर दिन इसका उपयोग कर रहे हैं?
रूबी खुद इनहेरिटेंस का उपयोग करता है जैसे मेथड्स को सक्षम करने के लिए:
putsclasssuper
ऐसा इसलिए है क्योंकि सभी रूबी ऑब्जेक्ट्स डिफ़ॉल्ट रूप से Object क्लास से इनहेरिट करते हैं।
तो यदि आप इस तरह एक क्लास बनाते हैं:
class Apple end
इसकी पेरेंट क्लास Object है:
Apple.superclass # Object
यही कारण है कि आप उपरोक्त उल्लिखित मेथड्स का उपयोग करने में सक्षम हैं।
उदाहरण के लिए, जब आप puts कॉल करते हैं तो रूबी इस मेथड को आपकी क्लास में ढूंढता है।
फिर:
- यह पेरेंट क्लासेस में से एक में मेथड ढूंढता है
- यदि नहीं मिला, तो यह ऑब्जेक्ट से फिर से शुरू होता है और
method_missingढूंढने का प्रयास करेगा - यदि नहीं मिला, तो यह
NoMethodErrorयाNameErrorउठाएगा यदि मेथड को बिना स्पष्ट ऑब्जेक्ट के कॉल किया गया था (a.sizeबनामsize, जहांaस्पष्ट ऑब्जेक्ट है)
आप रेल्स में इनहेरिटेंस के अधिक उदाहरण पा सकते हैं।
यहीं:
class ApplicationController < ActionController::Base end
कंट्रोलर:
class SessionsController < ApplicationController end
मॉडल:
class Comment < ApplicationRecord belongs_to :article end
इनहेरिटेंस रूबी में हर जगह है, लेकिन कभी-कभी यह सही समाधान नहीं है।
कम्पोजीशन: इनहेरिटेंस का विकल्प
इनहेरिटेंस की कुछ सीमाएं हैं।
उदाहरण के लिए:
आप पार्ट्स से एक कंप्यूटर बनाना चाहते हैं।
हम कहते हैं कि कंप्यूटर के पार्ट्स हैं, लेकिन व्यक्तिगत पार्ट्स अपने आप में कंप्यूटर नहीं हैं।
यदि आप उन्हें अलग करते हैं तो वे अपना कार्य नहीं कर सकते।
हमें कुछ और चाहिए...
हमें कम्पोजीशन चाहिए!
कम्पोजीशन क्लासेस बनाता है जहां विभिन्न पार्ट्स एक साथ आकर एक कार्य करते हैं।
बस एक कंप्यूटर की तरह।
यहां कम्पोजीशन का एक उदाहरण है:
class Computer def initialize(memory, disk, cpu) @memory = memory @disk = disk @cpu = cpu end end
कंप्यूटर को काम करने के लिए आवश्यक पार्ट्स दिए जाते हैं।
यह कम्पोजीशन है।
लिस्कोव सब्स्टीट्यूशन प्रिंसिपल
इनहेरिटेंस सही स्थितियों में उपयोग किए जाने पर शक्तिशाली होता है।
लेकिन सभी उपकरणों की तरह इसका दुरुपयोग किया जा सकता है!
वास्तव में, मूल डिज़ाइन पैटर्न बुक से एक लोकप्रिय उद्धरण है जो इस तरह जाता है:
“कम्पोजीशन को इनहेरिटेंस पर प्राथमिकता दें।”
Design Patterns: Elements of Reusable Object-Oriented Software
यह सुनिश्चित करने के लिए कि आप इनहेरिटेंस का सही उपयोग कर रहे हैं एक सिद्धांत है जिसका आप पालन कर सकते हैं, SOLID से L।
यह "लिस्कोव सब्स्टीट्यूशन प्रिंसिपल" के लिए खड़ा है।
यह कहता है कि आपके सबक्लासेस को आपके बेस क्लास के स्थान पर उपयोग करने में सक्षम होना चाहिए।
दूसरे शब्दों में:
यदि आप Fruit से इनहेरिट करते हैं और color एक स्ट्रिंग है, तो आप सबक्लास में color को सिंबल लौटाने के लिए नहीं बदलना चाहते।
उदाहरण:
Fruit के उपयोगकर्ता color के स्ट्रिंग लौटाने पर निर्भर करते हैं।
class Fruit def color "orange" end end
यह LSP को तोड़ता है:
class Orange < Fruit def color :orange end end
यदि आप color को सिंबल लौटाने के लिए बदलते हैं, तो आप Fruit ऑब्जेक्ट को Orange से प्रतिस्थापित नहीं कर सकते।
क्यों?
क्योंकि यदि आप सिंबल पर split जैसी मेथड कॉल करते हैं तो आपको त्रुटि मिलेगी।
यह एक मेथड है जो सिंबल्स के पास नहीं है।
लेकिन स्ट्रिंग्स के पास है।
एक और खतरे का संकेत है जब आपका सबक्लास पेरेंट क्लास का वास्तविक विशेषज्ञता नहीं है और आप केवल यूटिलिटी मेथड्स साझा करने के लिए पेरेंट क्लास का उपयोग कर रहे हैं।
सारांश
आपने रूबी में इनहेरिटेंस और कम्पोजीशन के बारे में सीखा!
आप इनहेरिटेंस का उपयोग पेरेंट क्लास का विशेष संस्करण बनाने के लिए कर सकते हैं, और कम्पोजीशन का उपयोग घटकों को एक साथ रखकर एक संपूर्ण बनाने के लिए। यदि आप गड़बड़ नहीं करना चाहते तो LSP सिद्धांत का पालन करना याद रखें।
अब आप बेहतर ऑब्जेक्ट-ओरिएंटेड कोड लिख सकते हैं 🙂
पढ़ने के लिए धन्यवाद।