2012-07-03 14 views
8

मुझे एक आंतरिक कक्षा के अंदर चर बदलने की आवश्यकता है और मुझे कुख्यात "एक अलग विधि में परिभाषित आंतरिक कक्षा के अंदर एक गैर-अंतिम चर का संदर्भ नहीं दे सकता" त्रुटि।आंतरिक वर्ग गैर-अंतिम परिवर्तनीय जावा

void onStart(){ 
    bt.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View v) { 
     int q = i; 
    } 
    }); 
} 

मैं जल्दी से एक वर्ग है कि चीजें मैं नहीं बदल करना चाहता था के सभी आयोजित किए गए और

class temp{ 
    int q; 
} 

void onStart(){ 
    final temp x = new temp(); 
    bt.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View v) { 
     x.q = i; 
    } 
    }); 
} 

यह लगता है कि मैं क्या जरूरत है हो सकता है और इसे करने के लिए आंतरिक कक्षा के बाहर कक्षा का अंतिम संस्करण बनाया काम करता है लेकिन मैं सोच रहा हूं कि इस समस्या के आसपास सही तरीके से काम करना है या नहीं। इसके अलावा, मैं वास्तव में अपनी कक्षा का नाम देने के लिए temp शब्द का उपयोग करने से नफरत करता हूं। क्या मैंने ऐसा करने के लिए एक वास्तविक प्रोग्रामिंग शब्द है ताकि मैं अपनी कक्षा के लिए एक और वर्णनात्मक नाम बना सकूं?

उत्तर

9

आप किसी अज्ञात व्यक्ति की बजाय एक आंतरिक कक्षा बना सकते हैं (जैसे आप वर्तमान में कर रहे हैं)। फिर आपके पास एक कन्स्ट्रक्टर और कोई अन्य तरीका है जिसे आप अपने सदस्यों को सेट करना चाहते हैं। कोई हैकनेस की आवश्यकता नहीं है (1 मामले की सरणी की तरह)।

मुझे यह क्लीनर मिल जाता है यदि कक्षा को बाहरी कक्षा के साथ डेटा के किसी भी विनिमय की आवश्यकता होती है, लेकिन यह स्वीकार करें कि यह एक व्यक्तिगत वरीयता है। 1 मुहावरे की सरणी भी काम करेगी और अधिक terse है, लेकिन स्पष्ट रूप से, यह सिर्फ fugly लग रहा है। मैं आमतौर पर उन अज्ञात आंतरिक कक्षाओं को सीमित करता हूं जो बाहरी वर्ग में डेटा अपडेट करने के बिना केवल क्रियाएं करते हैं।

उदाहरण के लिए:

private MyListener listener = new MyListener(); 

void onStart(){ 
    bt.setOnClickListener(listener); 
} 

class MyListener implements OnClickListener 
{ 
    String name; 
    int value; 

    void setName(String newName) 
    { 
     name = newName; 
    } 

    void setValue(int newValue) 
    { 
     value = newValue; 
    } 

    public void onClick(View v) 
    { 
     // Use the data for some unknown purpose 
    } 
} 

वहाँ एक से अधिक थ्रेड शामिल हैं, तो उचित तुल्यकालन रूप में अच्छी तरह से इस्तेमाल किया जा करना होगा।

+0

ब्रावो। दूसरी अच्छी बात यह है कि यह आंतरिक वर्ग अधिक विस्तारणीय और पुन: प्रयोज्य है। आईएमओ, गुमनाम आंतरिक कक्षाएं लगभग हमेशा एक बुरा विचार हैं। – user949300

+0

वे एक ऑफ एक्शन स्टाइल क्लास के रूप में अच्छी तरह से काम करते हैं, विशिष्ट घटनाओं के लिए हैंडलर जिसमें इनपुट के आधार पर क्रियाएं की जा सकती हैं। जीयूआई प्रोग्रामिंग में बहुत आम है, जो उसका उदाहरण है। इस मामले में छोड़कर उन वर्गों के बीच बातचीत है जो मामलों को जटिल बनाती हैं। – Robin

+0

यही वह है जिसे मैं ढूंढ रहा था! धन्यवाद! –

2

मैंने अपने other thread here में एक समान उत्तर पोस्ट किया। असल में विचार एक "रैपर" बनाना है जो किसी भी Object प्रकार पर बहुत अधिक लपेटता है। चूंकि जावा में final "कोई पुन: असाइनमेंट" नहीं है और "स्थिर" नहीं है, इसलिए यह चाल बहुत अच्छी तरह से काम करती है। लेकिन जैसा कि मूल पोस्ट में बताया गया है, सुनिश्चित करें कि आप बहु-थ्रेडेड वातावरण में इसका उपयोग करते समय सावधानी से चलें।

0

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

इसे सरलता से रखने के लिए, यदि आंतरिक वर्ग को इसे बदलने की आवश्यकता है, तो इसे आंतरिक कक्षा में एक चर बना दें।

0

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

इस तरह यदि बाद में मेनू या इरादा या एक इशारा है जो उसी सामान को निष्पादित करने की आवश्यकता है, तो कॉल वहां है।

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