Sunteți pe pagina 1din 25

În lecţia precedentă ne-am familiarizat cu noţiunea de Object Oriented

Programming în Java. Am văzut diferenţa dintre clase şi obiecte. Ne-am


familiarizat pe scurt şi cu câmpurile şi metodele, ca membri ai clasei.
În cadrul acestei lecţii vom aborda în detaliu membrii clasei şi crearea
acestora.

Vom crea un nou proiect Java. Spre deosebire de exemplul realizat în


cadrul primului modul, de data aceasta vom activa opţiunea Create
Main Class:

Imaginea 16.1 Crearea proiectului cu opţiunea bifată pentru crearea


automată a clasei main

Observăm că acest control box activează şi dezactivează în mod


automat crearea clasei Main (clasa principală). În câmpul de lângă
acest control box vedem scris textul myjavaprogram.MyJavaProgram.
Aceasta înseamnă că, dacă opţiunea este activată, clasa
MyJavaProgram va fi creată în pachetul myjavaprogram. Acesta nu este
doar un automatism, ci este consecinţa faptului că programul nu poate
funcţiona fără să aibă cel puţin o clasă. De fapt, programul Java propriu-
zis este o clasă, aşadar clasa MyJavaProgram, creată cu această
opţiune, va reprezenta de fapt baza programului nostru. Când creăm
proiectul conform parametrilor reprezentaţi, obţinem următoarea
structură:

Imaginea 16.2 Structura proiectului

Putem observa că mediul a creat pachetul pentru noi în mod automat,


precum şi clasa însăşi. Dacă privim acum conţinutul fişierului
MyJavaProgram.java, ne putem convinge de faptul că mai există ceva
ce a fost creat în mod automat:
Imaginea 16.3 Clasă creată în mod automat

Desigur, este vorba de metoda main, pe care am creat-o manual în


exemplele precedente. De data aceasta, metoda main este creată în
mod automat de către mediu. Ne vom reaminti de faptul că această
metodă reprezintă punctul de intrare al programului nostru şi că
fiecare aplicaţie Java stand alone ar trebuie să aibă definită această
metodă în proiect.

În pachetul creat vom adăuga acum încă o clasă cu denumirea Car.


Pentru a realiza adăugarea, putem da clic dreapta pe denumirea
pachetului, iar apoi alegem New - Java Class…
Imaginea 16.4 Crearea clasei

În fereastra care se deschide, introducem denumirea clasei: Car.


Imaginea 16.5. Denumirea clasei

Vom obţine o clasă goală. Dacă excludem comentariile pe care mediul


le-a generat în mod automat pentru noi, ne rămâne doar ceea ce este
important:

package myjavaprogram;
public class Car {
}

Cu prima linie este definit pachetul în care se găseşte clasa definită în


codul de mai jos. Urmează definiţia clasei. Clasa este alcătuită din
antet şi corp. În cazul nostru, antetul este alcătuit din modificatorul de
acces public, care ne spune că această clasă va fi vizibilă din toate
celelalte clase şi pachete. Urmează cuvântul cheie pentru definirea
clasei - class, iar apoi şi denumirea clasei care este, în cazul nostru,
Car. Corpul clasei se găseşte între parantezele acolade şi acesta este
momentan gol.

Haideţi să vedem acum ce conţine o clasă. Membrii unei clase pot fi:

câmpuri,

metode,

alte clase (acestea sunt aşa-numitele clase imbricare).

Mai devreme am menţionat modificatorul de acces al clasei Car. Nu


doar clasele, ci şi elementele acestora pot avea un modificator de
acces, aşadar acum este momentul oportun să ne familiarizăm cu
această noţiune.

Modificatorii de acces

În limbajul Java, există o tehnologie destinată controlului de acces la


anumite componente. Această tehnologie se mai numeşte şi domeniu
de vizibilitate (sau modificatori de acces, control de acces) şi
subînţelege câteva cuvinte cheie prin care creatorul specifică în ce
context va fi vizibilă componenta. Modificatorii de acces se pot folosi
pentru clase, interfeţe, câmpuri şi metode pentru a defini care dintre
celelalte clase şi interfeţe pot vedea sau modifica o anumită
componentă. În Java există 4 modificatori de acces: private, package-
private, protected şi public.

Private arată că membrii, declaraţi cu acest cuvânt cheie, vor


fi vizibili doar în cadrul clasei în care se găsesc. Acest
modificator nu se foloseşte niciodată la clase şi interfeţe
individuale, fiindcă astfel, aceste componente ar fi “invizibile”
pentru o utilizare ulterioară. De aceea, acest modificator se
foloseşte la clase şi interfeţe doar atunci când aceste
componente se găsesc în cadrul unei alte clase, respectiv
atunci când componentele sunt imbricate.

Package-private (adesea numit doar package) arată că toţi


ceilalţi membrii ai aceluiaşi pachet au acces la componenta
respectivă. Acest modificator de acces reprezintă modificatorul
implicit şi este singurul care nu posedă un cuvânt cheie. Pentru
a-l folosi, pur şi simplu trebuie să omitem cuvântul cheie.

Protected este cuvântul cheie care indică faptul că elementele


pentru care este specificat acest cuvânt cheie se pot accesa şi
din clasa în care sunt definite elementele, şi din clasele
derivate. Protected nu se poate folosi pentru clase şi interfeţe,
excepţie fiind cazul în care acestea sunt imbricate.

Public indică faptul că orice obiect are acces la element.

Modificat Clasă Pachet Subclasă Toate


or
public da da da da
protected da da da nu
fără da da nu nu
modificator
private da nu nu nu

Câmpuri

Câmpurile, după cum am spus deja, pot fi percepute ca anumite


caracteristici pe care le pot avea clasele. Desigur, fiecare automobil
are propriul producător şi model, precum şi un anumit număr de uşi.
Transformate într-un cod, acestea ar arătă astfel:

class Car
{
String make;
String model;
int numDoors;
}

Am declarat trei variabile care vor reprezenta câmpurile din clasa


noastră. Variabilele sunt: make, model şi numDoors.

Câmpurile pe care le-am declarat mai sus se numesc câmpuri de


instanţe sau obiectuale, fiindcă există doar în contextul obiectului.
Aceasta înseamnă că fără instanţierea clasei Car, nu putem accesa nici
aceste câmpuri. Dacă am fi încercat să le accesăm, editorul ne-ar fi
semnalat clar că încercăm să facem ceva ce nu este posibil:

Imaginea 16.6 Încercare de acces la un câmp nestatic într-un context


static

În codul de mai sus încercăm să accesăm câmpul clasei fără o


instanţiere prealabilă. Editorul ne anunţă că, în acest mod, nu este
posibil accesul la o variabilă statică.

Dacă am declara acum un câmp static în cadrul clasei Car, am avea


posibilitatea să-l accesăm fără instanţierea clasei.

class Car {
String make;
String model;
int numDoors;

static int wheels = 4;


}

Bineînţeles, fiecare maşină are 4 roţi. Aceasta este o caracteristică


referitoare la toate obiectele potenţiale ale acestei clase, aşadar nu ar
fi fost eficient dacă ar fi trebuit să instanţiem obiectul clasei pentru a
avea posibilitatea de acces la câmp. Prin specificarea cuvântului cheie
static, avem posibilitatea să accesăm câmpul cu ajutorul denumirii
clasei:

public static void main(String[] args) {


System.out.println(Car.wheels);
}

Următorul cod va rezulta următoarea ieşire:

Mai devreme am menţionat modificatorii de acces. Câmpurile pe care


le-am definit nu au specificaţi modificatorii de acces. Când modificatorii
de acces nu sunt definiţi, ca modificator implicit se foloseşte
modificatorul package-private. Acest modificator indică faptul că
atributele vor fi vizibile la nivelul întregului pachet în care se găseşte
clasa. Vom observa acum ce se va întâmpla dacă ca modificator de
acces specificăm cuvântul cheie private.

public class Car {


private String make;
String model;
int numDoors;
}

În clasa de mai sus, ca modificator de acces pentru câmpul make, am


definit modificatorul private. Vom încerca acum să accesăm acest
câmp din metoda noastră main:

Imaginea 16.7 Încercare de acces la câmpul privat al obiectului Car

Editorul ne semnalează un mesaj de eroare şi ne anunţă că respectivul


câmp creat conţine un modificator de acces privat deja definit.

Constructorii

În lecţia precedentă am menţionat că o clasă se instanţiază prin


utilizarea constructorului. Dacă constructorul nu este definit, Java va
crea unul implicit. Constructorul se defineşte explicit în cadrul corpului
clasei şi trebuie să aibă o denumire identică cu cea a clasei. Într-o
clasă pot fi definiţi mai mulţi constructori:

class Car
{
Car()
{
System.out.println("Car created");
}
Car(String carName)
{
System.out.println(carName + "created");
}
}

În codul de mai sus am creat doi constructori. Primul constructor nu


primeşte niciun parametru, în timp ce al doilea constructor primeşte un
parametru de tip String. Vă reamintiţi de polimorfism şi de
supraîncărcarea metodelor. Acesta este un exemplu practic de
polimorfism, în care se ajunge la supraîncărcarea (overloading-ul)
constructorului.

Pentru a vedea practic cum putem folosi aceşti constructori pentru


crearea obiectelor, trebuie să ne mutăm la clasa MyJavaProgram pe
care mediul a creat-o implicit în timpul creării proiectului.

Imaginea 16.8 Structura proiectului

În cadrul metodei main, pe care a creat-o mediul tot în mod automat,


putem executa instanţierea obiectului de tip Car.

Car car1 = new Car();


Car car2 = new Car("Ford");

Dacă acum executăm pornirea proiectului, la ieşire vom obţine:

Car created
Ford created

În primul caz am executat doar instanţierea obiectului Car prin


folosirea constructorului fără parametri. Fiindcă în corpul
constructorului este definită următoarea linie:

System.out.println("Car created");

la ieşire ne va fi scris:

Car created

La fel este şi cu a doua linie, numai că pentru crearea obiectelor


folosim un alt constructor care primeşte un parametru de tip String, iar
la ieşire ne afişează tipul de vehicul pe care îl creăm.

Desigur, modul în care am definit aceşti constructori se foloseşte rar în


practică, adică constructorii se folosesc foarte rar pentru scrierea unor
valori la ieşire. În cele mai frecvente cazuri, constructorul se foloseşte
pentru iniţializarea valorilor câmpurilor definite în cadrul unei clase.
Fiindcă am definit deja câmpurile din clasa noastră Car, vom vedea
acum cum iniţializăm valorile acestor câmpuri, folosind constructorul:

class Car{
String make;
String model;
int numDoors;

Car(String make, String model){


this.make = make;
this.model = model;
}

Car(String make, String model, int nDoors){


this.make = make;
this.model = model;
numDoors = nDoors;
}
}

Ca şi în exemplul precedent, am definit doi constructori. Ambii


constructori sunt parametrizaţi, ceea ce înseamnă că sunt definiţi în
aşa fel încât să accepte anumite valori. Aceasta înseamnă că obiectul
de tip Car nu se mai poate crea fără transmiterea parametrilor, fiindcă
nu mai există constructorul implicit. În momentul în care se defineşte
cel puţin un constructor, cel implicit încetează să existe, respectiv
încetează să existe acel constructor pe care îl creează Java în mod
automat în caz că constructorul lipseşte.

Valorile ce trebuie transmise contructorului în timpul creării obiectelor


se vor folosi pentru iniţializarea câmpurilor clasei.

Şi în exemplul de mai sus avem overloading-ul constructorului,


respectiv un exemplu practic de polimorfism.

Dacă în cadrul clasei există un număr mai mare de constructori,


constructorul corespunzător va fi găsit conform numărului şi tipului de
parametru pe care îl primeşte. Ce înseamnă aceasta în exemplul
nostru? Dacă cineva vrea să creeze o instanţă a clasei Car, iar în afară
de aceasta să transmită denumirea producătorului şi a modelului, fără
date despre numărul de uşi, acest lucru va fi legitim, fiindcă am creat
un constructor care acceptă doi parametri. Obiectul se poate, de
asemenea, crea şi prin transmiterea celor trei valori pentru model,
producător şi număr de uşi, folosind al doilea constructor.

Probabil vă întrebaţi care este semnificaţia cuvântului cheie this din


codul de mai sus. Cuvântul cheie this se foloseşte aici pentru a
specifica traducătorului că este vorba de o variabilă de clasă, respectiv
că este vorba de un câmp al clasei. Observaţi cum denumirile
parametrilor constructorului şi a variabilelor (câmpurilor) de clasă
coincid. Când scriem următoarele:

this.make

prin aceasta îi spunem traducătorului că ne referim la câmpul make


care este declarat în clasa propriu-zisă. Mediul de dezvoltare NetBeans
a separat clar câmpurile clasei, colorându-le cu verde. Cuvânt cheie
this reprezintă instanţa (obiectul) clasei în care se găseşte. Probabil vă
întrebaţi de ce folosim aceeaşi denumire şi pentru parametrul
constructorului, şi pentru câmpurile clasei. Corect ar fi dacă variabilelor
constructorului le-am fi dat ale denumiri. În acest caz nu am fi fost
obligaţi să scriem cuvântul cheie this. Acest lucru îl putem vedea în
exemplul iniţializării celui de-al treilea câmp:

numDoors = nDoors;

Aici nu era nevoie să folosim cuvântul cheie this, fiindcă avem


denumiri diferite. Totuşi, se recomandă utilizarea aceloraşi denumiri şi
pentru parametri constructorului, şi pentru câmpurile clasei. Este
important ca denumirile să ilustreze cât mai bine câmpurile pe care le
vor iniţializa, fiindcă după un anumit timp şi după un anumit număr de
linii de cod scrise, programatorul nu se mai poate baza pe memoria sa.
De asemenea, dacă lucraţi în echipă, poate că cineva din echipa dvs.
va instanţia obiectele acestei clase şi nu va fi sigur ce parametri
trebuie să transmită constructorului.

Imaginea 16.9 Reprezentarea constructorilor disponibili

În imaginea de mai sus vedem cum ne ajută mediul de dezvoltare în


timpul creării obiectelor. Sunt specificaţi constructorii oferiţi, precum şi
parametri pe care îi necesită aceştia. Dacă denumirile acestor
parametri nu ar fi atât de ilustrativi, noi nu am fi fost sută la sută siguri
ce date sunt necesare constructorului pentru crearea unui obiect.

Acum putem executa crearea obiectelor de tip Car, transmiţând


constructorilor valori pentru iniţializarea câmpurilor:

Car car1 = new Car("Ford", "Fiesta");


Car car2 = new Car("Ford", "Fiesta", 3);

În acest mod am instanţiat două obiecte ale aceluiaşi tip Car.


Denumirile acestor obiecte sunt car1 şi car2.

Metode

Am spus deja că în Java, prin clase, reprezentăm stări şi


comportamente. Stările se reprezintă prin câmpuri, în timp ce
comportamentele se pot reprezenta prin metode. Dacă am fi descris
structural metodele, această descriere ar fi coincis cu noţiunea de
funcţie. De fapt, metoda este o funcţie ce se caracterizează prin faptul
că apare în cadrul clasei. Fiindcă Java este total orientat pe obiecte,
putem spune că în acest program nici nu există funcţii, ci există doar
metode.

Prima metodă cu care ne-am întâlnit în timpul studierii acestui curs


este desigur metoda main. Vom analiza mai bine acum această
metodă:

public static void main(String[] args) {


}

În Java, metodele sunt alcătuite din două părţi: semnătura metodei şi


corpul metodei. În cazul metodei de mai sus, semnătura este:

public static void main(String[] args)

în timp ce corpul metodei este gol. Fiecare metodă are câteva


caracteristici, precum denumirea, domeniul de vizibilitate, parametrii
de intrare şi de ieşire şi, bineînţeles, corpul. Dacă observăm acum
metoda din exemplu, vom vedea că domeniul de vizibilitate este public
(deci, se vede şi în afara clasei), vedem apoi că are un modificator
static (ceea ce înseamnă că este static, adică nu trebuie instanţiat
obiectul clasei pentru a ajunge la această metodă). Cuvântul cheie void
reprezintă faptul că metoda nu returnează nicio valoare. Urmează apoi
denumirea metodei main, după care urmează parantezele rotunde
care conţin parametrii de intrare. În cele din urmă, începe şi se termină
corpul metodei care este încadrat cu paranteze acolade. În exemplu,
corpul este gol, însă desigur, poate conţine o logică de programare
nelimitat de mare. Şirul de stringuri, cu denumirea args (String[] args),
reprezintă parametrul de intrare, respectiv variabila de intrare.

Nu este întâmplător faptul că metoda din exemplu are denumirea


main. Aceasta este metoda care va fi prima apelată după activarea
programului. Mai exact, această metodă reprezintă punctul de intrare
al programului şi fără ea programul nu ar fi putut să funcţioneze. Dacă
în metoda main introducem o linie de cod, aceasta va fi executată
după activarea programului:

public static void main(String[] args) {


System.out.println("hello");
}

Caracteristica metodei main, a clasei main a programului, este aceea


că are un modificator static, respectiv este statică. Acest lucru este
logic, fiindcă programul trebuie să înceapă de undeva şi instanţierea sa
anterioară nu este posibilă. De aceea, clasa main a programului are
întotdeauna o metodă main statică, metodă care va da start
programului fără o instanţiere precedentă.

Vom defini acum o metodă în cadrul clasei Car. Aceasta va fi o metodă


pentru reprezentarea datelor referitoare la automobilul creat.

void printDetails()
{
System.out.println("Make " + make);
System.out.println("Model " + model);
System.out.println("Number of doors " + numDoors);
}

Metoda pe care am creat-o are denumirea de printDetails şi se


foloseşte pentru reprezentarea valorilor câmpurilor obiectului de tip
Car creat.

Dacă acum în cadrul metodei main a acestui proiect instanţiem


obiectul de tip Car, am putea să apelăm metoda pe care am creat-o.

public static void main(String[] args) {


Car car = new Car("Ford", "Fiesta", 3);
car.printDetails();
}

După executarea codului prezentat, la ieşire va fi scris:

Make = Ford
Model = Fiesta
Number of doors = 3

Metoda printDetails pe care am creat-o se mai numeşte şi metodă de


instanţă, fiindcă această metodă există doar în contextul obiectului. În
caz că obiectul nu există, nici metoda nu se va putea apela.

Pe lângă metodele obiectuale, adică cele de instanţă, mai avem şi


metodele de clasă. O metodă de clasă este de fapt metoda main pe
care am abordat-o deja. Vor exista situaţii când vom avea nevoie de
metode care descriu un comportament independent de obiectul
concret. Imaginaţi-vă situaţia în care trebuie să creaţi o clasă care va
executa diferite tipuri de conversii. Convertirea gradelor Celsius în
Fahrenheits se realizează întotdeauna în acelaşi mod, aşadar nu ar fi
fost eficient dacă ar fi trebuit să creăm un obiect pentru a putea să
folosim această funcţionalitate. De aceea, clasa şi metodele se
definesc în felul următor, folosind cuvântul cheie static:

class Conversions
{
static double c2f(double degrees)
{
return degrees*9.0/5.0+32;
}
static double f2c(double degrees)
{
return (degrees-32)*5.0/9.0;
}
}

Dacă definim metodele prin folosirea cuvântului cheie static, ca în


codul de mai sus, vom putea accesa metodele cu ajutorul denumirii
clasei. În mediul de dezvoltare NetBeans este suficient să tastăm
denumirea clasei şi să apăsăm tasta punct pentru a obţine următorul
meniu:

Imaginea 16.10. Metode statice disponibile

Aşadar, pentru apelarea metodei este suficient să scriem:

Conversions.c2f(33);

Acesta este momentul oportun pentru a ne familiariza cu parametrii de


intrare (input) şi de ieşire (output) ai metodelor.

Metodele, în general, recunosc două tipuri de parametri: cei de intrare


şi cei de ieşire. Parametrii de intrare sunt parametri care sunt transmişi
metodei şi sunt disponibili în cadrul metodei respective, însă nu şi în
afara ei. Parametrii de ieşire reprezintă valoarea pe care o returnează
metoda celui care o apelează. De asemenea, metoda se poate crea şi
în aşa fel încât să nu necesite niciun parametru, aşa cum poate exista
şi o metodă care să nu aibă nicio valoare returnată. Să analizăm acum
următoarea metodă:
void print()
{
System.out.println("message");
}

Metoda print nu necesită parametri de intrare şi nici nu returnează


nicio valoare. Metoda care nu returnează nicio valoare conţine în
semnătura sa cuvântul cheie void.

Vom observa acum exemplul metodei pentru conversia gradelor


Celsius în Fahrenheits:

static double c2f(double degrees)


{
return degrees*9.0/5.0+32;
}

Observăm că, pe lângă cuvântul cheie static, mai avem şi cuvântul


cheie pentru tipul de date - double. Aici, double reprezintă tipul de date
al valorii returnate. De asemenea, puteţi observa că în corpul metodei
este folosit un cuvânt cheie: return. Acest cuvânt cheie se foloseşte
pentru “emiterea” valorii de ieşire în afara funcţiei. Desigur, tipul de
valoare de ieşire trebuie să coincidă cu tipul specificat în semnătură.
Toate acestea înseamnă că această funcţie, după terminarea execuţiei,
va returna o valoare de tip double.

Al doilea tip de parametri sunt parametri de intrare, care se specifică în


cadrul parantezelor, după numele metodei. Desigur, nici parametri de
intrare nu sunt obligatorii. Definirea metodei fără parametri de intrare
este complet legitimă, aceasta în cazul în care metoda nu necesită
valori de intrare. Este posibilă definirea unui număr arbitrar de
parametri de intrare. Aceştia se specifică în aşa fel încât în primul rând
se introduce tipul de date al parametrului, iar apoi denumirea
parametrului pe care o va folosi acest parametru în corpul metodei. Fiţi
atenţi la faptul că parametri de intrare sunt disponibili doar în cadrul
metodei, nu şi în afara ei. Dacă este necesar să specificăm mai multe
variabile pentru parametri de intrare, acestea se separă cu virgulă, la
fel ca şi în cazul următoarei metode care adună două numere:

public int add(int a, int b)


{
return a+b;
}

Parametri primitivi/referenţiali

În limbajul de programare Java, unei metode i se poate transmite un


parametru de tip primitiv, însă i se poate transmite şi un obiect.

Vom vedea acum ce se întâmplă atunci când unei metode îi


transmitem un parametru de tip primitiv:

public class TestClass {

public static void main(String[] args) {

int x = 5;
System.out.println("This is initial value: " + x);
passMethod(x);
System.out.println("This is the value after the completion of the method: " + x);

public static void passMethod(int x) {


x = 10;
System.out.println("This is the value from method: " + x);
}
}

În codul de mai sus am definit o clasă cu denumirea TestClass. Această


clasă conţine o metodă main standard pentru pornirea aplicaţiei şi încă
o metodă cu denumirea passMethod pe care o vom analiza. Această
metodă primeşte un parametru de tip int şi îi setează valoarea la 10.

În cadrul metodei main am definit o variabilă primitivă întreagă de tip


int şi i-am atribuit valoarea 5. Apoi am apelat metoda passMethod şi i-
am transmis parametrul x, adică valoarea variabilei întregi x. În
metodă se execută schimbarea valorii. Pentru a putea să urmărim
valorile variabilei, în punctele critice am adăugat linii pentru
prezentarea valorilor. La ieşire obţinem următoarea scriere:

This is initial value: 5


This is the value from method: 10
This is the value after the completion of the method: 5

După cum putem vedea, metoda nu a executat schimbarea valorii


variabilei x. Aceasta se întâmplă fiindcă valorile variabilelor primitive
se transmit pe baza valorilor, adică metodele obţin doar copii ale
valorilor variabilelor. În acest mod, variabilele din afara metodelor
rămân nemodificate.

În Java, tipurile referenţiale de date sunt de asemenea transmise pe


baza valorii. În Java nu există transmitere pe baza referinţei. Când
transmitem un obiect unei metode, metodei i se transmite de fapt
referinţa la obiect, adică valoarea locaţiei din memorie a obiectului.
Totuşi, valorile câmpului unui obiect se pot modifica în cadrul metodei,
aceasta dacă au modificatorul de acces care permite modificarea. Vom
observa exemplul de mai jos, care este similar celui precedent, însă
este adaptat transmiterii unui parametru obiectual:

public class ReferenceType {


public int x = 5;

public static void main(String[] args) {

ReferenceType rt = new ReferenceType();

System.out.println("This is initial value: " + rt.x);


passMethod(rt);
System.out.println("This is the value after the completion of the method: " + rt.x);

public static void passMethod(ReferenceType rt) {


rt.x = 10;
System.out.println("This is the value from method: " + rt.x);
}

În codul de mai sus am definit clasa ReferenceType cu un câmp


întreg de tip int, care avea valoarea 5. În cadrul metodei main am
instanţiat obiectul şi l-am transmis metodei care în corpul său schimbă
valoarea câmpului. Ca şi în cazul precedent, am afişat valorile
câmpului în situaţiile critice. De data aceasta, valoarea câmpului va fi
modificată şi în afara metodei, iar la ieşire obţinem:

This is initial value: 5


This is the value from method: 10
This is the value after the completion of the method: 10
Numărul arbitrar de argumente

Există situaţii în care nu este cunoscut de dinainte câţi parametri va


obţine o metodă. Pentru un astfel de scenariu există o soluţie care
implică folosirea constructorului denumit varargs. Folosind această
abordare, în semnătura metodei se poate specifica că metoda va primi
un număr arbitrar de parametri ai unui anumit tip. Semnătura unei
astfel de metode ar arăta astfel:

public void getPerimeter(int... corners)

Observaţi că, după tipul de parametru, sunt introduse trei puncte (…).
În acest mod se specifică faptul că numărul de parametri poate fi unul
arbitrar.

Ca exemplu ilustrativ al folosirii acestui constructor, am luat calcularea


perimetrului unui poligon. Un poligon poate avea un număr arbitrar de
laturi, mai mare decât 2. Codul este următorul:

public class TestClass {

public static void main(String[] args) {


getPerimeter(13, 13, 13);
}

public static void getPerimeter(int... edges) {


int perimeter = 0;
if (edges.length < 3) {
System.out.println("Polygon must have more than two sides.");
} else {
for (int i = 0; i < edges.length; i++) {
perimeter += edges[i];
}
System.out.println(perimeter);
}
}
}
În cadrul metodei getPerimeter, se execută calcularea perimetrului
poligonului pe baza parametrilor transmişi. Sunt definite blocurile
condiţionate if/else pentru verificarea numărului de parametri
specificaţi, fiindcă numărul de laturi nu poate fi mai mic decât 3. La
sfârşit, din metoda main am executat apelul metodei cu trei parametri
transmişi.

S-ar putea să vă placă și