मैं एक आधार वर्ग है Base
। इसके दो उपवर्ग हैं, Sub1
और Sub2
। प्रत्येक उपवर्ग में कुछ अतिरिक्त विधियाँ हैं। उदाहरण के लिए, Sub1
है Sandwich makeASandwich(Ingredients... ingredients)
, और Sub2
है boolean contactAliens(Frequency onFrequency)
।
चूंकि ये विधियां अलग-अलग पैरामीटर लेती हैं और पूरी तरह से अलग चीजें करती हैं, वे पूरी तरह से असंगत हैं, और मैं इस समस्या को हल करने के लिए केवल बहुरूपता का उपयोग नहीं कर सकता।
Base
अधिकांश कार्यक्षमता प्रदान करता है, और मेरे पास Base
वस्तुओं का एक बड़ा संग्रह है । हालांकि, सभी Base
वस्तुओं या तो एक कर रहे हैं Sub1
या एक Sub2
, और कभी कभी मुझे पता है कि जो वे कर रहे हैं की जरूरत है।
यह निम्नलिखित करने के लिए एक बुरे विचार की तरह लगता है:
for (Base base : bases) {
if (base instanceof Sub1) {
((Sub1) base).makeASandwich(getRandomIngredients());
// ... etc.
} else { // must be Sub2
((Sub2) base).contactAliens(getFrequency());
// ... etc.
}
}
इसलिए मैं बिना कास्टिंग के इससे बचने की रणनीति के साथ आया। Base
अब ये तरीके हैं:
boolean isSub1();
Sub1 asSub1();
Sub2 asSub2();
और हां, Sub1
इन तरीकों को लागू करता है
boolean isSub1() { return true; }
Sub1 asSub1(); { return this; }
Sub2 asSub2(); { throw new IllegalStateException(); }
और Sub2
उन्हें विपरीत तरीके से लागू करता है।
दुर्भाग्य से, अब Sub1
और Sub2
इन विधियों के अपने एपीआई में हैं। इसलिए मैं यह कर सकता हूं, उदाहरण के लिए, पर Sub1
।
/** no need to use this if object is known to be Sub1 */
@Deprecated
boolean isSub1() { return true; }
/** no need to use this if object is known to be Sub1 */
@Deprecated
Sub1 asSub1(); { return this; }
/** no need to use this if object is known to be Sub1 */
@Deprecated
Sub2 asSub2(); { throw new IllegalStateException(); }
इस प्रकार, यदि वस्तु को केवल a के रूप में जाना जाता है Base
, तो ये विधियाँ बिना किसी को बताए की जाती हैं, और इसका उपयोग खुद को "अलग" करने के लिए किया जा सकता है, ताकि मैं इस पर उपवर्ग के तरीकों को लागू कर सकूं। यह मुझे एक तरह से सुरुचिपूर्ण लगता है, लेकिन दूसरी ओर, मैं एक वर्ग से "हटाने" के तरीके के रूप में डिप्रेस्ड एनोटेशन का दुरुपयोग कर रहा हूं।
चूंकि एक Sub1
उदाहरण वास्तव में एक आधार है, इसलिए यह इनकैप्सुलेशन के बजाय विरासत का उपयोग करने के लिए समझ में आता है। क्या मैं अच्छा कर रहा हूँ? क्या इस समस्या को हल करने का एक बेहतर तरीका है?
instanceof
एक तरह से जिसमें बहुत सारे टाइपिंग की आवश्यकता होती है, त्रुटि-प्रवण है, और अधिक उपवर्गों को जोड़ना कठिन बनाता है।
Sub1
और Sub2
कहीं भी इस्तेमाल नहीं किया जा सकता है, तो आप उन्हें इस तरह क्यों मानते हैं? अपने 'सैंडविच बनाने वालों' और 'एलियन-कॉन्टैक्टर्स' पर अलग से नज़र क्यों नहीं रखते?