2010-10-23 16 views
21

मैं Programming Scala पढ़ रहा हूं। अध्याय 4 की शुरुआत में, लेखक टिप्पणी करता है कि जावा स्थैतिक तरीकों का समर्थन करता है, जो "गैर-शुद्ध ओओ अवधारणाएं" नहीं हैं। ऐसा क्यों है?स्थिर ओओ अभ्यास क्यों नहीं माना जाता है?

+6

मुझे यकीन नहीं है कि "गैर-शुद्ध" तुरंत खराब अभ्यास से जुड़ा होना चाहिए। – mellowsoon

+0

बुरा व्यवहार नहीं है। लेखक के अनुसार, बस अच्छा अभ्यास नहीं है। – Mike

+1

क्या लेखक कोई तर्क नहीं देता है? –

उत्तर

17

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

ध्यान दें कि स्थिर विधियों के पास "super" तक पहुंच नहीं है, जिसका अर्थ है कि स्थिर तरीकों को किसी भी वास्तविक अर्थ में ओवरराइड नहीं किया जा सकता है। असल में, उन्हें केवल छुपाया नहीं जा सकता है, केवल छुपाया जा सकता है। इसे आज़माएं:

public class Test { 
    public static int returnValue() { 
     return 0; 
    } 

    public static void main(String[] arg) { 
     System.out.println(Test.returnValue()); 
     System.out.println(Test2.returnValue()); 
     Test x = new Test2(); 
     System.out.println(x.returnValue()); 
    } 
} 


public class Test2 extends Test { 
    public static int returnValue() { 
     return 1; 
    } 
} 

जब आप इसे चलाते हैं, तो आपको वह उम्मीद नहीं मिलेगी जो आप उम्मीद करते हैं। Test.returnValue() आपको जो उम्मीद है वह देता है। Test2.returnValue()छिपा सुपरक्लास में एक ही नाम की विधि (यह इसे ओवरराइड नहीं करता है), और यह आपको जो अपेक्षा करता है वह देता है।

एक मूर्खतापूर्वक उम्मीद कर सकता है कि "गैर-स्थैतिक" पॉलिमॉर्फिज्म का उपयोग करने के लिए एक स्थिर विधि को बुलाए। यह नहीं है जो भी वर्ग वैरिएबल घोषित किया गया है वह विधि को देखने के लिए उपयोग किया जाता है। यह खराब रूप है क्योंकि कोई व्यक्ति कोड को वास्तव में जो कुछ करता है उससे कुछ अलग करने की अपेक्षा कर सकता है।

इसका मतलब यह नहीं है, "स्थैतिक तरीकों का उपयोग न करें!"इसका मतलब यह है कि आपको उन उदाहरणों के लिए स्थैतिक तरीकों का उपयोग आरक्षित करना चाहिए जहां आप वास्तव में क्लास ऑब्जेक्ट को विधि के मालिक बनना चाहते हैं, न कि एक सिंगलटन बनाने का आलसी तरीका।

+0

यह उत्तर शायद मैंने जो देखा है उससे सबसे अधिक समझ में आता है। ट्रिनिटी अवधारणाओं में से एक तोड़ना निश्चित रूप से अनाज के खिलाफ चला जाता है। – Mike

+0

ऐसा नहीं है कि मैं इस पर विवाद कर रहा हूं लेकिन उदाहरण जो आप दिखाते हैं केवल जावा पर लागू होता है? आईआईआरसी, जावा एकमात्र ओओ भाषा है (जिसे मैंने सामना किया है) जो वर्ग के उदाहरण के माध्यम से स्थिर कार्यों को कॉल करने की अनुमति देता है। –

+0

@ जेफ: वीबी.नेट भी इस गैरकानूनी व्यवहार की अनुमति देता है। –

1

स्टेटिक विधियां इतनी शुद्ध ओओ अवधारणाएं नहीं हैं क्योंकि उन्हें वास्तव में उनके साथ जुड़े किसी वस्तु के बिना बुलाया जा सकता है। आप कक्षा का उपयोग करते हैं। आप उन्हें Classname.method(...);

+0

क्या होगा यदि मैं रूबी जैसे कुछ का उपयोग कर रहा हूं, जो कक्षाओं के रूप में वस्तुओं और स्थिर आमंत्रण का समर्थन करता है? एक वस्तु वास्तव में स्थिर कॉल से जुड़ी होगी। – Mike

+0

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

0

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

--Cheers

24

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

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

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

+0

ध्यान रखें कि मैंने कभी नहीं कहा था कि यह एक बुरा अभ्यास था, इसलिए मेरा प्रश्न वास्तव में उत्तर नहीं दिया गया था। ;) – Mike

+2

सच है। दूसरी तरफ, मैंने बहुत अधिक कोड देखा है जहां सबकुछ एक सिंगलटन है और सबकुछ स्थिर है। इस प्रकार का कोड आमतौर पर संशोधित करना अधिक कठिन होता है, विस्तार करना अधिक कठिन होता है, ऐसा कुछ करने के लिए रीमल्ड करना मुश्किल होता है जिसे मूल रूप से करने का इरादा नहीं था। उस ने कहा, बहुत से लोग इस बारे में बहुत ही विडंबनात्मक हैं। – Eddie

+0

असल में, 'atan2' फ़ंक्शन सकारात्मक एक्स-अक्ष में * एकल बिंदु * के कोण के रेडियंस को मापता है। दूसरे शब्दों में, इसे पहले स्थान पर दो संख्या तर्क नहीं लेना चाहिए, इसे एक बिंदु बिंदु तर्क लेना चाहिए। जो, ओओ शर्तों में, एक बिंदु वस्तु पर एक विधि के रूप में मॉडलिंग किया जा सकता है। –

40

ऑब्जेक्ट-ओरिएंटेशन लगभग तीन चीजें हैं :

  • संदेश,
  • स्थानीय प्रतिधारण और संरक्षण और राज्य प्रक्रिया के छिपने की, और
  • चरम देर बाध्यकारी सब बातों के
उन तीनों में से

। , सबसे महत्वपूर्ण एक संदेश है।

स्टेटिक विधियां कम से कम संदेश और देर से बाध्यकारी का उल्लंघन करती हैं।

संदेश का विचार है कि ओओ में, गणना स्वयं-निहित वस्तुओं के नेटवर्क द्वारा की जाती है जो एक-दूसरे को संदेश भेजते हैं। एक संदेश भेजना केवल संचार/गणना का तरीका है।

स्टेटिक विधियां ऐसा नहीं करती हैं। वे किसी भी वस्तु से जुड़े नहीं हैं। सामान्य परिभाषा के अनुसार, वे वास्तव में पर सभी पर विधियां नहीं हैं। वे वास्तव में सिर्फ प्रक्रियाएं हैं। जावा स्थैतिक विधि Foo.bar और एक बेसिक सबराउटिन FOO_BAR के बीच बहुत अंतर नहीं है।

देर से बाध्यकारी के लिए: इसके लिए एक और आधुनिक नाम गतिशील प्रेषण है। स्टेटिक विधियां इसका उल्लंघन करती हैं, वास्तव में, यह भी उनके नाम पर है: स्थिर विधियां।

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

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

+0

यह भी एक उत्कृष्ट जवाब है। इच्छा है कि मैं एक से अधिक स्वीकार कर सकता हूं। धन्यवाद। – Mike

1

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

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

1) पुन: प्रयोज्य से रोकता है:

स्टेटिक तरीकों ओवरराइड नहीं किया जा सकता

0

स्टेटिक विधियों के नीचे कारणों की वजह से अच्छा OO अभ्यास माना जाता है। इसका उपयोग इंटरफ़ेस में नहीं किया जा सकता है।

2) वस्तु लाइफटाइम बहुत लंबा है:

स्टेटिक तरीकों एक लॉग समय के लिए स्मृति में रहना और उसके कचरा संग्रहण लंबा समय लगता है। डेवलपर का स्टेटिक चर को नष्ट करने या बनाने पर नियंत्रण नहीं है। स्थिर चर के अत्यधिक उपयोग मेमोरी ओवरफ्लो के परिणामस्वरूप हो सकता है।

3) इसके अलावा, कुछ अन्य बिंदुओं:

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

संबंधित मुद्दे