"हाय अमीगो! मुझे आशा है कि आपको अपने तरीकों का उपयोग करके कार्यों को हल करने में मज़ा आया होगा, और आपको यह एहसास होगा कि तरीकों को बनाना कितना सुविधाजनक है। अब सबसे दिलचस्प विषय के बारे में बात करते हैं।"

"तुमने मेरी रुचि को बढ़ा दिया है, डिएगो... एक नया विषय?"

"हर विषय आपके लिए नया है, मेरे युवा रोबोट! और यह कोई अपवाद नहीं है। हालांकि एक बार फिर यह तरीकों के बारे में है। आपने शायद पहले से ही इस तरह के तरीकों से ध्यान दिया है कि हम तर्कों को विधियों में पारित कर सकते हैं। एक बार जब हम विधि के अंदर System.out.println()हैं , हम उन्हें पैरामीटर के रूप में संदर्भित करते हैं।"

"पैरामीटर वही हैं जो हम कोष्ठक के अंदर लिखते हैं?"

"हाँ, बिल्कुल। और, वास्तव में, पैरामीटर उन लाभों को बहुत बढ़ाते हैं जो हमें विधियों को बनाने और उपयोग करने से मिलते हैं।"

"मैं समझता हूं कि आप उनका उपयोग करने के बारे में क्या कह रहे हैं, और यह पता चला है कि मैंने इसे पहले ही कर लिया है। हम पैरामीटर के साथ एक विधि कैसे घोषित करते हैं?"

"यह वास्तव में काफी सरल है:

public static void name(parameters)
{
  method body
}

name" विधि का अनूठा नाम कहां है और method bodyविधि बनाने वाले आदेशों का प्रतिनिधित्व करता है। और parametersविधि पैरामीटर के लिए प्लेसहोल्डर है, जिसे अल्पविराम से अलग किया जाता है।"

"हम्म... मुझे लगता है कि मैं समझ गया...या शायद नहीं..."

"मैं आपको इस टेम्प्लेट के बारे में कुछ और विवरण देता हूं ताकि आप निश्चित हों कि आप समझ गए हैं कि आप समझते हैं:

public static void name(Type1 name1, Type2 name2, Type3 name3)
{
  method body
}

यहां कुछ उदाहरण दिए गए हैं:

कोड व्याख्या
public static void print(String str)
{
}
विधि printपैरामीटर के साथ घोषित की गई है:
String str
public static void print(String str, int count)
{
}
विधि printको दो मापदंडों के साथ घोषित किया गया है:
String str
int count
public static void write(int x, int y)
{
}
विधि writeको दो मापदंडों के साथ घोषित किया गया है:
int x
int y

"आह... अब यह स्पष्ट है। और अगर हम नहीं चाहते कि विधि में पैरामीटर हों, तो हम कोष्ठक को खाली छोड़ देते हैं।"

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

"उदाहरण के लिए, चलो एक विधि लिखते हैं जो पाठ की दी गई पंक्ति को दी गई संख्या में प्रदर्शित करती है। इसे कैसे करना है इस पर कोई विचार?"

"ठीक है ... ऐसा लगता है कि मैं अच्छी तरह से जानता हूं कि स्क्रीन पर कई बार स्ट्रिंग प्रदर्शित करने के लिए कोड कैसे लिखना है ..."

"आप प्रदर्शित होने वाली स्ट्रिंग को कैसे निर्दिष्ट करते हैं? और आप प्रदर्शित लाइनों की संख्या कैसे निर्दिष्ट करते हैं? क्या आप अनुमान लगा सकते हैं?"

"चीजें स्पष्ट होने लगी हैं ... शायद विधि मापदंडों की मदद से?"

"बिल्कुल सही। पाठ की पंक्ति के लिए एक स्ट्रिंग पैरामीटर, और प्रदर्शित पंक्तियों की संख्या के लिए एक संख्यात्मक पैरामीटर। ऐसा करने वाला कोड इस तरह दिखेगा:

कोड व्याख्या
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.println(text);
   }

   public static void main(String[] args)
   {
     printLines("Hi", 10);
     printLines("Bye", 20);
   }
}

हमने printLinesनिम्नलिखित मापदंडों के साथ विधि की घोषणा की:
String textविधि int count

स्ट्रिंग text countबार प्रदर्शित करती है



हम printLinesविभिन्न मापदंडों के साथ विधि को कॉल करते हैं

"हर बार जब किसी विधि को कहा जाता है, तो उसके मापदंडों को पास किए गए मान दिए जाते हैं, और उसके बाद ही हम विधि के अंदर आदेशों को निष्पादित करना शुरू करते हैं।

बहस

"मैं चाहता हूं कि आप उन कॉलिंग विधियों पर विशेष ध्यान दें जिनमें पैरामीटर हैं। विधि को पास किए गए मान आमतौर पर तर्क कहलाते हैं जब वे विधि में पारित होते हैं।

आइए हमारे उदाहरण पर एक और नज़र डालें:

कोड व्याख्या
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.println(text);
   }

   public static void main(String[] args)
   {
     printLines("Hi", 10);
     printLines("Bye", 20);
   }
}

printLinesहमने निम्नलिखित मापदंडों के साथ विधि की घोषणा की
String text: int count

विधि स्ट्रिंग text countबार प्रदर्शित करती है


हम printLinesनिम्नलिखित तर्कों के साथ विधि को कॉल करते हैं:
text = "Hi"; count = 10;
text = "Bye"; count = 20;

"जब printLinesपहली बार विधि को बुलाया गया था, तो इसके पैरामीटर को निम्नलिखित मान दिए गए थे:

String text = "Hi", int count = 10.

"जब printLinesविधि को दूसरी बार बुलाया गया था, तो इसके पैरामीटर को अलग-अलग मान दिए गए थे:

String text = "Bye", int count = 20.

"पैरामीटर वेरिएबल्स से अधिक नहीं हैं और न ही कम हैं जो एक विधि कहलाते समय कुछ मान निर्दिष्ट किए जाते हैं। मान "Hi", "Bye", 10और 20स्वयं तर्क कहलाते हैं।"

"मैं अंतर को याद रखने की कोशिश करूँगा और इन अवधारणाओं को भ्रमित नहीं करूँगा।"

किसी विधि को कॉल करते समय परस्पर विरोधी चर नाम

"जब आप एक विधि कहते हैं, तो आप तर्कों के रूप में चर का उपयोग कर सकते हैं।

"ठीक है, यह समझ में आता है!"

"यह समझ में आता है, लेकिन यह संभावित रूप से कुछ कठिनाइयाँ पैदा कर सकता है। आइए एक बार फिर अपने उदाहरण पर वापस जाएँ, लेकिन इस बार हम तर्कों को अलग-अलग चरों में ले जाएँगे:

कोड व्याख्या
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.print(text);
   }

   public static void main(String[] args)
   {
     String str = "Hi";
     String n = 10;
     printLines(str, n);
   }
}

printLinesहमने निम्नलिखित मापदंडों के साथ विधि की घोषणा की
String text: int count

विधि स्ट्रिंग text countबार प्रदर्शित करती है



हम printLinesनिम्नलिखित तर्कों के साथ विधि को कॉल करते हैं:
text = str;
count = n;

"हम्म ... मुझे कोई कठिनाई नहीं दिख रही है। हमारे पास एक strचर है। textजब विधि को कॉल किया जाता है तो इसका मान पैरामीटर को असाइन किया जाता है। हमारे पास एक nचर होता है। इसका मान पैरामीटर को असाइन किया जाता है countजब विधि को कॉल किया जाता है।" "अब तक, सब कुछ स्पष्ट है।"

"अच्छा, अच्छा। अब विधि में हमारे चर का नाम बदलें main:

कोड व्याख्या
class Solution
{
   public static void printLines(String text, int count)
   {
     for (int i = 0; i < count; i++)
       System.out.print(text);
   }

   public static void main(String[] args)
   {
     String text = "Hi";
     String count = 10;
     printLines(text, count);
   }
}

printLinesहमने निम्नलिखित मापदंडों के साथ विधि की घोषणा की
String text: int count

विधि स्ट्रिंग text countबार प्रदर्शित करती है



हम printLinesनिम्नलिखित तर्कों के साथ विधि को कॉल करते हैं:
text = text;
count = count;

"दो बातों पर ध्यान दो

पहला: हमारे पास अलग-अलग तरीकों से एक ही नाम के वेरिएबल्स हैं। ये अलग-अलग चर हैं (हम जानबूझकर अलग-अलग रंगों का उपयोग करके उन्हें चित्रित करते हैं)। सब कुछ पिछले उदाहरण की तरह ही काम करता है, जहां विधि में वेरिएबल्स का mainनाम दिया गया था strऔर n.

दूसरा: विधि कहलाने पर कुछ भी जादुई नहीं होता है। मापदंडों को केवल तर्क मान निर्दिष्ट किए जाते हैं। चाहे वे संख्याएँ हों, तार हों, चर हों या भाव हों।

"मुख्य विधि में चर का नाम बदलने के बाद, कुछ भी नहीं बदला है। वे पहले अलग-अलग तरीकों में अलग-अलग चर थे , और इसलिए वे बने रहते हैं। दो textचर के बीच कोई जादुई संबंध नहीं है।"

"अब मुझे पता है।"

विधियों के संदर्भ पास करना

"मुझे आशा है कि आप पहले से ही उन सभी बातों को आत्मसात कर चुके होंगे जो मैंने आपको तरीकों के लिए तर्क पारित करने के बारे में बताई हैं। मैं ऐसा इसलिए कहता हूँ, क्योंकि अब हम इस विषय में थोड़ा और गहरा गोता लगाने जा रहे हैं। ध्यान से सुनें।"

"आप पहले से ही जानते हैं कि जावा में कुछ वेरिएबल्स वैल्यू को स्टोर नहीं करते हैं, बल्कि इसके बजाय एक रेफरेंस , यानी मेमोरी के ब्लॉक का पता जहां वैल्यू स्थित हैं। इस तरह स्ट्रिंग वेरिएबल्स और एरे वेरिएबल्स काम करते हैं।

"जब एक डेवलपर एक सरणी चर के लिए एक और सरणी चर निर्दिष्ट करता है, तो क्या होता है?"

"क्या वे फिर उसी पते पर इंगित करते हैं?"

"सही। स्मृति में एक ही स्थान को संदर्भित करने के लिए दो चर शुरू होते हैं:

"और क्या होता है यदि इनमें से एक चर एक विधि पैरामीटर है?

कोड व्याख्या
class Solution
{
   public static void sum(int[] data)
   {
     int total = 0;
     for (int i = 0; i < data.length; i++)
       total = total + data[i];
     System.out.println(total);
   }
   
   public static void main(String[] args)
   {
     int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30};
     sum(months);
   }
}


विधि sumपारित सरणी में संख्याओं के योग की गणना करती है और इसे स्क्रीन पर प्रदर्शित करती है

"बिल्कुल वही होता है: dataपैरामीटर में चर के रूप में स्मृति के समान क्षेत्र का संदर्भ होगा months। जब विधि को कॉल किया जाता है, तो एक साधारण असाइनमेंट होता है :।data = months

"और चूंकि दोनों चर एक पूर्णांक को संग्रहीत करने वाली मेमोरी के समान क्षेत्र को संदर्भित करते हैं, तो sumविधि न केवल सरणी से मान पढ़ सकती है, बल्कि उन्हें बदल भी सकती है!"

"मुझे लगता है कि मैं समझता हूं, लेकिन मुझे और उदाहरण चाहिए!"

"ठीक है, उदाहरण के लिए, हम अपनी खुद की विधि लिख सकते हैं जो एक ही मान के साथ द्वि-आयामी सरणी भरती है। यह इस तरह दिख सकता है:

कोड व्याख्या
class Solution
{
   public static void fill(int[][] data, int value)
   {
     for (int i = 0; i < data.length; i++)
     {
       for (int j = 0; j < data[i].length; j++)
         data[i][j] = value;
     }
  }

   public static void main(String[] args)
   {
     int[][] months = {{31, 28}, {31, 30, 31}, {30, 31, 31}};
     fill (months, 8);
   }
}


विधि fill पारित द्वि-आयामी सरणी में प्रत्येक सेल पर पुनरावृत्त करती है और valueउन्हें असाइन करती है।






हम एक द्वि-आयामी सरणी बनाते हैं।
हम पूरे सरणी को संख्या से भरते हैं 8

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

"अब एक बार फिर विधि नामों पर लौटते हैं।"

"मैं कल्पना नहीं कर सकता कि नामों के बारे में और क्या कहा जा सकता है!"

"ठीक है, जावा भाषा मानक को अद्वितीय नाम रखने के लिए एक ही कक्षा में सभी विधियों की आवश्यकता होती है।

"तो, एक ही कक्षा में दो समान नामित विधियों की घोषणा करना असंभव है?"

"अब - पूरा ध्यान दें! कक्षा में विधियों में वास्तव में समान नाम हो सकते हैं! लेकिन इस मामले में, उनके पास अलग-अलग पैरामीटर होना चाहिए। दूसरे शब्दों में, समानता के लिए विधियों की तुलना की जाती है, न केवल नामों को ध्यान में रखा जाता है, बल्कि यह भी पैरामीटर के प्रकार ! ध्यान दें कि मैंने विशेष रूप से प्रकार कहा है। पैरामीटर के नाम पर ध्यान नहीं दिया जाता है । उदाहरण:

कोड व्याख्या
void fill(int[] data, int value) {
}
void fill(int[][] data, int value) {
}
void fill(int[][][] data, int value)  {
}
ये तीन तरीके अलग-अलग तरीके हैं। उन्हें एक ही कक्षा में घोषित किया जा सकता है।
void print(String str) {
}
void print(String str, String str2) {
}
void print(int val) {
}
void print(double val) {
}
void print() {
}
इन पांच विधियों में से प्रत्येक को अलग-अलग माना जाता है । उन्हें एक ही कक्षा में घोषित किया जा सकता है।
void sum(int x, int y) {
}
void sum(int data, int value) {
}
"इन दो विधियों को समान माना जाता है , जिसका अर्थ है कि उन्हें एक ही कक्षा में घोषित नहीं किया जा सकता है।"

"मैं पूरी तरह से भ्रमित हूँ! हमें इन सबकी आवश्यकता क्यों है? कुछ विधियों को समान क्यों माना जाता है , जबकि अन्य भिन्न हैं? और किसी विधि की विशिष्टता का निर्धारण करते समय पैरामीटर नामों को ध्यान में क्यों नहीं रखा जाता है? अद्वितीयता क्यों आवश्यक है? सभी?"

"बात यह है कि जब संकलक किसी प्रोग्राम को संकलित करता है, तो उसे पता होना चाहिए कि आप किसी भी स्थान पर किस विधि को कॉल करना चाहते हैं।

"उदाहरण के लिए, यदि आप लिखते हैं , तो संकलक स्मार्ट है और आसानी से निष्कर्ष निकालेगा कि आप पैरामीटर के साथ यहां विधि को कॉल करने का इरादा रखते हैं । लेकिन यदि आप लिखते हैं , तो संकलक पैरामीटर के साथ विधि को कॉल देखेगा । इसका कोई पता नहीं है विधि घोषित करते समय प्रोग्रामर ने पैरामीटर को क्या नाम दिया था।"System.out.println("Hi")println()StringSystem.out.println(1.0)println()double

आह, ऐसा लगता है कि यह शुरू हो रहा है!

"जब किसी विधि को कहा जाता है, तो संकलक यह सुनिश्चित करता है कि तर्कों के प्रकार पैरामीटर के प्रकार से मेल खाते हैं। यह तर्कों के नाम पर कोई ध्यान नहीं देता है। जावा में, पैरामीटर नाम संकलक को यह निर्धारित करने में मदद नहीं करते हैं कि कौन सी विधि कॉल करें। प्रोग्रामर को उनकी जरूरत है, कंपाइलर की नहीं।

"और मुझे लगता है कि किसी विधि की विशिष्टता का निर्धारण करते समय उन्हें ध्यान में क्यों नहीं रखा जाता है?"

"हाँ, यह पूरी तरह से सही है। एक विधि का नाम और उसके मापदंडों के प्रकार को विधि हस्ताक्षर कहा जाता है । उदाहरण के लिए, sum (int, int)"

"इसलिए प्रत्येक वर्ग के पास अद्वितीय नामों वाले तरीकों के बजाय अद्वितीय हस्ताक्षर वाले तरीके होने चाहिए।"

"शाबाश, अमीगो! आपने इस पाठ को पूरी तरह से सारांशित किया है। अगर कुछ अस्पष्ट रहता है, तो घबराएं नहीं। कुछ कार्यों के बाद यह विषय स्पष्ट हो जाएगा।"