क्या C ++ और Java में अमूर्त कक्षाओं / इंटरफेस के लिए एक अलग उपयोग तर्क है


13

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


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

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

1
संभवतः संबंधित: stackoverflow.com/q/1231985/484230 जावा में एब्सट्रैक्ट क्लासेस को प्राथमिकता देता है। C ++ के लिए यह कारण मुक्त कार्यों की मौजूदगी के कारण सही नहीं लगता है जो इंटरफ़ेस स्तर पर कार्यक्षमता जोड़ सकते हैं
मार्टिन

1
मुझे लगता है कि गोल्डन रूल "नॉन-लीफ क्लास एब्सट्रैक्ट" बनाना है, लेकिन इससे कोई "केवल शुद्ध" या "खाली" आवश्यकताएं नहीं बनती हैं।
केरेक एसबी

1
अगर यह आपके लिए काम करता है तो यह आपके लिए काम करता है। मैं वास्तव में यह नहीं देखता कि लोग क्यों एक बार घबरा जाते हैं क्योंकि उनका कोड अब नवीनतम रायों का पालन नहीं करता है।
जेम्स

जवाबों:


5

OOP की रचना और प्रतिस्थापन है।

C ++ में कई उत्तराधिकार, टेम्पलेट विशेषज्ञता, एम्बेडिंग और मूल्य / चाल / सूचक शब्दार्थ हैं।

जावा में एकल वंशानुक्रम और इंटरफेस, एम्बेडिंग और संदर्भ शब्दार्थ हैं।

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

जावा यह सब अपने ही java.lang.Objectनिहित पदानुक्रम से करता है। C ++ में एक पूर्वनिर्धारित आम रूट नहीं है, इसलिए आपको कम से कम इसे परिभाषित करना चाहिए, एक ही "चित्र" पर आने के लिए (लेकिन यह कुछ C ++ संभावनाओं को सीमित कर रहा है ...)।

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

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

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

OOP को जावा से C ++ की तुलना में यह मान लेना कि केवल एक और केवल OOP तरीका है, दोनों भाषाओं की क्षमताओं को सीमित कर रहा है।

जब तक जावा कोडिंग मुहावरों का कड़ाई से पालन करने के लिए C ++ मजबूर है, C ++ को जावा को C ++ के रूप में व्यवहार करने के लिए मजबूर करना है - जैसे भाषा जावा को भंग कर रहा है।

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


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

1
@Martin: "तकनीकी भावना" आप यहां पर ठीक है, में, लेकिन अगर आप की जरूरत polymorophism क्रम (क्योंकि instantiated वस्तुओं के वास्तविक प्रकार कार्यक्रम इनपुट पर निर्भर करता है) एक "रूट" ( 'a' है एक लेख, नहीं के लिए एक शॉर्टकट " एक और केवल ") वह है जो सभी वस्तु को" चचेरे भाई "बनाता है, और पदानुक्रम रन-टाइम-वॉक करने योग्य है। अलग-अलग जड़ें अलग - अलग वंशों की उत्पत्ति करती हैं जो एक-दूसरे से संबंधित नहीं हैं। यह "अच्छा" है या "बुरा" संदर्भ का विषय है, मुहावरा नहीं।
एमिलियो गरवाग्लिया

यह सच है। मुझे लगा कि आप पूरे सी ++ प्रोग्राम के लिए एक सामान्य जड़ को कृत्रिम रूप से छिद्रित करने की बात कर रहे थे और इसे दोष के रूप में देखा कि यह जावा की तुलना में मौजूद नहीं है। लेकिन अपने संपादन के बाद आप बिंदु को काफी स्पष्ट कर देते हैं। एक बार फिर धन्यवाद
मार्टिन

12

सिद्धांत दोनों भाषाओं के लिए है, लेकिन आप उचित तुलना नहीं कर रहे हैं। आपको जावा इंटरफ़ेस के साथ C ++ शुद्ध अमूर्त वर्गों की तुलना करनी चाहिए।

C ++ में भी, आपके पास अमूर्त कक्षाएं हो सकती हैं, जिनमें कुछ कार्य कार्यान्वित हैं, लेकिन शुद्ध सार वर्ग (कोई कार्यान्वयन नहीं) से प्राप्त होते हैं। जावा में, आपके पास समान सार वर्ग (कुछ कार्यान्वयनों के साथ) होंगे, जो इंटरफेस (कोई कार्यान्वयन नहीं) से प्राप्त हो सकते हैं।


तो आप c ++ में इंटरफ़ेस क्लास पर अमूर्त क्लास कब पसंद करेंगे। मैंने हमेशा c ++ में इंटरफ़ेस प्लस गैर-सदस्य कार्यों के लिए चुना।
मार्टिन

1
@ मर्टिन जो डिजाइन पर निर्भर करता है। असल में, हमेशा एक इंटरफ़ेस पसंद करते हैं। लेकिन " हमेशा " नियमों में अपवाद हैं ...
लुचियन ग्रिगोर

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

3
@ मर्टिन अच्छी तरह से मुक्त कार्य जावा में संभव नहीं हैं, इसलिए यह एक कारण हो सकता है, हाँ। अच्छी जगह! अपने सवाल का जवाब दिया! आप स्वयं एक उत्तर जोड़ सकते हैं, मुझे लगता है कि यह है।
लुचियन ग्रिगोर

4

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


0

कभी-कभी यह कुछ डिफ़ॉल्ट कार्यान्वयन के लिए समझ में आता है। उदाहरण के लिए एक जेनेरिक PrintError (string msg) विधि जो सभी उप वर्गों के लिए लागू है।

virtual PrintError(string msg) { cout << msg; }

यह वास्तव में आवश्यक होने पर ओवरराइड किया जा सकता है, लेकिन आप क्लाइंट को केवल जेनेरिक संस्करण को कॉल करने की अनुमति देकर कुछ परेशानी से बचा सकते हैं।

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