2010-01-31 13 views
7

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

String[] moveArray = {moveRight,moveDown,moveLeft,moveUp}; 
for (i = 0; i < 4; i++) { 
    while (myWumpus.moveArray[i]) { 
     myWumpus.moveArray[i]; 
     generator.updateDisplay(); 
    } 
} 

जब मैं संकलन मैं

not a statement myWumpus.moveArray[i](); 
';' expected myWumpus.moveArray[i](); 

पाने की कोशिश

तो (यह पहले बयान करते हुए पाश में संदर्भित करता है), मुझे लगता है कि शायद है क्योंकि मैं: यह है कि मैं क्या है मैं इसे स्ट्रिंग प्रकार का एक ऐरे बना रहा हूँ? क्या कोई प्रकार का तरीका है? क्या ये संभव भी है? कोई समाधान स्वागत है :)। इसके अलावा, मैं लूप के दौरान 4 का उपयोग कर काम करने के लिए इसे प्राप्त कर सकता हूं, इसलिए आपको मुझे वह समाधान दिखाने की ज़रूरत नहीं है। धन्यवाद!

उत्तर

14

आप सीधे सरणी में विधियों को स्टोर नहीं कर सकते हैं। हालांकि आप वस्तुओं को स्टोर कर सकते हैं, जो एक ही विधि को अलग-अलग लागू करते हैं। उदाहरण के लिए:

Mover[] moveArray = {new RightMover(), new DownMover() new LeftMover(), new UpMover() }; 
for (i = 0; i < 4; i++) { 
    while (myWumpus.moveArray[i]) { 
     moveArray[i].move(); 
     generator.updateDisplay(); 
    } 
} 
+0

बहुत अच्छी व्याख्या। मैं अब चार लूपों के साथ रहूंगा लेकिन अगर यह उससे कहीं अधिक है तो मैं इसे आजमाउंगा! – Paul

+0

एक भिन्नता enums का उपयोग करता है। आपको कन्स्ट्रक्टर की बजाय विधि कॉल में पैरामीटर के माध्यम से संचालित ऑब्जेक्ट को पास करने की आवश्यकता है। –

5

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

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

+0

+1 हां, इंटरफेस अधिकांश समय प्रतिबिंब का उपयोग करने से बेहतर होते हैं।:-) –

+0

java.lang.reflect.Method एक प्रथम श्रेणी वस्तु है, लेकिन मैं आपके द्वारा प्रस्तुत किए गए सामान्य समाधान से सहमत हूं –

+1

@ ब्रायन: हाँ, लेकिन यह विधि का प्रतिनिधित्व करने वाला एक ऑब्जेक्ट है, यह वास्तव में प्रति विधि नहीं है -se। आप विधि का उदाहरण "कॉल" नहीं कर सकते (आप उदाहरण पर एक विधि कहते हैं)। – Draemon

3

हां, आप Reflection का उपयोग करके सरणी में विधियों को स्टोर कर सकते हैं, हालांकि यह संभावना है कि आप वास्तव में इस स्थिति में क्या करना चाहते हैं polymorphism का उपयोग करें।

आपकी समस्या के संबंध में बहुरूपता का एक उदाहरण के रूप में - कहते हैं कि तुम एक अंतरफलक बनाया इस प्रकार है:

public interface MoveCommand { 
    void move(); 
} 

तो आप क्रियान्वयन कर सकें इस प्रकार है:

public class MoveLeftCommand implements MoveCommand { 
    public void move() { 
     System.out.println("LEFT"); 
    } 
} 

आदि अन्य के लिए विकल्प ले जाएँ। इसके बाद आप उदाहरण के लिए एक MoveCommand[] या एक List<MoveCommand> तरह संग्रह में इन संग्रहीत कर सकती है, और उसके बाद प्रत्येक तत्व पर) सरणी/संग्रह बुला चाल से अधिक पुनरावृति (,:

public class Main { 

    public static void main(String[] args) { 
     List<MoveCommand> commands = new ArrayList<MoveCommand>(); 
     commands.add(new MoveLeftCommand()); 
     commands.add(new MoveRightCommand()); 
     commands.add(new MoveLeftCommand()); 

     for (MoveCommand command:commands) { 
      command.move(); 
     } 
    } 

} 

बहुरूपता बहुत शक्तिशाली है, और इसके बाद के संस्करण एक है Command Pattern नामक किसी चीज़ का बहुत सरल उदाहरण। अपने बाकी वम्पस विश्व कार्यान्वयन का आनंद लें :)

4

आप इस तरह के तरीकों को कॉल नहीं कर सकते हैं। लेकिन तुम प्रतिबिंब का उपयोग कर सकते हैं:

बस, जबकि पाश में पहली पंक्ति को बदलने:

Method m = myWumps.getClass().getMethod(moveArray[i]); // if the method is void 
m.invoke(myWumps); 

(यदि आप यह घोषणा/कुछ अपवादों को पकड़ने के लिए होगा) लेकिन आप बेहतर था प्रतिबिंब से बचें, और इसके बजाय Command pattern का उपयोग करें।

+0

प्रतिबिंब से बचने के लिए बेहतर क्यों है? प्रतिबिंब समय लेने या स्मृति भारी है? उपरोक्त कोड बहुत साफ दिखते हैं। – byteBiter

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