इंटरफ़ेस में स्थिर और डिफ़ॉल्ट विधियों के बीच अंतर


107

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

public interface interfacesample2 {
    public static void method() {
        System.out.println("hello world");
    }

    public default void menthod3() {
        System.out.println("default print");
    }
}

कृपया दोनों के अंतर को स्पष्ट करें और यह भी बताएं कि जब हम इसका उपयोग करेंगे तो इसका उदाहरण अच्छा होगा। Interfaces पर थोड़ा उलझन में।


4
क्या आपने जावा ट्यूटोरियल में स्टैटिक तरीकों को पढ़ने की कोशिश की?
दाऊद इब्न करीम

1
तो आप एक स्थैतिक विधि को ओवरराइड करने में सक्षम नहीं होने के बारे में हिस्सा याद किया?
दाऊद इब्न करीम

1
के बारे में समझ में नहीं आया
विपिन मेनन 5

9
स्थिर विधि इंटरफ़ेस के लिए एक स्थिर सदस्य है, खिचड़ी भाषा को ओवरराइड किया जा सकता है (वर्ग के साथ), डिफ़ॉल्ट विधि default implementationएक विधि का तरीका है जिसे ओवरराइड किया जा सकता है।
शैलगंगा Sha

2
जरा सोचकर: आपने कभी यहां एक उत्तर क्यों स्वीकार नहीं किया?
भूतकाट

जवाबों:


116

जावा 8 में स्थिर और डिफ़ॉल्ट तरीकों के बीच अंतर:

1) क्लास को लागू करने में डिफ़ॉल्ट तरीकों को ओवरराइड किया जा सकता है , जबकि स्थिर नहीं हो सकता

2) स्टेटिक विधि केवल इंटरफ़ेस वर्ग के अंतर्गत आता है , इसलिए आप केवल इंटरफ़ेस क्लास पर स्थिर पद्धति को लागू कर सकते हैं, इस इंटरफ़ेस को लागू करने वाले वर्ग पर नहीं, देखें:

public interface MyInterface {
    default void defaultMethod(){
        System.out.println("Default");
    }

    static void staticMethod(){
        System.out.println("Static");
    }    
}

public class MyClass implements MyInterface {

    public static void main(String[] args) {

        MyClass.staticMethod(); //not valid - static method may be invoked on containing interface class only
        MyInterface.staticMethod(); //valid
    }
}

3) क्लास और इंटरफ़ेस दोनों में समान नामों के साथ स्थिर तरीके हो सकते हैं , और न ही अन्य को ओवरराइड करता है!

public class MyClass implements MyInterface {

    public static void main(String[] args) {

        //both are valid and have different behaviour
        MyClass.staticMethod();
        MyInterface.staticMethod();
    }

    static void staticMethod(){
        System.out.println("another static..");
    }
}

2
लेकिन 'स्थिर' क्यों? जावा 8 में क्या उद्देश्य है?
शशांक विवेक

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

हाँ, लेकिन हम अभी भी ओवरराइड करने के बजाय इंटरफ़ेस स्थिर विधि को छिपा सकते हैं, .... मुझे लगता है कि दोनों एक ही purpose( एक सामान्य कार्यान्वयन का उपयोग करें ) को पूरा करते हैं और implementing the logic again in subclass ( ओवरराइडिंग, छुपकर ) अस्पष्टता का समाधान करते हैं । एकमात्र समझदार कारण इस कारण से होगा कि [स्थैतिक इंटरफ़ेस विधियों को विरासत में नहीं मिला है] ( stackoverflow.com/questions/25169175/… ) और इसलिए हम उन्हें उपवर्ग उदाहरण का उपयोग करके कॉल नहीं कर सकते।
अमरनाथ

29

एक स्थिर विधि एक ऐसी विधि है जो कक्षा के 'नामस्थान' पर लागू होती है, इसलिए बोलने के लिए। तो इंटरफ़ेस की एक staticविधि द्वारा पहुँचा जाता है । ध्यान दें कि फ़ंक्शन कॉल इंटरफ़ेस के किसी विशेष उदाहरण पर लागू नहीं होता है ।fooInterfaceInterface.foo()

barदूसरी ओर एक डिफ़ॉल्ट कार्यान्वयन , द्वारा बुलाया जाता है

Interface x = new ConcreteClass();
x.bar();

एक staticइंटरफ़ेस विधि thisचर के बारे में नहीं जान सकती , लेकिन एक डिफ़ॉल्ट कार्यान्वयन कर सकती है।


19

1. दोनों के अंतर को स्पष्ट करें

स्टेटिक इंटरफ़ेस मेथड्स स्टैटिक क्लास मेथड की तरह होते हैं (यहाँ वे केवल इंटरफ़ेस से संबंधित हैं)। जहाँ डिफ़ॉल्ट इंटरफ़ेस विधियाँ इंटरफ़ेस विधियाँ प्रदान करती हैं default implementation(जो कक्षाएं लागू कर सकती हैं override)
लेकिन याद रखें यदि कोई वर्ग implementing more than one interface with same defaultविधि हस्ताक्षर है तो कार्यान्वयन कक्षाneeds to override the default method

आप नीचे एक सरल उदाहरण पा सकते हैं (विभिन्न मामलों के लिए DIY कर सकते हैं)

public class Test {
    public static void main(String[] args) {
        // Accessing the static member
        I1.hello();

        // Anonymous class Not overriding the default method
        I1 t = new I1() {
            @Override
            public void test() {
                System.out.println("Anonymous test");
            }
        };
        t.test();
        t.hello("uvw");

        // Referring to class instance with overridden default method
        I1 t1 = new Test2();
        t1.test();
        t1.hello("xyz");

    }
}

interface I1 {

    void test();
    //static method
    static void hello() {
        System.out.println("hello from Interface I1");
    }

    // default need not to be implemented by implementing class
    default void hello(String name) {
        System.out.println("Hello " + name);
    }
}

class Test2 implements I1 {
    @Override
    public void test() {
        System.out.println("testing 1234...");
    }

    @Override
    public void hello(String name) {
        System.out.println("bonjour" + name);
    }
}

2. जब हम इसका इस्तेमाल करेंगे तो अच्छा होगा।

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

यहाँ एक अच्छा पढ़ा है: /software/233053/why-were-default-and-static-methods-added-to-interfaces-in-java-8-when-we-alread

नीचे दिए गए oracle doc मौजूदा इंटरफेस को विकसित करने के लिए डिफ़ॉल्ट और स्थिर तरीके बताते हैं:

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

http://docs.oracle.com/javase/tutorial/java/IandI/nogrow.html


मुझे एक शंका है। क्या एक इंटरफ़ेस का ऑब्जेक्ट बनाना संभव है? आपके कोड में यह पंक्ति है: I1 t = new I1 ()
Hackinet

@Hackinet कृपया उस कथन पर जावा टिप्पणी पढ़ें। अनाम वर्गों के बारे में भी पढ़ें। आशा है कि आपकी मदद करता है
Shail016

12

यहाँ मेरा विचार है:

इंटरफ़ेस में स्थिर विधि :

  • आप इसे सीधे (InterfacetA.staticMethod ()) कह सकते हैं

  • उप-वर्ग ओवरराइड नहीं कर पाएगा।

  • उप-वर्ग में स्टेथमेथोड के समान नाम के साथ विधि हो सकती है

इंटरफ़ेस में डिफ़ॉल्ट विधि :

  • आप इसे सीधे नहीं कह सकते।

  • उप-वर्ग इसे ओवरराइड करने में सक्षम होगा

फायदा:

  • स्थैतिक विधि: आपको उपयोगिता विधि के लिए अलग वर्ग बनाने की आवश्यकता नहीं है।

  • डिफ़ॉल्ट विधि: डिफ़ॉल्ट विधि में सामान्य कार्यक्षमता प्रदान करें।


8

इस लिंक में कुछ उपयोगी जानकारियां हैं, उनमें से कुछ को यहाँ सूचीबद्ध किया गया है।

डिफ़ॉल्ट और स्थिर तरीकों ने इंटरफेस और अमूर्त वर्गों के बीच के अंतर को कम कर दिया है ।

इंटरफ़ेस डिफ़ॉल्ट तरीके:

  • यह उपयोगिता वर्गों से बचने में मदद करता है, जैसे कि सभी संग्रह वर्ग विधि को इंटरफेस में ही प्रदान किया जा सकता है।
  • यह कार्यान्वयन कक्षाओं को तोड़ने के डर के बिना इंटरफेस को विस्तारित करने में मदद करता है।

इंटरफ़ेस स्थिर तरीके:

  • वे इंटरफ़ेस का हिस्सा हैं, हम इसे क्लास ऑब्जेक्ट के कार्यान्वयन के लिए उपयोग नहीं कर सकते हैं।
  • यह कार्यान्वयन वर्गों को उन्हें ओवरराइड करने की अनुमति नहीं देकर सुरक्षा प्रदान करने में मदद करता है।

एक और उपयोगी संदर्भ उद्धृत करना पसंद करते हैं ।


3

इंटरफ़ेस डिफ़ॉल्ट तरीके:

यह उपयोगिता वर्गों से बचने में मदद करता है, जैसे कि सभी संग्रह वर्ग विधि को इंटरफेस में ही प्रदान किया जा सकता है।

यह कार्यान्वयन कक्षाओं को तोड़ने के डर के बिना इंटरफेस को विस्तारित करने में मदद करता है।

इंटरफ़ेस स्थिर तरीके:

वे इंटरफ़ेस का हिस्सा हैं, हम इसे क्लास ऑब्जेक्ट के कार्यान्वयन के लिए उपयोग नहीं कर सकते हैं।

यह कार्यान्वयन वर्गों को उन्हें ओवरराइड करने की अनुमति नहीं देकर सुरक्षा प्रदान करने में मदद करता है।

अब कैसे स्थैतिक विधि सुरक्षा प्रदान करती है। एक उदाहरण देखते हैं।

interface MyInterface {
    /*
     * This is a default method so we need not to implement this method in the implementation classes
     */
    default void newMethod() {
        System.out.println("Newly added default method in Interface");
    }

    /*
     * This is a static method. Static method in interface is similar to default method except that we cannot override them in the implementation classes. Similar to default methods, we need to implement these methods in implementation classes so we can safely add them to the existing interfaces.
     */
    static void anotherNewMethod() {
        System.out.println("Newly added static method in Interface");
    }

    /*
     * Already existing public and abstract method We must need to implement this method in implementation classes.
     */
    void existingMethod(String str);
}

public class Example implements MyInterface {
    // implementing abstract method
    public void existingMethod(String str) {
        System.out.println("String is: " + str);
    }

    public void newMethod() {
        System.out.println("Newly added default method in Class");
    }

    static void anotherNewMethod() {
        System.out.println("Newly added static method in Class");
    }

    public static void main(String[] args) {
        Example obj = new Example();

        // calling the default method of class
        obj.newMethod();
        // calling the static method of class

        obj.anotherNewMethod();

        // calling the static method of interface
        MyInterface.anotherNewMethod();

        // calling the abstract method of interface
        obj.existingMethod("Java 8 is easy to learn");

    }
}

यहां obj.newMethod();प्रिंटिंग क्लास इम्प्लीमेंटेशन लॉजिक, मतलब हम इम्प्लीमेंटेशन क्लास के अंदर उस तरीके के लॉजिक को बदल सकते हैं।

लेकिन obj.anotherNewMethod();मुद्रण वर्ग कार्यान्वयन तर्क, लेकिन इंटरफ़ेस कार्यान्वयन नहीं बदला। तो अगर कोई एन्क्रिप्शन-डिक्रिप्शन लॉजिक उस विधि के अंदर लिखा है जिसे आप बदल नहीं सकते


यह जवाब ऐसा लगता है जैसे यह कहीं अच्छा जा रहा था, फिर अचानक उछाल! अंत में कोई सार्थक व्याख्या नहीं। लेकिन नहीं बदला इंटरफ़ेस कार्यान्वयन इसका क्या मतलब है?
अमरनाथ

2

Oracle के Javadocs के अनुसार: http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

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

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

आम तौर पर, इंटरफ़ेस में स्थिर विधि का उपयोग हेल्पर विधियों के रूप में किया जाता है, जबकि डिफ़ॉल्ट विधि का उपयोग उन वर्गों के लिए डिफ़ॉल्ट कार्यान्वयन के रूप में किया जाता है जो उस इंटरफ़ेस को लागू करते हैं।

उदाहरण:

interface IDemo {

    //this method can be called directly from anywhere this interface is visible
    static int convertStrToInt(String numStr) {
       return Integer.parseInt(numStr);
    }


    //getNum will be implemented in a class
    int getNum();       

    default String numAsStr() {
       //this.getNum will call the class's implementation
       return Integer.toString(this.getNum());
    }   

}

1

Java14 के अनुसार JLS doc:

डिफ़ॉल्ट विधि:

  • यह एक उदाहरण विधि है जिसे डिफ़ॉल्ट संशोधक के साथ इंटरफेस में घोषित किया गया है

  • इसे केवल लागू करने वाले वर्ग के उदाहरण से ही एक्सेस किया जा सकता है

  • इसके शरीर को हमेशा एक ब्लॉक द्वारा दर्शाया जाता है, जो विधि को ओवरराइड किए बिना किसी भी कार्यान्वयन वर्ग के लिए एक डिफ़ॉल्ट कार्यान्वयन या व्यवहार प्रदान करता है

  • यह कभी भी स्थिर या निजी नहीं हो सकता

स्थैतिक विधि:

  • इसे क्लास स्टैटिक मेथड्स की तरह ही किसी विशेष ऑब्जेक्ट के संदर्भ में इंटरफेस द्वारा लागू किया जा सकता है

  • स्थैतिक विधि निजी हो सकती है

  • कार्यान्वयन वर्ग स्थैतिक विधि तक नहीं पहुँच सकता है

नीचे दिए गए उदाहरण कोड की मदद से इसे समझते हैं:

            public interface MyInterface {
        
            private void privateMethod() {
                System.out.println("Hi, this is privateMethod");
            }
        
            private static void staticPrivateMethod() {
                System.out.println("Hi, this is staticPrivateMethod");
            }
        
            static void staticMethod() {
                //privateMethod();    // Non-static method cannot be referenced from a static contex
                System.out.println("Hi, this is staticMethod");
                staticPrivateMethod();
            }
        
            default void defaultMethod() {
                System.out.println("Hi, this is defaultMethod");
            }
        
        }
    
    public class MyInterfaceImpl implements MyInterface{
        public static void main(String[] args) {
    
            MyInterface.staticMethod();
            // myInterface.staticMethod(); // Not allowed
    
            MyInterface myInterface = new MyInterfaceImpl();
            myInterface.defaultMethod();
            // MyInterface.defaultMethod(); // Not allowed
    
        }
    }

0

हम निष्पादित नहीं कर सकते Interfacesample2.menthod3();क्योंकि यह स्थिर विधि नहीं है। निष्पादित करने के लिए method3()हमें Interfacesample2इंटरफ़ेस का एक उदाहरण चाहिए ।

कृपया निम्नलिखित व्यावहारिक उदाहरण देखें:

public class Java8Tester {
   public static void main(String args[]){
      // Interfacesample2.menthod3(); Cannot make a static reference to the non-static method menthod3 from the type Interfacesample2

      new Interfacesample2(){ }.menthod3();// so in order to call default method we need an instance of interface

       Interfacesample2.method(); // it
   }
}

interface Interfacesample2 {
    public static void method() {
        System.out.println("hello world");
    }

    public default void menthod3() {
        System.out.println("default print");
    }
}

0

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

उदाहरण

public interface Calculator {
    int add(int a, int b);
    int subtract(int a, int b);

    default int multiply(int a, int b) {
         throw new RuntimeException("Operation not supported. Upgrade to UltimateCalculator");
    }

    static void display(String value) {
        System.out.println(value);
    }
}

इंटरफ़ेस के स्थिर और डिफ़ॉल्ट विधि के बीच अंतर डिफ़ॉल्ट विधि है जो विरासत का समर्थन करता है लेकिन स्थिर विधि नहीं करता है। इनहेरिटिंग इंटरफ़ेस में डिफ़ॉल्ट विधि को ओवरराइड किया जा सकता है।

यहाँ इंटरफ़ेस डिफ़ॉल्ट विधि और स्थैतिक विधि के बारे में अच्छा पढ़ा गया है। जावा 8 में इंटरफ़ेस डिफ़ॉल्ट विधि


0

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

Static functions can be used for static factory methods. 

स्थैतिक कारखाना विधि वे विधियाँ हैं जो किसी वस्तु को वापस करती हैं। वे कंस्ट्रक्टर की तरह काम करते हैं। विशिष्ट मामलों में, स्थिर फैक्ट्री विधि कंस्ट्रक्टर का उपयोग करने की तुलना में अधिक पठनीय कोड प्रदान करती है।

किताब से उद्धरण - प्रभावी जावा, जोशुआ बलोच द्वारा तीसरा संस्करण

जावा 8 से पहले, इंटरफेस में स्थिर तरीके नहीं हो सकते थे। अधिवेशन के द्वारा, प्रकार नाम के एक इंटरफेस के लिए स्थिर कारखाने के तरीकों को गैर-परिवर्तनीय साथी वर्ग (आइटम 4) में टाइप नाम दिया गया था।

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

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

इसके अलावा वह बताते हैं कि एपीआई केवल छोटा नहीं है, यह कोड पठनीयता और एपीआई आसानी के साथ मदद करता है।

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

यहाँ java.util.Collections वर्ग से एक स्थिर विधि है:

public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
    return new UnmodifiableCollection<>(c);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.