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


100

मैं सिर्फ समझने के लिए क्यों एक अंतरफलक में परिभाषित सभी क्षेत्रों परोक्ष हैं कोशिश कर रहा हूँ staticऔर final। फ़ील्ड रखने का विचार staticमुझे समझ में आता है क्योंकि आपके पास एक इंटरफ़ेस की वस्तुएं नहीं हो सकती हैं लेकिन वे क्यों हैं final(संक्षेप में)?

कोई भी जानता है कि जावा डिजाइनर एक इंटरफ़ेस में फ़ील्ड बनाने के साथ क्यों गए staticऔर final?


खुद के लिए एक नोट के लिए: यह स्थिर है क्योंकि इंटरफ़ेस के क्षेत्र उस ऑब्जेक्ट का हिस्सा नहीं बनेंगे जो इसे लागू करता है।
बारिश

जवाबों:


126

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

BTW: जावा में एक स्थैतिक को एक स्थिर अंतिम क्षेत्र द्वारा परिभाषित किया गया है (और सम्मेलन में नाम UPPER_CASE_AND_UNDERSCORES का उपयोग करता है)।


54
यह जरूरी नहीं है कि अंतिम क्षेत्र निरंतर हैं; यह केवल आदिम प्रकारों के लिए गारंटी है। सामान्य तौर पर, अंतिम कीवर्ड का मतलब है कि मेमोरी लोकेशन नहीं बदलेगा।
पोप

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

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

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

यह जावा डिज़ाइनरों द्वारा एक इंटरफ़ेस को स्टेटलेस बनाने के इरादे से किया गया हो सकता है, लेकिन वे असफल रहे क्योंकि एक उदाहरण क्षेत्र एक परिवर्तनीय वर्ग हो सकता है। यह स्वीकार करने के बजाय कि वे विफल हो गए हैं, वे उदाहरण के लिए फ़ील्ड्स को बाध्य करने का विकल्प चुनते हैं static final, जो कि वास्तविक (वास्तविक सी / सी ++) के करीब है जैसा constकि आप जावा में प्राप्त कर सकते हैं। दुर्भाग्य से यह अंतर्निहित है और गैर-विशेषज्ञ के लिए भ्रम पैदा कर सकता है। (मुझे सिर्फ एहसास हुआ कि वे staticइसलिए हैं क्योंकि मैंने अनपेक्षित व्यवहार का अवलोकन किया। मैंने सीखा कि वे finalकेवल इस उत्तर से हैं।)
नहीं-एक-उपयोगकर्ता

27

होने की वजह final

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

होने की वजह static

यदि वे स्थिर हैं, तो वे इंटरफ़ेस के हैं, न कि ऑब्जेक्ट, और न ही ऑब्जेक्ट का रन-टाइम प्रकार।


18

यहाँ पर कुछ बिंदु स्पष्ट हैं:

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

interface I {
  String TOKEN = SomeOtherClass.heavyComputation();
  JButton BAD_IDEA = new JButton("hello");
}

(खबरदार कि एनोटेशन डेफिनिशन के अंदर ऐसा करना , इस तथ्य से संबंधित है कि ऊपर वास्तव में एक स्टेटिक इनिशियलाइज़र को संकलित करता है, संबंधित javac को भ्रमित कर सकता है।)

इसके अलावा, इस प्रतिबंध का कारण तकनीकी की तुलना में अधिक शैलीगत है, और बहुत सारे लोग इसे आराम से देखना चाहेंगे


9

फ़ील्ड स्थिर होनी चाहिए क्योंकि वे सार नहीं हो सकते हैं (जैसे विधियाँ)। क्योंकि वे अमूर्त नहीं हो सकते हैं, कार्यान्वयनकर्ता तार्किक रूप से खेतों के विभिन्न कार्यान्वयन प्रदान करने में सक्षम नहीं होंगे।

खेतों को अंतिम होना चाहिए, मुझे लगता है, क्योंकि खेतों को कई अलग-अलग कार्यान्वयनकर्ताओं द्वारा एक्सेस किया जा सकता है, जिससे वे परिवर्तनशील हो सकते हैं वे समस्याग्रस्त हो सकते हैं (तुल्यकालन के रूप में)। साथ ही इसे फिर से लागू करने (छिपाए जाने) से बचने के लिए।

बस मेरा विचार।


NawMan, "फेल्ड्स को स्थिर होना चाहिए ..." के बारे में आपका स्पष्टीकरण बहुत मायने नहीं रखता है। लेकिन आप बहुत सही थे "खेतों को अंतिम होना चाहिए ..."
चोटी 23

1
मुझे नहीं लगता कि वह इस कारण के बारे में सही है कि खेतों को अंतिम क्यों होना चाहिए। किसी क्षेत्र को बदलने के लिए अलग-अलग कार्यान्वयनकर्ताओं को समस्याग्रस्त करना समस्याग्रस्त नहीं है, क्योंकि अन्यथा विरासत समस्याग्रस्त होगी। एड्रियन ने कहा, फील्ड्स अंतिम होना चाहिए, क्योंकि एक इंटरफ़ेस है, और चाहिए, स्टेटलेस होना चाहिए। मूल रूप से एक राज्य के साथ एक इंटरफ़ेस एक सार वर्ग होना चाहिए।
एक्सल ज़ीग्लर

यदि आपके पास एक ऐसा public staticक्षेत्र है जो नहीं है final, तो ढूंढना शिकायत करेगा (ठीक है!)।
टॉम हैटिन -

2

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

public interface iMine {
    String __ImplementationConstant();
    ...
}

public class AClass implements iMine {
    public String __ImplementationConstant(){
        return "AClass value for the Implementation Constant";
    }
    ...
}

public class BClass implements iMine {
    public String __ImplementationConstant(){
        return "BClass value for the Implementation Constant";
    }
    ...
}

हालाँकि, इस सिंटैक्स का उपयोग करने के लिए इसे लागू करना सरल, स्पष्ट और कम प्रवण होगा:

public interface iMine {
    String __ImplementationConstant;
    ...
}

public class AClass implements iMine {
    public static String __ImplementationConstant =
        "AClass value for the Implementation Constant";
    ...
}

public class BClass implements iMine {
    public static String __ImplementationConstant =
        "BClass value for the Implementation Constant";
    ...
}

आपको लगता है कि अंतिम होने की तुलना में क्षेत्रों के स्थिर होने के बारे में अधिक शिकायत है।
डैनियल यांकोव्स्की

0

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

स्काला में हमारे पास इंटरफेस में क्षेत्र हो सकते हैं, हालांकि आंतरिक रूप से वे लागू किए जाते हैं जैसा कि मैंने ऊपर (विधियों के रूप में) समझाया।


-1

static:

कुछ भी (चर या विधि) है कि staticजावा में के रूप में लागू किया जा सकता है Classname.variablenameया Classname.methodnameया सीधे। केवल वस्तु नाम का उपयोग करके इसे लागू करना अनिवार्य नहीं है।

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

final:

यह एक चर के लिए एक निरंतर मूल्य बनाए रखने में मदद करता है क्योंकि यह अपने उपवर्गों में ओवरराइड नहीं किया जा सकता है।

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