जावा में डिफ़ॉल्ट रूप से इंटरफ़ेस चर स्थिर और अंतिम क्यों हैं?
जावा में डिफ़ॉल्ट रूप से इंटरफ़ेस चर स्थिर और अंतिम क्यों हैं?
जवाबों:
फिलिप शॉ द्वारा जावा इंटरफ़ेस डिज़ाइन FAQ से:
इंटरफ़ेस चर स्थिर हैं क्योंकि जावा इंटरफेस को अपने आप में त्वरित नहीं किया जा सकता है; चर के मूल्य को एक स्थिर संदर्भ में सौंपा जाना चाहिए जिसमें कोई उदाहरण मौजूद नहीं है। अंतिम संशोधन यह सुनिश्चित करता है कि इंटरफ़ेस चर को सौंपा गया मूल्य एक वास्तविक स्थिरांक है जिसे प्रोग्राम कोड द्वारा फिर से असाइन नहीं किया जा सकता है।
static
संशोधक के लिए यह स्पष्टीकरण पूरी तरह से सहज है। एक वर्ग के सार्वजनिक उदाहरण चर इसके इंटरफ़ेस का हिस्सा हैं और कोई कारण नहीं है कि उन्हें जावा में सार नहीं किया जाना चाहिए interface
, उदाहरण के तरीकों की तरह। इससे कोई फर्क नहीं पड़ता है कि एक जावा interface
को सीधे नहीं किया जा सकता है - आपके पास अभी भी ऐसे वर्ग हैं जो interface
इसे लागू कर सकते हैं और यह आवश्यक है कि उनके पास एक निश्चित सार्वजनिक उदाहरण चर हो। के रूप में इस भाग के लिए final
, कि सभी में एक स्पष्टीकरण की पेशकश नहीं करता है - यह सिर्फ क्या final
मतलब है का वर्णन करता है।
चूँकि इंटरफ़ेस में कोई प्रत्यक्ष ऑब्जेक्ट नहीं है, इसलिए उन्हें एक्सेस करने का एकमात्र तरीका एक क्लास / इंटरफ़ेस का उपयोग करना है और इसलिए यही है कि यदि इंटरफ़ेस चर मौजूद है, तो यह स्थिर होना चाहिए अन्यथा यह बाहरी दुनिया में सभी के लिए सुलभ नहीं होगा। अब चूंकि यह स्थिर है, यह केवल एक मूल्य और किसी भी वर्ग को पकड़ सकता है जो इसे लागू करता है और इसे बदल सकता है और इसलिए यह सभी गड़बड़ हो जाएगा।
इसलिए अगर सब पर एक इंटरफ़ेस चर है, यह स्पष्ट रूप से स्थिर, अंतिम और स्पष्ट रूप से सार्वजनिक होगा !!!
interface
। एक वर्ग इंटरफ़ेस को लागू करेगा, उदाहरण चर (इंटरफ़ेस द्वारा आवश्यक) की घोषणा करते हुए। इसके निर्माता (या अन्य विधि) उदाहरण चर सेट करता है। जब कक्षा का एक उदाहरण त्वरित किया जाता है, तो आप इसके उदाहरण चर का उपयोग करने में सक्षम होंगे।
सार्वजनिक : सभी वर्गों में पहुंच के लिए, इंटरफ़ेस में मौजूद तरीकों की तरह
स्थिर : जैसा कि इंटरफ़ेस में कोई ऑब्जेक्ट नहीं हो सकता है, इंटरफ़ेसनाम .variableName का उपयोग इसे संदर्भित करने के लिए किया जा सकता है या इसे लागू करने वाले वर्ग में सीधे variableName।
अंतिम : उन्हें निरंतर बनाने के लिए। यदि 2 कक्षाएं समान इंटरफ़ेस को लागू करती हैं और आप दोनों को मूल्य बदलने का अधिकार देते हैं, तो वर्जन के वर्तमान मूल्य में संघर्ष होगा, यही कारण है कि केवल एक बार आरम्भ करने की अनुमति है।
इन सभी संशोधक एक इंटरफ़ेस के लिए निहित हैं, आपको वास्तव में उनमें से किसी को निर्दिष्ट करने की आवश्यकता नहीं है।
( यह एक दार्शनिक उत्तर नहीं है, लेकिन व्यावहारिक रूप से अधिक है )। 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
।
क्योंकि कुछ और कार्यान्वयन का हिस्सा है, और इंटरफेस में कोई भी कार्यान्वयन नहीं हो सकता है।
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
मुझे लगता है कि यह एक कारण है कि इंटरफ़ेस चर स्थिर क्यों हैं।
इंटरफ़ेस के अंदर चर घोषित न करें।
static final
चर के पहले लिखा हुआ न दिखे जो वास्तव में स्थिर और अंतिम हो।
स्थिर - क्योंकि इंटरफ़ेस में कोई उदाहरण नहीं हो सकता है। और अंतिम - क्योंकि हमें इसे बदलने की आवश्यकता नहीं है।
इसलिये:
Static
: चूंकि हमारे पास इंटरफेस की वस्तुएं नहीं हो सकती हैं, इसलिए हमें ऑब्जेक्ट स्तर के सदस्य चर का उपयोग करने से बचना चाहिए और वर्ग स्तर के चर यानी स्थिर का उपयोग करना चाहिए।
Final
: ताकि हमें चर (डायमंड समस्या - मल्टीपल इनहेरिटेंस) के लिए अस्पष्ट मान न हों।
और प्रलेखन इंटरफ़ेस के अनुसार एक अनुबंध है और कार्यान्वयन नहीं है।
संदर्भ: Quora पर अभिषेक जैन का जवाब
जावा इंटरफेस में अमूर्त चर और / या कंस्ट्रक्टर परिभाषाओं की अनुमति नहीं देता है। समाधान: बस अपने इंटरफ़ेस और आपके कार्यान्वयन के बीच एक अमूर्त वर्ग को लटकाएं जो केवल अमूर्त वर्ग का विस्तार करता है जैसे:
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
}
आप किसी भी इंटरफ़ेस के बिना एक सार वर्ग का उपयोग कर सकते हैं यदि आप सुनिश्चित हैं कि आप इसे बाद में अन्य इंटरफेस के साथ लागू नहीं करना चाहते हैं। कृपया ध्यान दें कि आप एक अमूर्त वर्ग का उदाहरण नहीं बना सकते हैं जिसे आप पहले विस्तारित करना चाहते हैं।
("संरक्षित" कीवर्ड का मतलब है कि केवल विस्तारित वर्ग ही इन तरीकों और चर तक पहुंच सकते हैं।)
स्पायरो
एक इंटरफ़ेस दो पक्षों के बीच अनुबंध है, जो कि पत्थर में खुदी हुई है, इसलिए अंतिम है। अनुबंध द्वारा डिजाइन देखें ।
इंटरफ़ेस: सिस्टम आवश्यकता सेवा।
इंटरफ़ेस में, चर सार्वजनिक, स्थिर, अंतिम पहुंच संशोधक द्वारा डिफ़ॉल्ट रूप से असाइन किए जाते हैं । इसलिये :
सार्वजनिक: यह कुछ बार होता है कि इंटरफ़ेस किसी अन्य पैकेज में रखा जा सकता है। तो यह परियोजना में कहीं से भी चर का उपयोग करने की जरूरत है।
स्थिर: जैसा कि अधूरा वर्ग वस्तु नहीं बना सकता है। इसलिए प्रोजेक्ट में हमें ऑब्जेक्ट के बिना वेरिएबल को एक्सेस करने की आवश्यकता है ताकि हम इसकी मदद से एक्सेस कर सकेंinterface_filename.variable_name
अंतिम: मान लें कि कई वर्ग द्वारा एक इंटरफ़ेस लागू किया गया है और सभी वर्ग इंटरफ़ेस चर को एक्सेस और अपडेट करने का प्रयास करते हैं। इसलिए यह बदलते डेटा को असंगत करता है और हर दूसरे वर्ग को प्रभावित करता है। इसलिए इसे फाइनल के साथ एक्सेस मॉडिफायर घोषित करना होगा।
में Java
, इंटरफ़ेस आपको किसी भी उदाहरण चर घोषित करने की अनुमति नहीं देता है। एक उदाहरण चर के रूप में एक इंटरफ़ेस में घोषित एक चर का उपयोग करना एक संकलन समय त्रुटि लौटाएगा।
आप एक निरंतर चर घोषित कर सकते हैं, static final
जिसका उपयोग करके एक उदाहरण चर से अलग है।
इंटरफ़ेस को किसी भी वर्ग द्वारा लागू किया जा सकता है और यदि उस मूल्य को वहां लागू करने वाले वर्ग द्वारा बदल दिया गया तो अन्य कार्यान्वयन कक्षाओं के लिए गुमराह किया जाएगा। इंटरफ़ेस मूल रूप से दो corelated लेकिन अलग-अलग इकाई को संयोजित करने के लिए एक संदर्भ है। इस कारण से इंटरफ़ेस के अंदर घोषित चर स्पष्ट रूप से अंतिम होगा और स्थिर भी होगा क्योंकि इंटरफ़ेस तुरंत नहीं हो सकता है।
एक वेब एप्लिकेशन के बारे में सोचें जहां आपके पास इंटरफ़ेस परिभाषित है और अन्य वर्ग इसे लागू करते हैं। जैसा कि आप एक स्थिर कीवर्ड के लिए आवश्यक चर का उपयोग करने के लिए इंटरफ़ेस का एक उदाहरण नहीं बना सकते। चूंकि इसके स्थैतिक में मूल्य में कोई भी परिवर्तन अन्य उदाहरणों को प्रतिबिंबित करेगा जिसने इसे लागू किया है। इसलिए इसे रोकने के लिए हम उन्हें अंतिम रूप देते हैं।
सिर्फ एक्लिप्स में कोशिश की गई, इंटरफ़ेस में चर अंतिम होने के लिए डिफ़ॉल्ट है, इसलिए आप इसे बदल नहीं सकते। मूल वर्ग की तुलना में, चर निश्चित रूप से परिवर्तनशील हैं। क्यों? मेरे दृष्टिकोण से, कक्षा में चर एक विशेषता है जो बच्चों को विरासत में मिलेगी, और बच्चे अपनी वास्तविक आवश्यकता के अनुसार इसे बदल सकते हैं। इसके विपरीत, इंटरफ़ेस केवल व्यवहार को परिभाषित करता है, विशेषता नहीं। इंटरफ़ेस में वेरिएबल्स में डालने का एकमात्र कारण उन्हें उस इंटरफ़ेस से संबंधित कॉन्स्ट्स के रूप में उपयोग करना है। हालांकि, निम्नलिखित अंश के अनुसार यह एक अच्छा अभ्यास नहीं है:
"जावा में शुरुआती दिनों में एक इंटरफ़ेस में स्थिरांक एक लोकप्रिय तकनीक थी, लेकिन अब कई लोग इसे इंटरफेस का एक अरुचिकर उपयोग मानते हैं, क्योंकि इंटरफेस को किसी ऑब्जेक्ट द्वारा प्रदान की गई सेवाओं से निपटना चाहिए, न कि इसके डेटा के साथ। एक वर्ग द्वारा आम तौर पर एक कार्यान्वयन विवरण होता है, लेकिन एक इंटरफ़ेस में रखने से उन्हें कक्षा के सार्वजनिक एपीआई में बढ़ावा मिलता है। "
मैंने या तो स्थिर रखने की कोशिश की या फिर कोई फर्क नहीं पड़ा। कोड इस प्रकार है:
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));
}
}