मैं एक baseclass, Statement
है, जो कई अन्य वर्गों से विरासत, आदि IfStatement
नाम है, WhereStatement
, ... क्या एक if
में एक परीक्षण प्रदर्शन करने के लिए सबसे अच्छा तरीका है यह निर्धारित करने के लिए कि किस प्रकार का Statement
वर्ग एक उदाहरण से लिया गया है?करता जावा एक है परीक्षा पद्धति "वर्ग की तरह है"
उत्तर
if (obj.getClass().isInstance(Statement.class)) {
doStuffWithStatements((Statement) obj));
}
इस तकनीक ("के रूप में instanceof" कीवर्ड के खिलाफ) के बारे में अच्छी बात यह है कि आप एक वस्तु के रूप आसपास परीक्षण स्तरीय पारित कर सकते हैं है। लेकिन, हाँ, इसके अलावा, यह "उदाहरण" के समान है।
नोट: मैंने जानबूझकर संपादकीयकरण से बचा है कि टाइप-इंस्टेंस-चेकिंग सही करने के लिए है या नहीं। हाँ, ज्यादातर मामलों में, polymorphism का उपयोग करना बेहतर है। लेकिन ओपी ने यही नहीं पूछा, और मैं सिर्फ उसके सवाल का जवाब दे रहा हूं।
if(object instanceof WhereStatement) {
WhereStatement where = (WhereStatement) object;
doSomething(where);
}
नोट इस तरह है कि कोड आमतौर पर मतलब है कि आपके आधार वर्ग एक बहुरूपी विधि याद आ रही है। यानी doSomething()
Statement
का एक तरीका होना चाहिए, संभवतः सार, जो उप-वर्गों द्वारा ओवरराइड किया गया है।
अतिरिक्त जानकारी के लिए धन्यवाद! मैं यह देखने के लिए देखूंगा कि डिजाइन में सुधार करने का एक साफ तरीका है या नहीं।उत्तर के लिए –
+1, हालांकि मैं जोड़ता हूं कि 'exampleof' में बहुत सारे वैध उपयोग हैं - यह हमेशा एक डिजाइन गंध नहीं है। उदाहरण के लिए, यदि 'doSomething()' केवल क्लॉज पर लागू होता है तो यह पैटर्न कृत्रिम रूप से स्टेटमेंट क्लास के 'कुछ()' भाग (जहां यह तर्कसंगत रूप से फिट नहीं होता) कृत्रिम रूप से बेहतर होता है। – mikera
'exampleof' कहां उपयोगी है इसका एक और उदाहरण है। जावाएफएक्स में, आपके पास एक फलक है। मुझे बाल नोड्स के पेड़ को पार करने की जरूरत है। 'getChildren()' नोड्स देता है। लेकिन अगर नोड्स में से एक एक फलक है, तो मुझे _its_ बच्चों को भी पार करने की ज़रूरत है। नोड में 'getChildren()' विधि नहीं है और यह एक को जोड़ने के लिए मेरा नहीं है। तो मुझे यह देखने के लिए कि मुझे नोड को एक फलक में डालने और अपने बच्चों को पार करने की आवश्यकता है, मुझे 'नोड इंस्टेंस फलक' का उपयोग करना होगा। – dwilliss
आपके प्रश्न का उत्तर उदाहरण है।
हालांकि, ध्यान रखें कि यदि आपके कोड को उदाहरण की आवश्यकता है, तो यह एक संकेत है कि आपके डिजाइन के साथ कुछ सही नहीं है। ऐसे कुछ मामले हैं जब उदाहरण उचित है, लेकिन वे अपवाद हैं। आमतौर पर, यदि आपके उप-वर्गों को अलग-अलग व्यवहार करने की आवश्यकता है, तो आपको() एस के बजाय बहुरूपता का उपयोग करना होगा।
एकमात्र चीज जो मैं आपकी प्रशंसा में जोड़ूंगा वह इंटरफेस द्वारा प्रोग्रामिंग का मजबूत सुझाव है। – monksy
यह ऑब्जेक्ट-उन्मुख तरीके से चीजों को करने का तरीका है, यह पुराने कोड/डेटा डिकोटॉमी पर फेंक रहा है। अब यह एक बुरी चीज नहीं है (यदि आप जानते हैं कि आप क्या कर रहे हैं) लेकिन इसे गैर-ऑब्जेक्ट-उन्मुख भाषाओं जैसे सी
उचित डिज़ाइन के साथ, आपको उस तरह के व्यवहार की आवश्यकता नहीं है । निर्माण के बजाय:
if (obj.getClass().isInstance(Statement.class)) {
doStuffWithStatements((Statement) obj));
}
(क्षमा याचना 'चोरी' अपने कोड के लिए benjismith के लिए), तुम सच में कर रही किया जाना चाहिए वस्तु ही अपनी ही गतिविधियों इस प्रकार के लिए जिम्मेदार:
obj.doStuff();
फिर प्रत्येक अलग obj
कक्षा में doStuff
के लिए अपनी परिभाषा होगी। ऐसा करने का यह सही तरीका है।
यदि केवल एक उप-वर्ग कर सकता है स्टफ (™ paxdiabio) और आपके पास ऑब्जेक्ट्स की एक सरणी है जिसमें से कुछ उप-वर्ग की एक सुपर क्लास हैं तो यह करने का बेहतर तरीका है (नो-ऑप्ड जोड़ने के बजाय सुपर-क्लास (एसएस) के लिए doStuff विधियां जो अर्थहीन हो सकती हैं (या "केवल गलत"))। – geowar
@geowar, यदि आपके पास गैर-सजातीय चीजों का संग्रह है, तो शायद उन्हें संग्रह में * नहीं होना चाहिए। या, कम से कम, आपको उस संग्रह पर इस तरह से पुन: प्रयास नहीं करना चाहिए जो करना चाहता है। इसे संभालने के कई तरीके हैं लेकिन इसे बदलते समय कक्षा के नाम या प्रकार को टाइप करना बहुत ही समस्याग्रस्त हो सकता है। विरासत/ओओ दुनिया में, सुपरक्लास के लिए एक शून्य कार्य करने के लिए जो इस मामले के लिए कुछ भी नहीं करना चाहता है वास्तव में एक ठोस समाधान है, जिससे प्रसंस्करण कोड बहुत साफ हो जाता है। – paxdiablo
कक्षा सेAssignableFrom (java.lang.Class) है आपका उत्तर है। http://download.oracle.com/javase/6/docs/api/java/lang/Class.html#isAssignableFrom(java.lang.Class)
इस प्रयास करें:
if (Statement.class.isInstance(obj)) {
doStuffWithStatements((Statement) obj));
}
Class.isInstance() के बाद विधि एक पैरामीटर के रूप एक वस्तु उदाहरण ले जाता है।
क्यों न केवल सरल उदाहरण का उपयोग करें? –
उदाहरण गेटो की तरह बुरा नहीं है। एक कारण यह है कि इसे भाषा में जोड़ा गया था और क्यों इसे बहिष्कृत नहीं किया गया है। –
+1 "के लिए संपादकीयकरण नहीं है कि टाइप-इंस्टेंस-जांच करना सही है या नहीं" –