क्लास इनहेरिटेंस एक मौलिक OOP (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) फीचर है जो आपको किसी भी क्लास का अधिक विशिष्ट और विशिष्ट संस्करण बनाने में मदद करता है।
यहां एक उदाहरण दिया गया है :
Food -> Fruit -> Orange
इन वर्गों के बीच एक संबंध है!
हम कह सकते हैं कि संतरा एक फल है, लेकिन फल भी भोजन है।
पैरेंट क्लास (जिसे सुपर क्लास . भी कहा जाता है) या आधार वर्ग ) हमेशा उपवर्गों की तुलना में अधिक सामान्य होता है।
Fruit
(अधिक सामान्य) Orange
. का मूल वर्ग है (अधिक विशिष्ट)।
रूबी में ऐसा दिखता है :
class Food end class Fruit < Food end class Orange < Fruit end
विरासत . के प्रभावों में से एक रूबी में यह है कि प्रत्येक विधि और प्रत्येक स्थिरांक Food
. पर परिभाषित है Fruit
पर उपलब्ध होगा , और Orange
. पर भी ।
विधियों को बेस क्लास से पारित किया जाता है, लेकिन दूसरी तरफ नहीं।
विरासत का उद्देश्य क्या है?
आप सोच सकते हैं कि ऑब्जेक्ट पदानुक्रम बनाना आपके कोड के लिए किसी प्रकार का "फील गुड" संगठन प्रदान करता है, लेकिन इसमें और भी बहुत कुछ है।
वंशानुक्रम का उपयोग मूल वर्ग का एक अलग संस्करण बनाने के लिए किया जाता है जो किसी विशेष उद्देश्य के लिए उपयुक्त होता है। हो सकता है कि इसे कुछ अतिरिक्त सुविधाओं या विधियों की आवश्यकता हो जो मूल वर्ग में समझ में न आए।
यहां एक उदाहरण दिया गया है :
सभी फलों का एक रंग, वजन और एक नाम होता है।
कुछ फलों में विशेष विशेषताएं हो सकती हैं जिन्हें अन्य फलों के साथ साझा नहीं किया जाता है, इसलिए आप एक नया वर्ग बनाते हैं जो सभी फलों (रंग, वजन, आदि) की विशेषताओं को प्राप्त करता है और फिर आप विशेष विशेषता जोड़ते हैं।
विशेषज्ञता से मेरा यही मतलब है।
एक और उदाहरण :
आपके पास एक वर्ग है जो एक डेटाबेस को लिखता है, लेकिन आप कक्षा का एक और संस्करण चाहते हैं (शायद डिबगिंग उद्देश्यों के लिए) जो सभी डेटाबेस संचालन को लॉग करता है।
इस मामले में, आप डेकोरेटर पैटर्न चाहते हैं।
आप इस लेख पर विस्तृत विवरण पढ़ सकते हैं, लेकिन मूल विचार यह है कि आप किसी अन्य वर्ग को लपेटने के लिए वंशानुक्रम का उपयोग करते हैं और फिर उसमें कुछ नया जोड़ते हैं।
मूल को बदले बिना!
असली दुनिया में विरासत
ठीक है।
हमने विरासत के बारे में सीखा है, लेकिन क्या आप जानते हैं कि आप रूबी डेवलपर के रूप में हर दिन इसका इस्तेमाल कर रहे हैं?
रूबी स्वयं विरासत . का उपयोग करती है इस तरह के तरीकों को सक्षम करने के लिए:
puts
class
super
ऐसा इसलिए है क्योंकि सभी रूबी ऑब्जेक्ट 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
कंप्यूटर को काम करने के लिए आवश्यक भाग दिए जाते हैं।
यह रचना है।
लिस्कोव प्रतिस्थापन सिद्धांत
जब सही परिस्थितियों में उपयोग किया जाता है तो वंशानुक्रम शक्तिशाली होता है।
लेकिन सभी उपकरणों की तरह इसका दुरुपयोग किया जा सकता है!
वास्तव में, मूल डिज़ाइन पैटर्न पुस्तक का एक लोकप्रिय उद्धरण है जो इस प्रकार है:
<ब्लॉककोट>
"विरासत की जगह रचना को प्राथमिकता दें।"
डिज़ाइन पैटर्न:पुन:प्रयोज्य ऑब्जेक्ट-ओरिएंटेड सॉफ़्टवेयर के तत्व
यह सुनिश्चित करने के लिए कि आप विरासत का सही उपयोग कर रहे हैं एक सिद्धांत है जिसका आप अनुसरण कर सकते हैं, L
सॉलिड से।
यह "लिस्कोव प्रतिस्थापन सिद्धांत" के लिए खड़ा है।
यह कहता है कि आपके उपवर्गों को आपके आधार वर्ग के स्थान पर उपयोग करने में सक्षम होना चाहिए।
दूसरे शब्दों में :
अगर आपको Fruit
. से विरासत में मिला है और color
एक स्ट्रिंग है, आप color
बदलना नहीं चाहते हैं उपवर्ग में एक प्रतीक वापस करने के लिए।
उदाहरण :
Fruit
के उपयोगकर्ता color
पर निर्भर करता है एक स्ट्रिंग लौटा रहा है।
class Fruit def color "orange" end end
यह एलएसपी को तोड़ता है :
class Orange < Fruit def color :orange end end
अगर आप color
बदलते हैं किसी प्रतीक को वापस करने के लिए, तो आप Fruit
. को प्रतिस्थापित नहीं कर सकते Orange
. के साथ ऑब्जेक्ट ।
क्यों?
क्योंकि अगर आप split
. जैसी कोई मेथड कॉल करते हैं तो प्रतीक पर आपको एक त्रुटि मिलेगी।
यह एक ऐसा तरीका है जिसमें प्रतीकों का अभाव होता है।
लेकिन तार करते हैं।
एक और लाल झंडा तब होता है जब आपका उपवर्ग मूल वर्ग की सच्ची विशेषज्ञता नहीं है और आप उपयोगिता विधियों को साझा करने के लिए केवल मूल वर्ग का उपयोग कर रहे हैं।
सारांश
आपने रूबी में विरासत और संरचना के बारे में सीखा है!
आप विरासत . का उपयोग कर सकते हैं अभिभावक वर्ग का एक विशेष संस्करण बनाने के लिए, और रचना एक पूरे में घटकों को एक साथ रखने के लिए। LSP
का पालन करना न भूलें सिद्धांत अगर आप कोई गड़बड़ नहीं करना चाहते हैं।
अब आप बेहतर ऑब्जेक्ट-ओरिएंटेड कोड लिख सकते हैं 🙂
पढ़ने के लिए धन्यवाद।