इंटरफ़ेस के भीतर का वर्ग


97

क्या एक इंटरफ़ेस के भीतर एक आंतरिक वर्ग बनाना संभव है ?
अगर यह संभव है तो हम इस तरह से एक आंतरिक वर्ग क्यों बनाना चाहते हैं क्योंकि हम कोई इंटरफ़ेस ऑब्जेक्ट नहीं बनाने जा रहे हैं?

क्या ये आंतरिक कक्षाएं किसी भी विकास प्रक्रिया में मदद करती हैं?

जवाबों:


51

हाँ, आप एक नेस्टेड क्लास या इनर क्लास दोनों को एक जावा इंटरफेस के अंदर बना सकते हैं (ध्यान दें कि लोकप्रिय धारणा के विपरीत " स्टैटिक इनर क्लास " जैसी कोई चीज नहीं है : यह बस कोई मतलब नहीं है, "आंतरिक" और नहीं "कुछ भी नहीं है" जब नेस्टेड क्लास स्थिर होता है, तो "क्लास", इसलिए यह "स्टैटिक इनर" नहीं हो सकता है)।

वैसे भी, निम्नलिखित संकलन ठीक है:

public interface A {
    class B {
    }
}

मैंने देखा है कि इसे सीधे इंटरफ़ेस डेफिनिशन में किसी तरह का "कॉन्ट्रैक्ट चेकर" लगाने के लिए इस्तेमाल किया जाता है (अच्छी तरह से, इंटरफ़ेस में नेस्टेड क्लास में, जो स्टैटिक तरीके हो सकते हैं, इसके विपरीत इंटरफेस ही है, जो नहीं हो सकता है)। इस तरह से देख रहा हूँ अगर मुझे सही से याद है।

public interface A {
    static class B {
        public static boolean verifyState( A a ) {
            return (true if object implementing class A looks to be in a valid state)
        }
    }
}

ध्यान दें कि मैं ऐसी किसी चीज की उपयोगिता पर टिप्पणी नहीं कर रहा हूं, मैं बस आपके प्रश्न का उत्तर दे रहा हूं: यह किया जा सकता है और यह एक तरह का उपयोग है जो मैंने इसे बनाया है।

अब मैं इस तरह के एक निर्माण की उपयोगिता पर टिप्पणी नहीं करूंगा और मैंने देखा है: मैंने इसे देखा है, लेकिन यह बहुत सामान्य निर्माण नहीं है।

200KLOC कोडबेस यहां होता है जहां यह बिल्कुल शून्य समय होता है (लेकिन तब हमें बहुत सी अन्य चीजें मिली हैं जो हम बुरे व्यवहारों पर विचार करते हैं जो बिल्कुल शून्य समय भी होता है कि अन्य लोग पूरी तरह से सामान्य पाएंगे ...)।


क्या आप उपयोग के कुछ उदाहरण जोड़ सकते हैं? मैंने कुछ समय पहले कुछ इसी तरह का परीक्षण किया है और समझ नहीं पाया है कि इस निर्माण का उपयोग करने से मुझे क्या हासिल हो सकता है।
रोमन

@ रोमन: अच्छी तरह से मुझे याद है कि मैंने इसका सामना किसी प्रोजेक्ट पर किया है (अपेक्षाकृत स्वच्छ प्रोजेक्ट मैं जोड़ूंगा लेकिन वे मेरे नहीं थे) लेकिन मुझे नहीं पता कि यह वास्तव में साफ है या नहीं। मैंने एक छोटा सा उदाहरण जोड़ा है जो जैसा दिखता है उसे मैंने एक बार फिर से देखा है: यह मेरा कोड नहीं था और मैं उस निर्माण का उपयोग नहीं कर रहा हूं इसलिए मैं वैध उदाहरणों के साथ आने के लिए सबसे योग्य नहीं हूं :) IIRC क्लास के अंदर हमेशा नाम रखा गया था, उदाहरण के लिए StateChecker और कॉल्स हमेशा की तरह दिखेंगे : A.StateChecker.check (a) या ऐसा कुछ।
SyntaxT3rr0r

8
यदि आप कहते हैं कि " स्टैटिक इनर क्लास " जैसी कोई चीज़ नहीं है, तो आपका जवाब है कि "आप एक नेस्टेड क्लास या जावा इंटरफेस के अंदर के इनर क्लास दोनों को बना सकते हैं" मौलिक रूप से गलत है। अपनी संकुचित परिभाषा का उपयोग करते हुए, आंतरिक वर्ग नहीं हो interfaceसकते । आप एक 's नेस्टेड वर्ग के संशोधक को छोड़ सकते हैं लेकिन फिर भी, यह एक नेस्टेड वर्ग है, आंतरिक वर्ग नहीं। staticinterface
होल्गर

6
यह उत्तर गलत है। इंटरफेस में स्थिर नेस्टेड कक्षाएं हो सकती हैं लेकिन आंतरिक कक्षाएं नहीं।
पॉल बोडिंगटन

1
@PaBBoddington आप सही हैं। यहां तक ​​कि 'स्टैटिक' को हटाकर,B क्लास एक स्टैटिक नेस्टेड क्लास है, न कि इनर क्लास; इंटरफेस को विशेष उपचार मिलता है। मैं इस ऑनलाइन का उल्लेख नहीं पा रहा था, केवल कल्पना के अलावा: "एक इंटरफ़ेस का एक सदस्य वर्ग अंतर्निहित रूप से स्थिर है इसलिए इसे कभी भी आंतरिक वर्ग नहीं माना जाता है।" docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3
मैक्स

109

हां, हमारे पास इंटरफेस के अंदर कक्षाएं हो सकती हैं। उपयोग का एक उदाहरण हो सकता है

public interface Input
{
    public static class KeyEvent {
         public static final int KEY_DOWN = 0;
         public static final int KEY_UP = 1;
         public int type;
         public int keyCode;
         public char keyChar;
    }
    public static class TouchEvent {
         public static final int TOUCH_DOWN = 0;
         public static final int TOUCH_UP = 1;
         public static final int TOUCH_DRAGGED = 2;
         public int type;
         public int x, y;
         public int pointer;
    }
    public boolean isKeyPressed(int keyCode);
    public boolean isTouchDown(int pointer);
    public int getTouchX(int pointer);
    public int getTouchY(int pointer);
    public float getAccelX();
    public float getAccelY();
    public float getAccelZ();
    public List<KeyEvent> getKeyEvents();
    public List<TouchEvent> getTouchEvents();
}

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


3
@Levit सोच रहा था, कार्यान्वित वर्ग कैसा दिखेगा?
ओवरएक्सचेंज

1
उपरोक्त उपयोग के लिए कार्रवाई में कार्यान्वयन देखना पसंद करेंगे। धन्यवाद।
प्रकाश के

45

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

उदाहरण द्वारा:

interface UserChecker {
   Ticket validateUser(Credentials credentials);

   class Credentials {
      // user and password
   }

   class Ticket {
      // some obscure implementation
   }
}

लेकिन वैसे भी ... यह केवल स्वाद की बात है।


35

जावा 7 युक्ति से उद्धरण :

इंटरफेस में सदस्य प्रकार की घोषणाएं हो सकती हैं ()8.5)।

एक इंटरफ़ेस में एक सदस्य प्रकार की घोषणा स्पष्ट रूप से स्थिर और सार्वजनिक है। इसे इन दोनों संशोधक में से किसी को या तो निर्दिष्ट करने की अनुमति है।

जावा इंटरफेस के अंदर गैर-स्थिर कक्षाओं की घोषणा करना संभव नहीं है, जो मुझे समझ में आता है।


धन्यवाद। यह शायद सभी का सबसे संक्षिप्त जवाब है।
जोसेफ

1
यह वह उत्तर है जिसकी मुझे तलाश थी .. लेकिन ओपी कई सवाल पूछता है .. वैसे भी मेरा अपडाउन है।
चार्ली वालेस

11

एक दिलचस्प उपयोग का मामला एक आंतरिक वर्ग के माध्यम से एक डिफ़ॉल्ट कार्यान्वयन के प्रकार प्रदान करने के लिए है जैसा कि यहां बताया गया है: https://stackoverflow.com/a/3442218/454667 (एकल-वर्ग-विरासत की समस्या को दूर करने के लिए)।


और यही कारण है कि निजी सदस्य वर्ग समझ में आता है।
विंसेंट

7

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

interface MyInterface {

   public static class MyInterfaceException extends Exception {
   }

   void doSomething() throws MyInterfaceException;
}

7

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

public interface User {
    public enum Role {
        ADMIN("administrator"),
        EDITOR("editor"),
        VANILLA("regular user");

        private String description;

        private Role(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }

    public String getName();
    public void setName(String name);
    public Role getRole();
    public void setRole(Role role);
    ...
}

1

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


1

शायद जब आप कुछ अलग कार्यान्वयन व्यवहार जैसे अधिक जटिल निर्माण चाहते हैं, तो विचार करें:

public interface A {
    public void foo();

    public static class B implements A {
        @Override
        public void foo() {
            System.out.println("B foo");
        }
    }
}

यह आपका इंटरफ़ेस है और यह कार्यान्वयनकर्ता होगा:

public class C implements A {
    @Override
    public void foo() {
        A.B b = new A.B();
        b.foo(); 
    }

    public static void main(String[] strings) {
        C c = new C();
        c.foo();
    }
}

कुछ स्थिर कार्यान्वयन प्रदान कर सकते हैं, लेकिन यह भ्रामक नहीं होगा, मुझे नहीं पता।


0

मुझे इस प्रकार के निर्माण के लिए एक उपयोग प्राथमिकी मिली।

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

आपके पास सभी स्थिरांक तक पहुंच है; वर्ग का नाम इस मामले में एक नाम स्थान के रूप में कार्य करता है।


0

आप इस इंटरफ़ेस को लागू करने वाली वस्तुओं के लिए सामान्य कार्यक्षमता के लिए "हेल्पर" स्थिर कक्षाएं भी बना सकते हैं:

public interface A {
    static class Helper {
        public static void commonlyUsedMethod( A a ) {
           ...
        }
    }
}

0

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

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


0

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

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