1. Предаване на аргументи

И сега започва забавлението. Вероятно вече знаете от подобни методи 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

Ако не искаме методът да има параметри, тогава просто оставяме скобите празни.

Параметрите са специални променливи в метода. С тяхна помощ можете да предавате различни стойности на метода, когато бъде извикан.

Например, нека напишем метод, който показва низ от текст определен брой пъти.

Вече знаете How да пишете code за показване на низ на екрана няколко пъти. Но кой низ трябва да отпечатате? И колко пъти? Ето за Howво са ни необходими параметрите.

Кодът, който прави това, ще изглежда така:

Код Обяснение
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("Hello", 10);
     printLines("Bye", 20);
   }
}


Декларирахме printLinesметода със следните параметри:
String text, int count
Методът показва text countвремена на низове





. Извикваме printLinesметода с различни параметри

Всеки път, когато се извика метод, на неговите параметри се присвояват предадените стойности и едва тогава започваме да изпълняваме командите вътре в метода.


2. Аргументи

Бих искал да насоча вниманието ви малко повече към извикването на метод с параметри.

Стойностите, предавани на метода, обикновено се наричат ​​аргументи, когато се предават на метода.

Нека да разгледаме друг пример:

Код Обяснение
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("Hello", 10);
     printLines("Bye", 20);
   }
}


Декларирахме printLinesметода със следните параметри:
String text, int count
Методът показва String 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се наричат ​​аргументи."


3. Конфликтни имена на променливи при извикване на метод

Променливите могат да се използват като аргументи на метода. Това е просто и разбираемо, но потенциално може да създаде някои трудности. Нека се върнем към същия пример, но този път ще преместим аргументите в отделни променливи:

Код Обяснение
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";
     int n = 10;
     printLines(str, n);
   }
}


Декларирахме printLinesметода със следните параметри:
String text, int count
Методът показва String 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";
     int count = 10;
     printLines(text, count);
   }
}


Декларирахме printLinesметода със следните параметри:
String text, int count
Методът показва String text countпъти







. Извикваме printLinesметода със следните аргументи:
text = text;
count = count;

Обърнете внимание на две неща

Първо: имаме променливи с едно и също име в различни методи. Това са различни променливи (умишлено ги изобразяваме с различни цветове). Всичко работи по същия начин, Howто в предишния пример, където променливите в mainметода са именувани strи n.

Второ: Нищо магическо не се случва, когато методът бъде извикан. На параметрите просто се присвояват стойностите на аргумента. Независимо дали са числа, низове, променливи or изрази.

След като преименуваме променливите в основния метод, нищо не се е променило. Те бяха различни променливи в различни методи преди това и така си остават. Няма магическа връзка между променливите text и text .



4. Предаване на препратки към методи

Надявам се, че сте разбрали всичко от предишния урок, защото сега ще преразгледаме предаването на аргументи към методите, само че ще се потопим по-дълбоко.

Както вече знаете, някои Java променливи съхраняват не самите стойности, а instead of това препратка, т.е. address на блока от паметта, където се намират стойностите. Ето How работят низовите променливи и масивните променливи.

Когато присвоите друга променлива от масив към променлива от масив, Howво се случва? Това е вярно. Двете променливи започват да се отнасят към едно и също пространство в паметта:

Предаване на препратки към методи

И Howво се случва, ако една от тези променливи е параметър на метод?

Код Обяснение
class Solution
{
   public static void printArraySum(int[] data)
   {
     int sum = 0;
     for (int i = 0; i < data.length; i++)
       sum = sum + data[i];
     System.out.println(sum);
   }

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


Методът printArraySumизчислява сбора на числата в предадения масив и го показва на екрана

Случва се абсолютно същото: data параметърът ще съдържа препратка към същата област от паметта като променливата months. Когато методът бъде извикан, възниква просто присвояване: .data = months

И тъй като и двете променливи се отнасят до една и съща област от паметта, съхраняваща цяло число, тогава методът printArraySum може не само да чете стойности от масива, но и да ги променя!

Например, можем да напишем наш собствен метод, който запълва двуизмерен масив със същата стойност. Ето How може да изглежда:

Код Обяснение
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.


5. Методи със същото име

Сега нека се върнем отново към имената на методите.

Стандартите на Java изискват всички методи в един и същ клас да имат уникални имена. С други думи, невъзможно е да декларирате два метода с еднакви имена в един и същи клас.

Когато методите се сравняват за еднаквост, се вземат предвид не само имената, но и типовете на параметрите ! Имайте предвид, че имената на параметрите не се вземат предвид . Примери:

Код Обяснение
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) {
}
Тези два метода се считат за еднакви , което означава, че не могат да бъдат декларирани в един и същи клас.

Защо някои методи се считат за еднакви , докато други са различни ? И защо имената на параметрите не се вземат предвид при определяне на уникалността на даден метод?

Защо изобщо е необходима уникалност? Работата е там, че когато компилаторът компorра програма, той трябва да знае точно кой метод възнамерявате да извикате на дадено място.

Например, ако напишете , компилаторът е умен и лесно ще заключи, че възнамерявате да извикате метода тук с параметър.System.out.println("Hi")println()String

Но ако напишете , компилаторът ще види извикване на метода с параметър.System.out.println(1.0)println()double

Когато се извика метод, компилаторът гарантира, че типовете на аргументите съответстват на типовете на параметрите. Не обръща внимание на името на аргументите. В Java имената на параметрите не помагат на компилатора да определи кой метод да извика. И затова те не се вземат предвид при определяне уникалността на даден метод.

Името на метода и типовете на неговите параметри се наричат ​​сигнатура на метода . Например,sum(int, int)

Всеки клас трябва да има методи с уникални сигнатури, а не методи с уникални имена.