मैं जावा इंटरफ़ेस में एक स्थिर विधि को क्यों नहीं परिभाषित कर सकता?


498

संपादित करें: जावा 8 के रूप में, स्थिर तरीकों को अब इंटरफेस में अनुमति दी गई है।

यहाँ उदाहरण है:

public interface IXMLizable<T>
{
  static T newInstanceFromXML(Element e);
  Element toXMLElement();
}

बेशक यह काम नहीं करेगा। पर क्यों नहीं?

संभावित मुद्दों में से एक होगा, जब आप कॉल करते हैं तो क्या होता है:

IXMLizable.newInstanceFromXML(e);

इस मामले में, मुझे लगता है कि इसे एक खाली विधि (यानी {}) कहना चाहिए। सभी उपवर्गों को स्थैतिक विधि को लागू करने के लिए मजबूर किया जाएगा, इसलिए वे सभी स्थैतिक विधि को कॉल करते समय ठीक होंगे। तो यह क्यों संभव नहीं है?

संपादित करें: मुझे लगता है कि मैं उस उत्तर की तलाश कर रहा हूं जो "से अधिक गहरा है क्योंकि यह जावा है"।

क्या कोई विशेष तकनीकी कारण है कि स्थिर तरीकों को अधिलेखित क्यों नहीं किया जा सकता है? यही कारण है कि, जावा के डिजाइनरों ने उदाहरण के तरीकों को ओवरड्रिजेबल बनाने का फैसला किया, लेकिन स्थिर तरीकों से नहीं?

संपादित करें: मेरे डिजाइन के साथ समस्या यह है कि मैं एक कोडिंग सम्मेलन को लागू करने के लिए इंटरफेस का उपयोग करने की कोशिश कर रहा हूं।

यही है, इंटरफ़ेस का लक्ष्य दो गुना है:

  1. मैं चाहता हूं कि IXMLizable इंटरफ़ेस मुझे एक्सएमएल तत्वों को लागू करने वाली कक्षाओं को बदलने की अनुमति देता है (बहुरूपता का उपयोग करके, ठीक काम करता है)।

  2. अगर कोई IXMLizable इंटरफ़ेस को लागू करने वाले वर्ग का एक नया उदाहरण बनाना चाहता है, तो उन्हें हमेशा पता चलेगा कि एक newInstanceFromXML (तत्व ई) स्टैटिक कंस्ट्रक्टर होगा।

क्या यह सुनिश्चित करने का कोई अन्य तरीका है, केवल इंटरफ़ेस में एक टिप्पणी डालने के अलावा?


4
आप इंटरफेस, btw में सार्वजनिक के साथ अव्यवस्था विधि (और क्षेत्र) परिभाषाओं की जरूरत नहीं है।
टॉम हॉकिन -

हम्म, stackoverflow.com/questions/21817/… का डुप्लिकेट लगता है । इससे पहले नहीं देखा था।
माइकल मायर्स

1
क्या आप कुछ कोड प्रदान कर सकते हैं कि आप स्थैतिक इंटरफ़ेस विधियों का उपयोग कैसे करना चाहेंगे?
पावेल फेल्डमैन

43
यह जावा 8 में संभव होगा: docs.oracle.com/javase/tutorial/java/IandI/…
dakshang

1
@dakshang हाँ, लेकिन यह वह नहीं करता जो ओपी चाहता है।
user253751

जवाबों:


518

जावा 8 स्थिर इंटरफ़ेस विधियों की अनुमति देता है

जावा 8 के साथ, इंटरफेस में स्थिर तरीके हो सकते हैं। उनके पास ठोस आवृत्ति विधियाँ भी हो सकती हैं, लेकिन उदाहरण क्षेत्र नहीं।

यहाँ वास्तव में दो प्रश्न हैं:

  1. बुरे पुराने दिनों में, इंटरफेस में स्थिर तरीके क्यों नहीं हो सकते हैं?
  2. स्थैतिक तरीकों को ओवरराइड क्यों नहीं किया जा सकता है?

इंटरफेस में स्थैतिक तरीके

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

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

स्थैतिक तरीकों को ओवरराइड करना

दूसरे प्रश्न का उत्तर थोड़ा अधिक जटिल है।

संकलित तरीकों को संकलित समय पर resolvable हैं। डायनेमिक डिस्पैच उदाहरण के तरीकों के लिए समझ में आता है, जहां कंपाइलर ठोस प्रकार के ऑब्जेक्ट को निर्धारित नहीं कर सकता है, और इस प्रकार, आह्वान करने की विधि को हल नहीं कर सकता है। लेकिन एक स्थैतिक विधि को लागू करने के लिए एक वर्ग की आवश्यकता होती है, और चूंकि उस कक्षा को सांख्यिकीय रूप से जाना जाता है - संकलन समय - गतिशील प्रेषण अनावश्यक है।

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

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

यदि एक सुपरक्लास और एक उपवर्ग दोनों में एक ही विधि हस्ताक्षर के लिए अपनी तालिकाओं में एक प्रविष्टि है, तो उप-वर्ग का संस्करण पहले सामने आया है, और सुपरक्लास के संस्करण का उपयोग कभी नहीं किया गया है - यह एक "ओवरराइड" है।

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


निर्माता "इंटरफेस"

यहां प्रश्न के हाल के संपादन को संबोधित करने के लिए थोड़ी अधिक सामग्री है।

ऐसा लगता है कि आप प्रत्येक क्रियान्वयन के लिए एक कंस्ट्रक्टर जैसी विधि को प्रभावी ढंग से लागू करना चाहते हैं IXMLizable। एक मिनट के लिए इंटरफ़ेस के साथ इसे लागू करने की कोशिश करने के बारे में भूल जाओ, और यह दिखावा करो कि आपके पास कुछ कक्षाएं हैं जो इस आवश्यकता को पूरा करती हैं। आप इसका उपयोग कैसे करेंगे?

class Foo implements IXMLizable<Foo> {
  public static Foo newInstanceFromXML(Element e) { ... }
}

Foo obj = Foo.newInstanceFromXML(e);

चूंकि आपको Fooनई वस्तु को "निर्माण" करते समय स्पष्ट रूप से ठोस नाम देना है , इसलिए संकलक यह सत्यापित कर सकता है कि उसके पास वास्तव में आवश्यक फैक्ट्री विधि है। और अगर ऐसा नहीं है, तो क्या? मैं एक को लागू कर सकते हैं IXMLizableकि "निर्माता" का अभाव है, और मैं एक उदाहरण बना सकते हैं और अपने कोड में इसे पारित, यह है एक IXMLizableसभी आवश्यक इंटरफेस के साथ।

निर्माण कार्यान्वयन का हिस्सा है, न कि इंटरफ़ेस। इंटरफ़ेस के साथ सफलतापूर्वक काम करने वाला कोई भी कोड कंस्ट्रक्टर की परवाह नहीं करता है। किसी भी कोड को कंस्ट्रक्टर के बारे में परवाह करने के लिए कंक्रीट प्रकार को जानने की जरूरत है, और इंटरफ़ेस को अनदेखा किया जा सकता है।


प्रोजेक्ट कॉइन पर अच्छा कॉल। mail.openjdk.java.net/pipermail/coin-dev/2009-March/000117.html
माइकल मायर्स

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

1
@ shrini1000 - नहीं, स्थिर तरीकों का संकलन समय पर किया जाता है। अस्पष्टता को उसी तरह से संभाला जा सकता है जिस तरह इसे स्थिरांक के साथ संभाला जाता है: संकलक त्रुटि के साथ। हालांकि, कुछ अप्रत्याशित कठिनाइयों का हवाला देते हुए प्रोजेक्ट कॉइन के तहत प्रस्ताव को अस्वीकार कर दिया गया था। निश्चित नहीं कि वे क्या थे, लेकिन मुझे नहीं लगता कि यह इन पंक्तियों के साथ था।
इरिकसन

1
@ tgm1024 हाँ, अनुभाग "कंस्ट्रक्टर 'इंटरफेस'" बताता है कि क्यों संकलन समय पर ज्ञात प्रकार के माध्यम से बहुरूपी व्यवहार को लागू करने की कोशिश करना समझ में नहीं आता है। आप RESET()किसी दिए गए वर्ग पर कैसे आह्वान करेंगे ? आप लिखेंगे SomeClass.RESET()। तो आपको उस एपीआई का वर्णन करने के लिए एक इंटरफ़ेस की आवश्यकता नहीं है; यह स्थिर है। जब आप संकलन-समय पर ठोस प्रकार नहीं जानते हैं तो इंटरफेस का उपयोग किया जाता है। स्थैतिक विधि के साथ ऐसा नहीं है।
इरिकसन

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

48

यह पहले से ही यहाँ पूछा गया था और उत्तर दिया गया था

मेरे उत्तर की नकल करने के लिए:

एक इंटरफ़ेस में एक स्थिर विधि घोषित करने का कोई मतलब नहीं है। उन्हें सामान्य कॉल MyInterface.staticMethod () द्वारा निष्पादित नहीं किया जा सकता है। यदि आप कार्यान्वयन वर्ग MyImplementor.staticMethod () को निर्दिष्ट करके उन्हें कॉल करते हैं, तो आपको वास्तविक वर्ग पता होना चाहिए, इसलिए यह अप्रासंगिक है कि इसमें इंटरफ़ेस शामिल है या नहीं।

इससे भी महत्वपूर्ण बात, स्थैतिक तरीकों को कभी भी ओवरराइड नहीं किया जाता है, और यदि आप करने की कोशिश करते हैं:

MyInterface var = new MyImplementingClass();
var.staticMethod();

स्थैतिक के नियमों का कहना है कि घोषित प्रकार के var में परिभाषित विधि को निष्पादित किया जाना चाहिए। चूंकि यह एक इंटरफ़ेस है, यह असंभव है।

आप "परिणाम = MyInterface.staticMethod ()" को निष्पादित नहीं कर सकते, इसका कारण यह है कि इसे MyInterface में परिभाषित विधि के संस्करण को निष्पादित करना होगा। लेकिन MyInterface में एक संस्करण परिभाषित नहीं किया जा सकता है, क्योंकि यह एक इंटरफ़ेस है। इसमें परिभाषा के अनुसार कोड नहीं है।

जबकि आप कह सकते हैं कि यह मात्रा "क्योंकि जावा ऐसा करता है", वास्तव में निर्णय अन्य डिजाइन निर्णयों का एक तार्किक परिणाम है, यह भी बहुत अच्छे कारण के लिए बनाया गया है।


14
यदि आप उपयोग करते हैं <T एक सामान्य प्रकार के पैरामीटर के रूप में MyInterface> का विस्तार करता है, तो इंटरफ़ेस के माध्यम से गारंटी देना अच्छा होगा कि T। .DoSomething ()।
क्रिस बेट्टी

4
जब मैं तर्कों को समझता हूं, तो मैं @Chris_Betti (गैर-सामान्य प्रकारों के लिए भी) से सहमत हूं: यह अच्छा होगा कि कोड संरचना यह सुनिश्चित करती है कि कुछ कक्षाएं एक विशिष्ट स्थिर एपीआई को लागू करती हैं । शायद यह एक अलग अवधारणा का उपयोग करना संभव है ...
Juh_

@Juh_, ..... या बिल्कुल जरूरी होने पर नया कीवर्ड। मेरा मानना staticहै कि वैसे भी भाषाओं में एक कठिन शब्द है, और बहुत दूर तक फैला हुआ है। तो अपने आप से यह पहले से ही स्केच है। ऊपर मेरे उदाहरण देखें stackoverflow.com/questions/512877/... {कंधे उचकाने की क्रिया}।

3
यह असत्य लगता है: "इंटरफ़ेस में स्थिर विधि की घोषणा करने का कोई मतलब नहीं है।" यदि मेरे पास ऐसी कक्षाओं का संग्रह है, जो बिना इंस्टेंट किए हुए हैं, तो मुझे कुछ जानकारी प्रदान कर सकती हैं, लेकिन मुझे इस स्थिर वर्ग-स्तरीय जानकारी को डालने के लिए एक सामान्य इंटरफ़ेस की आवश्यकता होगी (अर्थात एक अतिव्यापी स्थिर विधि वाला इंटरफ़ेस) तो यह एक वैध उपयोग है । प्रतिबिंब ++ के बारे में सोचें, जहां आप गुण, प्रतिबिंब आदि के साथ हैकिंग के बिना वर्ग गुणों के बारे में मेटा-जानकारी पर कब्जा कर सकते हैं
जेसन

1
"एक इंटरफ़ेस में एक स्थिर विधि घोषित करने का कोई बिंदु नहीं है।" यह सच नहीं है: कल्पना करें कि आपके सिस्टम में एक डिफ़ॉल्ट वर्ग रिज़ॉल्वर है। यदि यह पता लगाता है कि आप कंटेनरइन्जेक्शन को लागू करते हैं :: बनाएँ (कंटेनर $ कंटेनर) विधि, तो यह उदाहरण के लिए इस फ़ंक्शन के साथ ऑब्जेक्ट बनाएगा।
user3790897

37

आम तौर पर यह एक फैक्टरी पैटर्न का उपयोग करके किया जाता है

public interface IXMLizableFactory<T extends IXMLizable> {
  public T newInstanceFromXML(Element e);
}

public interface IXMLizable {
  public Element toXMLElement();
}

7
+1 फैक्टरी पैटर्न समस्या के समाधान जैसा लगता है। (हालांकि सवाल के लिए नहीं)
pvgoddijn

क्या कोई मुझे बता सकता है कि डालने का क्या मतलब है <T यहाँ IXMLizable> का विस्तार किया गया है। मैं java में नया हूँ। यह क्या करता है?
नुवान हर्षकुमार पियाराथना

1
@NuwanHarshakumaraPiyarathna T एक वर्ग है जिसका विस्तार IXMLizable है। जावा जेनरिक में देखें कि इसका बेहतर अर्थ क्या है
एड्रियन

37

जावा 8 के आगमन के साथ अब इंटरफ़ेस में डिफ़ॉल्ट और स्थिर तरीकों को लिखना संभव है। docs.oracle/staticMethod

उदाहरण के लिए:

public interface Arithmetic {

    public int add(int a, int b);

    public static int multiply(int a, int b) {
        return a * b;
    }
}
public class ArithmaticImplementation implements Arithmetic {

    @Override
    public int add(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) {
        int result = Arithmetic.multiply(2, 3);
        System.out.println(result);
    }
}

परिणाम : 6

सुझाव: एक स्थिर इंटरफ़ेस विधि को कॉल करने के लिए किसी भी वर्ग द्वारा लागू करने की आवश्यकता नहीं है। निश्चित रूप से, ऐसा इसलिए होता है क्योंकि सुपरक्लास में स्थिर तरीकों के लिए समान नियम इंटरफेस पर स्थिर तरीकों के लिए लागू होते हैं।


यह इस प्रश्न का एक आदर्श उदाहरण है।

21

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


2
आप किसी भी स्थिर इंटरफ़ेस विधियों को लागू करने के लिए हमेशा प्रत्येक प्रकार को बाध्य कर सकते हैं। टाइपकास्ट, कोई भी?
माइकलजी

16
अपने आप से बाहर कदम रखें और इस सवाल का जवाब दें: स्थैतिक तरीकों को ओवरराइड क्यों नहीं किया जा सकता है? यदि स्थैतिक तरीकों को ओवरराइड किया जा सकता है, तो यह कैसा दिखेगा? आप उनके साथ क्या कर सकते थे? यह उत्तर मूल रूप से "आप नहीं कर सकते क्योंकि आप नहीं कर सकते।"
इरिकसन

10

मैं जावा इंटरफ़ेस में एक स्थिर विधि को क्यों नहीं परिभाषित कर सकता?

वास्तव में आप जावा 8 में कर सकते हैं।

जावा डॉक्टर के अनुसार :

एक स्थिर विधि एक विधि है जो उस वर्ग से जुड़ी होती है जिसमें इसे किसी वस्तु के बजाय परिभाषित किया जाता है। कक्षा का हर उदाहरण अपने स्थिर तरीकों को साझा करता है

जावा 8 में एक इंटरफेस में डिफ़ॉल्ट तरीके और स्थिर तरीके हो सकते हैं । इससे हमें अपने पुस्तकालयों में सहायक विधियों को व्यवस्थित करने में आसानी होती है। हम स्थिर तरीकों को एक अलग वर्ग के बजाय एक ही इंटरफ़ेस में एक इंटरफ़ेस के लिए विशिष्ट रख सकते हैं।

डिफ़ॉल्ट विधि का उदाहरण:

list.sort(ordering);

के बजाय

Collections.sort(list, ordering);

स्थिर विधि का उदाहरण ( डॉक से ही):

public interface TimeClient {
    // ...
    static public ZoneId getZoneId (String zoneString) {
        try {
            return ZoneId.of(zoneString);
        } catch (DateTimeException e) {
            System.err.println("Invalid time zone: " + zoneString +
                "; using default time zone instead.");
            return ZoneId.systemDefault();
        }
    }

    default public ZonedDateTime getZonedDateTime(String zoneString) {
        return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }    
}

6

इंटरफेस का संबंध बहुरूपता से है, जो स्वाभाविक रूप से ऑब्जेक्ट इंस्टेंस से जुड़ा होता है, न कि कक्षाओं से। इसलिए स्टेटिक एक इंटरफेस के संदर्भ में कोई मतलब नहीं रखता है।


स्पष्ट, संक्षिप्त तर्क। अच्छे से कहा।
ऑक उवेच्यू

6

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

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

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


5

उदाहरण के तरीकों की तरह स्थैतिक तरीके आभासी नहीं होते हैं, इसलिए मुझे लगता है कि जावा डिजाइनरों ने फैसला किया कि वे उन्हें इंटरफेस में नहीं चाहते हैं।

लेकिन आप इंटरफेस के अंदर स्थिर तरीकों से युक्त कक्षाएं लगा सकते हैं। आप कोशिश कर सकते हैं कि!

public interface Test {
    static class Inner {
        public static Object get() {
            return 0;
        }
    }
}

5
  • "क्या कोई विशेष कारण है कि स्थिर तरीकों को ओवरराइड नहीं किया जा सकता है"।

मुझे उन शब्दों को फिर से शब्द दें जिन्हें आप परिभाषाओं में भरते हैं।

  • "क्या कोई विशेष कारण है कि संकलन समय पर हल की गई विधियों को रनटाइम पर हल नहीं किया जा सकता है।"

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


3

कई जवाबों ने समस्याओं पर अत्यधिक स्थिर तरीकों की अवधारणा के साथ चर्चा की है। हालाँकि कभी-कभी आप एक ऐसे पैटर्न पर आ जाते हैं जहाँ ऐसा लगता है कि यह वही है जो आप उपयोग करना चाहते हैं।

उदाहरण के लिए, मैं एक ऑब्जेक्ट-रिलेशनल लेयर के साथ काम करता हूं, जिसमें वैल्यू ऑब्जेक्ट्स हैं, लेकिन वैल्यू ऑब्जेक्ट्स को मैनिपुलेट करने के लिए भी कमांड्स हैं। विभिन्न कारणों से, प्रत्येक मूल्य ऑब्जेक्ट क्लास को कुछ स्थिर तरीकों को परिभाषित करना पड़ता है जो फ्रेम को कमांड उदाहरण को खोजने देता है। उदाहरण के लिए, एक व्यक्ति बनाने के लिए जो आप करेंगे:

cmd = createCmd(Person.getCreateCmdId());
Person p = cmd.execute();

और आईडी द्वारा एक व्यक्ति को लोड करने के लिए आप क्या करेंगे

cmd = createCmd(Person.getGetCmdId());
cmd.set(ID, id);
Person p = cmd.execute();

यह काफी सुविधाजनक है, हालांकि इसकी समस्याएं हैं; विशेष रूप से स्थिर तरीकों का अस्तित्व इंटरफ़ेस में लागू नहीं किया जा सकता है। इंटरफेस में एक स्थाई स्थिर तरीका ठीक वैसा ही होगा जैसा हमें चाहिए, यदि केवल यह किसी तरह काम कर सकता है।

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


3

टिप्पणी करते हुए EDIT: As of Java 8, static methods are now allowed in interfaces.

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


2

खैर, जेनरिक के बिना, स्थिर इंटरफेस बेकार हैं क्योंकि सभी स्थिर विधि कॉल को संकलन समय पर हल किया जाता है। इसलिए, उनके लिए कोई वास्तविक उपयोग नहीं है।

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


1
जेनरिक को इससे क्या लेना-देना है? एक इंटरफ़ेस पर एक स्थिर विधि अभी भी अप्राप्य होगी।
डीजेकेवर्थ

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

2
Why can't I define a static method in a Java interface?

एक इंटरफ़ेस में सभी विधियाँ स्पष्ट रूप से सार हैं और इसलिए आप उन्हें स्थैतिक के रूप में परिभाषित नहीं कर सकते हैं क्योंकि स्थैतिक विधियाँ सार नहीं हो सकती हैं।


1

एक इंटरफ़ेस को कभी भी सांख्यिकीय रूप से चित्रित नहीं किया जा सकता है, जैसे ISomething.member। एक इंटरफ़ेस को हमेशा एक चर के माध्यम से संदर्भित किया जाता है जो इंटरफ़ेस के एक उपवर्ग के उदाहरण को संदर्भित करता है। इस प्रकार, एक इंटरफ़ेस संदर्भ कभी नहीं जान सकता है कि यह उप-वर्ग के उदाहरण के बिना किस उपवर्ग को संदर्भित करता है।

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

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

इंटरफ़ेस में एक परस्पर स्थिर स्थिर फ़ील्ड प्राप्त करने का तरीका एक स्थिर इंटरफ़ेस में गैर-स्थिर गेट्टर और सेटर विधियों का उपयोग करना है, जिससे कि उप-क्षेत्र में उस स्थिर फ़ील्ड का उपयोग किया जा सके। सिडेनोट, जाहिरा तौर पर अपरिवर्तनीय स्टैटिक्स के साथ जावा इंटरफ़ेस में घोषित किया जा सकता है static final


0

इंटरफेस बस उन चीजों की एक सूची प्रदान करते हैं जो एक वर्ग प्रदान करेगा, न कि उन चीजों का वास्तविक कार्यान्वयन, जो आपकी स्थिर वस्तु है।

यदि आप स्टैटिक्स चाहते हैं, तो एक अमूर्त वर्ग का उपयोग करें और इसे विरासत में दें, अन्यथा, स्थैतिक को हटा दें।

उम्मीद है की वो मदद करदे!


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

0

आप किसी इंटरफ़ेस में स्थिर विधियों को परिभाषित नहीं कर सकते हैं क्योंकि स्थिर विधियाँ वर्ग के उदाहरण के वर्ग की नहीं होती हैं, और इंटरफ़ेस वर्ग नहीं होते हैं। यहाँ और पढ़ें

हालाँकि, यदि आप चाहें तो आप ऐसा कर सकते हैं:

public class A {
  public static void methodX() {
  }
}

public class B extends A {
  public static void methodX() {
  }
}

इस मामले में आपके पास दो अलग-अलग स्थिर विधियों के साथ दो कक्षाएं हैं जिन्हें मेथएक्स () कहा जाता है।


0

मान लीजिए आप कर सकते हैं; इस उदाहरण पर विचार करें:

interface Iface {
  public static void thisIsTheMethod();
}

class A implements Iface {

  public static void thisIsTheMethod(){
    system.out.print("I'm class A");
  }

}

class B extends Class A {

  public static void thisIsTheMethod(){
    System.out.print("I'm class B");
  } 
}

SomeClass {

  void doStuff(Iface face) {
    IFace.thisIsTheMethod();
    // now what would/could/should happen here.
  }

}

1
यह "मैं कक्षा ए हूँ" प्रिंट होगा। हालाँकि, अगर आपने टाइप किया है A.thisIsTheMethod()तो वह "I am class B" होगा।
cdmckay

लेकिन oyr इंटरफ़ेस पर तरीकों को बुलाते हुए आप कैसे (या संकलक) जानते हैं कि किस विधि को कहा जाना चाहिए? (रीम्बर वहाँ और अधिक कक्षाएं dricetly इफ़ेक्ट लागू कर सकते हैं
pvgoddijn

क्षमा करें, मेरा कहने का मतलब था: हालांकि, अगर आप टाइप B.thisIsTheMethod()करते हैं तो यह "मैं क्लास बी हूं" प्रिंट होगा।
cdmckay

मैंने उद्देश्य पर IFace.thisIsTHeMethod कहा क्योंकि इसमें समस्या है। अपरिभाषित व्यवहार के बिना इंटरफ़ेस पर इसे कॉल करना संभव नहीं होगा (भले ही इसके बारे में घोषित किया गया हो)
pvgoddijn

0

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

SI si = clazz.getStatic(SI.class); // null if clazz doesn't implement SI
// alternatively if the class is known at compile time
SI si = Someclass.static.SI; // either compiler errror or not null

तो आप कॉल कर सकते हैं si.method(params)। यह उपयोगी होगा (उदाहरण के लिए फ़ैक्टरी डिज़ाइन पैटर्न के लिए) क्योंकि आप एक संकलित समय अज्ञात वर्ग से SI स्थैतिक विधियों के कार्यान्वयन (या कार्यान्वयन की जांच) कर सकते हैं! एक गतिशील प्रेषण आवश्यक है और आप इसे (जब स्थिर इंटरफ़ेस के माध्यम से कहा जाता है) को बढ़ाकर एक वर्ग के स्थिर तरीकों (यदि अंतिम नहीं) को ओवरराइड कर सकते हैं। जाहिर है, ये विधियां केवल अपनी कक्षा के स्थिर चर तक ही पहुंच सकती हैं।


0

जब मुझे पता चलता है कि जावा 8 इस मुद्दे को हल करता है, तो मैंने सोचा कि मैं एक ऐसे परिदृश्य के साथ झंकार करूंगा, जो मैं वर्तमान में काम कर रहा हूं (जावा 7 का उपयोग करने में बंद) जहां एक इंटरफ़ेस में स्थिर तरीकों को निर्दिष्ट करने में सक्षम होना सहायक होगा।

मेरे पास कई enum परिभाषाएँ हैं, जहाँ मैंने "id" और "displayName" फ़ील्ड्स को परिभाषित किया है, साथ ही विभिन्न कारणों के लिए मानों का मूल्यांकन करने वाली सहायक विधियों के साथ। एक इंटरफ़ेस को लागू करने से मुझे यह सुनिश्चित करने की अनुमति मिलती है कि गेट्टर विधियाँ हैं लेकिन स्थिर सहायक विधियाँ नहीं हैं। एक एनम होने के नाते, वास्तव में एक विरासत वाले सहायक वर्ग में सहायक विधियों को बंद करने का एक साफ तरीका नहीं है या कुछ ऐसा है जिससे विधियों को एनम में ही परिभाषित किया जाना है। क्योंकि यह एक एनम है, आप कभी भी वास्तव में इसे एक इंस्टेंस ऑब्जेक्ट के रूप में पारित नहीं कर पाएंगे और इसे इंटरफ़ेस प्रकार के रूप में मान सकते हैं, लेकिन एक इंटरफ़ेस के माध्यम से स्थैतिक सहायक विधियों के अस्तित्व की आवश्यकता के लिए सक्षम होना चाहिए जो मुझे पसंद है यह जावा 8 में समर्थित है।

यहाँ कोड मेरी बात को दर्शाता है।

इंटरफ़ेस परिभाषा:

public interface IGenericEnum <T extends Enum<T>> {
    String getId();
    String getDisplayName();
    //If I was using Java 8 static helper methods would go here
}

एक एनुम परिभाषा का उदाहरण:

public enum ExecutionModeType implements IGenericEnum<ExecutionModeType> {
    STANDARD ("Standard", "Standard Mode"),
    DEBUG ("Debug", "Debug Mode");

    String id;
    String displayName;

    //Getter methods
    public String getId() {
        return id;
    }

    public String getDisplayName() {
        return displayName;
    }

    //Constructor
    private ExecutionModeType(String id, String displayName) {
        this.id = id;
        this.displayName = displayName;
    }

    //Helper methods - not enforced by Interface
    public static boolean isValidId(String id) {
        return GenericEnumUtility.isValidId(ExecutionModeType.class, id);
    }

    public static String printIdOptions(String delimiter){
        return GenericEnumUtility.printIdOptions(ExecutionModeType.class, delimiter);
    }

    public static String[] getIdArray(){
        return GenericEnumUtility.getIdArray(ExecutionModeType.class);
    }

    public static ExecutionModeType getById(String id) throws NoSuchObjectException {
        return GenericEnumUtility.getById(ExecutionModeType.class, id);
    }
}

सामान्य एनुम उपयोगिता परिभाषा:

public class GenericEnumUtility {
    public static <T extends Enum<T> & IGenericEnum<T>> boolean isValidId(Class<T> enumType, String id) {       
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(enumOption.getId().equals(id)) {
                return true;
            }
        }

        return false;
    }

    public static <T extends Enum<T> & IGenericEnum<T>> String printIdOptions(Class<T> enumType, String delimiter){
        String ret = "";
        delimiter = delimiter == null ? " " : delimiter;

        int i = 0;
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(i == 0) {
                ret = enumOption.getId();
            } else {
                ret += delimiter + enumOption.getId();
            }           
            i++;
        }

        return ret;
    }

    public static <T extends Enum<T> & IGenericEnum<T>> String[] getIdArray(Class<T> enumType){
        List<String> idValues = new ArrayList<String>();

        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            idValues.add(enumOption.getId());
        }

        return idValues.toArray(new String[idValues.size()]);
    }

    @SuppressWarnings("unchecked")
    public static <T extends Enum<T> & IGenericEnum<T>> T getById(Class<T> enumType, String id) throws NoSuchObjectException {
        id = id == null ? "" : id;
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(id.equals(enumOption.getId())) {
                return (T)enumOption;
            }
        }

        throw new NoSuchObjectException(String.format("ERROR: \"%s\" is not a valid ID. Valid IDs are: %s.", id, printIdOptions(enumType, " , ")));
    }
}

0

मान लीजिए कि स्थैतिक तरीकों को इंटरफेस में अनुमति दी गई थी: * वे सभी कार्यान्वयन वर्गों को उस पद्धति को घोषित करने के लिए मजबूर करेंगे। * इंटरफेस आमतौर पर वस्तुओं के माध्यम से उपयोग किया जाएगा, इसलिए उन पर केवल प्रभावी तरीके गैर-स्थैतिक होंगे। * कोई भी वर्ग जो किसी विशेष इंटरफ़ेस को जानता है, अपने स्थिर तरीकों को लागू कर सकता है। इसलिए एक कार्यान्वयन वर्ग की स्थैतिक विधि को नीचे कहा जाएगा, लेकिन आक्रमणकारी वर्ग को यह पता नहीं है कि कौन है। इसे कैसे जानें? यह अनुमान लगाने के लिए कोई तात्कालिकता नहीं है कि!

वस्तुओं के साथ काम करते समय इंटरफेस का उपयोग करने के लिए सोचा गया था। इस तरह, किसी विशेष वर्ग से किसी वस्तु को तुरंत हटा दिया जाता है, इसलिए यह अंतिम मामला हल हो जाता है। आह्वान करने वाले वर्ग को यह नहीं पता होता है कि कौन सा वर्ग विशेष है क्योंकि तात्कालिकता किसी तीसरे वर्ग द्वारा हो सकती है। तो इनवॉइस क्लास केवल इंटरफ़ेस जानता है।

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

मेटाक्लास इस उद्देश्य के लिए काम करते हैं। आप जावा के क्लास क्लास की कोशिश कर सकते हैं। लेकिन समस्या यह है कि जावा इसके लिए पर्याप्त लचीला नहीं है। आप इंटरफ़ेस के वर्ग ऑब्जेक्ट में एक विधि घोषित नहीं कर सकते।

यह एक मेटा मुद्दा है - जब आपको गधा करने की आवश्यकता होती है

..ब्लह ब्लाह

वैसे भी आपके पास एक आसान समाधान है - विधि को एक ही तर्क के साथ गैर-स्थिर बनाना। लेकिन फिर आपको विधि को कॉल करने के लिए पहले एक ऑब्जेक्ट बनाना होगा।


0

इसे हल करने के लिए: त्रुटि: लापता विधि शरीर, या सार स्थिर शून्य मुख्य घोषित करें (स्ट्रिंग [] आर्ग्स);

interface I
{
    int x=20;
    void getValue();
    static void main(String[] args){};//Put curly braces 
}
class InterDemo implements I
{
    public void getValue()
    {
    System.out.println(x);
    }
    public static void main(String[] args)
    {
    InterDemo i=new InterDemo();
    i.getValue();   
    }

}

आउटपुट: 20

अब हम इंटरफ़ेस में स्थिर विधि का उपयोग कर सकते हैं


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

-2

मुझे लगता है कि जावा में स्थिर इंटरफ़ेस विधियां नहीं हैं क्योंकि आपको उनकी आवश्यकता नहीं है। आप सोच सकते हैं कि आप करते हैं, लेकिन ... आप उनका उपयोग कैसे करेंगे? यदि आप उन्हें पसंद करना चाहते हैं

MyImplClass.myMethod()

फिर आपको इसे इंटरफ़ेस में घोषित करने की आवश्यकता नहीं है। यदि आप उन्हें पसंद करना चाहते हैं

myInstance.myMethod()

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

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

MyImplClass.myMethod()

इस तथ्य पर भरोसा नहीं करता है कि प्रत्येक इंटरफ़ेस कार्यान्वयन में यह विधि है, इसलिए आपको इसके साथ सुनिश्चित होने में मदद करने के लिए जावा की आवश्यकता नहीं है।


-5

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

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