व्यवहार उपप्रकार

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

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

यह उदाहरण व्यवहारिक सबटाइपिंग का उल्लंघन करता है क्योंकि टाइप स्टैक टाइप क्यू का व्यवहारिक सबटाइप नहीं है: यह स्पष्ट नहीं है कि टाइप स्टैक के द्वारा वर्णित व्यवहार (अर्थात LIFO व्यवहार) टाइप क्यू के वर्णन के अनुरूप है (जो FIFO व्यवहार की आवश्यकता होती है)।

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

महत्वपूर्ण यह है कि टाइप टी के विनिर्देशन (अर्थात प्रलेखन) पर निर्भर करता है कि क्या टाइप एस, टाइप टी का व्यवहारिक उपप्रकार है; इसका कोई अप्रभाव नहीं पड़ता कि टाइप प्रकार टी का कार्यान्वयन होता है या नहीं। वास्तव में, टाइप टी को कार्यान्वयन करने की भी आवश्यकता नहीं है; यह एक पूर्णतः अमूर्त वर्ग हो सकता है। एक और मामले के रूप में, टाइप बैग का विनिर्देश निर्दिष्ट नहीं करता है कि मेथड get द्वारा कौन सा तत्व हटाया जाना चाहिए, तो यहां उपस्थित स्टैक टाइप बैग का एक व्यवहारिक उपप्रकार होने के बावजूद, टाइप स्टैक बैग का एक व्यवहारिक उपप्रकार है। इसका अर्थ है कि व्यवहारिक उपप्रकार की चर्चा एक विशेष (व्यवहारिक) विनिर्देश के संबंध में ही की जा सकती है और यदि सम्मिलित प्रकार में कोई अच्छी प्रकार से परिभाषित व्यवहार विनिर्देश नहीं है तो व्यवहारिक उपप्रकार की चर्चा सार्थक नहीं हो सकती है।

व्यवहार उपप्रकार सत्यापित करना
एक प्रकार S, प्रकार T का आचरणीय उपप्रकार होता है यदि S के विनिर्देश के अनुसार स्वीकृत प्रत्येक व्यवहार का उपयोग T के विनिर्देश के अनुसार स्वीकार्य होता हो। इसमें विशेष रूप से, T का प्रत्येक विधि M के लिए, S में M का विनिर्देश T में से अधिक मजबूत होता है।

यदि किसी मेथड की पूर्व-शर्त Psऔर उत्तर-शर्त Qs दी गई हो तथा एक अन्य मेथड की पूर्व-शर्त Pt और उत्तर-शर्त Qt दी गई हो (औपचारिक रूप से: (Ps, Qs ) ⇒ (Pt, Qt)) तो यदि Ps Pt से कमजोर होता है (अर्थात Pt Ps को समर्थन करता है) और Qs Qtसे ज़्यादा मजबूत होता है (अर्थात Qs Qt को समर्थित करता है) तो Ps और Qs की मेथड विशिष्टता बढ़ सकती है। अधिक विशिष्ट मेथड विशेषण तब होते हैं जब उनमें पहले से समर्थित इनपुट के लिए आउटपुट पर अधिक विशिष्ट प्रतिबंध लगाए जाएँ या फिर ज़्यादा इनपुट को समर्थित होने की आवश्यकता हो।

उदाहरण के रूप में, एक तर्क x के एक तत्व के शुद्धार्थ की गणना करने वाली एक विधि के लिए (बहुत कमजोर) निर्देशिका का विचार करें, जो एक पूर्व-शर्त 0 ≤ x और एक पोस्ट-शर्त 0 ≤ परिणाम निर्धारित करती है। यह निर्देशिका यह कहती है कि विधि को x के लिए नकारात्मक मूल्यों का समर्थन करने की आवश्यकता नहीं है, और इसे सुनिश्चित करने की आवश्यकता है कि परिणाम भी नॉन-नेगेटिव हो। इस निर्देशिका को मजबूत करने के दो संभव तरीके हैं, जिसमें पोस्ट-शर्त को बलवान बनाकर स्थिति को परिभाषित किया जाता है कि परिणाम = | x | होता है, अर्थात परिणाम x के शुद्धार्थ के बराबर होता है, या पूर्व-शर्त को "सत्य" बनाकर कमजोर किया जाता है, अर्थात सभी x के लिए समर्थित होना चाहिए। बेशक, हम इन दोनों को एक साथ मिलाकर भी ला सकते हैं, जिसमें उल्लेख किया जाता है कि परिणाम किसी भी मान के x के लिए x के शुद्धार्थ के बराबर होना चाहिए।

ध्यान दें, हालांकि, पोस्टकंडीशन (Qs ⇏ Qt) को मजबूत किए बिना स्पष्टीकरण ((Ps, Qs) ⇒ (Pt, Qt)) को मजबूत किया जा सकता है। एक निश्चित मूल्य की विधि के लिए एक विधान सोचें जो एक पूर्व-शर्त 0 ≤ x और एक पोस्ट-शर्त परिणाम = x को निर्धारित करता है। एक विधान जो एक पूर्व-शर्त "सत्य" और एक पोस्ट-शर्त परिणाम = |x| निर्धारित करता है जो इस विधान को मजबूत करता है, भले ही पोस्ट-शर्त परिणाम परिणाम = x को मजबूत नहीं करता हो (या कमजोर नहीं करता हो)। Ps से पहले और "Qs या नहीं Ps" को "Qt या नहीं Pt" से मजबूत होने का आवश्यक शर्त एक विधान के लिए होता है। वास्तव में, "परिणाम = |x| या झूठा" "परिणाम = x या x <0" से मजबूत करता है।

स्थानापन्नता
डेटा एबस्ट्रैक्शन और क्लास हायरार्कीज पर एक प्रभावशाली कीनोट एड्रेस में, OOPSLA 1987 प्रोग्रामिंग भाषा अनुसंधान सम्मेलन पर, बारबरा लिस्कोवने निम्नलिखित कहा: "यहाँ चाहिए कुछ ऐसा जैसा निम्नलिखित स्थानांतरण गुण हो: अगर प्रत्येक ऑब्जेक्ट o1 के लिए S के प्रकार के एक ऑब्जेक्ट o2 होता है जिसके लिए T के प्रकार के सभी प्रोग्राम P के लिए, P का व्यवहार बदलाव नहीं करता है जब o1 o2 के लिए इस्तेमाल किया जाता है, तो S T का उप-प्रकार है।" यह विशेषण बाद में लिस्कोव प्रतिस्थापन सिद्धांत (LSP) के रूप में जाना जाता है। दुर्भाग्य से, इसमें कई मुद्दे हैं। पहले, इसकी मूल रूप में, यह बहुत मजबूत है: हम धारक वर्ग के व्यवहार को अक्सर उसके उप-वर्ग के व्यवहार से अलग नहीं चाहते हैं; एक उप-वर्ग वस्तु को एक धारक वर्ग वस्तु के लिए बदलना आमतौर पर कार्यक्रम के व्यवहार को बदलने की इच्छा से किया जाता है, हालांकि, यदि व्यवहारी उप-प्रकार का सम्मान किया जाता है, तो इस तरह के बदलाव को कार्यक्रम की वांछनीय गुणवत्ताओं को बरकरार रखने वाले तरीके से किया जाता है। दूसरे, इसमें विनिर्देशों का कोई उल्लेख नहीं है, इसलिए यह गलत रीडिंग के लिए निमंत्रित होता है जहां प्रकार S का अंतर्निर्माण प्रकार T के अंतर्निर्माण से तुलना की जाती है। इसके कई कारण हैं, एक कारण है कि यह आम स्थिति का समर्थन नहीं करता है जहां T एक अंतर्जात टाइप है और उसका कोई अमल नहीं होता। तीसरे और सबसे छिपी कमी ओब्जेक्ट-ओरिएंटेड इम्पेरेटिव प्रोग्रामिंग के सन्दर्भ में है कि किसी विशिष्ट टाइप के ऑब्जेक्ट्स पर समग्र या अस्तित्ववादी रूप से किसी दूसरे ऑब्जेक्ट की जगह लेने का विवरण निर्धारित करना मुश्किल होता है, या एक ऑब्जेक्ट को दूसरे के लिए बदलना। ऊपर दिए गए उदाहरण में, हम एक स्टैक ऑब्जेक्ट को एक बैग ऑब्जेक्ट के रूप में उपयोग कर रहे हैं, हम एक स्टैक ऑब्जेक्ट को बैग ऑब्जेक्ट के लिए बदलने नहीं कर रहे हैं।

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