Am văzut în cadrul episodului anterior cum putem transmite anumite valori unei funcții și funcția poate opera cu ele. Dar, este posibil și o comunicare în sens invers; în urma executării unei funcții, apelantul poate primi o valoare. Se spune că funcția returnează acea valoare.
În Java trebuie să precizăm care este tipul valorii returnate de o funcție. Am văzut în cadrul episodului anterior că funcțiile erau precedate de trei cuvinte ciudate: private static void. Este momentul să explicăm unul dintre ele: void. Acesta reprezintă tipul funcției (sau tipul valorii returnate). În acest caz, void indică faptul că funcția nu returnează nicio valoare. Putem spune că nu are tip sau că tipul său este vid.
Așa cum ne așteptăm, putem folosi orice alt tip. Să presupunem că vrem să determinăm ultima cifră a unui număr. Am putea scrie următoarea funcție:
1 2 3 |
private static int ultima(int nr) { return nr % 10; } |
Vedem cuvântul return. Acesta este folosit în cadrul unei instrucțiuni care precizează valoarea care trebuie returnată de funcție. În cazul nostru returnăm ultima cifră, adică restul împărțirii la 10 a parametrului. Nu va funcționa corect pentru numere negative, dar acest lucru nu este relevant acum.
Putem face ce vrem cu valoarea returnată de o funcție. De exemplu, o putem atribui unei variabile. Funcția noastră ar putea fi apelată astfel:
1 |
int c = ultima(2457); |
Valoarea variabilei c va fi 7. Probabil v-ați dat seama deja, funcția poate fi utilizată în cadrul expresiilor. De exemplu, am putea avea:
1 |
int v = ultima(2457) + ultima(47); |
În această situație, valoarea variabilei v va fi 14.
Mai trebuie să precizăm faptul că, în Java, după executarea instrucțiunii care returnează o valoare, nicio altă instrucțiune din cadrul funcției nu se mai execută. Evident, avem excepții, dar nu sunt importante acum.
Putem avea mai multe instrucțiuni return în cadrul unei funcții, dacă ambele au șanse să fie apelate. De exemplu, următoarea funcție este corectă:
1 2 3 4 5 6 7 |
private static String paritate(int nr) { if (nr % 2 == 0) { return "Număr par"; } else { return "Număr impar"; } } |
În funcție de valoarea variabilei nr, una dintre cele două instrucțiuni return se va executa.
Dar, următoarea variantă nu mai este corectă (cea de-a treia instrucțiune return nu are șanse să se execute):
1 2 3 4 5 6 7 8 |
private static String paritate(int nr) { if (nr % 2 == 0) { return "Număr par"; } else { return "Număr impar"; } return "Altceva"; } |
Este obligatoriu ca o funcție să returneze o valoare. Așadar, oricâte ramificații am avea, este obligatoriu ca, la un moment dat, să fie întâlnită o instrucțiune care returnează o valoare (cu excepția cazului când tipul funcției este void). Varianta care urmează nu este corectă:
1 2 3 4 5 |
private static String paritate(int nr) { if (nr % 2 == 0) { return "Număr par"; } } |
Dacă parametrul nu este par, nu este întâlnită nicio instrucțiune de returnare. În schimb, am putea scrie următoarea funcție:
1 2 3 4 5 6 7 8 |
private static String paritate(int nr) { if (nr % 2 == 0) { return "Număr par"; } else { nr++; } return "Altceva"; } |
Cam ciudat codul, dar este valid. Până la urmă este întâlnită o instrucțiune de returnare, indiferent dacă parametrul este par sau nu.
Să revenim puțin la funcțiile fără tip (sau cu tip void). Putem folosi instrucțiunea return și în cadrul lor; nu precizăm și o valoare returnată; efectul este întreruperea execuției funcției.
Să presupunem că am dori să scriem o funcție care afișează un număr pe care îl primește ca parametru, dar numai dacă acesta este par. Una dintre variantele prin care aceasta ar putea fi implementată este:
1 2 3 4 5 6 |
private static void paritate(int nr) { if (nr % 2 != 0) { return; } System.out.println(nr); } |
Se poate evita întreruperea execuției (pentru acest exemplu adăugând un simplu else), dar de multe ori este mult mai simplu să întrerupem execuția în anumite cazuri, evitând scrierea de condiții din ce în ce mai complicate.
Va urma
În cadrul episodului următor vom vedea în ce condiții putem folosi o variabilă. Vom vedea ce se întâmplă cu variabilele declarate în interiorul funcțiilor, precum și ce se întâmplă cu modificările aduse parametrilor funcțiilor.