क्यों इंटरफ़ेस चर स्थिर और अंतिम डिफ़ॉल्ट रूप से हैं?


274

जावा में डिफ़ॉल्ट रूप से इंटरफ़ेस चर स्थिर और अंतिम क्यों हैं?


41
आपको इंटरफेसेस के अंदर कोई वैरिएबल नहीं रखना चाहिए।
चेरोविम

34
क्योंकि इंटरफेस अनुबंधों को परिभाषित करते हैं जिन्हें विभिन्न तरीकों से लागू किया जा सकता है। एक चर का मूल्य कार्यान्वयन है।
चेरोविम

10
हम निश्चित रूप से कर सकते हैं जब हम जानते हैं कि इंटरफ़ेस को लागू करने वाले सभी वर्गों में कुछ निरंतर चर (उदाहरण के लिए फ़ील्ड नाम) हैं।
अनिकेत ठाकुर

क्या यह एक अच्छा विचार है कि एक वर्ग में इंटरफ़ेस को एक उदाहरण के रूप में बनाया जा सकता है जो कक्षा को लागू करता है? यह मैंने पहले भी सुना है।
डग Hauf

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

जवाबों:


264

फिलिप शॉ द्वारा जावा इंटरफ़ेस डिज़ाइन FAQ से:

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

स्रोत


39
ध्यान दें कि अमूर्त वर्गों को "अपने आप में" तुरंत नहीं किया जा सकता है और न ही उदाहरण के चर हो सकते हैं।
मैकियास

18
staticसंशोधक के लिए यह स्पष्टीकरण पूरी तरह से सहज है। एक वर्ग के सार्वजनिक उदाहरण चर इसके इंटरफ़ेस का हिस्सा हैं और कोई कारण नहीं है कि उन्हें जावा में सार नहीं किया जाना चाहिए interface, उदाहरण के तरीकों की तरह। इससे कोई फर्क नहीं पड़ता है कि एक जावा interfaceको सीधे नहीं किया जा सकता है - आपके पास अभी भी ऐसे वर्ग हैं जो interfaceइसे लागू कर सकते हैं और यह आवश्यक है कि उनके पास एक निश्चित सार्वजनिक उदाहरण चर हो। के रूप में इस भाग के लिए final, कि सभी में एक स्पष्टीकरण की पेशकश नहीं करता है - यह सिर्फ क्या finalमतलब है का वर्णन करता है।
प्रातः

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

6
राज्य की समस्याओं के एकाधिक उत्तराधिकार से बचने के लिए इंटरफेस में उदाहरण चर नहीं हो सकते। Docs.oracle.com/javase/tutorial/java/IandI/… देखें । एक वर्ग एक ही कारण से एक से अधिक वर्ग का विस्तार नहीं कर सकता है।
Denis

1
डिफ़ॉल्ट तरीके कैसे पेश किए जाते हैं और उनके पास उदाहरण होते हैं, फिर भी उदाहरण चर का समर्थन नहीं किया जाता है ...
एम। केज़म अखगीरी

41

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

इसलिए अगर सब पर एक इंटरफ़ेस चर है, यह स्पष्ट रूप से स्थिर, अंतिम और स्पष्ट रूप से सार्वजनिक होगा !!!


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

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

36

सार्वजनिक : सभी वर्गों में पहुंच के लिए, इंटरफ़ेस में मौजूद तरीकों की तरह

स्थिर : जैसा कि इंटरफ़ेस में कोई ऑब्जेक्ट नहीं हो सकता है, इंटरफ़ेसनाम .variableName का उपयोग इसे संदर्भित करने के लिए किया जा सकता है या इसे लागू करने वाले वर्ग में सीधे variableName।

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

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


15

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

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

public interface Actionable {
    public static boolean isActionable = false;

    public void performAction();
}

public NuclearAction implements Actionable {

    public void performAction() {
        // Code that depends on isActionable variable
        if (isActionable) {
            // Launch nuclear weapon!!!
        }
    }
}

अब जरा सोचिए कि अगर कोई अन्य वर्ग जो Actionableइंटरफ़ेस चर की स्थिति को लागू करता है तो क्या होगा :

public CleanAction implements Actionable  {

    public void performAction() {
        // Code that can alter isActionable state since it is not constant
        isActionable = true;
    }
}

यदि इन कक्षाओं को एक कक्षा लोडर द्वारा एकल JVM के भीतर लोड किया जाता है, तो NuclearActionकिसी अन्य वर्ग द्वारा प्रभावित किया जा सकता है CleanAction, जब इसके performAction()लागू होने के बाद इसे लागू किया CleanActionजाता है (उसी धागे में या अन्यथा), जो इस मामले में विनाशकारी हो सकता है (शब्दार्थ है कि)।

चूँकि हम नहीं जानते हैं कि प्रत्येक का क्रियान्वयन interfaceइन चरों का उपयोग कैसे करने जा रहा है, इसलिए उनका अर्थ होना चाहिए final


9

क्योंकि कुछ और कार्यान्वयन का हिस्सा है, और इंटरफेस में कोई भी कार्यान्वयन नहीं हो सकता है।


1
फिर फाइनल होने का क्या कारण है।
जोती

7
यह इंगित करने के लिए कि यह एक स्थिर है। जावा में एक कॉन्स्टेबल कीवर्ड नहीं है। स्थिर अंतिम यह है कि आप स्थिरांक की घोषणा कैसे करते हैं।
अमीर अफगानी

5
जावा 8 के बाद से, वे एक कार्यान्वयन शामिल कर सकते हैं, लेकिन इसका अत्यधिक उपयोग करने की सिफारिश की जाती है यदि आपको बैकवाटर संगतता की आवश्यकता नहीं है। :)
कोडप्लेब

6
public interface A{
    int x=65;
}
public interface B{
    int x=66;
}
public class D implements A,B {
    public static void main(String[] a){
        System.out.println(x); // which x?
    }
}

यहाँ समाधान है।

System.out.println(A.x); // done

मुझे लगता है कि यह एक कारण है कि इंटरफ़ेस चर स्थिर क्यों हैं।

इंटरफ़ेस के अंदर चर घोषित न करें।


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

मैं जवाब से असहमत हूं, क्योंकि @Marco ने कहा कि यह संकलन भी नहीं करेगा। मुझे अब तक कोई और नुकसान नहीं मिला, हो सकता है कि आपको static finalचर के पहले लिखा हुआ न दिखे जो वास्तव में स्थिर और अंतिम हो।
माइक

5

स्थिर - क्योंकि इंटरफ़ेस में कोई उदाहरण नहीं हो सकता है। और अंतिम - क्योंकि हमें इसे बदलने की आवश्यकता नहीं है।


15
"हमें ज़रूरत नहीं है" == "हमें अनुमति नहीं है", अर्थों को मिलाएं नहीं।
पेटेर - मोनिका

3

इसलिये:

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

Final : ताकि हमें चर (डायमंड समस्या - मल्टीपल इनहेरिटेंस) के लिए अस्पष्ट मान न हों।

और प्रलेखन इंटरफ़ेस के अनुसार एक अनुबंध है और कार्यान्वयन नहीं है।

संदर्भ: Quora पर अभिषेक जैन का जवाब


2

जावा इंटरफेस में अमूर्त चर और / या कंस्ट्रक्टर परिभाषाओं की अनुमति नहीं देता है। समाधान: बस अपने इंटरफ़ेस और आपके कार्यान्वयन के बीच एक अमूर्त वर्ग को लटकाएं जो केवल अमूर्त वर्ग का विस्तार करता है जैसे:

 public interface IMyClass {

     void methodA();
     String methodB();
     Integer methodC();

 }

 public abstract class myAbstractClass implements IMyClass {
     protected String varA, varB;

     //Constructor
     myAbstractClass(String varA, String varB) {
         this.varA = varA;
         this.varB = VarB;
     }

     //Implement (some) interface methods here or leave them for the concrete class
     protected void methodA() {
         //Do something
     }

     //Add additional methods here which must be implemented in the concrete class
     protected abstract Long methodD();

     //Write some completely new methods which can be used by all subclasses
     protected Float methodE() {
         return 42.0;
     }

 }

 public class myConcreteClass extends myAbstractClass {

     //Constructor must now be implemented!
     myClass(String varA, String varB) {
         super(varA, varB);
     }

     //All non-private variables from the abstract class are available here
     //All methods not implemented in the abstract class must be implemented here

 }

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

("संरक्षित" कीवर्ड का मतलब है कि केवल विस्तारित वर्ग ही इन तरीकों और चर तक पहुंच सकते हैं।)

स्पायरो



1

इंटरफ़ेस: सिस्टम आवश्यकता सेवा।

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

सार्वजनिक: यह कुछ बार होता है कि इंटरफ़ेस किसी अन्य पैकेज में रखा जा सकता है। तो यह परियोजना में कहीं से भी चर का उपयोग करने की जरूरत है।

स्थिर: जैसा कि अधूरा वर्ग वस्तु नहीं बना सकता है। इसलिए प्रोजेक्ट में हमें ऑब्जेक्ट के बिना वेरिएबल को एक्सेस करने की आवश्यकता है ताकि हम इसकी मदद से एक्सेस कर सकेंinterface_filename.variable_name

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


0

में Java , इंटरफ़ेस आपको किसी भी उदाहरण चर घोषित करने की अनुमति नहीं देता है। एक उदाहरण चर के रूप में एक इंटरफ़ेस में घोषित एक चर का उपयोग करना एक संकलन समय त्रुटि लौटाएगा।

आप एक निरंतर चर घोषित कर सकते हैं, static finalजिसका उपयोग करके एक उदाहरण चर से अलग है।


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

0

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


0

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


0

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

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

मैंने या तो स्थिर रखने की कोशिश की या फिर कोई फर्क नहीं पड़ा। कोड इस प्रकार है:

public interface Addable {
    static int count = 6;

    public int add(int i);

}

public class Impl implements Addable {

    @Override
    public int add(int i) {
        return i+count;
    }
}

public class Test {

    public static void main(String... args) {
        Impl impl = new Impl();

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