मुख्यधारा की मजबूत स्थिर ओओपी भाषाएँ आदिम विरासत को क्यों रोकती हैं?


53

यह ठीक क्यों है और अधिकतर अपेक्षित है:

abstract type Shape
{
   abstract number Area();
}

concrete type Triangle : Shape
{
   concrete number Area()
   {
      //...
   }
}

... जबकि यह ठीक नहीं है और कोई भी शिकायत नहीं करता है:

concrete type Name : string
{
}

concrete type Index : int
{
}

concrete type Quantity : int
{
}

मेरी प्रेरणा संकलन-समय शुद्धता सत्यापन के लिए प्रकार प्रणाली के उपयोग को अधिकतम कर रही है।

पुनश्च: हाँ, मैं पढ़ लिया है इस और रैपिंग एक hacky है काम के आसपास।


1
टिप्पणियाँ विस्तारित चर्चा के लिए नहीं हैं; इस वार्तालाप को बातचीत में स्थानांतरित कर दिया गया है ।
maple_shaft

इस प्रश्न में मेरी समान प्रेरणा थी , आपको यह दिलचस्प लग सकता है।
default.kramer

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

जवाबों:


83

मुझे लगता है कि आप जावा और सी # जैसी भाषाओं के बारे में सोच रहे हैं?

उन भाषाओं में आदिम (जैसे int) मूल रूप से प्रदर्शन के लिए एक समझौता है। वे वस्तुओं की सभी विशेषताओं का समर्थन नहीं करते हैं, लेकिन वे तेज़ और कम ओवरहेड के साथ हैं।

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

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

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

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

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


12
@ जेन: stringसील कर दिया जाता है क्योंकि यह अपरिवर्तनीय व्यवहार करने के लिए डिज़ाइन किया गया है। यदि कोई स्ट्रिंग से विरासत में प्राप्त कर सकता है, तो उत्परिवर्तित तार बनाना संभव होगा, जो इसे वास्तव में त्रुटि प्रवण बना देगा। कोड के टोंस, .NET फ्रेमवर्क को ही शामिल करता है, बिना किसी साइड-इफ़ेक्ट वाले तारों पर निर्भर करता है। यहाँ भी देखें, आपको वही बताता है: quora.com/Why-String-class-in-C-is-a-sealed-class
डॉक्टर ब्राउन

5
@DocBrown यह भी जावा में Stringचिह्नित कारण है final
देव

47
"जब जावा को डिज़ाइन किया गया था, तो स्मॉलटाक को बहुत धीमा माना गया था [...]। जावा को बेहतर प्रदर्शन प्राप्त करने के लिए कुछ लालित्य और वैचारिक पवित्रता का त्याग किया।" विडंबना यह है कि निश्चित रूप से, जावा ने वास्तव में उस प्रदर्शन को हासिल नहीं किया, जब तक कि सन ने स्मॉलटाकल कंपनी को स्मॉलटाकल वीएम तकनीक तक पहुंच प्राप्त करने के लिए नहीं खरीदा, क्योंकि सन की खुद की जेवीएम कुत्ते-धीमी थी, और हॉटस्पॉट जेवीएम, थोड़ा संशोधित स्मॉलकैप वीएम जारी किया।
जार्ज डब्ल्यू मित्तग

3
@underscore_d: आपने जो उत्तर दिया वह बहुत स्पष्ट रूप से कहा गया है कि C not में आदिम प्रकार नहीं हैं। ज़रूर, कुछ प्लेटफ़ॉर्म जिसके लिए C or का कार्यान्वयन मौजूद है, में आदिम प्रकार हो सकते हैं या नहीं, लेकिन इसका मतलब यह नहीं है कि C types में आदिम प्रकार हैं। उदाहरण के लिए, सीएलआई के लिए रूबी का कार्यान्वयन है, और सीएलआई में आदिम प्रकार हैं, लेकिन इसका मतलब यह नहीं है कि रूबी के पास आदिम प्रकार हैं। कार्यान्वयन प्लेटफ़ॉर्म के आदिम प्रकारों पर मैपिंग करके मूल्य प्रकारों को लागू करने का चयन कर सकता है या नहीं भी कर सकता है, लेकिन यह एक निजी आंतरिक कार्यान्वयन विवरण है और कल्पना का हिस्सा नहीं है।
जोर्ग डब्ल्यू मित्तग

10
यह अमूर्तता के बारे में है। हमें अपना सिर साफ रखना होगा, अन्यथा हम बकवास करते हैं। उदाहरण के लिए: C♯ .NET पर लागू किया गया है। .NET को Windows NT पर लागू किया गया है। Windows NT को x86 पर लागू किया गया है। x86 को सिलिकॉन डाइऑक्साइड पर लागू किया जाता है। SiO Si सिर्फ रेत है। तो, stringC , में रेत है? नहीं, बिल्कुल नहीं, stringC♯ में C , का अनुमान क्या है, यह कहता है। इसे कैसे लागू किया जाता है यह अप्रासंगिक है। C native का एक मूल कार्यान्वयन बाइट सरणियों के रूप में तार को लागू करेगा, एक ECMAScript कार्यान्वयन उन्हें ECMAScript Strings, आदि में मैप करेगा
Jörg W Mittag

20

क्या कुछ भाषा का प्रस्ताव उपवर्ग नहीं है, लेकिन उपप्रकार । उदाहरण के लिए, Ada आपको व्युत्पन्न प्रकार या उपप्रकार बनाने देता है । एडीए प्रोग्रामिंग / प्रकार प्रणाली अनुभाग सभी विवरण को समझने के लिए पढ़ने लायक है। आप मानों की श्रेणी को सीमित कर सकते हैं, जो कि आप ज्यादातर समय चाहते हैं:

 type Angle is range -10 .. 10;
 type Hours is range 0 .. 23; 

यदि आप उन्हें स्पष्ट रूप से परिवर्तित करते हैं, तो आप दोनों प्रकार के इंटर्जर के रूप में उपयोग कर सकते हैं। ध्यान दें कि आप एक का उपयोग दूसरे के स्थान पर नहीं कर सकते हैं , तब भी जब सीमाएँ संरचनात्मक रूप से समतुल्य हों (प्रकार नामों द्वारा जाँच की जाती हैं)।

 type Reference is Integer;
 type Count is Integer;

उपरोक्त प्रकार असंगत हैं, भले ही वे समान श्रेणी के मूल्यों का प्रतिनिधित्व करते हैं।

(लेकिन आप अनियंत्रित_कॉनवर्जन का उपयोग कर सकते हैं; लोगों को यह न बताएं कि मैंने आपको बताया है)


2
दरअसल, मुझे लगता है कि यह शब्दार्थ के बारे में अधिक है। एक मात्रा का उपयोग करना जहां एक सूचकांक की उम्मीद है, फिर उम्मीद है कि एक संकलन समय त्रुटि का कारण होगा
Marjan Venema

@MarjanVenema यह करता है, और यह तर्क त्रुटियों को पकड़ने के उद्देश्य से किया जाता है।
coredump

मेरा कहना था कि वे सभी मामले नहीं हैं जहाँ आप शब्दार्थ चाहते हैं, आपको श्रेणियों की आवश्यकता होगी। तब आपके पास ऐसा होगा type Index is -MAXINT..MAXINT;जो किसी तरह से मेरे लिए कुछ नहीं करता क्योंकि सभी पूर्णांक मान्य होंगे? तो अगर मैं एक एंगल को एक इंडेक्स से पार कर रहा हूं, तो उस त्रुटि को किस तरह से जांचा जाएगा?
मार्जन वेनमा

1
@MarjanVenema दूसरे उदाहरण में दोनों प्रकार के पूर्णांक के उपप्रकार हैं। हालाँकि, यदि आप एक फ़ंक्शन की घोषणा करते हैं जो एक गिनती स्वीकार करता है, तो आप एक संदर्भ पास नहीं कर सकते क्योंकि टाइपिंग जाँच नाम तुल्यता पर आधारित है , जो "सभी की जाँच की गई है जो इसके विपरीत हैं" रेंज हैं। यह पूर्णांकों तक सीमित नहीं है, आप एन्यूमरेटेड प्रकार या रिकॉर्ड का उपयोग कर सकते हैं। ( Archive.adaic.com/standards/83rat/html/ratl-04-03.html )
coredump

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

16

मुझे लगता है कि यह बहुत अच्छी तरह से एक एक्स / वाई प्रश्न हो सकता है। प्रश्न से मुख्य बिंदु, ...

मेरी प्रेरणा संकलन-समय शुद्धता सत्यापन के लिए प्रकार प्रणाली के उपयोग को अधिकतम कर रही है।

... और आपकी टिप्पणी से विस्तृत:

मैं एक दूसरे के लिए एक स्थानापन्न करने में सक्षम नहीं होना चाहता।

माफ करना, अगर मुझे कुछ याद आ रहा है, लेकिन ... अगर ये आपके उद्देश्य हैं, तो पृथ्वी पर आप विरासत के बारे में क्यों बात कर रहे हैं? निहित प्रतिस्थापन है ... जैसे ... इसकी पूरी बात। Y'know, Liskov प्रतिस्थापन सिद्धांत?

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

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

अतिरिक्त समस्या यह है कि यदि कोई व्यक्ति Int से विरासत में मिला था, तो आपके पास "int x = y + 2" (जहाँ Y व्युत्पन्न वर्ग है) जैसे निर्दोष कोड होंगे जो अब डेटाबेस में एक लॉग लिखते हैं, एक URL और एक को खोलता है किसी तरह एल्विस को जीवित किया। आदिम प्रकार सुरक्षित माना जाता है और अधिक या कम गारंटीड, अच्छी तरह से परिभाषित व्यवहार के साथ।

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

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


4

वर्चुअल डिस्पैच के साथ विरासत की अनुमति देने के लिए 8which को अक्सर एप्लिकेशन डिजाइन में काफी वांछनीय माना जाता है), एक रनटाइम प्रकार की जानकारी की आवश्यकता होती है। प्रत्येक ऑब्जेक्ट के लिए, ऑब्जेक्ट के प्रकार के संबंध में कुछ डेटा संग्रहीत करना होगा। एक आदिम, प्रति परिभाषा, इस जानकारी का अभाव है।

दो (प्रबंधित, वीएम पर चलने वाली) मुख्यधारा ओओपी भाषाएं हैं जो आदिमता की सुविधा देती हैं: सी # और जावा। कई अन्य भाषाओं में पहली जगह में आदिम नहीं होते हैं, या उन्हें अनुमति देने / उनका उपयोग करने के लिए समान तर्क का उपयोग करते हैं।

आदिम प्रदर्शन के लिए एक समझौता है। प्रत्येक ऑब्जेक्ट के लिए, आपको इसके ऑब्जेक्ट हेडर (जावा में, 64-बिट VMs पर आमतौर पर 2 * 8 बाइट्स) के लिए स्थान की आवश्यकता होती है, साथ ही इसके क्षेत्र, प्लस अंतिम पैडिंग (हॉटस्पॉट में, प्रत्येक ऑब्जेक्ट कई बाइट्स को अधिग्रहित करता है, जो एक मल्टीपल है) 8)। तो एक intवस्तु के रूप में केवल 4 बाइट्स (जावा में) के बजाय, कम से कम 24 बाइट्स मेमोरी की आवश्यकता होगी।

इस प्रकार, प्रदर्शन में सुधार करने के लिए आदिम प्रकार जोड़े गए। वे बहुत सारी चीजों को आसान बनाते हैं। a + bयदि दोनों के उपप्रकार हैं तो इसका क्या अर्थ है int? सही जोड़ चुनने के लिए किसी तरह की डिस्पैचिंग को जोड़ना होगा। इसका मतलब आभासी प्रेषण है। जोड़ के लिए एक बहुत ही सरल opcode का उपयोग करने की क्षमता होने के नाते, बहुत तेज है, और संकलन-समय अनुकूलन के लिए अनुमति देता है।

Stringएक और मामला है। जावा और C # दोनों में, Stringएक ऑब्जेक्ट है। लेकिन सी # में इसकी मुहर लगी है, और जावा में इसका फाइनल है। क्योंकि जावा और सी # मानक पुस्तकालयों दोनों को Stringअपरिवर्तनीय होने की आवश्यकता होती है , और उन्हें उप-वर्गीकृत करने से यह अपरिवर्तनीयता टूट जाएगी।

जावा के मामले में, VM बेहतर स्ट्रिंग्स के लिए अनुमति देता है, और उन्हें आंतरिक स्ट्रिंग्स और "पूल" कर सकता है। यह केवल तभी काम करता है जब स्ट्रिंग्स वास्तव में अपरिवर्तनीय हों।

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


1
यह उत्तर संक्षिप्त है ... संकीर्ण है। to allow inheritance, one needs runtime type information.असत्य। For every object, some data regarding the type of the object has to be stored.असत्य। There are two mainstream OOP languages that feature primitives: C# and Java.क्या, C ++ अभी मुख्यधारा नहीं है? मैं इसे इस्तेमाल करेंगे के रूप में के रूप में मेरे खंडन क्रम प्रकार की जानकारी है एक सी ++ अवधि। यह पूरी तरह से उपयोग dynamic_castया जब तक आवश्यक नहीं है typeid। और अगर आरटीटीआई ऑन, इनहेरिटेंस केवल अंतरिक्ष की खपत करता है, अगर एक क्लास में ऐसी virtualविधियाँ हैं जिनके लिए तरीकों की एक प्रति-क्लास तालिका प्रति उदाहरण इंगित की जानी चाहिए
अंडरस्कोर_ड

1
C ++ में वंशानुगत एक वीएम पर चलने वाली भाषाओं में पूरी तरह से अलग काम करता है। आभासी प्रेषण के लिए आरटीटीआई की आवश्यकता होती है, कुछ ऐसा जो सी ++ का मुख्य भाग नहीं था। वर्चुअल डिस्पैच के बिना वंशानुक्रम बहुत सीमित है और मुझे यह भी पक्का नहीं है कि अगर आपको वर्चुअल डिस्पैच के साथ विरासत की तुलना करनी चाहिए। इसके अलावा, C ++ में "ऑब्जेक्ट" की धारणा बहुत अलग है, फिर यह C # या Java में है। आप सही हैं, कुछ ऐसी बातें हैं जिन्हें मैं बेहतर तरीके से कह सकता हूं, लेकिन tbh को सभी काफी सम्मिलित बिंदुओं में शामिल करने से भाषा डिजाइन पर एक पुस्तक लिखने की जल्दी होती है।
पॉलिग्नोम

3
इसके अलावा, यह मामला नहीं है कि "वर्चुअल डिस्पैच को C ++ में RTTI की आवश्यकता है"। फिर से, केवल dynamic_castऔर typeinfoउस की आवश्यकता है। वर्चुअल डिस्पैच को व्यावहारिक रूप से ऑब्जेक्ट के ठोस वर्ग के लिए पॉइंटर के लिए एक पॉइंटर का उपयोग करके कार्यान्वित किया जाता है, इस प्रकार सही कार्यों को बुलाया जाता है, लेकिन आरटीटीआई में निहित प्रकार और संबंध के विस्तार की आवश्यकता नहीं होती है। सभी संकलक को यह जानना होगा कि क्या किसी वस्तु का वर्ग बहुरूपी है और यदि हां, तो इसका उदाहरण vptr क्या है। एक तुच्छ रूप से वस्तुतः भेजे गए वर्गों को संकलित कर सकता है -fno-rtti
अंडरस्कोर_ड

2
यह वास्तव में दूसरा तरीका है, आरटीटीआई को आभासी प्रेषण की आवश्यकता है। सचमुच -C ++ dynamic_castवर्चुअल डिस्पैच के बिना कक्षाओं पर अनुमति नहीं देता है । कार्यान्वयन का कारण यह है कि RTTI आम तौर पर एक व्यवहार्य के छिपे हुए सदस्य के रूप में लागू किया जाता है।
एमएसलेटर

1
@MilesRout C ++ में ओओपी के लिए जरूरी भाषा है, कम से कम कुछ हद तक नए मानक। कोई यह तर्क दे सकता है कि पुराने C ++ मानकों में कुछ चीजों की कमी है जो ओओपी भाषा के लिए आवश्यक हैं, लेकिन यह भी एक खिंचाव है। C ++ एक उच्च स्तरीय ओओपी भाषा नहीं है, क्योंकि यह कुछ चीजों पर अधिक प्रत्यक्ष, निम्न स्तर के नियंत्रण की अनुमति देता है, लेकिन फिर भी यह ओओपी को अनुमति देता है। (उच्च स्तर / निम्न स्तर यहाँ अमूर्त के संदर्भ में , अन्य भाषाएं जैसे प्रबंधित सिस्टम का अधिक सार दूर तो C ++, इसलिए उनका अमूर्त अधिक है)।
पॉलीग्नोम

4

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

ऐसा करने के लिए, 'ऑब्जेक्ट' में उनके प्रकार के लिए एक पॉइंटर होता है। यह एक ओवरहेड है: एक विधि में कोड जो Shapeपहले एक इंस्टेंस का उपयोग करता है , उस Area()कॉल की सही जानकारी को जानने से पहले, उस इंस्टेंस की प्रकार की जानकारी तक पहुंचना होता है ।

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

तो इसका जवाब है:

मुख्यधारा की मजबूत स्थिर ओओपी भाषाएँ आदिम विरासत को क्यों रोकती हैं?

है:

  • बहुत कम मांग थी
  • और इसने भाषा को बहुत धीमा कर दिया होगा
  • सबटाइपिंग को मुख्य रूप से एक प्रकार के विस्तार के रूप में देखा गया था, न कि बेहतर (उपयोगकर्ता-परिभाषित) स्थिर प्रकार की जाँच करने के लिए।

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

ऐसी भाषाएं भी हैं जो 'उपयोगकर्ता-परिभाषित प्रकारों' को अनुमति देती हैं, जो परिवर्तित नहीं होती हैं (या विनिमय) जो एक प्रकार क्या करती हैं, लेकिन स्थिर प्रकार की जाँच में मदद करें; coredump का उत्तर देखें।


एफ # माप की इकाइयाँ एक अच्छी सुविधा है, हालाँकि दुर्भाग्य से इसका नाम नहीं है। इसके अलावा यह केवल संकलन-समय है, इसलिए संकलित NuGet पैकेज का उपभोग करते समय सुपर उपयोगी नहीं है। सही दिशा, यद्यपि।
डेन

यह ध्यान रखना शायद दिलचस्प है कि "आयाम" "प्रकार 'के अलावा कोई संपत्ति नहीं है", यह आपके लिए उपयोग किए जा सकने वाले प्रकार से अधिक समृद्ध प्रकार है।
porglezomp

3

मुझे यकीन नहीं है कि मैं यहाँ कुछ देख रहा हूँ, लेकिन जवाब आसान है:

  1. आदिम की परिभाषा है: आदिम मूल्य वस्तु नहीं हैं, आदिम प्रकार वस्तु प्रकार नहीं हैं, आदिम वस्तु वस्तु प्रणाली का हिस्सा नहीं हैं।
  2. विरासत वस्तु प्रणाली की एक विशेषता है।
  3. एर्गो, आदिम विरासत में भाग नहीं ले सकते हैं

ध्यान दें कि वास्तव में केवल दो मजबूत स्थिर ओओपी भाषाएं हैं, जिनमें आदिम भी हैं , AFAIK: जावा और C ++। (वास्तव में, मैं बाद वाले के बारे में भी निश्चित नहीं हूं, मुझे C ++ के बारे में ज्यादा जानकारी नहीं है, और जब मैंने खोजा तो मुझे भ्रम हुआ।)

C ++ में, आदिम मूल रूप से C. से विरासत में मिली विरासत (यमक इच्छित) हैं, इसलिए वे ऑब्जेक्ट सिस्टम (और इस प्रकार विरासत) में भाग नहीं लेते हैं क्योंकि C में न तो कोई ऑब्जेक्ट सिस्टम है और न ही विरासत।

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

एक और बात यह है कि विरासत में नहीं होना वास्तव में आदिम लोगों के लिए अद्वितीय नहीं है। C In में, structनिहित रूप से विरासत में मिला है System.Objectऔर interfaces को लागू कर सकता है , लेकिन वे न तो इन्हें विरासत में दे सकते हैं और न ही classes या structs द्वारा विरासत में प्राप्त कर सकते हैं । इसके अलावा, sealed classes से विरासत में नहीं लिया जा सकता है। जावा में, final classes से विरासत में नहीं मिला है।

टीएल; डीआर :

मुख्यधारा की मजबूत स्थिर ओओपी भाषाएँ आदिम विरासत को क्यों रोकती हैं?

  1. आदिम वस्तु प्रणाली का हिस्सा नहीं हैं (परिभाषा के अनुसार, यदि वे थे, तो वे आदिम नहीं होंगे), विरासत का विचार वस्तु प्रणाली से बंधा हुआ है, आदिम विरासत के संदर्भ में एक विरोधाभास है
  2. आदिम अद्वितीय नहीं हैं, बहुत से अन्य प्रकारों को भी विरासत में नहीं दिया जा सकता है ( finalया sealedजावा या C not में, structC Sc में, स्केला case classमें)

3
एहम ... मुझे पता है कि इसका उच्चारण "सी शार्प" है, लेकिन, एहम
मिस्टर लिस्टर

मुझे लगता है कि आप C ++ की ओर से बहुत गलत हैं। यह बिल्कुल भी शुद्ध OO भाषा नहीं है। डिफ़ॉल्ट रूप से वर्ग विधियां नहीं हैं virtual, जिसका अर्थ है कि वे एलएसपी का पालन नहीं करते हैं। ईजी std::stringएक आदिम नहीं है, लेकिन यह बहुत ही एक और मूल्य के रूप में व्यवहार करता है। ऐसे मूल्य शब्दार्थ काफी सामान्य होते हैं, C ++ का पूरा STL हिस्सा इसे मान लेता है।
MSalters

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

1
@cmaster: स्काला में आदिम नहीं है, और इसका संख्यात्मक प्रदर्शन बिल्कुल जावा के समान है। क्योंकि, ठीक है, यह JVM आदिम intएस में पूर्णांक संकलित करता है , इसलिए वे बिल्कुल वैसा ही प्रदर्शन करते हैं। (स्काला-मूल उन्हें आदिम मशीन के रजिस्टरों में संकलित करता है। स्कैला.जैसे उन्हें आदिम ECAScript s में संकलित करता है Number।) रूबी में आदिम नहीं है, लेकिन YARV और Rubinius प्रिमाइटर मशीन एग्रीगेटर में संकलित करते हैं, JRuby उन्हें JVM प्राइमिटिव longएस में संकलित करता है । बहुत अधिक हर लिस्प, स्मॉलटाक या रूबी कार्यान्वयन वीएम में प्राइमेटिव का उपयोग करता है । यही कारण है कि प्रदर्शन अनुकूलन ...
Jörg W Mittag

1
... संबंधित: संकलक में, भाषा नहीं।
जोर्ग डब्ल्यू मित्तग

2

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

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

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


2

अमूर्त स्तर पर, आप अपनी इच्छित भाषा में कुछ भी शामिल कर सकते हैं।

कार्यान्वयन के स्तर पर, यह अपरिहार्य है कि उनमें से कुछ चीजें लागू करने के लिए सरल होंगी, कुछ जटिल होंगी, कुछ को तेजी से बनाया जा सकता है, कुछ धीमा होने के लिए बाध्य हैं, और इसी तरह। इसके लिए, डिजाइनरों को अक्सर कठोर निर्णय लेने और समझौता करने पड़ते हैं।

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

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

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

अमूर्त स्तर पर, यह विधि आपको जानकारी को खोए बिना stringएक objectचर में (संदर्भ) को एक चर में संग्रहीत करने की अनुमति देती है जो इसे ए बनाती है string। यह सभी प्रकार के काम के लिए ठीक है और आप यह भी कह सकते हैं कि यह कई मामलों में सुरुचिपूर्ण है।

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


1

सामान्य रूप में

यदि एक वर्ग सार है (रूपक: छेद वाला एक बॉक्स), तो यह ठीक है (यहां तक ​​कि कुछ उपयोगी होने के लिए भी आवश्यक है!) "छेद (ओं) को भरने के लिए", यही कारण है कि हम सार कक्षाएं उप-वर्ग करते हैं।

यदि एक वर्ग ठोस है (रूपक: एक बॉक्स पूर्ण), तो मौजूदा को बदलना ठीक नहीं है क्योंकि यदि यह भरा हुआ है, तो यह पूर्ण है। हमारे पास बॉक्स के अंदर कुछ और जोड़ने के लिए कोई जगह नहीं है, यही कारण है कि हमें कंक्रीट कक्षाओं को उप-वर्ग नहीं करना चाहिए।

आदिम के साथ

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



लिंक एक दिलचस्प डिजाइन राय है। मेरे लिए और अधिक सोच की जरूरत है।
डेन

1

आमतौर पर विरासत आप चाहते हैं शब्दार्थ नहीं है, क्योंकि आप अपने विशेष प्रकार स्थानापन्न नहीं कर सकते कहीं भी एक आदिम की उम्मीद है। अपने उदाहरण से उधार लेने के लिए, Quantity + Indexशब्दार्थ से कोई मतलब नहीं है, इसलिए एक विरासत संबंध गलत संबंध है।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.