1. Transmiterea argumentelor

Și acum începe distracția. Probabil că știți deja că din metode de genul System.out.println()acesta putem transmite argumente metodelor. Odată ce suntem în interiorul metodei, ne referim la ei ca parametri. De fapt, parametrii sporesc foarte mult beneficiile pe care le obținem în urma creării și utilizării metodelor.

Cum declarăm o metodă cu parametri? De fapt, este destul de simplu:

public static void name(parameters)
{
  method body
}

Unde name este numele unic al metodei și method body reprezintă comenzile care alcătuiesc metoda. Și parameters este un substituent pentru parametrii metodei, despărțiți prin virgule. Să descriem acest șablon mai detaliat:

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

Exemple:

Cod Explicaţie
public static void print(String str)
{
}
Metoda printeste declarată cu un parametru:
String str
public static void print(String str, int count)
{
}
Metoda printeste declarată cu doi parametri:
String str
int count
public static void write(int x, int y)
{
}
Metoda writeeste declarată cu doi parametri:
int x
int y

Dacă nu dorim ca metoda să aibă parametri, atunci pur și simplu lăsăm parantezele goale.

Parametrii sunt variabile speciale dintr-o metodă. Cu ajutorul lor, puteți trece diverse valori metodei atunci când este apelată.

De exemplu, să scriem o metodă care afișează un șir de text de un anumit număr de ori.

Știți deja cum să scrieți cod pentru a afișa un șir pe ecran de mai multe ori. Dar ce șir ar trebui să imprimați? Și de câte ori? Pentru asta avem nevoie de parametri.

Codul care face acest lucru ar arăta astfel:

Cod Explicaţie
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);
   }
}


Am declarat printLinesmetoda cu următorii parametri:
String text, int count
Metoda afișează text counttimpii șirului





. Numim printLinesmetoda cu diverși parametri

De fiecare dată când o metodă este apelată, parametrilor acesteia li se atribuie valorile transmise și abia apoi începem să executăm comenzile din interiorul metodei.


2. Argumente

Aș dori să vă atrag puțin mai mult atenția asupra apelării unei metode cu parametri.

Valorile transmise metodei sunt de obicei numite argumente atunci când sunt transmise metodei.

Să ne uităm la un alt exemplu:

Cod Explicaţie
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);
   }
}


Am declarat printLinesmetoda cu următorii parametri:
String text, int count
Metoda afișează String text counttimes




Apelăm printLinesmetoda cu următoarele argumente:
text = "Hi"; count = 10;
text = "Bye"; count = 20;

Când printLines metoda a fost apelată pentru prima dată, parametrilor acesteia li s-au atribuit următoarele valori:
String text = "Hi", int count = 10.

Când printLinesmetoda a fost apelată a doua oară, parametrilor acesteia li s-au atribuit diferite valori:
String text = "Bye", int count = 20.

Parametrii sunt nici mai mult, nici mai puțin decât variabile cărora li se atribuie anumite valori atunci când o metodă este apelată. Valorile "Hi", "Bye", 10, și 20sunt ele însele numite argumente."


3. Nume de variabile conflictuale la apelarea unei metode

Variabilele pot fi folosite ca argumente de metodă. Acest lucru este simplu și de înțeles, dar poate produce unele dificultăți. Să ne întoarcem la același exemplu, dar de data aceasta vom muta argumentele în variabile separate:

Cod Explicaţie
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);
   }
}


Am declarat printLinesmetoda cu următorii parametri:
String text, int count
Metoda afișează String text counttimes







Apelăm printLinesmetoda cu următoarele argumente:
text = str;
count = n;

Până acum, foarte bine: avem o strvariabilă. Valoarea acestuia este atribuită parametrului textatunci când metoda este apelată. Avem o nvariabilă. Valoarea sa este atribuită parametrului countatunci când metoda este apelată.” Până acum, totul este clar.

Acum să redenumim variabilele noastre în mainmetoda:

Cod Explicaţie
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);
   }
}


Am declarat printLinesmetoda cu următorii parametri:
String text, int count
Metoda afișează String text counttimes







Apelăm printLinesmetoda cu următoarele argumente:
text = text;
count = count;

Fii atent la două lucruri

În primul rând: avem variabile cu același nume în metode diferite. Acestea sunt variabile diferite (le descriem în mod deliberat folosind culori diferite). Totul funcționează la fel ca în exemplul anterior, unde variabilele din mainmetodă au fost numite strși n.

În al doilea rând: Nimic magic nu se întâmplă atunci când metoda este apelată. Parametrilor li se atribuie pur și simplu valorile argumentului. Indiferent dacă sunt numere, șiruri, variabile sau expresii.

După ce redenumim variabilele din metoda principală, nimic nu s-a schimbat. Au fost diferite variabile în diferite metode anterior și, așadar, rămân. Nu există nicio legătură magică între variabile text și text .



4. Transmiterea referințelor la metode

Sper că ați înțeles totul din lecția anterioară, pentru că acum vom revizui trecerea argumentelor la metode, doar că vom aprofunda.

După cum știți deja, unele variabile Java stochează nu valorile în sine, ci o referință, adică adresa blocului de memorie în care se află valorile. Acesta este modul în care funcționează variabilele șir și variabilele matrice.

Când atribuiți o altă variabilă matrice unei variabile matrice, ce se întâmplă? Asta e corect. Cele două variabile încep să se refere la același spațiu din memorie:

Transmiterea referințelor la metode

Și ce se întâmplă dacă una dintre aceste variabile este un parametru al unei metode?

Cod Explicaţie
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);
   }
}


Metoda printArraySumcalculează suma numerelor din matricea transmisă și o afișează pe ecran

Exact același lucru se întâmplă: data parametrul va conține o referință la aceeași zonă de memorie ca și monthsvariabila. Când metoda este apelată, are loc o atribuire simplă: .data = months

Și din moment ce ambele variabile se referă la aceeași zonă de memorie care stochează un întreg, atunci metoda printArraySum poate nu numai să citească valori din matrice, ci și să le modifice!

De exemplu, putem scrie propria noastră metodă care umple o matrice bidimensională cu aceeași valoare. Cam asa ar putea arata:

Cod Explicaţie
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);
   }
}


Metoda fill iterează peste fiecare celulă din matricea bidimensională transmisă și valuele atribuie.








Creăm o matrice bidimensională.
Umplem întreaga matrice cu numărul 8.


5. Metode cu același nume

Acum să revenim la numele metodelor încă o dată.

Standardele Java necesită ca toate metodele din aceeași clasă să aibă nume unice. Cu alte cuvinte, este imposibil să declarați două metode cu nume identic în aceeași clasă.

Atunci când metodele sunt comparate pentru asemănarea, nu sunt luate în considerare numai numele, ci și tipurile de parametri ! Rețineți că numele parametrilor nu sunt luate în considerare . Exemple:

Cod Explicaţie
void fill(int[] data, int value) {
}
void fill(int[][] data, int value) {
}
void fill(int[][][] data, int value)  {
}
Aceste trei metode sunt metode diferite . Ele pot fi declarate în aceeași clasă.
void print(String str) {
}
void print(String str, String str2) {
}
void print(int val) {
}
void print(double val) {
}
void print() {
}
Fiecare dintre aceste cinci metode este considerată diferită . Ele pot fi declarate în aceeași clasă.
void sum(int x, int y) {
}
void sum(int data, int value) {
}
Aceste două metode sunt considerate la fel , adică nu pot fi declarate în aceeași clasă.

De ce unele metode sunt considerate la fel , în timp ce altele sunt diferite ? Și de ce nu sunt luate în considerare numele parametrilor atunci când se determină unicitatea unei metode?

De ce este necesară unicitatea? Chestia este că atunci când compilatorul compilează un program, trebuie să știe exact ce metodă intenționați să apelați în orice loc.

De exemplu, dacă scrieți , compilatorul este inteligent și va concluziona cu ușurință că intenționați să apelați metoda aici cu un parametru.System.out.println("Hi")println()String

Dar dacă scrieți , compilatorul va vedea un apel la metoda cu un parametru.System.out.println(1.0)println()double

Când o metodă este apelată, compilatorul se asigură că tipurile de argumente se potrivesc cu tipurile de parametri. Nu acordă nicio atenție denumirii argumentelor. În Java, numele parametrilor nu ajută compilatorul să determine ce metodă să apeleze. Și de aceea nu sunt luate în considerare atunci când se determină unicitatea unei metode.

Numele unei metode și tipurile de parametri ai acesteia se numesc semnătura metodei . De exemplu,sum(int, int)

Fiecare clasă trebuie să aibă mai degrabă metode cu semnături unice decât metode cu nume unice.