क्या जावा विकास में आमतौर पर C # /। NET की तुलना में अधिक उपवर्ग शामिल होते हैं?


34

मैंने हाल ही में Android विकास देखना शुरू किया है। इसने मुझे जावा सॉफ्टवेयर विकास की दुनिया में वापस ला दिया है। पिछली बार जब मैंने जावा के साथ काम किया था, तो मैं मानता हूँ, मैं OOP को लगभग नहीं समझता था (मुझे लगता है) अब मैं करता हूँ।

अपने करियर में मुख्य रूप से C # का उपयोग करने के बाद, मैं इस बात में एक चौंकाने वाला अंतर देख रहा हूं कि कैसे Java और C # का उपयोग किया जाता है।

सी # में ऐसा लग रहा था कि ज्यादातर स्थितियों में विरासत से बचा जा सकता है। .NET फ्रेमवर्क के ठोस वर्गों का उपयोग करके आमतौर पर कार्य को पूरा किया जा सकता है ।

जावा में, मैं कोड नमूनों से जो इकट्ठा कर रहा हूं, ऐसा लगता है कि जावा फ्रेमवर्क कई इंटरफेस या अमूर्त वर्ग की आपूर्ति करता है जो तब डेवलपर द्वारा लागू / विस्तारित किए जाने के लिए होते हैं।

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

इसके अलावा, क्या यह केवल एंड्रॉइड एसडीके तक सीमित है या यह ओओपी के लिए एक जावा-वाइड दृष्टिकोण है?

या दूसरे तरीके से डालें,

इन दो भाषाओं के डिज़ाइन के बारे में ऐसा क्या है जो (प्रोत्साहित करने के लिए) अन्य की तुलना में अधिक या कम विरासत का उपयोग करता है?

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


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

1
@MathewFoscarini यह केवल आपकी राय है । जावा परियोजनाओं में मैंने भाग लिया, डेवलपर्स एक प्लेग की तरह विरासत से बचने के लिए इच्छुक थे। यहां कुछ भी आधिकारिक नहीं, केवल मेरी राय । वाना चुनाव ?
gnat

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

1
@ThinkingMedia सामान्य तौर पर, जावा OSS ज़ीलोट्स / शुद्धतावादियों से आगे निकल गया है। शैक्षणिक सिद्धांत अति चिंताजनक हैं। । नेट डेवलपर्स व्यावहारिक हैं जो काम करवाने के बारे में चिंतित हैं। वे सबसे साफ कोड से अधिक काम करने वाले कोड को महत्व देते हैं।
एंडी

जवाबों:


31

यह सिर्फ स्टाइल को उबालने के लिए बहुत बड़ा अंतर प्रतीत होता है। इसके पीछे क्या कारण है?

मैं समझता हूँ कि यह काफी हद तक है है बस एक शैलीगत निर्णय। खैर, शायद शैली नहीं, लेकिन भाषा / वातावरण के मुहावरे। जावा मानक लाइब्रेरी डेवलपर्स ने डिज़ाइन दिशानिर्देशों के एक सेट का पालन किया और .NET डेवलपर्स दूसरे (हालांकि उनके पास यह देखने की क्षमता थी कि जावा का दृष्टिकोण कैसे काम करता है)।

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

  1. .NET ने बहुत पहले गैर-जेनेरिक कोड लागू होने से पहले, अपने जीवनकाल में जेनरिक की शुरुआत की। विशेषज्ञ चीजों को टाइप करने के लिए बहुत सारी विरासत है।

  2. एक बड़ा बदलाव यह था कि .NET समर्थित प्रतिनिधि थे। जावा में आप चर कार्यक्षमता के सबसे बुनियादी की आपूर्ति करने के लिए (अनाम) विरासत के साथ फंस गए हैं। यह अपेक्षाकृत बड़े अंतर की ओर जाता है कि कैसे कोड में या तो प्रतिनिधियों का लाभ लेने के लिए या जावा में इसे करने के लिए आवश्यक अजीब विरासत संरचनाओं से बचने के लिए डिज़ाइन किया गया है।


3
मुझे लगता है कि यह उत्तर बहुत प्रशंसनीय व्याख्या प्रस्तुत करता है। विशेष रूप से प्रतिनिधियों के स्थान पर अनाम विरासत के बारे में बात। मैंने इसे बहुत देखा है। धन्यवाद।
21

3
अनाम प्रकार और लैम्ब्डा वाक्यविन्यास / अभिव्यक्ति पेड़ों को न भूलें जो .NET 3.5 में पेश किए गए थे। और निश्चित रूप से .NET 4. में ऑप्ट-इन डायनामिक टाइपिंग है। यह लगभग निर्विवाद रूप से एक मिश्रित-प्रतिमान भाषा है, न कि वस्तु-उन्मुख।
एरॉन

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

6

ये बहुत अलग भाषाएं हैं, खासकर इस क्षेत्र में। मान लीजिए कि आपके पास एक वर्ग है। इस मामले में, हम इसे एक उपयोगकर्ता नियंत्रण बना देंगे, एक टेक्स्टबॉक्स जैसा कुछ। इसे UIControl कहें। अब हम इसे दूसरी कक्षा में रखना चाहते हैं। इस मामले में, चूंकि हम अपने उदाहरण के लिए UI का उपयोग कर रहे हैं, इसलिए हम इसे क्लेवरपैनल क्लास कहेंगे। हमारा क्लेवरपैनल उदाहरण विभिन्न कारणों से अपने यूआईसीओंट्रोल उदाहरण के बारे में जानना चाहता है। यह कैसे करना है?

सी # में, मूल दृष्टिकोण विभिन्न घटनाओं की जांच करना है, ऐसे तरीकों की स्थापना करना जो प्रत्येक दिलचस्प घटना को ट्रिगर करने पर निष्पादित करेंगे। जावा में, जिसमें घटनाओं की कमी होती है, सामान्य समाधान एक वस्तु को विभिन्न "घटना" से निपटने के तरीकों को पास करने के लिए होता है, एक UIControl विधि:

boolean  stillNeedIt =  ... ;
uiControl.whenSomethingHappens( new DoSomething()  {
    public void resized( Rectangle r )  { ... }
    public boolean canICloseNow()  { return !stillNeedIt; }
    public void closed()  { ... }
    ...
} );

अब तक, C # और Java के बीच का अंतर गहरा नहीं है। हालाँकि, हमारे पास DoSomething इंटरफ़ेस है जिसकी C # में आवश्यकता नहीं है। इसके अलावा, इस इंटरफ़ेस में बहुत सी विधियाँ शामिल हो सकती हैं जिनकी अधिकांश समय आवश्यकता नहीं होती है। C # में, हम केवल उस ईवेंट को हैंडल नहीं करते हैं। जावा में, हम एक वर्ग बनाते हैं जो सभी इंटरफ़ेस विधियों, DoSomethingAdapter के लिए एक अशक्त कार्यान्वयन प्रदान करता है। अब हम DoSomething को DoSomethingAdapter की जगह लेते हैं और हमें एक स्वच्छ संकलन के लिए किसी भी तरीके को लिखने की आवश्यकता नहीं है। हम कार्यक्रम को सही तरीके से पूरा करने के लिए जरूरी तरीकों को खत्म करते हैं। इसलिए हमें अंत में एक इंटरफेस की जरूरत है और जावा में इनहेरिटेंस का उपयोग करके मिलान करने के लिए कि हमने C # में घटनाओं के साथ क्या किया।

यह एक उदाहरण है, एक व्यापक चर्चा नहीं है, लेकिन यह मूल बातों को बताता है कि जावा में सी # के विपरीत इतना वंशानुक्रम क्यों है।

अब, जावा इस तरह से काम क्यों करता है? लचीलापन। जब वस्तु को पास किया गया था तबसेहेलिंगहैपेंस क्लीवरपैनल को पूरी तरह से कहीं और से पारित किया जा सकता था। यह कुछ हो सकता है कि कई क्लेवरपैनल उदाहरणों को अपने यूआईसीओंट्रोल जैसी वस्तुओं को पास करना चाहिए ताकि कहीं क्लीवरविंड ऑब्जेक्ट को सहायता मिल सके। या UIControl इसे अपने घटकों में से एक को सौंप सकता है ।

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

public class BigClass implements DoSomething  {
    ...many long methods...
    protected int getDiameter()  { return 5; }
}

फिर क्लीवरप्लानेल में:

uiControl.whenSomethingHappens( new BigClass()  {
    @Override
    public int getDiameter()  { return UIPanel.currentDiameter; }
} );

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

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

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

फिर, यह एक व्यापक चर्चा नहीं है; मैं यहां सिर्फ सतह को खुरच रहा हूं। लेकिन हां, जावा और C # के बीच इनहेरिटेंस का उपयोग कैसे किया जाता है , इसमें एक चौंकाने वाला अंतर है। वे इस संबंध में, बहुत अलग भाषाएं हैं। यह आपकी कल्पना नहीं है।


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

-2

जावा और C # के बीच विरासत को संभालने के तरीके में बिल्कुल कोई अंतर नहीं है। जब आप वास्तव में वंशानुक्रम या रचना का उपयोग करेंगे तो निश्चित रूप से एक डिजाइन निर्णय है और किसी भी तरह से कुछ ऐसा नहीं है जो जावा या सी # को प्रोत्साहित या हतोत्साहित करता है। मैं कृपया इस लेख को पढ़ने का सुझाव दूंगा ।

आशा है कि मैंने मदद की!


5
आप स्वयं भाषाओं के बारे में बात कर रहे हैं, लेकिन मुझे लगता है कि सवाल पुस्तकालयों और सामान्य उपयोग के बारे में भी है।
20

3
लेकिन वहाँ हैं भाषा के बाकी हिस्सों में quirks है कि जावा में अतिरिक्त विरासत प्रोत्साहित करते हैं; राल्फचैपिन का उत्तर देखें
इज़्काटा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.