2011-08-30 14 views
11

तो मैं अपने enumजावा सार्वजनिक enum विधि उद्देश्य

public enum Sample { 
    ValueA{ 
     @Override 
    public String getValue(){ return "A"; } 
}, 
ValueB{ 
    @Override 
    public String getValue(){ return "B"; } 

    public void doSomething(){ } 
}; 
abstract public String getValue(); 
}; 

है और मैं कुछ अन्य कोड enum उपयोग करने की कोशिश की है।

Sample.ValueB.doSomething(); 

कौन सा है जैसे कि यह मान्य होना चाहिए लगता है, लेकिन त्रुटि पैदा करता है ") विधि DoSomething (प्रकार नमूना के लिए अपरिभाषित है"।

Sample value = Sample.ValueB; 
value.doSomething(); 

जो एक ही त्रुटि उत्पन्न करता है और उचित लगता है।

मुझे लगता है कि पहला जवाब क्यों नहीं है और यह दो उदाहरणों से संबंधित है जो हुड के बराबर है। मैं उम्मीद कर रहा था कि कोई मुझे दस्तावेज की तरफ इशारा कर सकता है कि ऐसा क्यों है।

+0

यह वास्तव में मदद करेगा यदि आप कहेंगे कि आपको कौन सी त्रुटि मिल रही है ... –

+0

क्या आपको 'नमूना.डो कुछ()' नहीं कहा जाना चाहिए? – nfechner

+2

@ nfechner..the 'doSomething()' विधि स्थिर नहीं है .. –

उत्तर

15

"क्षेत्र" के प्रकार ValueASample है। इसका मतलब है कि आप केवल ValueA पर विधियों का आह्वान कर सकते हैं कि Sample प्रदान करता है। JLS §8.9.1. Enum Constants से:

उदाहरण तरीकों इन वर्ग निकायों में घोषित संलग्नित enum प्रकार के बाहर लागू किया जा सकता केवल अगर वे संलग्न enum प्रकार में सुलभ तरीकों को ओवरराइड।

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

10

मूल रूप से संकलन समय प्रकार Sample.ValueB की अभी भी नमूना है, भले ही मूल्य का निष्पादन समय प्रकार ValueB हो जाएगा। तो कोड के आपके दो स्निपेट समतुल्य हैं - ग्राहकों को "अतिरिक्त" विधियां नहीं मिलती हैं जो आपके enum मानों के कुछ में मौजूद हैं।

आप प्रभावी रूप से इस तरह की एक क्षेत्र घोषित करने के रूप में enum के बारे में सोच सकते हैं:

public static final Sample ValueB = new Sample() { 
    @Override 
    public String getValue(){ return "B"; } 

    public void doSomething(){ } 
}; 
4

जब आप लिखना

enum Sample 
{ 
    Value{ 
     public void doSomething() 
     { 
       //do something 
     } 
    }; 
} 

आप Sample enum, बल्कि enum Sample की एक अनाम उप-वर्ग का एक उदाहरण का उदाहरण बनाकर नहीं कर रहे हैं। यही कारण है कि विधि doSomething() अपरिभाषित है।

अद्यतन:

इस

System.out.println(Sample.ValueB.getClass().getName()); 

प्रिंट Sample$2

जिसका मतलब है कि आपके पास भले ही आप Sample$2 के उदाहरण में विधि doSomething() है जो का प्रयास करें: इस इस प्रकार साबित किया जा सकता ValueB नाम दिया गया है, आप इसे Sample के सुपर-क्लास संदर्भ के माध्यम से संदर्भित कर रहे हैं और इसलिए कक्षा Sample में परिभाषित केवल उन्हीं विधियों संकलन समय पर दृश्यमान।

हालांकि आप प्रतिबिंब के माध्यम से रनटाइम पर doSomething() पर कॉल कर सकते हैं।

+1

अधिक महत्वपूर्ण बात: "फ़ील्ड" का प्रकार 'मान' ** ** अभी भी ** नमूना 'और * नहीं *' नमूना $ 1' होगा। –

3

public void doSomething(){ }private void doSomething(){ } के समान प्रभाव होगा।

doSomething() वैल्यूबी के बाहर दिखाई नहीं दे रहा है जब तक आप doSomething()Sample पर नहीं जोड़ते।

प्रत्येक Sample मूल्य में Sample है, इसलिए इसमें अलग-अलग मानों (बाहरी परिप्रेक्ष्य से) के तरीकों के अलग-अलग सेट नहीं हो सकते हैं।

+0

चेतावनी: 'नमूना' * मान * ** ** ** के पास अधिक विशिष्ट प्रकार हैं यदि उनके पास कक्षा का शरीर है। 'नमूना' * फ़ील्ड * में केवल' नमूना 'प्रकार होता है। –

+0

@ जोचिम: निश्चित रूप से, लेकिन उन विशिष्ट प्रकार नमूने के अज्ञात उप-वर्ग हैं, इसलिए "बाहर" आप केवल नमूना द्वारा परिभाषित इंटरफ़ेस का उपयोग कर सकते हैं। मैंने अपना आत्म स्पष्ट नहीं किया - क्षमा करें। –

संबंधित मुद्दे