मैं एक आधार वर्ग है 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कहीं भी इस्तेमाल नहीं किया जा सकता है, तो आप उन्हें इस तरह क्यों मानते हैं? अपने 'सैंडविच बनाने वालों' और 'एलियन-कॉन्टैक्टर्स' पर अलग से नज़र क्यों नहीं रखते?