जावा प्रतिनिधि


194

क्या जावा भाषा में प्रतिनिधि विशेषताएं हैं, कैसे सी # प्रतिनिधियों के लिए समर्थन है?


20
@ सुमा यह एक डुप्लिकेट कैसे हो सकता है यदि आपके द्वारा उल्लिखित प्रश्न इस एक साल बाद पोस्ट किया गया था?
i

1
जावा 8 में प्रतिनिधियों की तरह एक विशेषता है। इसे लंबदा कहा जाता है।
त्बोद

4
@tbodt अधिक सही होने के लिए, जावा 8 में एक विशेषता काफी हद तक प्रतिनिधियों की तरह है। इसे कार्यात्मक इंटरफेस कहा जाता है । लैम्ब्डा इस तरह के प्रतिनिधि उदाहरण (गुमनाम रूप से) बनाने का एक तरीका है।
नवफाल

3
नीचे दिए गए उत्तर प्री-जावा 8 से हैं। पोस्ट जावा 8 इस धागे में उत्तर देखें: stackoverflow.com/questions/20311779/…
माइकल लॉयड ली एमएलक

@nffal, +1, लेकिन इससे भी अधिक सही होने के लिए, जावा 7 और नीचे पहले से ही एक विशेषता काफी हद तक प्रतिनिधियों की तरह है। इसे प्लेन इंटरफेस कहा जाता है।
पचेरियर

जवाबों:


152

नहीं वास्तव में कोई नहीं।

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

आपको यह लेख भी रोचक / उपयोगी लग सकता है : A Java Programmer C # Delegates (@kut.org) में दिखता है


3
इंटरफ़ेस के एकमात्र सदस्य फ़ंक्शन के रूप में इनवोक () के साथ समाधान वास्तव में अच्छा है।
स्टीफन रोलैंड

1
लेकिन मेरे उदाहरण देखने के लिए यहाँ एक क्या करेंगे, जावा 7 में भी, एक सी # प्रतिनिधि के बराबर पूरा करने के लिए।
टूलमेकरसैट

63

आपके द्वारा दिए गए अर्थ के आधार पर, आप रणनीति पैटर्न का उपयोग करके एक समान प्रभाव (किसी विधि के आसपास से गुजरना) प्राप्त कर सकते हैं।

एक लाइन के बजाय इस तरह एक नामित विधि हस्ताक्षर की घोषणा:

// C#
public delegate void SomeFunction();

एक इंटरफ़ेस घोषित करें:

// Java
public interface ISomeBehaviour {
   void SomeFunction();
}

विधि के ठोस कार्यान्वयन के लिए, उस वर्ग को परिभाषित करें जो व्यवहार को लागू करता है:

// Java
public class TypeABehaviour implements ISomeBehaviour {
   public void SomeFunction() {
      // TypeA behaviour
   }
}

public class TypeBBehaviour implements ISomeBehaviour {
   public void SomeFunction() {
      // TypeB behaviour
   }
}

फिर जहाँ भी आपको SomeFunctionC # में एक प्रतिनिधि मिला होगा, उसके ISomeBehaviourबजाय एक संदर्भ का उपयोग करें:

// C#
SomeFunction doSomething = SomeMethod;
doSomething();
doSomething = SomeOtherMethod;
doSomething();

// Java
ISomeBehaviour someBehaviour = new TypeABehaviour();
someBehaviour.SomeFunction();
someBehaviour = new TypeBBehaviour();
someBehaviour.SomeFunction();

अनाम आंतरिक कक्षाओं के साथ, आप अलग-अलग नामित वर्गों की घोषणा करने से भी बच सकते हैं और लगभग उन्हें वास्तविक प्रतिनिधि कार्यों की तरह व्यवहार कर सकते हैं।

// Java
public void SomeMethod(ISomeBehaviour pSomeBehaviour) {
   ...
}

...

SomeMethod(new ISomeBehaviour() { 
   @Override
   public void SomeFunction() {
      // your implementation
   }
});

यह संभवतः केवल तब उपयोग किया जाना चाहिए जब कार्यान्वयन वर्तमान संदर्भ के लिए बहुत विशिष्ट है और पुन: उपयोग होने से लाभ नहीं होगा।

और फिर जावा 8 में निश्चित रूप से, ये मूल रूप से मेमने के भाव बन जाते हैं:

// Java 8
SomeMethod(() -> { /* your implementation */ });

6
+1। यह एक सभ्य समाधान है, और भविष्य में स्थिरता द्वारा क्षतिपूर्ति की भरपाई की जा सकती है।
नवाफाल

यह बहुत अच्छा है ... वर्तमान में एक परियोजना पर काम कर रहा हूं जहां मैं परियोजना की बाधाओं के कारण प्रतिबिंब का उपयोग करने में असमर्थ हूं और इस समाधान से काम खूबसूरती से हो जाता है :)
जोनाथन कैमर्ना

क्या जावा में इंटरफेस के लिए आई-प्रीफिक्स नामकरण सम्मेलन है? मैंने पहले नहीं देखा है
काइल डेलाने

36

लघु कथा: नहीं

परिचय

Microsoft Visual J ++ विकास वातावरण का नवीनतम संस्करण एक भाषा निर्माण का समर्थन करता है जिसे प्रतिनिधि या बाध्य विधि संदर्भ कहा जाता है । यह निर्माण, और नए कीवर्ड delegateऔर multicastइसका समर्थन करने के लिए पेश किए गए, जावा टीएम प्रोग्रामिंग भाषा का हिस्सा नहीं हैं, जो कि जावा भाषा विनिर्देश द्वारा निर्दिष्ट है और जेडीकेटीएम 1.1 सॉफ्टवेयर के लिए प्रलेखन में शामिल इनर क्लासेस विनिर्देश द्वारा संशोधित है ।

यह संभावना नहीं है कि जावा प्रोग्रामिंग भाषा कभी भी इस निर्माण को शामिल करेगी। सन 1996 में पहले से ही ध्यान से इसे अपनाने और कार्यशील प्रोटोटाइप को त्यागने की सीमा तक माना जाता था। हमारा निष्कर्ष यह था कि बाध्य विधि संदर्भ भाषा के लिए अनावश्यक और हानिकारक है। यह निर्णय बोरलैंड इंटरनेशनल के परामर्श से किया गया था, जिन्हें डेल्फी ऑब्जेक्ट पास्कल में बाध्य विधि संदर्भों के साथ पिछला अनुभव था।

हमारा मानना ​​है कि बाध्य विधि संदर्भ अनावश्यक हैं क्योंकि एक अन्य डिजाइन विकल्प, आंतरिक कक्षाएं , समान या बेहतर कार्यक्षमता प्रदान करती हैं। विशेष रूप से, आंतरिक कक्षाएं पूरी तरह से उपयोगकर्ता-इंटरफ़ेस इवेंट हैंडलिंग की आवश्यकताओं का समर्थन करती हैं, और इसका उपयोग कम से कम विंडोज फाउंडेशन कक्षाओं के रूप में व्यापक रूप से उपयोगकर्ता-इंटरफ़ेस एपीआई को लागू करने के लिए किया गया है।

हम मानते हैं कि बाध्य विधि संदर्भ हानिकारक हैं क्योंकि वे जावा प्रोग्रामिंग भाषा की सरलता और एपीआई की व्यापक वस्तु-उन्मुख चरित्र से अलग हैं। बाउंड मेथड रेफरेंस भी भाषा के सिंटैक्स और स्कूपिंग नियमों में अनियमितता का परिचय देता है। अंत में, वे वीएम प्रौद्योगिकियों में निवेश को कम कर देते हैं क्योंकि वीएम को अतिरिक्त और असमान प्रकार के संदर्भों और विधि लिंकेज को कुशलतापूर्वक संभालने की आवश्यकता होती है।


जैसा कि यह बताता है कि पैट्रिक ने आपको किन वर्गों से जोड़ा है, इसके बजाय आप आंतरिक कक्षाओं का उपयोग करना चाहते हैं।
SCDF

16
बढ़िया लेख। मैं उनकी "सरल" की परिभाषा को पसंद करता हूं: जावा एक सरल भाषा होने के लिए डिज़ाइन किया गया है जैसा कि "जावा के लिए कंपाइलर / वीएम लिखने के लिए सरल होना चाहिए" जबकि "अनदेखा करना" जावा को किसी व्यक्ति द्वारा लिखने / पढ़ने के लिए सरल होना चाहिए " । बहुत कुछ समझाता है।
जुओजस कोंवेंटविस

5
मुझे लगता है कि SUN ने एक बड़ी गलती की है। वे सिर्फ कार्यात्मक प्रतिमान से आश्वस्त नहीं हुए हैं, और यह सब है।
स्टीफन रोलैंड

7
@ जोजस: पायथन को किसी व्यक्ति द्वारा लिखना / पढ़ना सरल बनाया जाता है और यह लंबोदर कार्यों / प्रतिनिधियों को लागू करता है
स्टीफन रोलैंड

5
एक आर्काइव.ऑर्ग लिंक के साथ प्रतिस्थापित। इसके अलावा, यह वास्तव में बेवकूफ है, ओरेकल।
पैट्रिक

18

आप पढ़ी है यह :

डेलिगेट्स घटना-आधारित प्रणालियों में एक उपयोगी निर्माण है। अनिवार्य रूप से प्रतिनिधि वे ऑब्जेक्ट हैं जो किसी निर्दिष्ट ऑब्जेक्ट पर एक विधि प्रेषण को एन्कोड करते हैं। इस दस्तावेज़ से पता चलता है कि जावा भीतरी वर्ग कैसे इस तरह की समस्याओं के लिए एक अधिक सामान्य समाधान प्रदान करते हैं।

एक प्रतिनिधि क्या है? वास्तव में यह C ++ में उपयोग किए जाने वाले एक पॉइंटर टू मेम्बर फ़ंक्शन के समान है। लेकिन एक प्रतिनिधि को शामिल करने की विधि के साथ लक्ष्य वस्तु शामिल है। आदर्श रूप में यह कहना अच्छा होगा:

obj.registerHandler (ano.methodOne);

..और यह कि विधि मेथड किसी विशेष घटना को प्राप्त होने पर एओ पर कॉल किया जाएगा।

यह वही है जो डेलिगेट संरचना प्राप्त करती है।

जावा इनर क्लासेस

यह तर्क दिया गया है कि जावा यह कार्यक्षमता अनाम आंतरिक वर्गों के माध्यम से प्रदान करता है और इस प्रकार अतिरिक्त डेलिगेट निर्माण की आवश्यकता नहीं है।

obj.registerHandler(new Handler() {
        public void handleIt(Event ev) {
            methodOne(ev);
        }
      } );

पहली नज़र में यह सही लगता है लेकिन एक ही समय में एक उपद्रव। क्योंकि कई ईवेंट प्रोसेसिंग उदाहरणों के लिए डेलिगेट्स सिंटैक्स की सादगी बहुत आकर्षक है।

जनरल हैंडलर

हालाँकि, यदि इवेंट-आधारित प्रोग्रामिंग का उपयोग अधिक व्यापक रूप से किया जाता है, तो उदाहरण के लिए, सामान्य अतुल्यकालिक प्रोग्रामिंग वातावरण के एक हिस्से के रूप में, दांव पर अधिक है।

ऐसी सामान्य स्थिति में, केवल लक्ष्य विधि और लक्ष्य वस्तु उदाहरण को शामिल करना पर्याप्त नहीं है। सामान्य तौर पर आवश्यक अन्य पैरामीटर हो सकते हैं, जो कि घटना के हैंडलर के पंजीकृत होने पर संदर्भ में निर्धारित किए जाते हैं।

इस अधिक सामान्य स्थिति में, जावा दृष्टिकोण एक बहुत ही सुंदर समाधान प्रदान कर सकता है, खासकर जब अंतिम चर के उपयोग के साथ जोड़ा जाता है:

void processState(final T1 p1, final T2 dispatch) { 
  final int a1 = someCalculation();

  m_obj.registerHandler(new Handler() {
    public void handleIt(Event ev) {
     dispatch.methodOne(a1, ev, p1);
    }
  } );
}

फाइनल * फाइनल * फाइनल

आपका ध्यान गया?

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

इसके विपरीत, डेलिगेट निर्माण इस अधिक सामान्य आवश्यकता के लिए एक समाधान प्रदान नहीं करता है, और जैसे कि एक मुहावरे के रूप में खारिज किया जाना चाहिए, जिस पर डिजाइन आधारित हो सकते हैं।


13

मुझे पता है कि यह पोस्ट पुरानी है, लेकिन जावा 8 में लैम्ब्डा, और एक कार्यात्मक इंटरफ़ेस की अवधारणा को जोड़ा गया है, जो कि केवल अन्य विधि के साथ कोई भी इंटरफ़ेस है। साथ में ये C # प्रतिनिधियों को समान कार्यक्षमता प्रदान करते हैं। अधिक जानकारी के लिए यहां देखें, या सिर्फ Google Java Lambdas। http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html


5

नहीं, लेकिन वे परदे के पीछे और प्रतिबिंब का उपयोग करने योग्य हैं:

  public static class TestClass {
      public String knockKnock() {
          return "who's there?";
      }
  }

  private final TestClass testInstance = new TestClass();

  @Test public void
  can_delegate_a_single_method_interface_to_an_instance() throws Exception {
      Delegator<TestClass, Callable<String>> knockKnockDelegator = Delegator.ofMethod("knockKnock")
                                                                   .of(TestClass.class)
                                                                   .to(Callable.class);
      Callable<String> callable = knockKnockDelegator.delegateTo(testInstance);
      assertThat(callable.call(), is("who's there?"));
  }

इस मुहावरे के बारे में अच्छी बात यह है कि आप सत्यापित कर सकते हैं कि प्रत्यायोजित विधि मौजूद है, और आवश्यक हस्ताक्षर हैं, उस बिंदु पर जहां आप प्रतिनिधि बनाते हैं (हालांकि संकलन-समय पर नहीं, दुर्भाग्य से, हालांकि FindBugs प्लग-इन हो सकता है यहां मदद करें), फिर विभिन्न उदाहरणों को सौंपने के लिए इसे सुरक्षित रूप से उपयोग करें।

अधिक परीक्षणों और कार्यान्वयन के लिए जीथब पर कार्ग कोड देखें ।


2

मैंने प्रतिबिंब का उपयोग करके जावा में कॉलबैक / प्रतिनिधि समर्थन लागू किया है। विवरण और कार्य स्रोत मेरी वेबसाइट पर उपलब्ध हैं ।

यह काम किस प्रकार करता है

WithParms नाम के नेस्टेड क्लास के साथ कॉलबैक नाम का एक सिद्धांत वर्ग है। जिस API को कॉलबैक की आवश्यकता है, वह एक कॉलबैक ऑब्जेक्ट को एक पैरामीटर के रूप में लेगा और यदि neccessary है, तो एक कॉलबैक .Parms विधि चर के रूप में बनाएं। चूंकि इस ऑब्जेक्ट के बहुत सारे अनुप्रयोग पुनरावर्ती होंगे, यह बहुत सफाई से काम करता है।

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

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

WithParms नेस्टेड क्लास है, तब, वैकल्पिक है और दो उद्देश्यों को पूरा करता है, इसमें कॉलबैक इनवोकेशन के लिए आवश्यक पैरामीटर ऑब्जेक्ट सरणी है, और यह 10 ओवरलोडेड इनवोक () विधियों (1 से 10 मापदंडों के साथ) प्रदान करता है जो पैरामीटर सरणी को लोड करते हैं और फिर कॉलबैक लक्ष्य प्राप्त करें।

निर्देशिका ट्री में फ़ाइलों को संसाधित करने के लिए कॉलबैक का उपयोग करके एक उदाहरण निम्न है। यह एक प्रारंभिक सत्यापन पास है जो सिर्फ फाइलों को प्रोसेस करने के लिए गिनता है और यह सुनिश्चित करता है कि कोई पूर्व निर्धारित अधिकतम आकार से अधिक न हो। इस मामले में हम बस एपीआई इनवोकेशन के साथ कॉलबैक इनलाइन बनाते हैं। हालाँकि, हम लक्ष्य पद्धति को एक स्थिर मूल्य के रूप में दर्शाते हैं ताकि प्रतिबिंब हर बार न हो।

static private final Method             COUNT =Callback.getMethod(Xxx.class,"callback_count",true,File.class,File.class);

...

IoUtil.processDirectory(root,new Callback(this,COUNT),selector);

...

private void callback_count(File dir, File fil) {
    if(fil!=null) {                                                                             // file is null for processing a directory
        fileTotal++;
        if(fil.length()>fileSizeLimit) {
            throw new Abort("Failed","File size exceeds maximum of "+TextUtil.formatNumber(fileSizeLimit)+" bytes: "+fil);
            }
        }
    progress("Counting",dir,fileTotal);
    }

IoUtil.processDirectory ():

/**
 * Process a directory using callbacks.  To interrupt, the callback must throw an (unchecked) exception.
 * Subdirectories are processed only if the selector is null or selects the directories, and are done
 * after the files in any given directory.  When the callback is invoked for a directory, the file
 * argument is null;
 * <p>
 * The callback signature is:
 * <pre>    void callback(File dir, File ent);</pre>
 * <p>
 * @return          The number of files processed.
 */
static public int processDirectory(File dir, Callback cbk, FileSelector sel) {
    return _processDirectory(dir,new Callback.WithParms(cbk,2),sel);
    }

static private int _processDirectory(File dir, Callback.WithParms cbk, FileSelector sel) {
    int                                 cnt=0;

    if(!dir.isDirectory()) {
        if(sel==null || sel.accept(dir)) { cbk.invoke(dir.getParent(),dir); cnt++; }
        }
    else {
        cbk.invoke(dir,(Object[])null);

        File[] lst=(sel==null ? dir.listFiles() : dir.listFiles(sel));
        if(lst!=null) {
            for(int xa=0; xa<lst.length; xa++) {
                File ent=lst[xa];
                if(!ent.isDirectory()) {
                    cbk.invoke(dir,ent);
                    lst[xa]=null;
                    cnt++;
                    }
                }
            for(int xa=0; xa<lst.length; xa++) {
                File ent=lst[xa];
                if(ent!=null) { cnt+=_processDirectory(ent,cbk,sel); }
                }
            }
        }
    return cnt;
    }

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

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


1

हां और नहीं, लेकिन जावा में प्रतिनिधि पैटर्न इस तरह से सोचा जा सकता है। यह वीडियो ट्यूटोरियल गतिविधि - अंशों के बीच डेटा विनिमय के बारे में है, और इसमें इंटरफेस का उपयोग करते हुए प्रतिनिधि सॉर्ट पैटर्न का बहुत सार है।

जावा इंटरफ़ेस


1

इसमें delegateC # के रूप में एक स्पष्ट कीवर्ड नहीं है , लेकिन आप एक कार्यात्मक इंटरफ़ेस (यानी बिल्कुल एक विधि के साथ कोई भी इंटरफ़ेस) और लंबोदा का उपयोग करके जावा 8 में समान हासिल कर सकते हैं:

private interface SingleFunc {
    void printMe();
}

public static void main(String[] args) {
    SingleFunc sf = () -> {
        System.out.println("Hello, I am a simple single func.");
    };
    SingleFunc sfComplex = () -> {
        System.out.println("Hello, I am a COMPLEX single func.");
    };
    delegate(sf);
    delegate(sfComplex);
}

private static void delegate(SingleFunc f) {
    f.printMe();
}

प्रत्येक प्रकार की नई वस्तु SingleFuncको लागू करना चाहिए printMe(), इसलिए विधि delegate(SingleFunc)को कॉल करने के लिए इसे किसी अन्य विधि (जैसे ) में पास करना सुरक्षित है printMe()


0

हालांकि यह लगभग साफ सुथरा नहीं है, लेकिन आप जावा प्रॉक्सी का उपयोग करके C # प्रतिनिधियों की तरह कुछ लागू कर सकते हैं ।


2
हालांकि यह लिंक प्रश्न का उत्तर दे सकता है, लेकिन उत्तर के आवश्यक भागों को शामिल करना और संदर्भ के लिए लिंक प्रदान करना बेहतर है। लिंक-केवल उत्तर अमान्य हो सकते हैं यदि लिंक किए गए पृष्ठ बदल जाते हैं।
स्टैकफॉल्ग

2
@StackFlowed लिंक पर जाएं, और आपको क्या मिलेगा? जानकारी के साथ एक पोस्ट। रखने के लिए वोट दें।
शिमोनस्टर

1
@ शिमस्टर क्या होगा यदि लिंक किसी भी अधिक मान्य नहीं है?
StackFlowed

@StackFlowed यह अभी भी एक उत्तर प्रदान करता है - एक जावा प्रॉक्सी का उपयोग करें।
शिमोनस्टर

तब इसे एक टिप्पणी के रूप में छोड़ा जा सकता है?
StackFlowed

0

नहीं, लेकिन इसका व्यवहार समान है, आंतरिक रूप से।

C # प्रतिनिधियों में एक अलग प्रविष्टि बिंदु बनाने के लिए उपयोग किया जाता है और वे फ़ंक्शन पॉइंटर की तरह बहुत काम करते हैं।

जावा में फंक्शन पॉइंटर (ऊपरी नज़र में) जैसी कोई चीज़ नहीं होती है, लेकिन आंतरिक रूप से जावा को अपने उद्देश्यों को प्राप्त करने के लिए उसी चीज़ को करने की आवश्यकता होती है।

उदाहरण के लिए, जावा में थ्रेड बनाने के लिए थ्रेड को एक्सटेंड करने या रननेबल को लागू करने के लिए एक क्लास की आवश्यकता होती है, क्योंकि एक क्लास ऑब्जेक्ट वेरिएबल का उपयोग मेमोरी मेमोरी पॉइंटर में किया जा सकता है।



0

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

  class Class1 {
        public void show(String s) { System.out.println(s); }
    }

    class Class2 {
        public void display(String s) { System.out.println(s); }
    }

    // allows static method as well
    class Class3 {
        public static void staticDisplay(String s) { System.out.println(s); }
    }

    public class TestDelegate  {
        public static final Class[] OUTPUT_ARGS = { String.class };
        public final Delegator DO_SHOW = new Delegator(OUTPUT_ARGS,Void.TYPE);

        public void main(String[] args)  {
            Delegate[] items = new Delegate[3];

            items[0] = DO_SHOW .build(new Class1(),"show,);
            items[1] = DO_SHOW.build (new Class2(),"display");
            items[2] = DO_SHOW.build(Class3.class, "staticDisplay");

            for(int i = 0; i < items.length; i++) {
                items[i].invoke("Hello World");
            }
        }
    }

-11

जावा के पास प्रतिनिधि नहीं हैं और इस पर गर्व है :)। यहाँ मैंने जो कुछ भी पढ़ा उससे मुझे नकली प्रतिनिधियों को 2 तरीके मिले: 1. प्रतिबिंब; 2. भीतरी वर्ग

प्रतिबिंब नारे हैं! इनर क्लास सरलतम उपयोग-मामले को कवर नहीं करता है: सॉर्ट फ़ंक्शन। विवरण में नहीं जाना चाहते हैं, लेकिन मूल रूप से आंतरिक वर्ग के साथ समाधान पूर्णांक की एक सरणी के लिए एक आवरण वर्ग बनाने के लिए आरोही क्रम में सॉर्ट किया जाता है और पूर्णांक में सरणी के पूर्णांक के लिए एक वर्ग बनाया जाता है।


आंतरिक वर्ग को छंटनी के साथ क्या करना है? और सवाल के साथ क्या करना है?
नवफाल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.