CodeGym /Java Blog /अनियमित /विधि घोषणा
John Squirrels
स्तर 41
San Francisco

विधि घोषणा

अनियमित ग्रुप में प्रकाशित
नमस्ते! आप पहले से ही फील्ड्स और मेथड्स के साथ अपनी खुद की क्लासेस बनाने के बारे में जान चुके हैं। अब हम तरीकों पर ध्यान केन्द्रित करेंगे।
विधि घोषणा - 1
बेशक, हम अपने पाठों में पहले ही इसे एक से अधिक बार कर चुके हैं, लेकिन हमने मुख्य रूप से सामान्यताओं को कवर किया है। आज, हम तरीकों का विश्लेषण करने जा रहे हैं, और अध्ययन करेंगे कि वे किस चीज से बने हैं, उन्हें बनाने के विभिन्न तरीके, और इसे कैसे प्रबंधित करें। :) चल दर!

विधि घोषणा

एक विधि को परिभाषित करने वाले सभी कोड को एक विधि घोषणा कहा जाता है । विधि घोषणा के सामान्य रूप को निम्नानुसार वर्णित किया जा सकता है:

access modifier, return type, method name (parameter list) {
    // method body
}
Dogउदाहरण के तौर पर, क्लास के विभिन्न तरीकों की घोषणाओं पर एक नज़र डालें ।

public class Dog {

   String name;

   public Dog(String name) {
       this.name = name;
   }

   public static void main(String[] args) {
       Dog max = new Dog("Max");
       max.woof();

   }

   public void woof() {
       System.out.println("A dog named " + name + " says \"Woof, woof!\"");
   }

   public void run(int distanceInFeet) {
       System.out.println("A dog named " + name + " ran " + distanceInFeet + " feet!");
   }

   public String getName() {
       return name;
   }
}

1. एक्सेस संशोधक

एक्सेस संशोधक हमेशा पहले इंगित किया जाता है। कक्षा के सभी Dogतरीकों को सार्वजनिक संशोधक के साथ चिह्नित किया गया है। इसका मतलब है कि हम उन्हें किसी अन्य वर्ग से बुला सकते हैं:

public class Main {

   public static void main(String[] args) {

       Dog butch = new Dog("Butch");
       butch.run(100);
   }

}
जैसा कि आप देख सकते हैं, क्लास के तरीकों को क्लास Dogमें आसानी से एक्सेस किया जा सकता है । यह सार्वजनिक संशोधक Mainके कारण संभव है । जावा में, अन्य संशोधक हैं। वे सभी विधियों को अन्य वर्गों में उपयोग करने की अनुमति नहीं देते हैं। हम उनके बारे में अन्य पाठों में बात करेंगे। याद रखने वाली मुख्य बात यह है कि संशोधक किसके लिए ज़िम्मेदार है: क्या कोई विधि अन्य वर्गों में उपलब्ध है :)

2. स्थिर खोजशब्द

विधियों में से एक Dog, main(), को कीवर्ड स्थिर के साथ चिह्नित किया गया है । यह विधि घोषणा का भी हिस्सा है, और हम इसका अर्थ पहले से ही जानते हैं। पाठ की शुरुआत में दिए गए विधि घोषणा टेम्पलेट में हमने इसका उल्लेख नहीं किया, क्योंकि यह वैकल्पिक है। यदि यह निर्दिष्ट है, तो इसे एक्सेस संशोधक के बाद आना चाहिए। याद रखें कि हाल के पाठों में हमने स्थैतिक (वर्ग) चरों के बारे में बात की थी? विधियों पर लागू होने पर, इस कीवर्ड का लगभग समान अर्थ होता है। यदि कोई विधि स्थिर है , तो इसका उपयोग कक्षा के किसी विशिष्ट वस्तु के संदर्भ के बिना किया जा सकता है। Dogऔर वास्तव में, आपको स्थिर main()विधि को चलाने के लिए किसी वस्तु की आवश्यकता नहीं हैDogकक्षा। यह एक के बिना ठीक चलेगा। यदि यह विधि स्थिर नहीं होती, तो हमें इसे चलाने के लिए पहले एक वस्तु बनाने की आवश्यकता होती।

3. रिटर्न वैल्यू

यदि हमारी पद्धति को कुछ वापस करना चाहिए, तो हम वापसी मूल्य के प्रकार को निर्दिष्ट करते हैं। यह गेटर के उदाहरण से स्पष्ट है getName():

public String getName() {
   return name;
}
यह एक Stringवस्तु लौटाता है। यदि कोई विधि कुछ भी वापस नहीं करती है, तो इसके बजाय कीवर्ड शून्य का उपयोग किया जाता है, जैसा कि विधि में है woof():

public void woof() {
   System.out.println("A dog named " + name + " says \"Woof, woof!\"");
}

एक ही नाम के तरीके

ऐसी परिस्थितियाँ होती हैं जब हमें किसी विधि को कॉल करने के कई अलग-अलग तरीके चाहिए होते हैं। अपनी खुद की आर्टिफिशियल इंटेलिजेंस क्यों नहीं बनाते? Amazon के पास Alexa है, Apple के पास सिरी है, तो हमारे पास एक क्यों नहीं होना चाहिए? :) फिल्म आयरन मैन में, टोनी स्टार्क अपनी खुद की अविश्वसनीय कृत्रिम बुद्धि, जार्विस बनाता है। आइए उस भयानक चरित्र को श्रद्धांजलि दें और उसके सम्मान में हमारे एआई का नाम दें। :) पहली चीज जो हमें करने की ज़रूरत है वह यह है कि जार्विस को कमरे में प्रवेश करने वाले लोगों को नमस्ते कहना सिखाना है (यह अजीब होगा अगर ऐसी अद्भुत बुद्धि असभ्य हो)।

public class Jarvis {

   public void sayHi(String name) {
       System.out.println("Good evening, " + name + ". How are you?");
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
   }
}
कंसोल आउटपुट: शुभ संध्या, टोनी स्टार्क। आप कैसे हैं? बहुत अच्छा! जार्विस अब मेहमानों का स्वागत करने में सक्षम है। बेशक, इससे अधिक बार उनके गुरु, टोनी स्टार्क होंगे। लेकिन क्या हुआ अगर वह अकेले नहीं आया! लेकिन हमारी sayHi()पद्धति केवल एक तर्क को स्वीकार करती है। और इसलिए यह केवल कमरे में प्रवेश करने वाले एक व्यक्ति का अभिवादन कर सकता है, और दूसरे की उपेक्षा करेगा। बहुत विनम्र नहीं, सहमत? : / इस मामले में, हम एक ही नाम के साथ केवल 2 विधियों को लिखकर समस्या का समाधान कर सकते हैं, लेकिन अलग-अलग पैरामीटर:

public class Jarvis {

   public void sayHi(String firstGuest) {
       System.out.println("Good evening, " + firstGuest + ". How are you?");
   }

   public void sayHi(String firstGuest, String secondGuest) {
       System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
   }

}
इसे मेथड ओवरलोडिंग कहा जाता है । मेथड ओवरलोडिंग हमारे प्रोग्राम को अधिक लचीला बनाता है और काम करने के विभिन्न तरीकों को समायोजित करता है। आइए समीक्षा करें कि यह कैसे काम करता है:

public class Jarvis {

   public void sayHi(String firstGuest) {
       System.out.println("Good evening, " + firstGuest + ". How are you?");
   }

   public void sayHi(String firstGuest, String secondGuest) {
       System.out.println("Good evening, " + firstGuest + " and " + secondGuest + ". How are you?");
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
कंसोल आउटपुट: शुभ संध्या, टोनी स्टार्क। आप कैसे हैं? शुभ संध्या, टोनी स्टार्क और कप्तान अमेरिका। आप कैसे हैं? बढ़िया, दोनों संस्करणों ने काम किया। :) लेकिन हमने समस्या का समाधान नहीं किया! क्या होगा अगर तीन मेहमान हैं? बेशक, हम sayHi()विधि को फिर से अधिभारित कर सकते हैं, ताकि यह तीन अतिथि नामों को स्वीकार कर सके। लेकिन 4 या 5 हो सकते हैं। अनंत तक। क्या जार्विस को किसी भी संख्या में नामों को संभालने के लिए सिखाने का कोई बेहतर तरीका नहीं है, sayHi()विधि को एक लाख बार ओवरलोड किए बिना ()? : / बेशक वहाँ है! अगर ऐसा नहीं होता, तो क्या आपको लगता है कि जावा दुनिया की सबसे लोकप्रिय प्रोग्रामिंग भाषा होगी? ;)

public class Jarvis {

   public void sayHi(String...names) {

       for (String name: names) {
           System.out.println("Good evening, " + name + ". How are you?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark");
       System.out.println();
       jarvis.sayHi("Tony Stark", "Captain America");
   }
}
जब ( स्ट्रिंग... नाम ) एक पैरामीटर के रूप में प्रयोग किया जाता है, तो यह इंगित करता है कि स्ट्रिंग्स का एक संग्रह विधि को पारित किया जाएगा। हमें पहले से निर्दिष्ट करने की आवश्यकता नहीं है कि कितने होंगे, इसलिए अब हमारी विधि अधिक लचीली है:

public class Jarvis {

   public void sayHi(String...names) {

       for (String name: names) {
           System.out.println("Good evening, " + name + ". How are you?");
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.sayHi("Tony Stark", "Captain America", "Black Widow", "Hulk");
   }
}
कंसोल आउटपुट: शुभ संध्या, टोनी स्टार्क। आप कैसे हैं? शुभ संध्या, कप्तान अमेरिका। आप कैसे हैं? शुभ संध्या, काली विधवा। आप कैसे हैं? शुभ संध्या, हल्क। आप कैसे हैं? विधि के अंदर, हम सभी तर्कों पर पुनरावृति करते हैं और नामों के साथ स्वरूपित वाक्यांशों को प्रदर्शित करते हैं। यहाँ हम एक सरलीकृत for-eachलूप का उपयोग करते हैं (जो आपने पहले देखा है)। यह यहाँ एकदम सही है, क्योंकि ( String...names ) नोटेशन का वास्तव में मतलब है कि कंपाइलर सभी पास किए गए तर्कों को एक सरणी में रखता है। नतीजतन, हम चर नामों के साथ काम कर सकते हैंजैसा कि हम एक सरणी के साथ काम करेंगे, जिसमें लूप में इसके माध्यम से पुनरावृति शामिल है। साथ ही, यह किसी भी पास की गई स्ट्रिंग्स के साथ काम करेगा! दो, दस, यहां तक ​​कि एक हजार—यह विधि किसी भी संख्या में मेहमानों के साथ ठीक से काम करेगी। क्या आपको नहीं लगता कि सभी संभावनाओं के लिए विधि को ओवरलोड करने से कहीं अधिक सुविधाजनक है? :) यहाँ मेथड ओवरलोडिंग का एक और उदाहरण है। आइए जार्विस को एक printInfoFromDatabase()विधि दें। यह डेटाबेस से किसी व्यक्ति के बारे में जानकारी प्रदर्शित करेगा। यदि डेटाबेस इंगित करता है कि कोई व्यक्ति सुपर हीरो या पर्यवेक्षक है, तो हम वह जानकारी प्रदर्शित करेंगे:

public class Jarvis {

   public void printInfoFromDatabase (String bio) {

       System.out.println(bio);
   }

   public void printInfoFromDatabase(String bio, boolean isEvil, String nickname) {

       System.out.println(bio);
       if (!isEvil) {
           System.out.println("Also known as the superhero " + nickname);
       } else {
           System.out.println("Also known as the supervillain " + nickname);
       }
   }

   public static void main(String[] args) {
       Jarvis jarvis = new Jarvis();
       jarvis.printInfoFromDatabase("Laura Palmer. Date of birth: July 22, 1972. Twin Peaks, Washington");
       System.out.println();
       jarvis.printInfoFromDatabase("Max Eisenhardt. Height: 15.6 ft. Weight: 189 lbs. ", true, "Magneto");
   }
}
आउटपुट: लौरा पामर। जन्म तिथि: 22 जुलाई, 1972। ट्विन पीक्स, वाशिंगटन मैक्स आइजनहार्ट। कद: 15.6 फुट वजन: 189 एलबीएस। सुपरविलेन मैग्नेटो सो के रूप में भी जाना जाता है, हमारी पद्धति का व्यवहार उस डेटा पर निर्भर करता है जिसे हम पास करते हैं। यहाँ एक और महत्वपूर्ण बिंदु है: तर्कों का क्रम मायने रखता है! मान लीजिए कि हमारी विधि एक स्ट्रिंग और एक संख्या लेती है:

public class Person {

   public static void sayYourAge(String greeting, int age) {
       System.out.println(greeting + " " + age);
   }

   public static void main(String[] args) {

       sayYourAge("My age is ", 33);
       sayYourAge(33, "My age is "); // Error!
   }
}
यदि Personवर्ग की sayYourAge()विधि इनपुट के रूप में एक स्ट्रिंग और संख्या लेती है, तो यह आदेश है कि इन तर्कों को विधि में पारित किया जाना चाहिए! यदि हम उन्हें एक अलग क्रम में पास करते हैं, तो संकलक एक त्रुटि उत्पन्न करेगा और व्यक्ति अपनी उम्र नहीं कह पाएगा। वैसे, कंस्ट्रक्टर, जिन्हें हमने पिछले पाठ में कवर किया था, वे भी विधियाँ हैं! आप उन्हें ओवरलोड भी कर सकते हैं (यानी पैरामीटर के विभिन्न सेट के साथ कई कन्स्ट्रक्टर बनाएं) और पारित तर्कों का क्रम भी उनके लिए मौलिक रूप से महत्वपूर्ण है। वे असली तरीके हैं! :)

समान पैरामीटर वाले तरीकों का आह्वान कैसे करें

जैसा कि आप जानते हैं, nullजावा में एक कीवर्ड है। यह समझना बहुत महत्वपूर्ण है कि यह nullन तो कोई वस्तु है और न ही डेटा प्रकार । कल्पना कीजिए कि हमारे पास एक Personवर्ग और एक introduce()विधि है जो व्यक्ति के नाम और उम्र की घोषणा करती है। इसके अलावा, उम्र को पाठ या संख्या के रूप में पारित किया जा सकता है।

public class Person {

   public void introduce(String name, String age) {
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person alex = new Person();
       alex.introduce ("Alex", "twenty-one");

       Person mary = new Person();
       mary.introduce("Mary", 32);
   }
}
हम पहले से ही ओवरलोडिंग से परिचित हैं, इसलिए हम जानते हैं कि दोनों विधियां वैसा ही व्यवहार करेंगी जैसा उन्हें करना चाहिए: मेरा नाम एलेक्स है। मेरी उम्र इक्कीस है मेरा नाम मैरी है। मेरी उम्र 32 वर्ष है लेकिन क्या होगा यदि हम nullएक स्ट्रिंग या संख्या के बजाय दूसरे पैरामीटर के रूप में पास हो जाते हैं?

public static void main(String[] args) {

   Person victor = new Person();
   victor.introduce("Victor", null);// Ambiguous method call!
}
हमें संकलन त्रुटि मिलेगी! इसका क्या कारण है और वास्तव में "अस्पष्टता" क्या है? वास्तव में, यह सब बहुत आसान है। समस्या यह है कि हमारे पास विधि के दो संस्करण हैं: एक a के साथ Stringदूसरे तर्क के रूप में, और एक के साथ Integerदूसरे तर्क के रूप में। लेकिन a Stringऔर an Integerदोनों हो सकते हैं null! क्योंकि वे संदर्भ प्रकार हैं, nullउन दोनों के लिए डिफ़ॉल्ट मान है। इसलिए इस स्थिति में कंपाइलर यह पता नहीं लगा सकता है कि उसे किस विधि के संस्करण को कॉल करना चाहिए। इस समस्या का समाधान काफी सरल है। Nullस्पष्ट रूप से एक विशिष्ट संदर्भ प्रकार में परिवर्तित किया जा सकता है। इस प्रकार, जब आप एक विधि कहते हैं, तो आप दूसरे तर्क के लिए इच्छित डेटा प्रकार कोष्ठक में इंगित कर सकते हैं! संकलक आपके "संकेत" को समझेगा और सही विधि कहेगा:

public class Person {

   public void introduce(String name, String age) {
       System.out.println("Method with two strings!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, Integer age) {
       System.out.println("Method with a string and a number!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person victor = new Person();
       victor.introduce("Victor", (String) null);
   }
}
आउटपुट: विधि दो तार के साथ! मेरा नाम विक्टर है। मेरी आयु शून्य हैint ध्यान दें कि यदि पूर्णांक संदर्भ प्रकार के उदाहरण के बजाय संख्या पैरामीटर आदिम होता , तो ऐसी कोई त्रुटि नहीं होती।

public class Person {

   public void introduce(String name, String age) {
       System.out.println("Method with two strings!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public void introduce(String name, int age) {
       System.out.println("Method with a string and a number!!");
       System.out.println("My name is " + name + ". My age is " + age);
   }

   public static void main(String[] args) {

       Person victor = new Person();
       victor.introduce("Victor", null);
   }
}
क्या आप अनुमान लगा सकते हैं क्यों? यदि आपने अनुमान लगाया कि क्यों, अच्छा किया! :) क्योंकि आदिम नहीं हो सकते null। अब कंपाइलर के पास केवल एक ही विकल्प है, यानी introduce()विधि को दो स्ट्रिंग्स के साथ कॉल करना। यह विधि का वह संस्करण है जो हर बार विधि कहे जाने पर चलेगा।
टिप्पणियां
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION