क्या अपवाद एक ओओपी अवधारणा हैं?


37

कल एक पोस्ट पढ़ने के बाद, मुझे एहसास हुआ कि मुझे अपवादों की उत्पत्ति के बारे में ज्यादा जानकारी नहीं है। क्या यह ओओपी से संबंधित अवधारणा है? मुझे लगता है कि यह है, लेकिन फिर से डेटाबेस अपवाद हैं।


मैंने एक बार पढ़ा कि एक "मिस्टर गुडेनफ" (या इसी तरह) ने "कभी बुरा नहीं मानना, यह गुडेनफ, एह!" के जवाब में अपवादों का आविष्कार किया। शैली बदमाशी। मुझे अब एक संदर्भ नहीं मिल रहा है - शायद कोई और कर सकता है। यह जानना दिलचस्प होगा कि उन्हें पहले किस भाषा में जोड़ा गया था।
स्टीव ३४

7
हास्केल के अपवाद हैं और यह
ओओपी

1
यद्यपि अपवाद स्वयं कड़ाई से वस्तु-उन्मुख नहीं हैं, अपवादों को वस्तुओं के रूप में परिभाषित करने और इन वस्तुओं के उदाहरणों को स्पष्ट रूप से फेंकने और पकड़ने का सामान्य अभ्यास बहुत ओओपी है।
डौग्वज '

अपवाद और GOTO में क्या अंतर है, यह एक दिलचस्प सवाल होगा।
ऑस्टिन हेनली

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

जवाबों:


5

अपवाद OOP अवधारणा नहीं हैं।

लेकिन वे एक छोटे से बिंदु में पूरी तरह से असंबंधित नहीं हैं।

जैसा कि अन्य उत्तरों से पता चला है: अपवादों की अवधारणा ने इसे कई गैर-ओओपी भाषाओं में बनाया है। उस अवधारणा में कुछ भी OOP से कुछ की आवश्यकता नहीं है ।

लेकिन कोई भी अगर सभी ओओपी भाषाएं जो ओओपी को गंभीरता से नहीं लेती हैं अपवादों की आवश्यकता होती है क्योंकि त्रुटि-हैंडलिंग के अन्य तरीके एक विशिष्ट बिंदु पर विफल होते हैं: निर्माता।

OOP के बिंदुओं में से एक यह है कि एक वस्तु पूरी तरह से और लगातार अपनी आंतरिक स्थिति को समाप्‍त और प्रबंधित करेगी। इसका अर्थ यह भी है कि शुद्ध OOP में आपको एक अवधारणा के साथ एक नई वस्तु बनाने की आवश्यकता होती है, जिसमें एक "स्थिर" स्थिति होती है - स्मृति आवंटन से सब कुछ (यदि आवश्यक हो) प्रारंभिक अवस्था में एक सार्थक स्थिति में (यानी सरल शून्य मेमोरी पर्याप्त नहीं है) एक अभिव्यक्ति में किया जाना चाहिए। इसलिए एक निर्माणकर्ता की आवश्यकता है:

Foo myFoo = Foo("foo", "bar", 42);

लेकिन इसका मतलब यह है कि निर्माणकर्ता कुछ त्रुटि के कारण भी विफल हो सकता है। बिना अपवाद के निर्माणकर्ता से त्रुटि सूचना का प्रचार कैसे करें?

  • प्रतिलाभ की मात्रा? चूँकि कुछ भाषाओं में असफलताएँ newकेवल लौट सकती हैं, nullलेकिन कोई अर्थपूर्ण जानकारी नहीं। अन्य भाषाओं में (जैसे C ++) myFooपॉइंटर नहीं है। आप इसके खिलाफ जाँच नहीं कर सकते null। इसके अलावा, आप myFooत्रुटि के बारे में नहीं पूछ सकते - यह आरंभीकृत नहीं है और इसलिए OOP सोच में "मौजूद नहीं है"।

  • वैश्विक त्रुटि ध्वज? राज्य और फिर कुछ वैश्विक परिवर्तन के बारे में इतना? H पर जाएँ ... ;-)

  • एक मिश्रण? किसी भी तरह से बेहतर नहीं है।

  • ?

इसलिए अपवाद OOP की तुलना में एक अधिक मौलिक अवधारणा है लेकिन OOP उन पर स्वाभाविक रूप से निर्माण करता है।


3
जहाँ तक मैं बता सकता हूँ, इस "उत्तर" में एकमात्र शब्द जो पूछे गए वास्तविक प्रश्न को संबोधित करता है, वह "नहीं" है। बाकी OOP में अपवादों के बारे में लगता है - मेरे कारण पूरे सम्मान के साथ यह कहीं न कहीं से संबंधित है और पूरी तरह से अप्रासंगिक है - फिर से पूछे गए सवाल के संदर्भ में
gnat

@gnat: TO यह भी कहता है कि वह अपवादों की उत्पत्ति के बारे में नहीं जानता है। इसलिए OO भूमि में हर जगह अपवाद हैं, थोड़ा पृष्ठभूमि मेरे लिए ठीक लग रहा था। YMMV
AH

1
@ हां मुझे ओपनिंग लाइन से हटकर gnat से सहमत होना होगा, यह वास्तव में प्रश्न को संबोधित नहीं करता है। आपका जवाब gnat था "कहते हैं कि वह अपवादों की उत्पत्ति के बारे में नहीं जानते हैं" फिर भी आपने वास्तव में अपवादों की उत्पत्ति नहीं की, वस्तु तात्कालिकता के दौरान अपवादों के कुछ यादृच्छिक उपयोग।

दोस्तों, गंभीरता से? -1? अन्य उत्तरों में से अधिकांश बिंदु पर 100% नहीं हैं, या तो। क्षतिपूर्ति करने के लिए मुझसे +1। यह उत्तर टूटे हुए वर्ग के डिजाइनों की दुनिया में अच्छी पृष्ठभूमि सलाह देता है। (संशोधन: मेंशन मल्टी-स्टेप कंस्ट्रक्टर्स से बचा जाना चाहिए)
जो

44

क्या यह ओओपी से संबंधित है?

सं अपवाद और OOP असंबंधित हैं।

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

सी की तुलना करना ( वास्तव में ओओपी भाषा नहीं है , किसी भी तरह सी में अपवादों का अनुकरण करना संभव है ) और सी ++ (ओओपी, अपवादों का समर्थन करता है), कुछ भी नहीं सी की मानक समिति को सी से निपटने के अपवादों को जोड़ने से रोकता है, यह अभी भी सी को ओओपी भाषा नहीं बनाएगा।


2
आप यह भी तर्क दे सकते हैं कि सामान्य ओएस में पहले से ही कुछ प्रकार के अपवाद समर्थित हैं। अपने प्रोग्राम को क्रैश (अनियोजित "अपवाद") और एक कोर डंप और डीबगर के साथ, आप एक स्टैक ट्रेस भी प्राप्त करें।
भाक ak

12
यहां तक ​​कि एमएस बेसिक 80 के शुरुआती अपवादों को भी संभालता है:ON ERROR GOTO xxxx
jernernyy

1
@bhaak वह विंडोज में मेमोरी
डंप्स के

11
@jernerny त्रुटि से निपटने? ज़रूर। लेकिन कोई भी उस अपवाद को संभालना नहीं कहेगा। वास्तव में, यह नियमित रूप से (संरचित) अपवाद हैंडलिंग के विपरीत था ।
कोनराड रूडोल्फ

1
@jwernerny सुनिश्चित नहीं हैं कि मैं अनुसरण करता हूं; अपवाद हैंडलिंग, जैसा कि मैंने समझा है कि त्रुटि से निपटने का एक बहुत ही विशिष्ट तरीका है। जब मैं अपवाद सुनता हूं तो मैं हमेशा try catchनिर्माण के बारे में सोचता हूं ।
एंडी

12

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

ऑब्जेक्ट ओरिएंटेड भाषाओं में आमतौर पर एक मूल अपवाद वर्ग होता है, और संदर्भ के आधार पर शब्द "अपवाद" वास्तव में सामान्य अवधारणा के बजाय उस मूल वर्ग को संदर्भित कर सकता है। ऑब्जेक्ट ओरिएंटेड अपवाद हैंडलिंग, ऑब्जेक्ट ओरिएंटेशन, सिंटैक्टिक शुगर के अधिकांश के रूप में है, और आसानी से निर्णायक गैर ऑब्जेक्ट ओरिएंटेड भाषाओं में अनुकरण किया जा सकता है। यहाँ एक सी उदाहरण है, सी प्रोग्रामिंग विकिबुक से :

#include <stdio.h>
#include <setjmp.h>

jmp_buf test1;

void tryjump()
{
    longjmp(test1, 3);
}

int main (void)
{
    if (setjmp(test1)==0) {
        printf ("setjmp() returned 0.");
        tryjump();
    } else {
        printf ("setjmp returned from a longjmp function call.");
    }
}

6
यह सिंटैक्टिक शुगर नहीं है। पूर्ण स्टैक अनइंडिंग और टाइप-आधारित कैच हैंडलर को फिर से सेट करना सेटजम्प के साथ मुश्किल है। इसके अतिरिक्त, अपवादों के विशेष संकलन से फायदे होते हैं जिन्हें सेटजम्प द्वारा नकल नहीं किया जा सकता है।
eda-qa mort-ora-y

3
मुझे वर्णन से नफरत है अपवाद असाधारण स्थिति हैं। मैं इसके बजाय कहना चाहूंगा कि जब कोई त्रुटि स्थिति वर्तमान संदर्भ के साथ हल नहीं की जा सकती है तो अपवादों को उत्पन्न (फेंकना) किया जाना चाहिए क्योंकि त्रुटि को सही ढंग से ठीक करने के लिए वर्तमान संदर्भ में पर्याप्त जानकारी नहीं है।
मार्टिन जॉर्ज


9

उत्तर एक सरल सं है।

अपवादों के साथ गैर-ओओ भाषा के लिए एक अच्छा उदाहरण एडीए है।


4
हम्म, एडीए एक ओओ भाषा क्यों नहीं है? दी गई, ADA83 में बहुरूपता का अभाव था लेकिन इसे अभी भी वस्तु आधारित माना जा सकता है। इसके अलावा ADA95 के बाद से भाषा पूरी तरह से उन्मुख है।
यानिस y

जहाँ तक मुझे पता है कि अपवाद हैंडलिंग ADA83 से पुरानी है इसलिए ADA अपने आप में अपवाद हैंडलिंग के साथ एक गैर-OO है।
उवे प्लोनस '

2
@YannisRizos: Ada83 में पैकेज और जेनेरिक पैकेज हैं, लेकिन ऑब्जेक्ट नहीं। उन्हें Ada95 के साथ पेश किया गया था।
मौवीसील

2
@ यानिस - बहुरूपता के बिना ऑब्जेक्ट नेस्टेड ब्लॉक के बिना संरचित प्रोग्रामिंग की तरह है। बहुरूपता OOP के परिभाषित लक्षणों में से एक है। यहां तक ​​कि Ada95 में, रन-टाइम बाइंडिंग का समर्थन करने वाले प्रकारों को "कक्षाएं" के बजाय "टैग किए गए प्रकार" कहा जाता है, हालांकि यह केवल वर्तनी है। Ada 83 में विभिन्न प्रकार के रिकॉर्ड और अन्य प्रकार थे, लेकिन उन प्रकारों में से कोई भी ऐसी सुविधाएँ प्रदान नहीं करता है जो OOP के लिए विशिष्ट हैं। Ada 83 मॉड्यूलर और संरचित था, लेकिन यह ऑब्जेक्ट ओरिएंटेड नहीं था।
स्टीव ३१

3
@Yannis - मूल रूप से, Ada समुदाय के कुछ लोग (जैसे अधिकांश भाषाओं के कुछ अधिवक्ता) यह स्वीकार नहीं कर सकते कि एक सुविधा अच्छी हो सकती है, फिर भी उनकी पसंदीदा भाषा में लागू नहीं की जाएगी, और अन्यथा विश्वास करने के लिए सभी प्रकार के बहाने बनाए जाएंगे। फिर भी ऐसा नहीं है कि यदि एक अच्छी भाषा के लिए सभी संभव अच्छी भाषा सुविधाएँ होनी चाहिए (हालाँकि ऐसा माना जाता है कि Ada डिजाइनरों का मानना ​​आसान है)। मैं वास्तव में भाषा के डिजाइन के लिए न्यूनतम दृष्टिकोण में विश्वास नहीं कर रहा हूं, लेकिन मैक्सिममिस्ट भाषाएं बिल्कुल भी सही नहीं हैं।
स्टीव ३१

7

कुछ बहुत अच्छे जवाब यहाँ पहले से ही। गैर-ओओपी प्रोग्रामिंग भाषाओं के अपवाद होने के अन्य उदाहरण:

  • Oracle PL / SQL

  • क्लासिक विज़ुअल बेसिक (V6 और नीचे, "ऑन एरर गोटो" IMHO अपवाद स्वरूप का एक रूप है)

(नट्टी होना: आपको दोनों भाषाओं में कुछ OO तत्व मिलते हैं, लेकिन अपवाद से निपटने वाले यांत्रिकी उनका उपयोग नहीं करते हैं, मुझे लगता है क्योंकि उन भाषाओं में OO तत्वों को जोड़े जाने से सालों पहले अवधारणा पेश की गई थी)।


डॉस पर कम से कम बाद के क्विकबासिक संस्करण (जो विजुअल बेसिक से पहले हुए थे; QB 4.5 विकिपीडिया के अनुसार 1988 था, VB 1.0 1991) में ON ERROR GOTOसिंटैक्स का उपयोग करते हुए त्रुटि से निपटने में त्रुटि हुई थी । यहां तक ​​कि QuickBASIC में कुछ OO- समान अवधारणाएं थीं (मुझे लगता है कि QB 4.5 यहां तक ​​कि कुछ प्रकार की समर्थित कक्षाएं भी हैं), लेकिन आपको ज्यादातर पारंपरिक-पारंपरिक BASIC को एक उचित ऑब्जेक्ट-ओरिएंटेड भाषा कहने में मुश्किल होगी। [विकिपीडिया ]
एक CVn

5

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

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

अपवाद स्वयं एक OOP अवधारणा नहीं हैं, लेकिन उन्हें अक्सर OOP अवधारणाओं का उपयोग करके कार्यान्वित किया जाता है जो उन्हें अधिक सुविधाजनक और शक्तिशाली बनाते हैं। उदाहरण के लिए, अपवाद को वंशानुगत पदानुक्रम के साथ परिभाषित किया जा सकता है। फ़ाइल खोलने और पढ़ने या लिखने के हमारे विचारशील उदाहरण का उपयोग करते हुए, उनमें से प्रत्येक कॉल विभिन्न प्रकार के अपवाद उत्पन्न कर सकती है - FileClosedException, DeviceFullException, NoSuchFileException, InsufficFilePilesException, आदि। इनमें से प्रत्येक FileException से विरासत में मिली हो सकती है, जो IOException से विरासत में मिल सकती है, जो हो सकता है। GenericException से विरासत में मिली।

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


3

अन्य लोगों ने भाषाओं के उदाहरणों के साथ "नहीं" का सही उत्तर दिया है। मुझे लगा कि मैं एक उदाहरण जोड़कर विस्तार कर सकता हूं कि कैसे ओओपी को शामिल किए बिना किसी भाषा में अपवादों को जोड़ा जाए।

मैं OZ के DSKL (घोषणात्मक अनुक्रमिक कर्नेल भाषा) के मामले में ऐसा करूंगा , एक भाषा जो इस तरह से अकादमिक सामान के लिए उपयुक्त है। DSKL (या DKL) को यहां (रैंडम सर्च रिजल्ट), स्टेटमेंट और वैल्यू भाग में देखा जा सकता है । सटीक परिभाषा महत्वपूर्ण नहीं है, इसके अलावा यह बहुत सरल भाषा है जिसमें कोई परिवर्तनीय चर नहीं हैं (वे घोषित किए गए हैं और बाद में बाध्य हैं), और कोई ओओपी नहीं बनाया गया है।

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

यदि हम कर्नेल भाषा में अपवाद जोड़ते हैं, तो हमारे पास कोई भी ओओपी-समर्थन वाली भाषा नहीं होगी, लेकिन अपवाद हैं। मुझे दिखाओ कैसे:

स्टैक और स्टोरेज के साथ एक अमूर्त मशीन को परिभाषित करते हुए, हम परिभाषित कर सकते हैं कि हमारी भाषा में प्रत्येक कथन ( कथन के शब्दार्थ ) को क्या करना चाहिए । उदाहरण के लिए skip, स्टैक में कुछ भी नहीं करना चाहिए, A = 3स्टैक में 3 से ए / (/) को बाइंड (एक करना) करना चाहिए।

हम अपने अपवाद को कैसे परिभाषित किया जाना चाहिए, इसका सिंटैक्स जोड़कर शुरू करते हैं । हम <statement>DKL में एक और दो खंड जोड़कर ऐसा करते हैं ।

<statement>  ::== ... (old stuff)
                 | try <statement> catch <id> then <statement> end
                 | raise <id> end

यहाँ ज्ञात प्रयास / पकड़ है, और अपवादों को बढ़ाने / फेंकने का एक तरीका है।

हम उनके शब्दार्थ को परिभाषित करते हैं कि उन्हें अमूर्त मशीन पर कैसे काम करना चाहिए:


शब्दार्थ कथन का प्रयास करें : (try <statement1> catch <id> then <statement2> end)
करें:

  1. स्टैक को सिमेंटिक स्टेटमेंट पर पुश करें (catch <id> then <statement2> end)
  2. स्टैक को सिमेंटिक स्टेटमेंट पर पुश करें (<statement1>)

ध्यान दें कि स्टेटमेंट 1 स्टैक के शीर्ष पर होगा, और पहले निष्पादित करने की कोशिश की जाएगी।

उठाएँ
अर्थ कथन है: (raise <id> end)
कार्य करें:

  1. यदि स्टैक पर अधिक कुछ नहीं है, तो रोकें और एक अनकहा अपवाद की रिपोर्ट करें।
  2. एल्स, स्टैक से पहला सिमेंटिक स्टेटमेंट पॉप करें। यदि यह कैच स्टेटमेंट नहीं है, तो चरण 1 पर जाएं।
  3. हम एक पकड़ प्राप्त कर चुके हैं, फॉर्म में स्टैक पर (catch <id> then <statement> end)
    पुश (<statement>)करें।

कैच
यदि हम सामान्य निष्पादन के दौरान कैच-स्टेटमेंट देखते हैं, तो इसका मतलब है कि जो कुछ भी इस स्तर तक अपवादों को उठाए बिना निष्पादित किया गया था। इस प्रकार हम केवल catchस्टैक के पॉप करते हैं और कुछ भी नहीं करते हैं।

QED, हमारे पास अपवादों वाली भाषा है और OOP की कोई संभावना नहीं है।

मैंने अमूर्त मशीन से पर्यावरण के हिस्से को सरल बनाने के लिए हटा दिया है।


1

नहीं।

IIRC, अपवाद पहली OO भाषाओं के सामने आए। AFAIK, अपवादों को पहले LISP कार्यान्वयन द्वारा समर्थित किया गया था। प्रारंभिक संरचित भाषाएँ (जैसे ALGOL) और प्रारंभिक OO भाषाएँ (जैसे SIMULA) अपवादों का समर्थन नहीं करती थीं।


ALGON 68, बेशक, अपवाद ("घटनाओं") था, लेकिन यह सब कुछ और भी था। PL / I के पास उन्हें ("शर्तों पर") भी था, और 1969 से उनके उपयोग का वर्णन करने वाला साहित्य है।
रॉस पैटरसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.