2011-03-04 11 views
6

अभी मैं निम्नलिखित है:क्या आप रनटाइम पर एक इंटरफ़ेस को लागू करने में जावा ऑब्जेक्ट को मजबूर कर सकते हैं?

1) एक जावा इंटरफ़ेस।

2) एक ठोस जावा वर्ग करता है नहीं ऊपर उल्लिखित इंटरफ़ेस को लागू है, लेकिन तरीकों इंटरफ़ेस में निर्धारित से हर एक मिलान एक विधि हस्ताक्षर शामिल नहीं करता है।

चूंकि मैं आइटम 2 के कार्यान्वयन को बदलने में असमर्थ हूं, इसलिए मैं यह जानना चाहता हूं कि एक विधि बनाने के लिए संभव है कि आइटम 1 के उदाहरण को एक तर्क के रूप में स्वीकार करें आइटम 2 क्लास कास्ट अपवाद के बिना स्वीकार करें।

ऐसा लगता है कि वसंत में विभिन्न बुनाई/जबरन/एओपी यांत्रिकी को यह संभव बनाना चाहिए, लेकिन मुझे नहीं पता कि यह कैसे करना है।

क्या ऐसा करने का कोई तरीका है?

+2

क्या आप सिर्फ एक रैपर नहीं बना सकते हैं जो इंटरफ़ेस लागू करता है और आगे सबकुछ करता है? – Erik

+0

रैपर –

+0

के लिए +1 क्या किसी को पता है कि इस पैटर्न के लिए कोई नाम है (क्या ओपी चाहता है) जहां आप किसी ऑब्जेक्ट पर मिलान हस्ताक्षर वाले ऑब्जेक्ट को 'कास्टिंग' कर रहे हैं? –

उत्तर

7

क्या आप रनटाइम पर एक इंटरफ़ेस को लागू करने में जावा ऑब्जेक्ट को मजबूर कर सकते हैं?

हां, dynamic proxies या बाइट-कोड पुनर्लेखन का उपयोग कर। हालांकि, मेरे लिए ऐसा लगता है कि आप Adapter pattern की तलाश में हैं।

+0

क्या आपके पास ऐसा करने के तरीके पर किसी दस्तावेज़ के लिंक हैं, अधिमानतः घोषणात्मक रूप से? – dskiles

+0

@ डिस्कील्स, प्रॉक्सी का उपयोग करके, ['जावा डायनामिक प्रॉक्सी - कैसे संदर्भ कंक्रीट क्लास' देखें] (http://stackoverflow.com/questions/5167185/java-dynamic-proxy-how-reference-concrete-class/5167267#5167267)। एओपी दृष्टिकोण के लिए [पहलू] (http://www.eclipse.org/aspectj/) या [cglib] (http://cglib.sourceforge.net/) परियोजनाओं पर एक नज़र डालें। –

+0

+1 - अच्छी सलाह। – Nilesh

3

आप ऑब्जेक्ट को इंटरफ़ेस को स्वयं लागू नहीं कर सकते हैं, लेकिन आप किसी ऑब्जेक्ट को बनाने के लिए Proxy जैसे कुछ का उपयोग कर सकते हैं जो इंटरफ़ेस लागू करता है और मूल ऑब्जेक्ट पर उपयुक्त सदस्य को कॉल करने के लिए प्रतिबिंब का उपयोग करता है।

बेशक

, अगर यह सिर्फ एक इंटरफ़ेस प्रकार और एक ठोस प्रकार है, आप आसानी से इस तरह के एक आवरण प्रॉक्सी का उपयोग किए बिना लिख ​​सकते हैं:

public class BarWrapper implements Foo 
{ 
    private final Bar bar; 

    public BarWrapper(Bar bar) 
    { 
     this.bar = bar; 
    } 

    public int someMethodInFoo() 
    { 
     return bar.someMethodInFoo(); 
    } 

    // etc 
} 
0

असल में वहाँ दो तरीके हैं:

क) अपने ऑब्जेक्ट के आस-पास एक सजावट लिखें जो आपके ऑब्जेक्ट पर इंटरफ़ेस और प्रतिनिधियों को लागू करता है (यह या तो प्रॉक्सी का उपयोग करके या एक साधारण एडाप्टर क्लास लिखकर किया जा सकता है)

बी) बाइट कोड बदलें। वसंत एओपी ऐसा करने के लिए पर्याप्त शक्तिशाली नहीं है, लेकिन AspectJ कंपाइलर है।

declare parents: YourClass implements YourInterface; 

जब से तुम वर्ग स्रोत के लिए पहुँच नहीं है या तो आप का उपयोग लोड समय बुनाई या पुस्तकालय जार बुनाई करना होगा: यह एक एक लाइनर है। यह सब AspectJ in ActionRamnivas Laddad

1

द्वारा अच्छी तरह से समझाया गया है यह एडाप्टर के साथ हल करने योग्य होना चाहिए।

void someMethod(YourInterface param) {} 

void test() { 
    YourClass object = getFromSomewhere(); 
    someMethod(YourAdapter(object)); 
} 
+0

मेरे पास अब यही है, लेकिन यदि संभव हो तो मैं एडाप्टर चरण को छोड़ने की उम्मीद कर रहा था। – dskiles

+0

फिर आपको कुछ अन्य उत्तरों में उल्लिखित प्रॉक्सी दृष्टिकोण के साथ जाना होगा, अगर आपको प्रतिबिंब नहीं लगता है। –

0

आप शायद कर सकते हैं: एक विधि है कि YourInterface उम्मीद और प्रकार YourClass की एक वस्तु को देखते हुए

class YourAdapter implements YourInterface { 

    private final YourClass realObject; 

    public YourAdapter(YourClass realObject) { 
     this.realObject = realObject; 
    } 

    @Override 
    public methodFromInterface() { 
     // you said the class has the same method signatures although it doesn't 
     // implement the interface, so this should work fine: 
     realObject.methodFromInterface(); 
    } 

    // ....... 

} 

अब: एक अन्य वर्ग में परिभाषित किया गया है कि वास्तविक वस्तु के लिए अपने इंटरफेस और प्रतिनिधियों को लागू करता है आप Javassist के साथ क्या चाहते हैं, या तो वर्ग के बाइटकोड को संशोधित करके या रैपर/प्रॉक्सी क्लास बनाकर।

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

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