कम्पोजीशन ओवर इनहेरिटेंस: Difference between revisions

From Vigyanwiki
(Created page with "{{Short description|Software design pattern}} {{Cleanup bare URLs|date=August 2022}} {{Confusing|date=October 2015}} File:UML diagram of composition over inheritance.svg|thu...")
 
 
(13 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{Short description|Software design pattern}}
{{Short description|Software design pattern}}
{{Cleanup bare URLs|date=August 2022}}
[[File:UML diagram of composition over inheritance.svg|thumb|right|444px|यह आरेख दर्शाता है कि इनहेरिटेंस डिजाइन सिद्धांत पर रचना का उपयोग करके कैसे एक जानवर के मक्खी और ध्वनि व्यवहार को लचीले विधि से डिजाइन किया जा सकता है।<ref name="FHDPs" />]][[ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग]] ऊप में इनहेरिटेंस पर रचना सिद्धांत या सम्मिश्र पुनः प्रयोग सिद्धांत के रूप में होता है तथा क्लासेस को [[बहुरूपता (कंप्यूटर विज्ञान)|बहुरूपता कंप्यूटर विज्ञान]] व्यवहार और कोड का पुन: उपयोग करना चाहिए तथा उनकी संरचना द्वारा अन्य क्लासेस के उदाहरण देना चाहिए जो किसी आधार या पैरेंट क्लास से प्राप्त [[वंशानुक्रम (कंप्यूटर विज्ञान)|इनहेरिटेंस कंप्यूटर विज्ञान]] के अतिरिक्त वांछित कार्यकार्यात्मकता को कार्यान्वित करते हैं।<ref>{{cite book
{{Confusing|date=October 2015}}
[[File:UML diagram of composition over inheritance.svg|thumb|right|444px|यह आरेख दर्शाता है कि वंशानुक्रम डिजाइन सिद्धांत पर रचना का उपयोग करके कैसे एक जानवर के मक्खी और ध्वनि व्यवहार को लचीले तरीके से डिजाइन किया जा सकता है।<ref name="FHDPs" />]][[ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग]] (OOP) में वंशानुक्रम (या समग्र पुन: उपयोग सिद्धांत) पर रचना सिद्धांत है कि कक्षाओं को [[बहुरूपता (कंप्यूटर विज्ञान)]] व्यवहार और कोड का पुन: उपयोग उनकी वस्तु संरचना द्वारा प्राप्त करना चाहिए (अन्य वर्गों के उदाहरणों को शामिल करके जो वांछित कार्यक्षमता को लागू करते हैं) आधार या मूल वर्ग से [[वंशानुक्रम (कंप्यूटर विज्ञान)]] के बजाय।<ref>{{cite book
  | url = https://books.google.com/books?id=4pjbgVHzomsC&q=composite+reuse+principle&pg=PA17
  | url = https://books.google.com/books?id=4pjbgVHzomsC&q=composite+reuse+principle&pg=PA17
  | title = Java Design - Objects, UML, and Process: 1.1.5 Composite Reuse Principle (CRP)
  | title = Java Design - Objects, UML, and Process: 1.1.5 Composite Reuse Principle (CRP)
Line 11: Line 9:
  | isbn = 9780201750447
  | isbn = 9780201750447
  | accessdate = 2012-05-29
  | accessdate = 2012-05-29
}}</ref> यह ओओपी का अक्सर कहा जाने वाला सिद्धांत है, जैसे प्रभावशाली पुस्तक [[डिजाइन पैटर्न्स]] (1994) में।<ref>{{Cite book | isbn = 0-201-63361-2 | title = [[Design Patterns|Design Patterns: Elements of Reusable Object-Oriented Software]] | last1 = Gamma | first1 = Erich | authorlink1 = Erich Gamma | last2 = Helm | first2 = Richard | last3 = Johnson | first3 = Ralph | authorlink3 = Ralph Johnson (computer scientist) | last4 = Vlissides | first4 = John | authorlink4 = John Vlissides | year = 1994 | publisher = [[Addison-Wesley]] | page = [https://archive.org/details/designpatternsel00gamm/page/20 20] | oclc = 31171684 }}
}}</ref> यह ऊप का प्रायः सिद्धांत है, जिसमे कि प्रभावशाली पुस्तक [[डिजाइन पैटर्न्स]] 1994 में हुआ था।<ref>{{Cite book | isbn = 0-201-63361-2 | title = [[Design Patterns|Design Patterns: Elements of Reusable Object-Oriented Software]] | last1 = Gamma | first1 = Erich | authorlink1 = Erich Gamma | last2 = Helm | first2 = Richard | last3 = Johnson | first3 = Ralph | authorlink3 = Ralph Johnson (computer scientist) | last4 = Vlissides | first4 = John | authorlink4 = John Vlissides | year = 1994 | publisher = [[Addison-Wesley]] | page = [https://archive.org/details/designpatternsel00gamm/page/20 20] | oclc = 31171684 }}
</ref>
</ref>
== मूल बातें ==
== मूल बातें ==
वंशानुक्रम पर रचना का कार्यान्वयन आम तौर पर विभिन्न इंटरफ़ेस (कंप्यूटिंग) के निर्माण के साथ शुरू होता है # ऑब्जेक्ट-ओरिएंटेड भाषाओं में उन व्यवहारों का प्रतिनिधित्व करता है जिन्हें सिस्टम को प्रदर्शित करना चाहिए। इंटरफेस बहुरूपता (कंप्यूटर विज्ञान) व्यवहार को सुविधाजनक बना सकते हैं। पहचाने गए इंटरफेस को लागू करने वाली कक्षाएं आवश्यकतानुसार व्यावसायिक डोमेन कक्षाओं में बनाई और जोड़ी जाती हैं। इस प्रकार, सिस्टम व्यवहार विरासत के बिना महसूस किए जाते हैं।
इनहेरिटेंस पर रचना का कार्यान्वयन सामान्यतः विभिन्न इंटरफ़ेस कंप्यूटिंग के निर्माण के साथ प्रारंभ होता है, ऑब्जेक्ट ओरिएंटेड लैंग्वेज में उन व्यवहारों का प्रतिनिधित्व करता है जिन्हें प्रणाली को प्रदर्शित करना चाहिए। इंटरफेस बहुरूपता कंप्यूटर विज्ञान को सुविधाजनक बना सकते हैं। आइडेंटिफाइड इंटरफेस को प्रयुक्त करने वाली क्लासेस आवश्यकतानुएब्स्ट्रक्ट व्यावसायिक डोमेन क्लासेस में बनाई और जोड़ी जाती हैं। इस प्रकार, प्रणाली व्यवहार इनहेरिटेंस के बिना अनुभव किए जाते हैं।


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


== उदाहरण ==
== उदाहरण ==


=== विरासत ===
=== इनहेरिटेंस ===
[[सी ++]] में एक उदाहरण इस प्रकार है:
[[सी ++]] में एक उदाहरण इस प्रकार है,
 
<वाक्यविन्यास लैंग = सीपीपी>
वर्ग वस्तु
{
जनता:
    आभासी शून्य अद्यतन () {
        // नो-ऑप
    }


    आभासी शून्य ड्रा () {
  class Object
        // नो-ऑप
    }


    आभासी शून्य टक्कर (ऑब्जेक्ट ऑब्जेक्ट्स []) {
{
        // नो-ऑप
public:
    }
  virtual void update() {
};
  // no-op
  }
  virtual void draw() {
  // no-op
  }
  virtual void collide(Object objects[]) {
  // no-op
  }
};
class Visible
: public Object
{
  Model* model;
public:
  virtual void draw() override {
  // code to draw a model at the position of this object
  }
};
class Solid : public Object
{
public:
  virtual void collide(Object objects[]) override {
  // code to check for and react to collisions with other objects
  }
};
class Movablej: public Object
{
public:
  virtual void update() override {
  // code to update the position of this object
  }
};


वर्ग दृश्यमान: सार्वजनिक वस्तु
{
    मॉडल * मॉडल;


जनता:
फिर, मान लीजिए कि हमारे पास ये काँक्रीट क्लास इस प्रकार है
    आभासी शून्य ड्रा () ओवरराइड {
        // कोड इस वस्तु की स्थिति पर एक मॉडल बनाने के लिए
    }
};


क्लास सॉलिड: पब्लिक ऑब्जेक्ट
* क्लास प्लेयर - जो सॉलिड, मूवेबल और विजिबल है
{
* क्लास क्लाउड - जो मूववेबल और दृश्यमान रूप में होती है, लेकिन ठोस नहीं होती है
जनता:
* क्लास बिल्डिंग - जो सॉलिड और विजिबल रूप में होती है, लेकिन मूवेबल नहीं होती है
    आभासी शून्य टक्कर (ऑब्जेक्ट ऑब्जेक्ट्स []) ओवरराइड {
* क्लास ट्रैप - जो ठोस रूप में होती है, लेकिन न तो दिखाई देती है और न ही चल सकती है
        // अन्य वस्तुओं के साथ टकराव की जांच करने और प्रतिक्रिया करने के लिए कोड
ध्यान दें कि मल्टीपल इनहेरिटेंस खतरनाक रूप में होते है, यदि इसे सावधानी से प्रयुक्त नहीं किया गया क्योंकि इससे मल्टीपल इनहेरिटेंस डायमंड की समस्या हो सकती है। इसका एक समाधान यह है कि प्रत्येक आवश्यक संयोजन के लिए विजिबल एंड सॉलिड विजिबल एंड मूवेबल विजिबल एंड सॉलिड एंड मूवेबल इत्यादि जैसी क्लासेस बनाई जाएं चूंकि, यह बड़ी मात्रा में दोहराव वाले कोड की ओर ले जाता है। C ++ मल्टीपल इनहेरिटेंस की डायमंड प्रॉब्लम को हल करने के लिए [[आभासी विरासत|वर्चुअल इनहेरिटेंस]] का उपयोग करता है।
    }
};
 
जंगम वर्ग: सार्वजनिक वस्तु
{
जनता:
    आभासी शून्य अद्यतन () ओवरराइड {
        // कोड इस वस्तु की स्थिति को अद्यतन करने के लिए
    }
};
</वाक्यविन्यास हाइलाइट>
 
फिर, मान लीजिए कि हमारे पास ये ठोस वर्ग भी हैं:
 
* कक्षा {{code|Player}} - जो है {{code|Solid}}, {{code|Movable}} और {{code|Visible}}
* कक्षा {{code|Cloud}} - जो है {{code|Movable}} और {{code|Visible}}, लेकिन नहीं {{code|Solid}}
* कक्षा {{code|Building}} - जो है {{code|Solid}} और {{code|Visible}}, लेकिन नहीं {{code|Movable}}
* कक्षा {{code|Trap}} - जो है {{code|Solid}}, लेकिन नहीं {{code|Visible}} और न {{code|Movable}}
ध्यान दें कि मल्टीपल इनहेरिटेंस खतरनाक है अगर सावधानी से लागू नहीं किया गया है क्योंकि इससे मल्टीपल इनहेरिटेंस#द डायमंड प्रॉब्लम हो सकती है। इसका एक समाधान इस तरह की कक्षाएं बनाना है {{code|VisibleAndSolid}}, {{code|VisibleAndMovable}}, {{code|VisibleAndSolidAndMovable}}, आदि हर आवश्यक संयोजन के लिए; हालाँकि, यह बड़ी मात्रा में दोहराव वाले कोड की ओर ले जाता है। C ++ मल्टीपल इनहेरिटेंस की डायमंड प्रॉब्लम को हल करने के लिए [[आभासी विरासत]] का उपयोग करता है।


=== संरचना और इंटरफेस ===
=== संरचना और इंटरफेस ===
इस खंड में सी ++ उदाहरण कोड पुन: उपयोग और बहुरूपता प्राप्त करने के लिए संरचना और इंटरफेस का उपयोग करने के सिद्धांत को प्रदर्शित करता है। सी ++ भाषा में इंटरफेस घोषित करने के लिए एक समर्पित कीवर्ड नहीं होने के कारण, निम्न सी ++ उदाहरण शुद्ध [[सार आधार वर्ग]] से विरासत का उपयोग करता है। अधिकांश उद्देश्यों के लिए, यह कार्यात्मक रूप से जावा और सी # जैसी अन्य भाषाओं में प्रदान किए गए इंटरफेस के बराबर है।
इस खंड में सी ++ उदाहरण से कोड पुन: उपयोग और बहुरूपता प्राप्त करने के लिए इंटरफेस और संरचना का उपयोग करने के सिद्धांत को प्रदर्शित करता है। सी ++ लैंग्वेज में इंटरफेस घोषित करने के लिए एक समर्पित कीवर्ड नहीं होने के कारण, सी ++ उदाहरण के लिए, शुद्ध [[सार आधार वर्ग|एब्स्ट्रक्ट आधार क्लास]] से इनहेरिटेंस का उपयोग किया जाता है। अधिकांश उद्देश्यों के लिए, यह कार्यात्मक रूप से जावा और सी डॉट जैसी अन्य लैंग्वेज में प्रदान किए गए इंटरफेस के बराबर होती है।
 
नामक एक अमूर्त वर्ग का परिचय दें {{code|VisibilityDelegate}}, उपवर्गों के साथ {{code|NotVisible}} और {{code|Visible}}, जो किसी वस्तु को खींचने का साधन प्रदान करता है:
 
<वाक्यविन्यास लैंग = सीपीपी>
वर्ग दृश्यता प्रतिनिधि
{
जनता:
    आभासी शून्य ड्रा () = 0;
};
 
क्लास नॉटविजिबल: पब्लिक विजिबिलिटी डेलिगेट
{
जनता:
    आभासी शून्य ड्रा () ओवरराइड {
        // नो-ऑप
    }
};
 
वर्ग दृश्यमान: सार्वजनिक दृश्यता प्रतिनिधि
{
जनता:
    आभासी शून्य ड्रा () ओवरराइड {
        // कोड इस वस्तु की स्थिति पर एक मॉडल बनाने के लिए
    }
};
</वाक्यविन्यास हाइलाइट>
 
नामक एक अमूर्त वर्ग का परिचय दें {{code|UpdateDelegate}}, उपवर्गों के साथ {{code|NotMovable}} और {{code|Movable}}, जो किसी वस्तु को स्थानांतरित करने का साधन प्रदान करता है:
 
<वाक्यविन्यास लैंग = सीपीपी>
वर्ग अद्यतन प्रतिनिधि
{
जनता:
    आभासी शून्य अद्यतन () = 0;
};
 
क्लास नॉटमूवेबल: पब्लिक अपडेटडिलेगेट
{
जनता:
    आभासी शून्य अद्यतन () ओवरराइड {
        // नो-ऑप
    }
};
 
क्लास मूवेबल: पब्लिक अपडेटडिलेगेट
{
जनता:
    आभासी शून्य अद्यतन () ओवरराइड {
        // कोड इस वस्तु की स्थिति को अद्यतन करने के लिए
    }
};
</वाक्यविन्यास हाइलाइट>
 
नामक एक अमूर्त वर्ग का परिचय दें {{code|CollisionDelegate}}, उपवर्गों के साथ {{code|NotSolid}} और {{code|Solid}}, जो किसी वस्तु से टकराने का साधन प्रदान करता है:
 
<वाक्यविन्यास लैंग = सीपीपी>
वर्ग टकराव प्रतिनिधि
{
जनता:
    आभासी शून्य टक्कर (ऑब्जेक्ट ऑब्जेक्ट्स []) = 0;
};


क्लास नॉटसॉलिड: पब्लिक कोलिशनडिलेगेट
विजिबिलिटी डेलिगेट नामक एक एब्स्ट्रक्ट क्लास का परिचय उपवर्गों के साथ नॉट विजिबल एंड विजिबल के रूप में होता है, जो किसी वस्तु को खींचने का एक साधन प्रदान करता है
{
जनता:
    आभासी शून्य टक्कर (ऑब्जेक्ट ऑब्जेक्ट्स []) ओवरराइड {
        // नो-ऑप
    }
};


क्लास सॉलिड: पब्लिक कोलिशनडिलेगेट
  class VisibilityDelegate
{
जनता:
    आभासी शून्य टक्कर (ऑब्जेक्ट ऑब्जेक्ट्स []) ओवरराइड {
        // अन्य वस्तुओं के साथ टकराव की जांच करने और प्रतिक्रिया करने के लिए कोड
    }
};
</वाक्यविन्यास हाइलाइट>


अंत में, नाम की एक कक्षा का परिचय दें {{code|Object}} इसकी दृश्यता को नियंत्रित करने के लिए सदस्यों के साथ ({{code|VisibilityDelegate}}), चलनशीलता (एक का उपयोग करके {{code|UpdateDelegate}}), और दृढ़ता (ए का उपयोग करके {{code|CollisionDelegate}}). इस वर्ग में ऐसी विधियाँ हैं जो इसके सदस्यों को सौंपती हैं, उदा। {{code|update()}} बस पर एक विधि कहते हैं {{code|UpdateDelegate}}:
{
public:
  virtual void draw() = 0;
};
class NotVisibles: public VisibilityDelegate
{
public:
  virtual void draw() override {
  // no-op
  }
};
class Visiblec: public VisibilityDelegate
{
public:
  virtual void draw() override {
  // code to draw a model at the position of this object
  }
};
अपडेट डेलिगेट नामक एक सार वर्ग का परिचय उपवर्गों के साथ मूववेबल और मूववेबल नहीं के रूप में होती है, जो किसी वस्तु को स्थानांतरित करने का साधन प्रदान करती है


<वाक्यविन्यास लैंग = सीपीपी>
  class UpdateDelegate
वर्ग वस्तु
{
    दृश्यता प्रतिनिधि* _v;
    UpdateDelegate* _u;
    CollisionDelegate* _c;


जनता:
{
    ऑब्जेक्ट (दृश्यता प्रतिनिधि * v, अद्यतन प्रतिनिधि * यू, टकराव प्रतिनिधि * सी)
public:
        : _वी (वी)
  virtual void update() = 0;
        , _तुम तुम)
};
        , _सी (सी)
    {}
class NotMovablev: public UpdateDelegate
{
public:
  virtual void update() override {
  // no-op
  }
};
class Movablec: public UpdateDelegate
{
public:
  virtual void update() override {
  // code to update the position of this object
  }
};
संघट्ट डेलिगेट नामक एक एब्स्ट्रक्ट क्लास का परिचय उपवर्गों ठोस और ठोस नहीं के साथ करते है, जो किसी वस्तु से टकराने का साधन प्रदान करता है
  class CollisionDelegate


    शून्य अद्यतन () {
{
        _यू-> अपडेट ();
public:
    }
  virtual void collide(Object objects[]) = 0;
};
class NotSolidS: public CollisionDelegate
{
public:
  virtual void collide(Object objects[]) override {
  // no-op
  }
};
class Solid
: public CollisionDelegate
{
public:
  virtual void collide(Object objects[]) override {
  // code to check for and react to collisions with other objects
  }
};


    शून्य ड्रा () {
नामक एक अमूर्त क्लास का परिचय दें {{code|UpdateDelegate}}, उपक्लासेस के साथ {{code|NotMovable}} और {{code|Movable}}, जो किसी वस्तु को स्थानांतरित करने का साधन प्रदान करता है:
        _v-> ड्रा ();
    }


    शून्य टक्कर (ऑब्जेक्ट ऑब्जेक्ट्स []) {
अंत में, सदस्यों के साथ ऑब्जेक्ट नामक क्लास का परिचय देते है, यदि इसकी दृश्यता को नियंत्रित करने के लिए एक अद्यतन प्रतिनिधि का उपयोग करके एक दृश्यता प्रतिनिधि की गतिशीलता का उपयोग किया जाता है और संघट्ट प्रतिनिधि का उपयोग करके ठोसता का उपयोग किया जाता है। इस वर्ग में ऐसी विधियाँ होती है, जो इसके सदस्यों को सौंपती हैं। जैसे अपडेट() केवल अपडेट डेलिगेट पर एक कॉल विधि का उपयोग करती है
        _c-> टकराना (ऑब्जेक्ट्स);
  class Object
    }
};
</वाक्यविन्यास हाइलाइट>


फिर, ठोस कक्षाएं दिखेंगी:
{
  VisibilityDelegate* _v;
  UpdateDelegate* _u;
  CollisionDelegate* _c;
public:
  Object(VisibilityDelegate* v, UpdateDelegate* u, CollisionDelegate* c)
  : _v(v)
  , _u(u)
  , _c(c)
  {}
  void update() {
  _u->update();
  }
  void draw() {
  _v->draw();
  }
  void collide(Object objects[]) {
  _c->collide(objects);
  }
};


<वाक्यविन्यास लैंग = सीपीपी>
तब कंक्रीट इस रूप में दिखती है,
क्लास प्लेयर: पब्लिक ऑब्जेक्ट
  class Player : public Object
{
जनता:
    खिलाड़ी ()
        : ऑब्जेक्ट (नया दृश्यमान (), नया चल (), नया ठोस ())
    {}


    // ...
{
};
public:
 
  Player()
वर्ग धुआँ: सार्वजनिक वस्तु
  : Object(new Visible(), new Movable(), new Solid())
{
  {}
जनता:
    धुआँ()
  // ...
        : ऑब्जेक्ट (नया दृश्यमान (), नया मूवेबल (), नया नॉटसॉलिड ())
};
    {}
 
class Smokea: public Object
    // ...
{
};
public:
</वाक्यविन्यास हाइलाइट>
  Smoke()
  k: Object(new Visible(), new Movable(), new NotSolid())
  {}
  // ...
};


== लाभ ==
== लाभ ==
वंशानुक्रम पर रचना का पक्ष लेना [[एक]] डिज़ाइन सिद्धांत है जो डिज़ाइन को उच्च लचीलापन देता है। उनके बीच समानता खोजने और पारिवारिक पेड़ बनाने की कोशिश करने की तुलना में विभिन्न घटकों से व्यवसाय-डोमेन कक्षाएं बनाना अधिक स्वाभाविक है। उदाहरण के लिए, एक त्वरक पेडल और एक स्टीयरिंग व्हील बहुत कम सामान्य गुण (कंप्यूटर प्रोग्रामिंग) साझा करते हैं, फिर भी दोनों एक कार में महत्वपूर्ण घटक हैं। वे क्या कर सकते हैं और कार को लाभ पहुंचाने के लिए उनका उपयोग कैसे किया जा सकता है, इसे आसानी से परिभाषित किया जा सकता है। संरचना लंबी अवधि में एक अधिक स्थिर व्यवसाय डोमेन भी प्रदान करती है क्योंकि यह परिवार के सदस्यों की विचित्रताओं से कम प्रभावित होती है। दूसरे शब्दों में, यह रचना करना बेहतर है कि कोई वस्तु क्या कर सकती है (है-ए) जो वह है (है-ए) का विस्तार करने के बजाय।<ref name="FHDPs">{{cite book
इनहेरिटेंस पर रचना का पक्ष लेना [[एक]] डिज़ाइन सिद्धांत है, जो डिज़ाइन को उच्च लचीलापन स्वरुप प्रदान करता है। उनके बीच समानता खोजने और फॅमिली ट्री बनाने की कोशिश करने की तुलना में विभिन्न घटकों से व्यावसायिक डोमेन क्लासेस बनाना अधिक स्वाभाविक होता है। उदाहरण के लिए, एक त्वरक पेडल और एक स्टीयरिंग व्हील बहुत कम सामान्य गुण कंप्यूटर प्रोग्रामिंग को साझा करते हैं, फिर दोनों कार में महत्वपूर्ण घटक के रूप में होते है। वे क्या कर सकते हैं और कार को लाभ पहुंचाने के लिए उनका उपयोग कैसे किया जा सकता है, इसे आसानी से परिभाषित किया जाता है। संरचना लंबी अवधि में अधिक स्थिर व्यवसाय डोमेन प्रदान करती है क्योंकि यह फॅमिली के सदस्यों की विचित्रताओं से कम प्रभावित होती है। दूसरे शब्दों में, यह रचना करना बहुत अच्छा होता है कि (ईस-ए) जो विस्तार करने से एक ऑब्जेक्ट (हैस-ए) क्या कर सकता है।<ref name="FHDPs">{{cite book
  | last1 = Freeman
  | last1 = Freeman
  | first1 = Eric
  | first1 = Eric
Line 230: Line 220:
  | isbn = 978-0-596-00712-6
  | isbn = 978-0-596-00712-6
}}</ref>
}}</ref>
विरासत के माध्यम से व्यवसाय-डोमेन वर्गों के बीच व्यवहार वितरित करने के लिए एक पदानुक्रमित संबंध बनाने के बजाय अलग-अलग इंटरफेस में सिस्टम ऑब्जेक्ट व्यवहार की पहचान करके प्रारंभिक डिजाइन को सरल बनाया गया है। यह दृष्टिकोण भविष्य की आवश्यकताओं के परिवर्तनों को अधिक आसानी से समायोजित करता है, अन्यथा इनहेरिटेंस मॉडल में व्यवसाय-डोमेन वर्गों के पूर्ण पुनर्गठन की आवश्यकता होगी। इसके अतिरिक्त, यह विरासत-आधारित मॉडल में अपेक्षाकृत मामूली परिवर्तनों से जुड़ी समस्याओं से बचा जाता है जिसमें कक्षाओं की कई पीढ़ियाँ शामिल होती हैं।
रचना संबंध अधिक लचीला है क्योंकि इसे रनटाइम पर बदला जा सकता है, जबकि उप-टाइपिंग संबंध स्थिर होते हैं और कई भाषाओं में पुनर्संकलन की आवश्यकता होती है।


कुछ भाषाएँ, विशेष रूप से गो (प्रोग्रामिंग भाषा)<ref>{{cite web |url=https://commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html |title=Less is exponentially more |last1=Pike |first1=Rob |date=2012-06-25 |accessdate=2016-10-01 }}</ref> और [[जंग (प्रोग्रामिंग भाषा)]],<ref>{{Cite web |title=Characteristics of Object-Oriented Languages - The Rust Programming Language |url=https://doc.rust-lang.org/stable/book/ch17-01-what-is-oo.html#inheritance-as-a-type-system-and-as-code-sharing |access-date=2022-10-10 |website=doc.rust-lang.org}}</ref> विशेष रूप से प्रकार की रचना का उपयोग करें।
इनहेरिटेंस के माध्यम से व्यवसाय-डोमेन क्लासेस के बीच व्यवहार वितरित करने के लिए एक पदानुक्रमित संबंध बनाने के अतिरिक्त भिन्न -भिन्न इंटरफेस में प्रणाली ऑब्जेक्ट व्यवहार की पहचान करके प्रारंभिक डिजाइन को सरल बनाया गया है। यह दृष्टिकोण भविष्य की आवश्यकताओं के परिवर्तनों को अधिक आसानी से समायोजित करता है, अन्यथा इनहेरिटेंस मॉडल में व्यवसाय डोमेन क्लासेस के पूर्ण पुनर्गठन की आवश्यकता होती है। इसके अतिरिक्त, यह इनहेरिटेंस आधारित मॉडल में अपेक्षाकृत सामान्य परिवर्तनों से जुड़ी समस्याओं से बचा जाता है जिसमें क्लासेस की कई जेनेरेशन सम्मलित होती हैं। रचना संबंध अधिक लचीला रूप में होता है, क्योंकि इसे रनटाइम पर बदला जा सकता है, जबकि उप-टाइपिंग संबंध स्थिर होते हैं और कई लैंग्वेज में पुनर्संकलन की आवश्यकता होती है।
 
कुछ लैंग्वेज , विशेष रूप से गो (प्रोग्रामिंग लैंग्वेज )<ref>{{cite web |url=https://commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html |title=Less is exponentially more |last1=Pike |first1=Rob |date=2012-06-25 |accessdate=2016-10-01 }}</ref> और [[जंग (प्रोग्रामिंग भाषा)|रस्ट (प्रोग्रामिंग लैंग्वेज )]],<ref>{{Cite web |title=Characteristics of Object-Oriented Languages - The Rust Programming Language |url=https://doc.rust-lang.org/stable/book/ch17-01-what-is-oo.html#inheritance-as-a-type-system-and-as-code-sharing |access-date=2022-10-10 |website=doc.rust-lang.org}}</ref> विशेष रूप से टाइप कंपोज़िशन का उपयोग करती हैं।


== कमियां ==
== कमियां ==
वंशानुक्रम के बजाय संरचना का उपयोग करने का एक सामान्य दोष यह है कि अलग-अलग घटकों द्वारा प्रदान की जाने वाली विधियों को व्युत्पन्न प्रकार में लागू करना पड़ सकता है, भले ही वे केवल [[अग्रेषण (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)]] हों (यह अधिकांश प्रोग्रामिंग भाषाओं में सच है, लेकिन नहीं सब; देखें {{section link|#Avoiding drawbacks}}). इसके विपरीत, वंशानुक्रम के लिए व्युत्पन्न वर्ग के भीतर आधार वर्ग के सभी तरीकों को फिर से लागू करने की आवश्यकता नहीं होती है। बल्कि, व्युत्पन्न वर्ग को केवल आधार वर्ग विधियों की तुलना में भिन्न व्यवहार वाले तरीकों को लागू (ओवरराइड) करने की आवश्यकता है। यदि बेस क्लास में डिफ़ॉल्ट व्यवहार प्रदान करने वाली कई विधियाँ हैं और उनमें से केवल कुछ को व्युत्पन्न वर्ग के भीतर ओवरराइड करने की आवश्यकता है, तो इसके लिए काफी कम प्रोग्रामिंग प्रयास की आवश्यकता हो सकती है।
इनहेरिटेंस के अतिरिक्त संरचना का उपयोग करने का एक सामान्य दोष यह है कि भिन्न -भिन्न घटकों द्वारा प्रदान की जाने वाली विधियों को व्युत्पन्न प्रकार में कार्यान्वित किया जा सकता है, यदि वे केवल तरीकों को [[अग्रेषण (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)|अग्रेषण ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग]] कर रहे हों, यह अधिकांश प्रोग्रामिंग लैंग्वेज में सच है, लेकिन नहीं सभी नहीं छद्म खामियों से बचने.के लिए देखे, इसके विपरीत, इनहेरिटेंस के लिए व्युत्पन्न क्लास के भीतर आधार क्लास के सभी विधियो को फिर से चालू करने की आवश्यकता नहीं होती है। यदि व्युत्पन्न क्लास को केवल आधार क्लास विधियों की तुलना में भिन्न व्यवहार वाले विधियो को ओवरराइड करने की आवश्यकता होती है। यदि बेस क्लास में डिफ़ॉल्ट व्यवहार प्रदान करने वाली कई विधियाँ हैं और उनमें से केवल कुछ को व्युत्पन्न क्लास के भीतर ओवरराइड करने की आवश्यकता है, तो इसके लिए अधिक कम प्रोग्रामिंग प्रयास की आवश्यकता होती है।


उदाहरण के लिए, नीचे दिए गए सी # कोड में, वेरिएबल्स और विधियों के {{code|Employee}} बेस क्लास द्वारा विरासत में मिला है {{code|HourlyEmployee}} और {{code|SalariedEmployee}} व्युत्पन्न उपवर्ग। केवल {{code|Pay()}} विधि को प्रत्येक व्युत्पन्न उपवर्ग द्वारा कार्यान्वित (विशेष) करने की आवश्यकता है। अन्य विधियों को आधार वर्ग द्वारा ही लागू किया जाता है, और इसके सभी व्युत्पन्न उपवर्गों द्वारा साझा किया जाता है; उन्हें फिर से लागू करने (ओवरराइड) या यहां तक ​​​​कि उपवर्ग परिभाषाओं में उल्लेख करने की आवश्यकता नहीं है।
उदाहरण के लिए, नीचे दिए गए सी डॉट कोड में कर्मचारी बेस क्लास के चर एवं विधियों उत्तराकर्मी और वेतन-भोगी कर्मचारी द्वारा इनहेरिटेंस में लिए गए व्युत्पन्न उपक्लास प्राप्त किए जाते हैं। प्रत्येक व्युत्पन्न उपक्लास के द्वारा केवल वेतन () पद्धति को कार्यान्वित करने की आवश्यकता होती है। अन्य विधियों का आधार क्लास द्वारा ही प्रयुक्त किया जाता है, और इसके सभी व्युत्पन्न उपक्लासेस द्वारा साझा किया जाता है; उन्हें फिर से कार्यान्वित (ओवरराइड) करने या उपक्लास परिलैंग्वेज में उल्लेखित करने की आवश्यकता नहीं होती है।


<वाक्यविन्यास प्रकाश लैंग = csharp>
  // Base class
// बेस क्लास
सार्वजनिक सार वर्ग कर्मचारी
{
    // गुण
    संरक्षित स्ट्रिंग नाम {प्राप्त करें; तय करना; }
    संरक्षित इंट आईडी {प्राप्त करें; तय करना; }
    संरक्षित दशमलव भुगतान दर {प्राप्त करें; तय करना; }
    संरक्षित int घंटे काम किया { प्राप्त करें; }


    // वर्तमान वेतन अवधि के लिए भुगतान प्राप्त करें
public abstract class Employee
    सार्वजनिक सार दशमलव वेतन ();
{
}
  // Properties
 
  protected string Name { get; set; }
// व्युत्पन्न उपवर्ग
  protected int ID { get; set; }
पब्लिक क्लास प्रति घंटा कर्मचारी: कर्मचारी
  protected decimal PayRate { get; set; }
{
  protected int HoursWorked { get; }
    // वर्तमान वेतन अवधि के लिए भुगतान प्राप्त करें
    सार्वजनिक ओवरराइड दशमलव वेतन ()
  // Get pay for the current pay period
    {
  public abstract decimal Pay();
        // काम किया गया समय घंटों में है
}
        वापसी के घंटे काम * वेतन दर;
    }
// Derived subclass
}
public class HourlyEmployee : Employee
 
{
// व्युत्पन्न उपवर्ग
  // Get pay for the current pay period
सार्वजनिक वर्ग के वेतनभोगी कर्मचारी: कर्मचारी
  public override decimal Pay()
{
  {
    // वर्तमान वेतन अवधि के लिए भुगतान प्राप्त करें
  // Time worked is in hours
    सार्वजनिक ओवरराइड दशमलव वेतन ()
  return HoursWorked * PayRate;
    {
  }
        // वेतन दर प्रति घंटे की दर के बजाय वार्षिक वेतन है
}
        वापसी के घंटे काम * वेतन दर / 2087;
    }
// Derived subclass
}
public class SalariedEmployee : Employee
</वाक्यविन्यास हाइलाइट>
{
  // Get pay for the current pay period
  public override decimal Pay()
  {
  // Pay rate is annual salary instead of hourly rate
  return HoursWorked * PayRate / 2087;
  }
}


=== कमियों से बचना ===
=== कमियों से बचना ===
ट्रेट्स (कंप्यूटर साइंस), [[mixin]]्स, (टाइप) [[एम्बेडिंग]], या [[प्रोटोकॉल (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)]] एक्सटेंशन का उपयोग करके इस कमी से बचा जा सकता है।
ट्रेट्स (कंप्यूटर साइंस), [[mixin|मैक्सिन]], प्रकार [[एम्बेडिंग]], या [[प्रोटोकॉल (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)]] एक्सटेंशन का उपयोग करके इस कमी से बचा जा सकता है।


कुछ भाषाएँ इसे कम करने के लिए विशिष्ट साधन प्रदान करती हैं:
कुछ लैंग्वेज इसे कम करने के लिए विशिष्ट साधन प्रदान करती हैं


* सी शार्प (प्रोग्रामिंग लैंग्वेज) | सी # संस्करण 8.0 के बाद से डिफ़ॉल्ट इंटरफ़ेस तरीके प्रदान करता है जो शरीर को इंटरफ़ेस सदस्य को परिभाषित करने की अनुमति देता है।<ref>{{cite web | url=https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#default-interface-methods | title=What's new in C# 8.0 | website=Microsoft Docs | publisher=Microsoft | access-date=2019-02-20}}</ref>
* सी शार्प (प्रोग्रामिंग लैंग्वेज): संस्करण 8.0 के बाद से डिफ़ॉल्ट इंटरफ़ेस विधि प्रदान करता है, जो बॉडी को इंटरफ़ेस सदस्य को परिभाषित करने की अनुमति देता है।<ref>{{cite web | url=https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#default-interface-methods | title=What's new in C# 8.0 | website=Microsoft Docs | publisher=Microsoft | access-date=2019-02-20}}</ref>
* [[डी (प्रोग्रामिंग भाषा)]] एक स्पष्ट उपनाम प्रदान करता है, यह घोषणा एक प्रकार के भीतर हर विधि और किसी अन्य निहित प्रकार के सदस्य को अग्रेषित कर सकती है।<ref>{{cite web | url=https://dlang.org/spec/class.html#alias-this | title=Alias This | website=D Language Reference| access-date=2019-06-15}}</ref>
* [[डी (प्रोग्रामिंग भाषा)|डी (प्रोग्रामिंग लैंग्वेज )]] डी एक प्रकार के भीतर स्पष्ट "एलियास यह" घोषणा प्रदान करता है जो इसे प्रत्येक विधि में और एक अन्य निहित प्रकार के सदस्य में अग्रेषित करने की अनुमति देता है।<ref>{{cite web | url=https://dlang.org/spec/class.html#alias-this | title=Alias This | website=D Language Reference| access-date=2019-06-15}}</ref>
* [[डार्ट (प्रोग्रामिंग भाषा)]] डिफ़ॉल्ट कार्यान्वयन के साथ मिक्सिन प्रदान करता है जिसे साझा किया जा सकता है।
* [[डार्ट (प्रोग्रामिंग भाषा)|डार्ट (प्रोग्रामिंग लैंग्वेज )]] डिफ़ॉल्ट कार्यान्वयन के साथ मिक्सिन प्रदान करता है जिसे साझा किया जा सकता है।
* गो (प्रोग्रामिंग लैंग्वेज) टाइप एम्बेडिंग अग्रेषण विधियों की आवश्यकता से बचाती है।<ref>{{cite web | url=https://golang.org/doc/effective_go.html#embedding | title=''(Type)'' Embedding | website=The Go Programming Language Documentation | access-date=2019-05-10}}</ref>
* गो (प्रोग्रामिंग लैंग्वेज) टाइप एम्बेडिंग अग्रेषण विधियों की आवश्यकता से बचाती है।<ref>{{cite web | url=https://golang.org/doc/effective_go.html#embedding | title=''(Type)'' Embedding | website=The Go Programming Language Documentation | access-date=2019-05-10}}</ref>
* [[जावा (प्रोग्रामिंग भाषा)]] संस्करण 8 के बाद से डिफ़ॉल्ट इंटरफ़ेस विधियाँ प्रदान करता है। प्रोजेक्ट लोम्बोक<ref>https://projectlombok.org</ref> प्रतिनिधिमंडल का समर्थन करता है {{code|@Delegate}} प्रत्यायोजित क्षेत्र से सभी विधियों के नामों और प्रकारों को कॉपी करने और बनाए रखने के बजाय क्षेत्र पर एनोटेशन।<ref>{{cite web | url=https://projectlombok.org/features/experimental/Delegate | title=@Delegate | website=Project Lombok | access-date=2018-07-11}}</ref> * [[जूलिया (प्रोग्रामिंग भाषा)]] मैक्रोज़ का उपयोग अग्रेषण विधियों को उत्पन्न करने के लिए किया जा सकता है। Lazy.jl जैसे कई कार्यान्वयन मौजूद हैं<ref>https://github.com/MikeInnes/Lazy.jl</ref> और TypedDelegation.jl।<ref>https://github.com/JeffreySarnoff/TypedDelegation.jl</ref><ref>{{cite web |title=Method forwarding macro |url=https://discourse.julialang.org/t/method-forwarding-macro/23355 |website=JuliaLang |access-date=18 August 2022 |language=en |date=20 April 2019}}</ref>
* [[जावा (प्रोग्रामिंग भाषा)|जावा (प्रोग्रामिंग लैंग्वेज )]] संस्करण 8 के बाद से डिफ़ॉल्ट इंटरफ़ेस विधियाँ प्रदान करता है। प्रोजेक्ट लोम्बोक<ref>https://projectlombok.org</ref> प्रतिनिधिमंडल का समर्थन करता है, डेलिगेट प्रत्यायोजित क्षेत्र से सभी विधियों के नामों और प्रकारों को कॉपी करने और बनाए रखने के अतिरिक्त क्षेत्र पर एनोटेशन प्रदान करता है।<ref>{{cite web | url=https://projectlombok.org/features/experimental/Delegate | title=@Delegate | website=Project Lombok | access-date=2018-07-11}}</ref> * [[जूलिया (प्रोग्रामिंग भाषा)|जूलिया (प्रोग्रामिंग लैंग्वेज )]] मैक्रोज़ का उपयोग अग्रेषण विधियों को उत्पन्न करने के लिए किया जा सकता है। लेजी जेएल और डेलिगेसन, <ref>https://github.com/MikeInnes/Lazy.jl</ref>जैसे कई कार्यान्वयन सम्मलित होती है।<ref>https://github.com/JeffreySarnoff/TypedDelegation.jl</ref><ref>{{cite web |title=Method forwarding macro |url=https://discourse.julialang.org/t/method-forwarding-macro/23355 |website=JuliaLang |access-date=18 August 2022 |language=en |date=20 April 2019}}</ref>
* [[कोटलिन (प्रोग्रामिंग भाषा)]] में लैंग्वेज सिंटैक्स में डेलिगेशन पैटर्न शामिल है।<ref>{{cite web | url=https://kotlinlang.org/docs/reference/delegated-properties.html | title=Delegated Properties | website=Kotlin Reference | publisher=JetBrains | access-date=2018-07-11}}</ref>
* [[कोटलिन (प्रोग्रामिंग भाषा)|कोटलिन (प्रोग्रामिंग लैंग्वेज )]] में सिंटैक्स में डेलिगेशन पैटर्न सम्मलित होता है।<ref>{{cite web | url=https://kotlinlang.org/docs/reference/delegated-properties.html | title=Delegated Properties | website=Kotlin Reference | publisher=JetBrains | access-date=2018-07-11}}</ref>
* [[PHP]] लक्षणों (कंप्यूटर विज्ञान) का समर्थन करता है।
* [[PHP|पीएचपी :]] लक्षणों (कंप्यूटर विज्ञान) का समर्थन करता है।
* [[राकू (प्रोग्रामिंग भाषा)]] एक प्रदान करता है {{code|handles}} विधि अग्रेषण की सुविधा के लिए विशेषता।<ref>{{cite web |title=Type system |url=https://docs.raku.org/language/typesystem#index-entry-handles_trait-handles |website=docs.raku.org |access-date=18 August 2022}}</ref>
* [[राकू (प्रोग्रामिंग भाषा)|राकू (प्रोग्रामिंग लैंग्वेज )]] : राकू विधि अग्रेषण की सुविधा के लिए एक हैंडल विशेषता प्रदान करता है<ref>{{cite web |title=Type system |url=https://docs.raku.org/language/typesystem#index-entry-handles_trait-handles |website=docs.raku.org |access-date=18 August 2022}}</ref>
* रस्ट (प्रोग्रामिंग लैंग्वेज) डिफ़ॉल्ट कार्यान्वयन के साथ लक्षण प्रदान करता है।
* रस्ट (प्रोग्रामिंग लैंग्वेज) डिफ़ॉल्ट कार्यान्वयन के साथ लक्षण प्रदान करता है।
* [[स्काला (प्रोग्रामिंग भाषा)]] (संस्करण 3 के बाद से) किसी वस्तु के चयनित सदस्यों के लिए उपनामों को परिभाषित करने के लिए एक निर्यात खंड प्रदान करता है।<ref>{{cite web | url=https://docs.scala-lang.org/scala3/reference/other-new-features/export.html | title=Export Clauses | website=Scala Documentation | access-date=2021-10-06}}</ref>
* [[स्काला (प्रोग्रामिंग भाषा)|स्काला (प्रोग्रामिंग लैंग्वेज )]] संस्करण 3 के बाद से किसी वस्तु के चयनित सदस्यों के लिए उपनामों को परिभाषित करने के लिए एक निर्यात खंड प्रदान करता है।<ref>{{cite web | url=https://docs.scala-lang.org/scala3/reference/other-new-features/export.html | title=Export Clauses | website=Scala Documentation | access-date=2021-10-06}}</ref>
* [[स्विफ्ट (प्रोग्रामिंग भाषा)]] एक्सटेंशन का उपयोग किसी प्रोटोकॉल के डिफ़ॉल्ट कार्यान्वयन को परिभाषित करने के लिए किया जा सकता है, बजाय किसी व्यक्तिगत प्रकार के कार्यान्वयन के।<ref>{{cite web | url=https://docs.swift.org/swift-book/LanguageGuide/Protocols.html | title=Protocols | website=The Swift Programming Language | publisher=Apple Inc | access-date=2018-07-11}}</ref>
* [[स्विफ्ट (प्रोग्रामिंग भाषा)|स्विफ्ट (प्रोग्रामिंग लैंग्वेज )]] एक्सटेंशन का उपयोग किसी प्रोटोकॉल के डिफ़ॉल्ट कार्यान्वयन को परिभाषित करने के लिए किया जाता है, इसके अतिरिक्त किसी व्यक्तिगत प्रकार के कार्यान्वयन के लिए प्रयोग की जाती है।<ref>{{cite web | url=https://docs.swift.org/swift-book/LanguageGuide/Protocols.html | title=Protocols | website=The Swift Programming Language | publisher=Apple Inc | access-date=2018-07-11}}</ref>
 
 
== अनुभवजन्य अध्ययन ==
== अनुभवजन्य अध्ययन ==
2013 में 93 ओपन सोर्स जावा प्रोग्राम (अलग-अलग आकार के) के एक अध्ययन में पाया गया कि:
भिन्न -भिन्न आकार के 93 ओपन सोर्स जावा प्रोग्राम के 2013 के एक अध्ययन में पाया गया कि,
 
{{blockquote|While there is not huge opportunity to replace inheritance with composition (...), the opportunity is significant (median of 2% of uses [of inheritance] are only internal reuse, and a further 22% are only external or internal reuse).


Our results suggest there is no need for concern regarding abuse of inheritance (at least in open-source Java software), but they do highlight the question regarding use of composition versus inheritance. If there are significant costs associated with using inheritance when composition could be used, then our results suggest there is some cause for concern.|Tempero ''et al.'', "What programmers do with inheritance in Java"<ref>{{cite conference |last1=Tempero |first1=Ewan |first2=Hong Yul |last2=Yang |first3=James |last3=Noble |title=ECOOP 2013 – Object-Oriented Programming |chapter=What programmers do with inheritance in Java |conference=ECOOP 2013–Object-Oriented Programming |year=2013 |pages=577–601 |chapter-url=https://www.cs.auckland.ac.nz/~ewan/qualitas/studies/inheritance/TemperoYangNobleECOOP2013-pre.pdf |doi=10.1007/978-3-642-39038-8_24 |isbn=978-3-642-39038-8 |series=Lecture Notes in Computer Science |volume=7920}}</ref>}}
{{blockquote|जबकि संरचना (...) के साथ इनहेरिटेंस को बदलने के लिए बहुत बड़ा अवसर महत्वपूर्ण नहीं होता है, इनहेरिटेंस के 2% उपयोग केवल आंतरिक पुन: उपयोग के रूप में हैं और आगे 22% केवल बाहरी या आंतरिक पुन: उपयोग के रूप में होता है। हमारे नतीजे बताते हैं कि कम से कम ओपन सोर्स जावा सॉफ़्टवेयर में इनहेरिटेंस के दुरुपयोग के बारे में चिंता करने की कोई आवश्यकता नहीं होती है, लेकिन वे संरचना बनाम हेरिटेंस के उपयोग के संबंध में प्रश्न को प्रदर्शित करते हैं। यदि संरचना का उपयोग किए जाने पर इनहेरिटेंस का उपयोग करने से जुड़ी महत्वपूर्ण लागतें हैं, तो हमारे परिणाम बताते हैं कि चिंता का कुछ कारण हो सकता है।|टेम्पेरो एट अल, जावा में इनहेरिटेंस के साथ प्रोग्रामर क्या करते हैं}}




Line 306: Line 291:
* [[प्रतिनिधिमंडल पैटर्न]]
* [[प्रतिनिधिमंडल पैटर्न]]
* [[लिस्कोव प्रतिस्थापन सिद्धांत]]
* [[लिस्कोव प्रतिस्थापन सिद्धांत]]
* [[वस्तु उन्मुख डिजाइन]]
* [[वस्तु उन्मुख डिजाइन|ऑब्जेक्ट ओरिएंटेड डिजाइन]]
* वस्तु रचना
* ऑब्जेक्ट रचना
* भूमिका-उन्मुख प्रोग्रामिंग
* रोल ओरिएंटेड प्रोग्रामिंग
* [[राज्य पैटर्न]]
* [[राज्य पैटर्न|स्टेट पैटर्न]]
* [[रणनीति पैटर्न]]
* [[रणनीति पैटर्न]]


Line 315: Line 300:
{{Reflist}}
{{Reflist}}


<!-- Categories -->[[Category: घटक-आधारित सॉफ्टवेयर इंजीनियरिंग]] [[Category: सॉफ़्टवेयर वास्तुशिल्प]] [[Category: प्रोग्रामिंग सिद्धांत]] [[Category: सी शार्प कोड उदाहरण के साथ लेख]]
<!-- Categories -->
 
 


[[Category: Machine Translated Page]]
[[Category:CS1 English-language sources (en)]]
[[Category:Created On 16/02/2023]]
[[Category:Created On 16/02/2023]]
[[Category:Lua-based templates]]
[[Category:Machine Translated Page]]
[[Category:Pages with script errors]]
[[Category:Short description with empty Wikidata description]]
[[Category:Templates Vigyan Ready]]
[[Category:Templates that add a tracking category]]
[[Category:Templates that generate short descriptions]]
[[Category:Templates using TemplateData]]
[[Category:घटक-आधारित सॉफ्टवेयर इंजीनियरिंग]]
[[Category:प्रोग्रामिंग सिद्धांत]]
[[Category:सी शार्प कोड उदाहरण के साथ लेख]]
[[Category:सॉफ़्टवेयर वास्तुशिल्प]]

Latest revision as of 15:17, 7 November 2023

यह आरेख दर्शाता है कि इनहेरिटेंस डिजाइन सिद्धांत पर रचना का उपयोग करके कैसे एक जानवर के मक्खी और ध्वनि व्यवहार को लचीले विधि से डिजाइन किया जा सकता है।[1]

ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग ऊप में इनहेरिटेंस पर रचना सिद्धांत या सम्मिश्र पुनः प्रयोग सिद्धांत के रूप में होता है तथा क्लासेस को बहुरूपता कंप्यूटर विज्ञान व्यवहार और कोड का पुन: उपयोग करना चाहिए तथा उनकी संरचना द्वारा अन्य क्लासेस के उदाहरण देना चाहिए जो किसी आधार या पैरेंट क्लास से प्राप्त इनहेरिटेंस कंप्यूटर विज्ञान के अतिरिक्त वांछित कार्यकार्यात्मकता को कार्यान्वित करते हैं।[2] यह ऊप का प्रायः सिद्धांत है, जिसमे कि प्रभावशाली पुस्तक डिजाइन पैटर्न्स 1994 में हुआ था।[3]

मूल बातें

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

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

उदाहरण

इनहेरिटेंस

सी ++ में एक उदाहरण इस प्रकार है,

 class Object
{
public:
 virtual void update() {
 // no-op
 }

 virtual void draw() {
 // no-op
 }

 virtual void collide(Object objects[]) {
 // no-op
 }
};

class Visible
: public Object
{
 Model* model;

public:
 virtual void draw() override {
 // code to draw a model at the position of this object
 }
};

class Solid : public Object
{
public:
 virtual void collide(Object objects[]) override {
 // code to check for and react to collisions with other objects
 }
};

class Movablej: public Object
{
public:
 virtual void update() override {
 // code to update the position of this object
 }
};


फिर, मान लीजिए कि हमारे पास ये काँक्रीट क्लास इस प्रकार है

  • क्लास प्लेयर - जो सॉलिड, मूवेबल और विजिबल है
  • क्लास क्लाउड - जो मूववेबल और दृश्यमान रूप में होती है, लेकिन ठोस नहीं होती है
  • क्लास बिल्डिंग - जो सॉलिड और विजिबल रूप में होती है, लेकिन मूवेबल नहीं होती है
  • क्लास ट्रैप - जो ठोस रूप में होती है, लेकिन न तो दिखाई देती है और न ही चल सकती है

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

संरचना और इंटरफेस

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

विजिबिलिटी डेलिगेट नामक एक एब्स्ट्रक्ट क्लास का परिचय उपवर्गों के साथ नॉट विजिबल एंड विजिबल के रूप में होता है, जो किसी वस्तु को खींचने का एक साधन प्रदान करता है

 class VisibilityDelegate
{
public:
 virtual void draw() = 0;
};

class NotVisibles: public VisibilityDelegate
{
public:
 virtual void draw() override {
 // no-op
 }
};

class Visiblec: public VisibilityDelegate
{
public:
 virtual void draw() override {
 // code to draw a model at the position of this object
 }
};

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

 class UpdateDelegate
{
public:
 virtual void update() = 0;
};

class NotMovablev: public UpdateDelegate
{
public:
 virtual void update() override {
 // no-op
 }
};

class Movablec: public UpdateDelegate
{
public:
 virtual void update() override {
 // code to update the position of this object
 }
};

संघट्ट डेलिगेट नामक एक एब्स्ट्रक्ट क्लास का परिचय उपवर्गों ठोस और ठोस नहीं के साथ करते है, जो किसी वस्तु से टकराने का साधन प्रदान करता है

 class CollisionDelegate
{
public:
 virtual void collide(Object objects[]) = 0;
};

class NotSolidS: public CollisionDelegate
{
public:
 virtual void collide(Object objects[]) override {
 // no-op
 }
};

class Solid
: public CollisionDelegate
{
public:
 virtual void collide(Object objects[]) override {
 // code to check for and react to collisions with other objects
 }
};

नामक एक अमूर्त क्लास का परिचय दें UpdateDelegate, उपक्लासेस के साथ NotMovable और Movable, जो किसी वस्तु को स्थानांतरित करने का साधन प्रदान करता है:

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

 class Object
{
 VisibilityDelegate* _v;
 UpdateDelegate* _u;
 CollisionDelegate* _c;

public:
 Object(VisibilityDelegate* v, UpdateDelegate* u, CollisionDelegate* c)
  : _v(v)
 , _u(u)
 , _c(c)
 {}

 void update() {
 _u->update();
 }

 void draw() {
 _v->draw();
 }

 void collide(Object objects[]) {
 _c->collide(objects);
 }
};

तब कंक्रीट इस रूप में दिखती है,

 class Player : public Object
{
public:
 Player()
  : Object(new Visible(), new Movable(), new Solid())
 {}

 // ...
};

class Smokea: public Object
{
public:
 Smoke()
 k: Object(new Visible(), new Movable(), new NotSolid())
 {}

 // ...
};

लाभ

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

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

कुछ लैंग्वेज , विशेष रूप से गो (प्रोग्रामिंग लैंग्वेज )[4] और रस्ट (प्रोग्रामिंग लैंग्वेज ),[5] विशेष रूप से टाइप कंपोज़िशन का उपयोग करती हैं।

कमियां

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

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

 // Base class
public abstract class Employee
{
 // Properties
 protected string Name { get; set; }
 protected int ID { get; set; }
 protected decimal PayRate { get; set; }
 protected int HoursWorked { get; }

 // Get pay for the current pay period
 public abstract decimal Pay();
}

// Derived subclass
public class HourlyEmployee : Employee
{
 // Get pay for the current pay period
 public override decimal Pay()
 {
 // Time worked is in hours
 return HoursWorked * PayRate;
 }
}

// Derived subclass
public class SalariedEmployee : Employee
{
 // Get pay for the current pay period
 public override decimal Pay()
 {
 // Pay rate is annual salary instead of hourly rate
 return HoursWorked * PayRate / 2087;
 }
}

कमियों से बचना

ट्रेट्स (कंप्यूटर साइंस), मैक्सिन, प्रकार एम्बेडिंग, या प्रोटोकॉल (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) एक्सटेंशन का उपयोग करके इस कमी से बचा जा सकता है।

कुछ लैंग्वेज इसे कम करने के लिए विशिष्ट साधन प्रदान करती हैं

  • सी शार्प (प्रोग्रामिंग लैंग्वेज): संस्करण 8.0 के बाद से डिफ़ॉल्ट इंटरफ़ेस विधि प्रदान करता है, जो बॉडी को इंटरफ़ेस सदस्य को परिभाषित करने की अनुमति देता है।[6]
  • डी (प्रोग्रामिंग लैंग्वेज ) डी एक प्रकार के भीतर स्पष्ट "एलियास यह" घोषणा प्रदान करता है जो इसे प्रत्येक विधि में और एक अन्य निहित प्रकार के सदस्य में अग्रेषित करने की अनुमति देता है।[7]
  • डार्ट (प्रोग्रामिंग लैंग्वेज ) डिफ़ॉल्ट कार्यान्वयन के साथ मिक्सिन प्रदान करता है जिसे साझा किया जा सकता है।
  • गो (प्रोग्रामिंग लैंग्वेज) टाइप एम्बेडिंग अग्रेषण विधियों की आवश्यकता से बचाती है।[8]
  • जावा (प्रोग्रामिंग लैंग्वेज ) संस्करण 8 के बाद से डिफ़ॉल्ट इंटरफ़ेस विधियाँ प्रदान करता है। प्रोजेक्ट लोम्बोक[9] प्रतिनिधिमंडल का समर्थन करता है, डेलिगेट प्रत्यायोजित क्षेत्र से सभी विधियों के नामों और प्रकारों को कॉपी करने और बनाए रखने के अतिरिक्त क्षेत्र पर एनोटेशन प्रदान करता है।[10] * जूलिया (प्रोग्रामिंग लैंग्वेज ) मैक्रोज़ का उपयोग अग्रेषण विधियों को उत्पन्न करने के लिए किया जा सकता है। लेजी जेएल और डेलिगेसन, [11]जैसे कई कार्यान्वयन सम्मलित होती है।[12][13]
  • कोटलिन (प्रोग्रामिंग लैंग्वेज ) में सिंटैक्स में डेलिगेशन पैटर्न सम्मलित होता है।[14]
  • पीएचपी : लक्षणों (कंप्यूटर विज्ञान) का समर्थन करता है।
  • राकू (प्रोग्रामिंग लैंग्वेज ) : राकू विधि अग्रेषण की सुविधा के लिए एक हैंडल विशेषता प्रदान करता है[15]
  • रस्ट (प्रोग्रामिंग लैंग्वेज) डिफ़ॉल्ट कार्यान्वयन के साथ लक्षण प्रदान करता है।
  • स्काला (प्रोग्रामिंग लैंग्वेज ) संस्करण 3 के बाद से किसी वस्तु के चयनित सदस्यों के लिए उपनामों को परिभाषित करने के लिए एक निर्यात खंड प्रदान करता है।[16]
  • स्विफ्ट (प्रोग्रामिंग लैंग्वेज ) एक्सटेंशन का उपयोग किसी प्रोटोकॉल के डिफ़ॉल्ट कार्यान्वयन को परिभाषित करने के लिए किया जाता है, इसके अतिरिक्त किसी व्यक्तिगत प्रकार के कार्यान्वयन के लिए प्रयोग की जाती है।[17]

अनुभवजन्य अध्ययन

भिन्न -भिन्न आकार के 93 ओपन सोर्स जावा प्रोग्राम के 2013 के एक अध्ययन में पाया गया कि,

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

— टेम्पेरो एट अल, जावा में इनहेरिटेंस के साथ प्रोग्रामर क्या करते हैं


यह भी देखें

संदर्भ

  1. 1.0 1.1 Freeman, Eric; Robson, Elisabeth; Sierra, Kathy; Bates, Bert (2004). Head First Design Patterns. O'Reilly. p. 23. ISBN 978-0-596-00712-6.
  2. Knoernschild, Kirk (2002). Java Design - Objects, UML, and Process: 1.1.5 Composite Reuse Principle (CRP). Addison-Wesley Inc. ISBN 9780201750447. Retrieved 2012-05-29.
  3. Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. p. 20. ISBN 0-201-63361-2. OCLC 31171684.
  4. Pike, Rob (2012-06-25). "Less is exponentially more". Retrieved 2016-10-01.
  5. "Characteristics of Object-Oriented Languages - The Rust Programming Language". doc.rust-lang.org. Retrieved 2022-10-10.
  6. "What's new in C# 8.0". Microsoft Docs. Microsoft. Retrieved 2019-02-20.
  7. "Alias This". D Language Reference. Retrieved 2019-06-15.
  8. "(Type) Embedding". The Go Programming Language Documentation. Retrieved 2019-05-10.
  9. https://projectlombok.org
  10. "@Delegate". Project Lombok. Retrieved 2018-07-11.
  11. https://github.com/MikeInnes/Lazy.jl
  12. https://github.com/JeffreySarnoff/TypedDelegation.jl
  13. "Method forwarding macro". JuliaLang (in English). 20 April 2019. Retrieved 18 August 2022.
  14. "Delegated Properties". Kotlin Reference. JetBrains. Retrieved 2018-07-11.
  15. "Type system". docs.raku.org. Retrieved 18 August 2022.
  16. "Export Clauses". Scala Documentation. Retrieved 2021-10-06.
  17. "Protocols". The Swift Programming Language. Apple Inc. Retrieved 2018-07-11.