Download - PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

Transcript
Page 1: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

PROGRAMARE OBIECTORIENTATA 2

Iolu Mihai - Stefan

19 noiembrie 2008

Page 2: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

ii

Page 3: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

Cuprins

1 Introducere 11.1 Mediul de programare Java . . . . . . . . . . . . . . . . . . . 3

2 Structuri fundamentale de programare ın Java 52.1 Primul program Java . . . . . . . . . . . . . . . . . . . . . . . 52.2 Transmiterea parametrilor din linie de comanda . . . . . . . . 82.3 Comentarii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92.4 Tipuri de date . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.4.1 Tipuri de date primitive . . . . . . . . . . . . . . . . . 122.4.2 Tipuri de date referinta . . . . . . . . . . . . . . . . . 13

2.5 Operatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132.6 Instructiuni decizionale . . . . . . . . . . . . . . . . . . . . . . 142.7 Instructiuni repetitive . . . . . . . . . . . . . . . . . . . . . . 152.8 Vectori si matrici . . . . . . . . . . . . . . . . . . . . . . . . . 16

2.8.1 Vectori . . . . . . . . . . . . . . . . . . . . . . . . . . . 162.8.2 Matrici . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

2.9 Siruri de caractere . . . . . . . . . . . . . . . . . . . . . . . . 232.9.1 Clasa String . . . . . . . . . . . . . . . . . . . . . . . . 232.9.2 Clasa StringBuffer . . . . . . . . . . . . . . . . . . . . 272.9.3 Clasa StringTokenizer . . . . . . . . . . . . . . . . . . 282.9.4 Expresii regulate ın Java . . . . . . . . . . . . . . . . . 29

3 Concepte si principii ın POO 313.1 Concepte ın programarea obiect orientata . . . . . . . . . . . . 313.2 Principii ale programarii obiect orientate . . . . . . . . . . . . 32

iii

Page 4: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

iv CUPRINS

3.3 Solutii pentru utilizarea eficienta a principiilor POO . . . . . . 34

4 Obiecte si clase 374.1 Definirea unei clase . . . . . . . . . . . . . . . . . . . . . . . . 374.2 Declararea atributelor unei clase . . . . . . . . . . . . . . . . . 38

4.2.1 Modificatorii de vizibilitate . . . . . . . . . . . . . . . . 394.2.2 Modificatorul final . . . . . . . . . . . . . . . . . . . . 404.2.3 Modificatorul static . . . . . . . . . . . . . . . . . . . . 414.2.4 Modificatorii transient si volatile . . . . . . . . . . . . 42

4.3 Declararea metodelor unei clase . . . . . . . . . . . . . . . . . 424.3.1 Modificatorul static . . . . . . . . . . . . . . . . . . . . 434.3.2 Transmiterea parametrilor la metode . . . . . . . . . . 43

4.4 Declararea constructorilor unei clase . . . . . . . . . . . . . . 444.5 Initializatorul static al unei clase . . . . . . . . . . . . . . . . 464.6 Probleme rezolvate . . . . . . . . . . . . . . . . . . . . . . . . 474.7 Probleme propuse . . . . . . . . . . . . . . . . . . . . . . . . . 65

5 Mostenirea ın Java 675.1 Notiuni generale . . . . . . . . . . . . . . . . . . . . . . . . . . 675.2 Exemplu de aplicatie folosind mostenirea . . . . . . . . . . . . 685.3 Polimorfismul . . . . . . . . . . . . . . . . . . . . . . . . . . . 735.4 Metode si clase finale . . . . . . . . . . . . . . . . . . . . . . . 755.5 Operatia de casting . . . . . . . . . . . . . . . . . . . . . . . . 755.6 Clase abstracte . . . . . . . . . . . . . . . . . . . . . . . . . . 765.7 Clasa Object . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

5.7.1 Metoda toString() . . . . . . . . . . . . . . . . . . . . 835.7.2 Metoda equals() . . . . . . . . . . . . . . . . . . . . . . 835.7.3 Metoda hashCode() . . . . . . . . . . . . . . . . . . . . 845.7.4 Metoda clone() . . . . . . . . . . . . . . . . . . . . . . 84

5.8 Implementarea colectiilor generice folosind Object . . . . . . . 855.9 Utilizarea colectiilor generice cu template-uri . . . . . . . . . . 89

5.9.1 Boxing si unboxing ın Java . . . . . . . . . . . . . . . . 90

6 Tratarea exceptiilor ın Java 936.1 Clasificarea exceptiilor . . . . . . . . . . . . . . . . . . . . . . 946.2 Crearea claselor exceptie . . . . . . . . . . . . . . . . . . . . . 956.3 Aruncarea exceptiilor . . . . . . . . . . . . . . . . . . . . . . . 966.4 Prinderea exceptiilor . . . . . . . . . . . . . . . . . . . . . . . 966.5 Indicatii referitoare la utilizarea exceptiilor . . . . . . . . . . . 986.6 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

Page 5: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

CAPITOLUL 1

Introducere

Acest curs se refera la programarea obiect orientata si principalele car-acteristici ale acesteia. Acestea vor fi prezentate ın contextul unui limbajcare ofera un foarte bun suport din acest punct de vedere, respectiv limbajulJava.

Java este, ın mod indiscutabil, unul din cele mai populare limbaje deprogramare obiect orientate (alaturi de limbaje precum C++, C# sau VisualBasic). Acest lucru a facut ca el sa fie folosit de milioane de dezvoltatori dinlumea ıntreaga mai ales ın contextul aplicatiilor web.

El a aparut la sfarsitul anului 1995 si a avut parte de o mare publicitateınca de la ınceput. Este un limbaj care ofera suport pentru toate tehnicilemoderne de programare precum: programarea ın retea, lucrul cu fire deexecutie, internationalizare, lucrul cu baze de date si multe altele.

De-a lungul timpului cei de la Sun Microsystems, care se ocupa de evolutialimbajului, au scos 7 revizii majore ale acestuia. Cea mai importanta a fostcea care a dus la aparitia versiunii JDK 5.0. Momentan s-a ajuns la versiuneaJDK 6.0.

Evolutia este impresionanta daca tinem cont ca s-a pornit de la un numarde aproximativ 200 de clase si s-a ajuns acum la peste 3000 de clase.

Java este mult mai mult decat un simplu limbaj. Java este o platformacare are o librarie imensa ce contine foarte mult cod reutilizabil precum siun mediu de executie care ofera servicii precum: securitate, portabilitate pediverse medii de executie precum si garbage collection. Unele din principaleleavantaje ale acestui mediu Java sunt urmatoarele:

1

Page 6: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

2 CAPITOLUL 1. INTRODUCERE

• Limbajul Java este un limbaj relativ simplu. Dupa cum vom vedea ıncele ce urmeaza ın Java nu avem numeroase constructii care existau ınC/C++ precum: pointeri, structuri, fisiere header, directive de prepro-cesor, supraıncarcare de operatori, mostenire virtuala etc.

• Limbajul Java este obiect orientat. In ziua de azi, majoritatea limba-jelor care exista pe piata si au o foarte larga raspandire au la bazaprincipiile programarii obiect orientate (vezi C++, C#, Visual Basic).

• Java are un bogat suport pentru aplicatiile distribuite. Exista numeroaseclase care permit crearea unor aplicatii care sa ruleze ın retea, folosinddiverse modalitati de lucru: sockets, RMI, CORBA etc.

• Java este un limbaj robust. Cei care au dezvoltat acest limbaj au avutca scop foarte important ıncercarea de a evita pe cat posibil aparitiaerorilor, prin depistarea acestora cat mai rapida sau prin usurarea mod-ului de a programa. Un astfel de exemplu este lipsa pointerilor care faceca programarea sa fie mai usoara si practic face imposibila corupereamemoriei care se putea produce destul de usor ın C/C++.

• Java este portabil. Aceasta ınseamna ca daca scriem un cod pe plat-forma Windows, exact acelasi cod fara modificari va putea rula si pe oplatforma Linux de exemplu. Nu acelasi lucru se ıntampla, de exemplu,ın cazul C++. Tipul int putea avea dimensiuni diferite ın functie deplatforma tinta.

• Java este neutru din punct de vedere arhitectural. In momentul ın carese compileaza codul Java, rezultatul produs este un bytecode. Acestaeste rulat cu ajutorul unei masini virtuale Java (JVM - Java VirtualMachine). Din cauza acestui mod de gandire este posibil ca acelasicod sa ruleze pe orice sistem de operare, doar implementarea masiniivirtuale diferind. Un mecanism asemanator a fost dezvoltat si de catrecei de la Microsoft pentru platforma .NET, care are la baza tot o masinavirtuala.

Voi ıncerca ın cele ce urmeaza sa prezint un curs ın care accentul se vapune mai ales pe partea practica a limbajului si pe facilitatile oferite deacesta pentru programarea obiect orientata. Din cauza timpului limitat, nuvom prezenta facilitatile pentru lucrul cu interfete grafice, pentru programareweb sau pentru realizarea aplicatiilor pe mobil. Acestea sunt subiecte de mareinteres care pot fi studiate ıntr-un curs viitor.

Totusi trebuie precizat ınca de la ınceput ca se foloseste mediul Javapentru a realiza mai multe tipuri de aplicatii:

Page 7: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

1.1. MEDIUL DE PROGRAMARE JAVA 3

• Aplicatii consola (ın linie de comanda): se pot rula din linie de co-manda, neavand o interfata grafica

• Aplicatii grafice (folosesc librarii AWT sau Swing)

• Applet-uri - sunt un anumit tip de aplicatii grafice care pot fi introduseın pagini web, facand ca o pagina web sa aiba un aspect mult maidinamic asemanator aplicatiilor desktop

• Pagini web dinamice - sunt create cu ajutorul unor tehnologii care s-audezvoltat peste Java si care adauga functionalitati noi limbajului (veziJSP, Servlets, Spring etc.)

• Aplicatii pe mobil (se realizeaza cu ajutorul unei distributii Java numitaJ2ME - Java 2 Microedition).

Accentul ın continuare se va pune mai ales pe primul tip de aplicatie,doar tangential se vor atinge celelalte tipuri.

Trebuie spus ca majoritatea ideilor prezentate vis-a-vis de programareaobiect orientata sunt aplicabile si ın cazul altor limbaje obiect orientate pre-cum C++ (deja studiat) si C# (care va fi studiat ın semestrul urmator).

Voi ıncerca sa prezint ın continuare urmatoarele lucruri:

• Structurile de programare fundamentale ın Java

• Lucrul cu obiecte si clase, mostenirea si lucrul cu interfete

• Tratarea exceptiilor

• Stream-uri Java

• Programarea generica si colectiile

• Lucrul cu baze de date

• Annotations

• Java Reflection

1.1 Mediul de programare Java

In aceasta sectiune vom prezenta acele softuri necesare pentru a rulaaplicatiile Java pe care le vom prezenta ın continuare precum si diverselemoduri ın care se poate lucra folosind mai mult sau mai putin editoare ded-icate pentru lucrul cu Java.

Page 8: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4 CAPITOLUL 1. INTRODUCERE

Pentru a folosi Java, ın functie de tipul aplicatiilor care se doreste a ficreate, se poate descarca una din urmatoarele variante:

• J2ME - Java 2 Micro Edition (se foloseste pentru crearea aplicatiilorpentru mobile)

• J2SE - Java 2 Standard Edition (se foloseste pentru crearea aplicatiilorconsola sau grafice obisnuite)

• J2EE - Java 2 Enterprise Edition (se foloseste pentru crearea aplicatiilorweb).

Pentru a putea compila si rula aplicatii Java este bine sa ıncepem prin ainstala JDK -ul (Java Development Kit).

Acesta poate fi descarcat gratuit la urmatoarea adresa web:

http://java.sun.com/javase/downloads/index.jsp.

In acest moment se poate alege ıntre o versiune beta care este mai nouasau o versiune stabila.

Este recomandabil, de asemenea, sa se downloadeze si documentatia pen-tru JDK care se gaseste ın sectiunea Java SE 6 Documentation.

Dupa ce se instaleaza JDK (procesul este foarte usor, motiv pentru carenici nu va fi descris) se poate dezarhiva directorul docs si, eventual, se poatecopia ın directorul ın care a fost salvat JDK.

Page 9: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

CAPITOLUL 2

Structuri fundamentale de programare ın Java

2.1 Primul program Java

In aceasta sectiune vom crea primul nostru program Java, pe care-l vomrula din linie de comanda. Acest program arata astfel:

public class Welcome

{public static void main(String[] args)

{System.out.println("Hello world!");

}}

Pentru a rula acest program din linie de comanda se parcurg mai multipasi:

1. Se introduce programul ıntr-un editor si apoi se salveaza cu extensia.java. Uneori numele trebuie sa respecte anumite conditii dar asupraacestui aspect vom reveni. In cazul nostru vom salva programul cunumele Welcome.java.

2. Intram ın linie de comanda prin Start+Run...+cmd (sau command, ıncazul calculatoarelor care ruleaza Win 98 sau Win ME ), dupa care nepozitionam ın directorul ın care a fost salvat fisierul anterior.

5

Page 10: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

6CAPITOLUL 2. STRUCTURI FUNDAMENTALE DE PROGRAMARE IN JAVA

3. Tastam SET PATH=%PATH%;c:\program files\Java\jdk1.6.0 07\binpentru a adauga directorul bin din distributia Java ın cale. Aceastacale poate fi diferita ın functie de locul ın care a fost instalat Java saude versiunea de JDK instalata.

4. Se compileaza aplicatia cu javac Welcome.java. Daca apar erori, aces-tea trebuie corectate, dupa care fisierul trebuie salvat si se recompileazaaplicatia pana cand nu avem erori.

5. In final se ruleaza aplicatia cu java Welcome.

Observatii:

• Limbajul Java este case-sensitive, ceea ce ınseamna ca se face diferentaıntre litere mici si mari. Astfel, daca cuvintele class sau System nusunt scrise exact ca ın exemplu s-ar genera o eroare de compilare.

• Numele fisierului trebuie sa fie chiar Welcome.java deoarece ın programavem o clasa publica numita Welcome.

• In directorul ın care am instalat Java exista mai multe directoare pre-cum: bin, include, lib etc. O semnificatie deosebit o are directorul binın care sunt pozitionate mai multe fisiere executabile precum java.exesi javac.exe. Este necesar pasul 3 deoarece aceste fisiere executabile nusunt implicit ın calea sistemului de operare. De altfel, la pasii 4 si 5,compilarea respectiv rularea programelor se face folosind aceste fisiereexecutabile.

• In faza de compilare utilitarul javac primeste ca intrare fisierul Wel-come.java si, ın cazul ın care compilarea reuseste, genereaza fisierulWelcome.class. In faza de rulare, utilitarul java.exe foloseste acestfisier generat ın faza de compilare.

In Java tot codul care va fi scris trebuie sa fie introdus ın cadrul unorclase, motiv pentru care si aici am scris codul ın cadrul unei clase. Aceastaclasa are plasata ınaintea definitiei sale cuvntul cheie public ceea ce ınseamnaca ea poate fi accesata de oriunde. Vom vorbi mai multe despre indicatoriide acces atunci cand vom prezenta modul ın care se lucreaza cu clase.

In interiorul acestei clase avem definita o metoda main() care este publicasi statica. Aceasta metoda este mai speciala, ea fiind ıntotdeauna publica sistatica. Ce o face mai speciala este faptul ca ea constituie punctul de intrareın program. Aceasta ınseamna ca atunci cand rulam o aplicatie, executiaacesteia ıncepe cu aceasta metoda.

Page 11: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

2.1. PRIMUL PROGRAM JAVA 7

Metoda main() primeste un sir de siruri de caractere, care reprezintaparametrii din linie de comanda. Aceasta constructie este asemanatoare cuceea ce stiam din limbajul C++.

Dupa cum se poate usor observa ın Java, instructiunile sunt separate prin”;”, la fel ca si ın limbajul C/C++.

In acest exemplu avem un obiect, System.out, asupra caruia se apeleaza ometoda println(), care primeste ca parametru un sir de caractere si realizeazaafisarea acestuia pe ecran precum si saltul la linie noua. Daca nu doreamsalt la linie noua foloseam metoda print().

In Java delimitarea blocurilor de cod se face folosind caracterele ”{” si”}”.

Cuvantul cheie void are aceeasi semnificatie ca si ın C/C++ si anumefaptul ca metoda main nu returneaza nimic.

Foarte important atunci cand lucram cu limbajul Java este sa respectamregulile de denumire a claselor, obiectelor, metodelor si constantelor.

Astfel, numele unei clase ıncepe ıntotdeauna cu litera mare iar ın cazulın care cuvantul care se refera la numele clasei este alcatuit din mai multecuvinte, fiecare cuvant este scris cu litera mare. Numele unei clase trebuiesa fie un substantiv la singular. Ex: Stack, StackOverflowException etc.

Numele metodelor ıncep cu litera mica iar ın cazul ın care sunt alcatuitedin mai multe cuvinte, numele primului cuvant se scrie cu litera mica iarnumele celorlalte cuvinte cu litera mare. Ex: println(), printWords(), as-sertEquals() etc.

Numele obiectelor respecta exact aceleasi reguli ca numele metodelor.

Numele constantelor se scriu ıntotdeauna numai cu litere mari. Ex:MAX VALUE, MIN etc.

Observatii:

• Compilatorul nu genereaza eroare daca aceste reguli nu sunt respectateıntocmai, dar este recomandabila respectarea lor.

• Numele de clase, metode, variabile nu pot contine caracterul spatiu.

• In momentul ın care se scrie cod Java, acesta trebuie aliniat core-spunzator. Compilatorul nu va ”plange” daca nu se respecta aceastaregula, dar aceasta indica un programator care de multe ori nu ıntelegeceea ce programeaza.

Page 12: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

8CAPITOLUL 2. STRUCTURI FUNDAMENTALE DE PROGRAMARE IN JAVA

2.2 Transmiterea parametrilor din linie de co-

manda

In aceasta sectiune vom prezenta un program foarte asemanator cu celprezentat ınainte, program care va folosi parametri transmisi din linie decomanda.

public class Welcome2

{public static void main(String[] args)

{for(int i=0;i<args.length;i++)

System.out.println("Hello "+args[i]+"!");

}}

Acesta este un program foarte simplu care are ca efect afisarea unui mesajde ıntampinare pentru fiecare nume transmis din linie de comanda.

Astfel, vom rula programul cu urmatoarea comanda:

java Welcome2 radu aurel "ana maria"

efectul lui fiind afisarea urmatoarelor mesaje:

Hello radu!

Hello aurel!

Hello ana maria!

In acest fel am exemplificat utilitatea parametrului args al metodei main.Acesta este un sir de siruri de caractere. Asemenea oricarui vector ın Javael are un atribut length care reprezinta lungimea vectorului.

Anticipam un pic prezentarea vectorilor prin a spune ca ın Java vectoriisunt indexati ıncepand de la pozitia 0.

Mai prezentam ın continuare un alt exemplu de aplicatie care rezolvaecuatia de gradul al doilea care are coeficientii transmisi din linie de comanda:

public class EcGr2

{public static void main(String[] args) {

if(args.length<3)

{System.out.println("Nu sunt suficienti parametri");

Page 13: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

2.3. COMENTARII 9

System.exit(0);

}double a=Double.parseDouble(args[0]);

double b=Double.parseDouble(args[1]);

double c=Double.parseDouble(args[2]);

double delta=b*b-4*a*c;

if(delta<0)

System.out.println("Ecuatia nu are solutii reale");

else

if(delta==0)

System.out.println("Solutie unica: "+ (-b)/(2*a));

else

{double x1=(-b-Math.sqrt(delta))/(2*a);

double x2=(-b+Math.sqrt(delta))/(2*a);

System.out.println("x1="+x1);

System.out.println("x2="+x2);

}}

}

Observatii:

• Metoda statica parseDouble() a clasei Double are rolul de a transformaun sir de caractere ıntr-un numar de tip double. In mod asemanatorexista Integer.parseInt() si Float.parseFloat().

• Functiile matematice gata definite ın limbajul Java sunt implemen-tate ın clasa Math, ele fiind functii statice. Un exemplu este functiaMath.sqrt() folosita pentru a calcula radicalul unui numar.

2.3 Comentarii

In Java se pot realiza trei tipuri de comentarii care sunt toate prezentateın exemplul urmator. Aceasta aplicatie calculeaza suma cifrelor unui numarıntreg:

/**

*

* @author mihai

Page 14: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

10CAPITOLUL 2. STRUCTURI FUNDAMENTALE DE PROGRAMARE IN JAVA

* @version 1.0

*/

public class ExempluComentariu

{/**

* @param n

* numarul pentru care se calculeaza suma cifrelor.

* Trebuie sa fie un numar mai mare decat 0.

* @return suma cifrelor numarului

*/

public static int sumaCif(int n)

{/*

* Metoda sumaCif este o metoda recursiva

* care calculeaza suma cifrelor unui numar

*/

if(n<9)

return n;

return n%10+sumaCif(n/10); //aici are loc apelul recursiv

}

/**Calculeaza suma cifrelor unui numar folosind o metoda recursiva

* @param args reprezinta argumentele din linie de comanda pentru

* programul meu

*/

public static void main(String[] args)

{int n=234;

System.out.println("Suma cifrelor este: "+sumaCif(n));

}}

Cele trei tipuri de comentarii care se pot realiza sunt urmatoarele:

• Comentarii pe o singura linie, care se realizeaza la fel ca ın C/C++folosind caracterele ”//”

• Comentarii pe mai multe linii, care sunt cuprinse ıntre ”/*”’ si ”*/”’

• Comentarii care ajuta la generarea documentatiei, care sunt cuprinseıntre ”/**” si ”*/”

Page 15: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

2.3. COMENTARII 11

Primele doua moduri de lucru sunt identice cu ceea ce ıntalnim ın C/C++,motiv pentru care ne vom axa ın principal pe a treia modalitate de generarea documentatiei.

Comentariile care ajuta la generarea documentatiei sunt folosite pentrua genera niste fisiere HTML care descriu clasa pe care am scris-o. Acestefisiere vor arata exact la fel ca documentatia furnizata ımpreuna cu mediulJDK.

Generarea acestor fisiere se poate face utilizand utilitarul javadoc astfel:

javadoc ExempluComentariu.java

Vom remarca aparitia ın directorul ın care avem fisierul a mai multor fisiereHTML. Daca deschidem fisierul ExempluComentariu.html vom putea vedeadocumentatia.

Un rol foarte important ın cadrul documentatiei ıl au tag-urile predefinite,cu ajutorul carora se pot specifica anumite informatii mai speciale:

• @name - reprezinta numele celui care a scris codul pentru aceasta clasa

• @version - reprezinta versiunea clasei

• @return - specifica ce returneaza metoda respectiva

• @param - descrie un anumit parametru

• Exista si alte tag-uri care sunt foarte utile. Cel mai bine se poate studiamodul ın care sunt ele folosite daca examinam codul sursa Java prezentın fisierul src.zip aflat ın directorul ın care este instalat Java.

Aceste comentarii vor conduce la obtinerea unor fisiere HTML, motivpentru care este posibil ca ın interiorul lor sa folosim cod HTML.

Scrierea documentatiei pentru clasele pe care le creem este necesara deoarece,de multe ori, se ıntampla ca cel care foloseste clasa sa nu fie aceeasi persoanacu cea care a scris codul pentru clasa. Nu este normal ca pentru a folosi oclasa sa trebuiasca neaparat sa umblam ın codul ei.

Acesta idee poarta numele de ıncapsulare. Practic, putem sa ne gandimla o clasa ca la un fel de cutie neagra (black-box) care are o interfata pe careo putem folosi fara a cunoaste continutul ei.

Generarea documentatiei ın Eclipse se poate face prin alegerea optiuniiGenerate JavaDoc din meniul Project. La un moment dat trebuie introdusacalea catre utilitarul javadoc, dupa care se urmeaza pasii sugerati de wizard.

Page 16: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

12CAPITOLUL 2. STRUCTURI FUNDAMENTALE DE PROGRAMARE IN JAVA

2.4 Tipuri de date

Un tip de date reprezinta o plaja de valori pe care o variabila le poatelua precum si operatiile care se pot efectua asupra acesteia.

Java este un limbaj strong typed ceea ce ınseamna ca orice variabila areun tip foarte bine definit. Acest lucru face posibila determinarea mai usoaraa erorilor din program la momentul compilarii.

In Java avem trei tipuri de date: tipuri de date primitive (byte, short, int,long, char, float, double, boolean), tipuri de date referinta (class, interface,array) si tipul de date null (corespunzator literalului null).

2.4.1 Tipuri de date primitive

Tipurile de date primitive sunt de mai multe feluri:

• tipuri numerice: byte, short, int, long, float, double

• tipul caracter

• tipul boolean

Tipurile de date numerice sunt prezentate ın urmatorul tabel:

Tabela 2.1: Tipuri de date numerice

Tip Dimensiune Valori admisebyte 1 byte -128...127

short 2 bytes -32768 ... 32767int 4 bytes -2,147,483,648 ... 2,147,483, 647

long 8 bytes -9,223,372,036,854,775,808 ...9,223,372,036,854,775,807

float 4 bytes aproximativ 3.40282347E+38F (6-7 cifre zeci-male semnificative)

double 8 bytes aproximativ 1.79769313486231570E+308 (15cifre zecimale semnificative)

Numerele scrise n baza 16 au prefixul 0x iar numerele scrise ın baza 8 auprefixul 0.

Observatii:

• Ceea ce este foarte important ın Java si un mare avantaj fata de C/C++este faptul ca indiferent de platforma, tipurile de date vor avea exactaceeasi dimensiune de reprezentare.

Page 17: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

2.5. OPERATORI 13

• In Java se pot reprezenta valori speciale gen Double.NaN, Double.POSITIVE INFINITY sau Double.NEGATIVE INFINITY (precumsi corespondentul lor relativ la tipul float). Ele au urmatoarele semnificatii:

– NaN se refera la faptul ca putem avea o operatie care sa nugenereze un numar. Ex: radical dintr-un numar negativ sauımpartirea 0/0.

– POSITIVE INFINITY se poate obtine daca ımpartim un numarpozitiv la 0. Aceste constante se folosesc foarte rar ın practica.Pentru a vedea daca un numar este de tipul NaN se procedeazaastfel:

if (Double.isNaN(x))

....

Un tip de date mai deosebit este tipul char. In Java variabilele de tipchar se reprezinta ıntre caractere ”. La fel ca si ın C/C++ exista caracteremai speciale care sunt tratate folosind secvente escape: \b, \t, \n, \r, \’, \”,\\.

In Java tipul boolean are doua valori true si false. Nu se mai respectaconventia din C/C++ care spunea ca valoarea 0 ınseamna false si valoarediferita de 0 reprezinta true.

2.4.2 Tipuri de date referinta

In plus fata de tipurile de date primitive, ın Java avem si tipurile dedate referinta care se refera la obiecte (instante ale unor clase) precum sila vectori. Nu vom prezenta acest subiect aici, urmand a reveni ıntr-unsubcapitol ulterior.

Vom preciza doar un singur lucru, si anume faptul ca diferenta ıntre cele2 tipuri de date consta ın faptul ca pentru tipurile de date primitive se retineexact valoarea lor ın timp ce pentru tipurile de date referinta se retine ınvariabila corespunzatoare lor adresa unei zone de memorie unde se retine defapt valoarea lor.

Acest lucru va avea un impact foarte important la transmiterea parametrilor.

2.5 Operatori

Un operator utilizeaza unul sau mai multi operanzi pentru a produce onoua valoare. Un operator poate, de asemenea, sa schimbe valoarea unuioperand.

Page 18: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

14CAPITOLUL 2. STRUCTURI FUNDAMENTALE DE PROGRAMARE IN JAVA

Operatorii din Java se pot clasifica astfel:

• Operatorul de atribuire =

• Operatorii aritmetici:

– Operatorii binari: adunare(+), scadere(-), ınmultire(*), ımpartire(/),restul ımpartirii(%)

– Operatorii unari: semnul minus(-), semnul plus(+), incrementare(++),decrementare(–)

• Operatorii relationali: egal(==), diferit(!=), mai mare(>), mai mic(<),mai mare sau egal(>=), mai mic sau egal(<=)

• Operatori logici:

– Conditionali: si(&&), sau(||), negatie(!), xor(ˆ)

– Pe biti: si(&), sau(|), xor(ˆ), complementare(∼), deplasare lastanga(<<), deplasare la dreapta (>>)

• Operatorii de atribuire combinati (atat aritmetici cat si pe biti: +=,-=, /=, %=, &=, |=, ˆ==, <<==, >>==

• Operatorul conditional: expr logica ? val1 : val2

• Operatorul adunare de siruri de caractere

• Operatorul de cast

• Operatorul instanceof

2.6 Instructiuni decizionale

In Java avem 2 instructiuni conditionale: if-else si switch.Instructiunea if-else are urmatoarea structura:

if (conditie)

secventa1

[else

secventa2]

Instructiunea switch permite executarea uneia din mai multe secvente deinstructiuni ın functie de valoarea unei expresii. Forma generala a acesteiaeste:

Page 19: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

2.7. INSTRUCTIUNI REPETITIVE 15

switch(expresie)

{case val1: secventa1

[break;]

case val2: secventa2

[break;]

....

case valN: secventaN

[break;]

[default:

secventa]

}

Instructiunea se evalueaza astfel: se calculeaza valoarea expresiei dupacare se gaseste case-ul corespunzator expresiei. Incepand de la acesta seevalueaza toate secven�ele pana la ıntalnirea lui break. In cazul ın care nici eexpresie nu se potriveste se executa instructiunea din clauza default.

Vom prezenta exemple atunci cand vom prezenta lucrul cu siruri de car-actere.

2.7 Instructiuni repetitive

In Java avem trei tipuri de structuri repetitive: while, do-while si for.Instructiunea while are urmatoarea forma:

while (conditie)

instructiune

Ideea acestei instructiuni este ca, atta timp cat este adevaarata conditia,se executa instructiunea cuprinsa ın ciclul while.

Instructiunea do-while are urmatoarea forma:

do

instructiune

while (conditie);

Ideea acestei instructiuni este ca se tot executa instructiunea (care poatefi simpla sau compusa) atata timp cat este adevarata conditia.

Cea de-a treia instructiune repetitiva, care de asemenea exista si ın lim-bajul C/C++ este instructiunea for :

Page 20: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

16CAPITOLUL 2. STRUCTURI FUNDAMENTALE DE PROGRAMARE IN JAVA

for (expresie initializare; conditie continuare; secventa incrementare)

instructiune

Ideea acestei instructiuni este ca ıntai se executa initializarile prevazuteın expresie initializare, dupa care se evalueaza conditia de continuare. Atatatimp cat conditia este adevarata se executa instructiunea simpa sau com-pusa, dupa care se executa secventa de incrementare si se revine la evaluareaconditiei de continuare.

Singura diferenta fata de limbajul C/C++ este ca, daca declaram siinitializam o variabila ın expresia de initializare, atunci aceasta variabilanu este vizibila decat ın corpul instructiunii for.

Un rol important ın cadrul instructiunilor repetitive ıl are instructiuneabreak care odata folosita are ca efect iesirea din ciclul repetitiv cel mai interiorsi trecerea la urmatoarea instructiune de executat dupa acesta.

2.8 Vectori si matrici

2.8.1 Vectori

Un tablou (vector) este o lista de elemente de acelasi tip plasate ıntr-ozona continua de memorie, care pot fi accesate printr-un nume comun. Toateelementele dintr-un tablou trebuie sa aiba acelasi tip. Tipurile admise sunttoate tipurile primitive sau orice tip referinta.

In Java tablourile sunt obiecte. Un tablou are toate metodele pe carele are clasa Object si ın plus are un membru length care ne spune care estedimensiunea tabloului.

Declararea si alocarea de memorie pentru un tablou

Un tablou se poate declara ıntr-unul din urmatoarele doua moduri echiva-lente:

tip[] nume;

tip nume[];

Doar declarand un tablou, nu putem face nimic cu el. Pentru a-l puteafolosi trebuie sa si alocam memorie pentru el. Aceasta se poate face ın douamoduri:

• Prin folosirea operatorului new :

nume=new tip[dimensiune];

Page 21: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

2.8. VECTORI SI MATRICI 17

• Prin initializarea directa a elementelor tabloului:

tip[] nume={element1, element2, element3};

Dupa cum se poate observa, ın acest al doilea caz declararea si alocareade memorie se fac ın aceeasi instructiune.

Observatii:

• Se poate realiza atat declararea tabloului cat si alocarea de memorieıntr-o singura instructiune:

tip[] nume=new tip[dimensiune];

• Atunci cand se aloca memorie pentru un tablou, elementele acestuia vorfi initializate cu valoarea implicita corespunzatoare tipului elementelortabloului (0 - valori numerice intregi, 0.0 pentru valori reale, false -pentru tipul boolean, null - pentru obiecte).

• Tablourile ın limbajul Java sunt 0 indexate ceea ce ınseamna ca seıncepe de la elementul cu indicele 0 pana la elementul cu indicele n− 1daca tabloul are n elemente. In cazul ın care vom accesa un element altabloului care nu exista vom observa faptul ca se va produce o eroaresi executia programului se va opri.

• Orice tablou are o data membra length care returneaza lungimea tablouluirespectiv, ca ın exemplul urmator:

int[] a=new int[10];

System.out.println(a.length); //afiseaza valoarea 10

Pentru a accesa elementele unui tablou vom folosi, la fel ca si ın C/C++numele tabloului si numarul elementului ın cadrul tabloului:

nume[indice];

Tipul tablou este un tip referinta ceea ce ınseamna ca variabila cu ajutorulcareia am declarat tabloul, de fapt retine adresa zonei efective de memorieunde se retin elementele tabloului.

Acesta este motivul pentru care daca vom transmite ca parametru untablou la o metoda modificarile efectuate asupra elementelor acestuia se vorpastra.

Page 22: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

18CAPITOLUL 2. STRUCTURI FUNDAMENTALE DE PROGRAMARE IN JAVA

Probleme rezolvate

Problema 1: Se citeste de la tastatura un sir de numere ıntregi. Sa sesorteze crescator elementele sirului si sa se afiseze sirul astfel obtinut.

Rezolvarea acestei probleme ar putea arata astfel:

import java.util.*;

public class SortareSir

{public static void main(String args[])

{Scanner s=new Scanner(System.in);

System.out.print("n=");

int n=s.nextInt();

int[] a=new int[n];

for(int i=0;i<a.length;i++)

{System.out.print("a["+i+"]=");

a[i]=s.nextInt();

}sortare(a);

afisare(a);

}

static void sortare(int[] a)

{for(int i=0;i<a.length-2;i++)

for(int j=i+1;j<a.length;j++)

if(a[i]>a[j])

{int aux=a[i];

a[i]=a[j];

a[j]=aux;

}}

static void afisare(int[] a)

{for(int i=0;i<a.length;i++)

System.out.print(a[i]+" ");

Page 23: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

2.8. VECTORI SI MATRICI 19

}}

Observatii:

• Se putea realiza afisarea sirului si ın alt mod, folosind capabilitatileoferite de JDK 1.6:

for(int x:a)

System.out.println(x+" ");

• Pentru lucrul cu siruri avem clasa Arrays care are definite catevametode foarte utile. Astfel, puteam sorta elementele sirului folosindurmatorul cod:

Arrays.sort(a);

Se recomanda consultarea API-ului Java pentru studierea celorlaltemetode utile pentru lucrul cu siruri.

Problema 2: Sa se scrie o metoda care primeste ca parametru un sir denumere ıntregi si returneaza sirul obtinut prin inserarea ıntre fiecare 2 ele-mente a sumei lor.

Metoda ar putea arata astfel:

static int[] generareSir(int[] a)

{int[] b=new int[2*a.length-1];

for(int i=0;i<a.length;i++)

b[2*i]=a[i];

for(int i=1;i<b.length;i+=2)

b[i]=b[i-1]+b[i+1];

return b;

}

Problema 3: Sa se scrie o metoda care primeste ca parametru un sir a,o pozitie poz si o valoare val si returneaza ıntr-un sir, vectorul obtinut prininserarea elementului val pe pozitia poz ın sirul initial.

In Java exista o metoda prin care putem copia elemente dintr-un sir inalt sir elegant si eficient, folosind metoda arraycopy a clasei System. Antetulacestei metode este urmatorul:

Page 24: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

20CAPITOLUL 2. STRUCTURI FUNDAMENTALE DE PROGRAMARE IN JAVA

public static native void arraycopy(Object src, int srcPosition,

Object dst, int dstPosition, int length)

Efectul apelului acestei metode consta ın faptul ca se copiaza din sirulsrc, ıncepand de la pozitia srcPosition, length elemente, care se vor plasa ınsirul dst ıncepand de la pozitia dstPosition.

Aceasta metoda va fi folosita la rezolvarea problemei:

static int[] inserare(int[] a, int poz, int val)

{int[] b=new int[a.length+1];

System.arraycopy(a, 0, b, 0, poz);

b[poz]=val;

System.arraycopy(a, poz, b, poz+1, a.length-poz);

return b;

}

Metoda poate fi apelata scriind cod precum urmatorul:

a=inserare(a, 2, 3);

2.8.2 Matrici

In Java, o matrice este retinuta sub forma unui sir de siruri. O matricese poate declara si initializa ın trei feluri.

Cea mai simpla varianta este sa declaram matricea si sa alocam memoriepentru ea ca ın exemplul urmator:

int[][] a=new int[nrLinii][nrColoane];

Matricile se pot si initializa direct. Prezentam modul ın care se poateinitializa o matrice cu 2 linii si 3 coloane:

int[][] a= {{2, 3, 4},{1, 4, 2}};

Totusi, ın Java o matrice poate avea un numar variabil de elemente pefiecare linie:

int[][] a= {{2, 3},{1, 4, 2, 5}};

In acest caz, numarul de linii ale matricii este a.length iar numarul decoloane ale liniei i este a[i].length.

Daca dorim sa citim o astfel de matrice de la tastatura putem procedaastfel:

Page 25: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

2.8. VECTORI SI MATRICI 21

int[][] a=new int[nrLinii][];

for(int i=0;i<a.length;i++)

/

// citire dimensiune m

a[i]=new int[m];

for(int j=0;j<a[i].length;j++)

//citire element a[i][j]

/

Cel mai bine se va vedea cum se lucreaza cu astfel de matrici ın exempleleurmatoare.

Problema 1 Se citeste de la tastatura o matrice a, patratica de ordin n.Sa se verifice daca toate elementele de pe diagonala principala sunt mai maridecat suma elementelor de pe liniile corespunzatoare lor.

Rezolvarea problemei ar putea arata astfel:

import java.util.*;

public class VerificareMatrice

{public static void main(String args[])

{Scanner s=new Scanner(System.in);

System.out.print("n=");

int n=s.nextInt();

int[][] a=new int[n][n];

for(int i=0;i<a.length;i++)

for(int j=0;j<a.length;j++)

{System.out.print("a["+i+"]["+j+"]=");

a[i][j]=s.nextInt();

}if(verificare(a))

System.out.println("Se respecta conditia");

else

System.out.println("Nu se respecta conditia");

}

static boolean verificare(int[][] a)

{for(int i=0;i<a.length;i++)

Page 26: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

22CAPITOLUL 2. STRUCTURI FUNDAMENTALE DE PROGRAMARE IN JAVA

{int s=0;

for(int j=0;j<a[i].length;j++)

s+=a[i][j];

if(2*a[i][i]<=s)

return false;

}return true;

}}

Problema 2 Se citeste o matrice a cu n linii si numar variabil de elementepe fiecare linie. Sa se calculeze si sa se afiseze minimul dintre maximele depe fiecare linie.

Rezolvarea ar putea arata ın felul urmator:

import java.util.*;

public class MatriceNeregulata

{public static void main(String args[])

{Scanner s=new Scanner(System.in);

System.out.print("Numarul de linii: ");

int n=s.nextInt();

int[][] a=new int[n][];

for(int i=0;i<a.length;i++)

{System.out.print("Numarul de coloane ale liniei "+i+":");

int m=s.nextInt();

a[i]=new int[m];

for(int j=0;j<a[i].length;j++)

{System.out.print("a["+i+"]["+j+"]=");

a[i][j]=s.nextInt();

}}System.out.println(minMax(a));

}

static int maximSir(int[] a)

{

Page 27: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

2.9. SIRURI DE CARACTERE 23

int max=a[0];

for(int i=1;i<a.length;i++)

if(a[i]>max)

max=a[i];

return max;

}

static int minMax(int[][] a)

{int min=maximSir(a[0]);

for(int i=1;i<a.length;i++)

if(maximSir(a[i])<min)

min=maximSir(a[i]);

return min;

}}

2.9 Siruri de caractere

Avem mai multe clase care ne ajuta sa lucram cu siruri de caractere.Cele mai cunoscute si care vor fi prezentate ın continuare sunt: String,StringBuffer si StringTokenizer.

2.9.1 Clasa String

In principiu, pentru a retine un sir de caractere se foloseste clasa String.Aceasta retine un sir de caractere de tip char.

Un sir de caractere se poate initializa astfel:

String nume="Adi";

Pentru a vedea lungimea unui sir de caractere folosim metoda length() aclasei String astfel:

System.out.println(nume.length());

Efectul acestei instructiuni va fi afisarea valorii 3.Se poate obtine caracterul de pe pozitia i al unui sir de caractere folosind

metoda charAt() a clasei String care are urmatorul antet:

char charAt(int index)

Page 28: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

24CAPITOLUL 2. STRUCTURI FUNDAMENTALE DE PROGRAMARE IN JAVA

Pentru a compara daca doua siruri de caractere s1 si s2 sunt egale, nufolosim operatorul == ci mai degraba metoda equals ca ın exemplul urmator:

if (s1.equals(s2))

...

Principalele metode pentru lucrul cu siruri de caractere sunt:

• char charAt(int index)

returneaza caracterul de pe pozitia index

• int compareTo(String other)

returneaza o valoare mai mica decat 0 daca sirul de caractere asupracaruia se face operatia este mai mic decat cel transmis ca parametru,0 daca sunt egale si o valoare mai mare decat 0 ın celelalte cazuri.

• boolean endsWith(String suffix)

returneaza true daca sirul de caractere se termina cu caracterele siruluisuffix.

• boolean equals(Object other)

• boolean equalsIgnoreCase(String other)

• int indexOf(String str)

• int indexOf(String str, int fromIndex)

• int lastIndexOf(String str)

• int length()

• boolean startsWith(String prefix)

• String substring(int beginIndex, int endIndex)

• String toLowerCase()

• String toUpperCase()

• String trim()

Page 29: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

2.9. SIRURI DE CARACTERE 25

Trebuie spus ca pentru lucrul cu siruri de caractere exista numeroasealte metode ale clasei String. Pentru a le putea cunoaste pe toate esterecomandata studierea API-ului Java.

O operatie foarte importanta ın lucrul cu siruri de caractere este con-catenarea care am vazut ın mai multe exemple ca se face cu operatorul +.

Vom prezenta ın continuare cateva exemple de lucru cu siruri de caractere:Problema 1 Se citeste de la tastatura un sir de caractere. Sa se verifice

daca acest sir are aspect de palindrom.

import java.util.*;

public class StringPalindrom

{static boolean palindrom(String s)

{for(int i=0;i<=(s.length()-2)/2;i++)

if(s.charAt(i)!=s.charAt(s.length()-i-1))

return false;

return true;

}

public static void main(String args[])

{Scanner s=new Scanner(System.in);

System.out.print("Sirul de caractere: ");

String str=s.nextLine();

if(palindrom(str))

System.out.println("Are aspect de palindrom");

else

System.out.println("Nu are aspect de palindrom");

}}

Problema 2 Se citeste un sir de siruri de caractere. Sa se sorteze crescatorsirul si sa se afiseze sirul astfel obtinut.

import java.util.*;

public class SortareStringuri

{public static void main(String args[])

Page 30: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

26CAPITOLUL 2. STRUCTURI FUNDAMENTALE DE PROGRAMARE IN JAVA

{Scanner s=new Scanner(System.in);

System.out.print("n=");

int n=s.nextInt();

s.nextLine();

String[] str=new String[n];

for(int i=0;i<str.length;i++)

{System.out.print("str["+i+"]=");

str[i]=s.nextLine();

}sortare(str);

afisare(str);

}

static void sortare(String str[])

{for(int i=0;i<str.length-1;i++)

for(int j=i+1;j<str.length;j++)

if(str[i].compareTo(str[j])>0)

{String aux=str[i];

str[i]=str[j];

str[j]=aux;

}}

static void afisare(String[] str)

{for(String s:str)

System.out.print(s+" ");

}}

Observatie importanta:

Clasa String este immutable ceea ce ınseamna ca niciodata o variabilade tip String nu se poate modifica. Se poate doar ca ea sa retina o altareferinta. Daca vrem sa putem modifica un sir de caractere folosim clasaStringBuffer.

Page 31: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

2.9. SIRURI DE CARACTERE 27

2.9.2 Clasa StringBuffer

Problema 1 Se citeste un sir de caractere. Sa se ınlocuiasca fiecare vocalacu urmatorul caracter din alfabet si sa se afiseze sirul obtinut.

import java.util.Scanner;

public class InlocuireVocale

{static boolean vocala(char c)

{/*switch(Character.toLowerCase(c))

{case ’a’:

case ’e’:

case ’i’:

case ’o’:

case ’u’: return true;

}return false;*/

c=Character.toLowerCase(c);

return ("aeiou".indexOf(c)>=0);

}

static String inlocuireVocaleBun(String s)

{StringBuffer sb=new StringBuffer(s);

for(int i=0;i<sb.length();i++)

if(vocala(sb.charAt(i)))

sb.setCharAt(i,(char)(s.charAt(i)+1));

return sb.toString();

}

static String inlocuireVocaleNuAsaBun(String s)

{String s2="";

for(int i=0;i<s.length();i++)

if(vocala(s.charAt(i)))

s2+=(char)(s.charAt(i)+1);

else

s2+=s.charAt(i);

return s2;

Page 32: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

28CAPITOLUL 2. STRUCTURI FUNDAMENTALE DE PROGRAMARE IN JAVA

}

public static void main(String args[])

{Scanner s=new Scanner(System.in);

System.out.print("Sirul de caractere: ");

String str=s.nextLine();

System.out.println("Sirul transformat: "+inlocuireVocaleBun(str));

}}

Problema s-ar mai fi putut rezolva si ın alt mod, si anume prin folosireametodei append() a clasei StringBuffer:

static String inlocuireVocaleNuAsaBun2(String s)

{StringBuffer s2=new StringBuffer("");

for(int i=0;i<s.length();i++)

if(vocala(s.charAt(i)))

s2.append(s.charAt(i)+1);

else

s2.append(s.charAt(i));

return s2.toString();

}

2.9.3 Clasa StringTokenizer

Clasa StringTokenizer se foloseste pentru a sparge un sir de caractereın mai multi tokeni. Exemplificam folosirea ei printr-o problema:

Problema 1 Se citeste o expresie matematica. Sa se afiseze toti operanziidin aceasta expresie.

import java.util.*;

public class AfisareOperanzi

{public static void main(String args[])

{Scanner s=new Scanner(System.in);

System.out.print("Expresia matematica: ");

String expr=s.nextLine();

Page 33: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

2.9. SIRURI DE CARACTERE 29

StringTokenizer st=new StringTokenizer(expr,"+-*/% ");

while(st.hasMoreTokens())

System.out.println(st.nextToken());

}}

2.9.4 Expresii regulate ın Java

Una din cele mai importante facilitati legate de lucrul cu siruri de carac-tere ın Java o constituie lucrul cu expresii regulate.

Acesta ne permite sa ne definim un anumit sablon si sa vedem daca sirulde caractere respecta acel sablon sau sa gasim toate aparitiile ıntr-un text aunor subsiruri de caractere care verifica acel sablon.

Problema 1 De exemplu, pentru a verifica daca un sir de caractere estealcatuit din exact 3 cifre, prima fiind diferita de zero putem proceda astfel:

import java.util.regex.Pattern;

import java.util.*;

public class ExpresiiRegulate {public static void main(String args[]) {Scanner s = new Scanner(System.in);

System.out.print("Introduceti sirul");

String str=s.nextLine();

if(Pattern.matches("[\\d&&[^0]]\\d\\d", str))

System.out.println("Respecta");

else

System.out.println("Nu respecta");

}}

Tabela 2.2: Clase caracter si clase predefinite

Reprezentare Semnificatie[abc] a, b sau c[ˆabc] orice caracter cu exceptia lui a, b sau c[a-zA-Z] caractere ıntre a-z si A-Z[a-d[m-p]] caractere ıntre a-d si m-p[a-z&&[def]] d, e sau f (intersectie)[a-z&&[ˆbc]] de la a la z, cu exceptia lui b si c[a-z&&[ˆm-p]] de la a la z, cu exceptia lui m-p

Page 34: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

30CAPITOLUL 2. STRUCTURI FUNDAMENTALE DE PROGRAMARE IN JAVA

Tabelul 2.2 (continuare)Reprezentare Semnificatie. Orice caracter\d O cifra: [0-9]\D Un caracter care nu e cifra: [ˆ0-9]\s Un caracter spatiu: [ \t\n\r]\S Un caracter non-spatiu [ˆ\s]\w Un caracter dintr-un cuvant: [a-zA-Z 0-9]\W Un caracter care nu face parte dintr-un cuvant: [ˆ\w]

Am prezentat ın tabelul anterior principalele clase de caractere si clasepredefinite care sunt definite pentru lucrul cu expresii regulate ın Java.

Se poate ca pentru un astfel de caracter sa specificam numarul exact deaparitii ın text, folosind cuantificatorii prezentati ın tabelul urmator.

Problema 2 Sa se scrie fragmentul de cod care verifica daca un sir decaractere citit de la tastatura este alcatuit din concatenarea a ıntre 2 si 4numere de cate doua cifre, prima fiind diferita de 0.

if(Pattern.matches("([\\d&&[^0]]\\d)2,4", str))

System.out.println("Respecta");

else

System.out.println("Nu respecta");

Tabela 2.3: Cuantificatori pentru lucrul cu expresii reg-ulate

Reprezentare SemnificatieX? X, odata sau delocX* X, de zero sau mai multe oriX+ X, odata sau de mai multe oriX{n} X, exact de n oriX{n,} X, de cel putin n oriX{n,m} X, de cel putin n ori dar nu mai mult de m ori

Page 35: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

CAPITOLUL 3

Concepte si principii ın POO

Programarea obiect orientata (POO) este o paradigma de programarecare foloseste obiecte precum si interactiunile ıntre ele pentru a construiaplicatii si programe. Tehnicile de programare specifice POO se bazeaza penotiuni precum: ıncapsulare, modularitate, polimorfism si mostenire.

Programarea obiect orientata a ajuns ın prim plan la ınceputul anilor ’90odata cu folosirea pe scara larga a limbajelor C++ si Java.

Aproape toate limbajele de programare importante din zilele noastrefolosesc programarea obiect orientata. Este cazul limbajelor C++, Java,C#, Visual Basic, Object Pascal si lista ar putea continua.

POO poate fi vazuta ca o colectie de obiecte care coopereaza, spre deose-bire de programarea procedurala care era vazuta ca o grupare de task-uri deefectuat (subrutine). In POO, fiecare obiect este capabil de a primi mesaje,de a procesa date si de a trimite mesaje la alte obiecte.

3.1 Concepte ın programarea obiect orientata

Clasa defineste caracteristicile comune mai multor lucruri (obiecte), in-cluzand partea informationala a acestora (atribute, campuri sau proprietati)si comportamentul lor (lucrurile pe care le pot face - reprezentate prin metode).

Clasa este un tip de date deoarece, la fel ca si tipul float are o partede informatie precum si o parte de comportament. Practic, lucrul cu clasepermite definirea de noi tipuri de date ın loc de a folosi doar tipurile caresunt deja existente ın limbaj.

31

Page 36: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

32 CAPITOLUL 3. CONCEPTE SI PRINCIPII IN POO

Astfel se ımbogateste limbajul prin adaugarea de tipuri de date nece-sare programatorului. Limbajul nu numai ca permite acest lucru dar ıl siıncurajeaza puternic.

Odata creata o clasa se pot crea oricate obiecte de tipul acelei clase,obiecte care vor corespunde obiectelor din domeniul problemei.

Clasele ofera de asemenea modularitate si structura ıntr-un program bazatpe programarea obiect orientata.

Obiectul este un exemplar al unei clase (o instanta a unei clase).Instanta este un obiect creat la momentul rularii pe baza unei clase.

Setul de valori ale atributelor unui obiect reprezinta starea acelui obiect.Metodele se refera la abilitatile unui obiect. In cadrul unui program

prin folosirea unei metode este afectat un singur obiect, cel asupra caruiaeste apelata metoda respectiva (exceptie fac aici metodele statice).

Transmiterea de mesaje este procesul prin care un obiect trimite datealtui obiect sau ıi cere altui obiect sa apeleze o metoda.

In urma cu ceva timp un programator descria limbajul Smalltalk astfel:

• Totul este un obiect (Un obiect este o variabila mai deosebita care areatat stare cat si comportament)

• Un program este alcatuit dintr-un set de obiecte care-si spun unul altuiace sa faca.

• Fiecare obiect are propria sa memorie alcatuita eventual din alte obiecte.

• Fiecare obiect are un tip (este o instanta a unei clase).

• Toate obiectele de acelasi tip pot primi aceleasi mesaje (chiar si ıncontextul mostenirii).

Dupa cum putem usor observa toate aceste lucruri sunt valabile si acumın contextul limbajului Java.

3.2 Principii ale programarii obiect orientate

Abstractizarea reprezinta simplificarea realitatii complexe prin mode-larea de clase potrivite problemei de rezolvat precum si lucrul la cel maipotrivit nivel de mostenire pentru un anumit aspect al unei probleme.

Toate limbajele de programare ofera un anumit grad de abstractizare.Complexitatea problemei de abstractizat depinde foarte mult de tipul ab-stractizarii si de calitatea acesteia.

Page 37: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

3.2. PRINCIPII ALE PROGRAMARII OBIECT ORIENTATE 33

Limbajul de asamblare este o mica abstractizare fata de limbajul codmasina.

Urmatoarele limbaje care au aparut sunt abstractizari ale limbajului deasamblare. Ne referim aici la limbaje gen Basic si C.

Aceste limbaje reprezinta o ımbunatatire majora fata de limbajul deasamblare dar tot ne fac sa gandim ın termen de structura a calculatoru-lui, nu numai ın termeni referitori la domeniul problemei de rezolvat.

Astfel, avem programe destul de greu de scris si greu de mentinut.Abordarea obiect-orientata ofera programatorului instrumente pentru a

reprezenta elementele din spatiul problemei.POO ne permite sa exprimam problema ın termenii domeniului core-

spunzator ei. Vom folosi obiecte care au fiecare o stare si un comportament.Incapsularea se refera la detaliile functionale ale unei clase din punct

de vedere al obiectelor care trimit mesaje catre acea clasa. Incapsularea seobtine prin specificarea clara a claselor care pot folosi membrii unui obiect.Rezultatul consta ın faptul ca fiecare obiect expune unei anumite clase oanumita interfata - acei membri accesibili acelei clase.

Motivatia folosirii ıncapsularii o constituie prevenirea folosirii de catreclienti a acelor parti ale unei clase care s-ar putea sa se schimbe ın viitor.Astfel, metodele sunt publice, private sau private, determinand daca suntvalabile tuturor claselor, numai claselor derivate sau numai ın clasa ın caresunt definite.

Din punctul de vedere al modului ın care folosesc clasele programatoriise ımpart ın doua mari categorii:

• cei care creeaza clasa - acestia sunt cei care cunosc toate detaliile despreclasa respectiva, fiind cei care realizeaza crearea unui nou tip de date

• cei care sunt doar clienti ai clasei - acestia sunt acei programatori caredoar folosesc clasa respectiva nefiind interesati de modul ın care clasaeste implementata efectiv, ci doar de serviciile pe care aceasta le ofera.Acestea sunt specificate prin interfat a clasei respective.

Putem practic afirma ca interfata unei clase reprezinta un contract ıntreprima categorie de programatori si ceea de-a doua, ın sensul ın care cre-atorii clasei le ofera o asigurare celor care folosesc acea clasa ca metodele dininterfata nu se vor modifica ın viitor chiar daca implementarile vor fi altele.

Mostenirea se refera la anumite clase care partajeaza anumite informatiiprecum si comportament. Subclasele sunt versiuni mai specializate ale unorclase, care mostenesc atribute si comportament de la clasele lor parinte si isiintroduc propriile lor atribute si metode.

Fiecare subclasa ısi poate altera caracteristicile mostenite.

Page 38: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

34 CAPITOLUL 3. CONCEPTE SI PRINCIPII IN POO

In unele limbaje, nu si ın Java, putem avea mostenire multipla. Aceastaınseamna sa mostenesti atribute si comportament din mai multe clase debaza.

Polimorfismul permite programatorului sa trateze metodele claselorderivate ca si pe metodele claselor lor parinte. Mai exact, polimorfismulreprezinta capabilitatea obiectelor care apartin unor tipuri de date diferitesa raspunda la apeluri de metode cu acelasi nume, fiecare corespunzatoareunui comportament specific tipului lor.

3.3 Solutii pentru utilizarea eficienta a prin-

cipiilor POO

Exista un anumit numar de provocari pe care un dezvoltator le ıntalnesteın mod regulat atunci cand face designul unui sistem obiect orientat. Existade asemenea si solutii acceptate la scara larga pentru aceste probleme.

Cele mai cunoscute astfel de solutii sunt cele oferite de sabloanele deproiectare documentate ın GoF (cartea Design patterns - Elements of ReusableObject Oriented Software scrisa de Gamma, Helm, Johnsson si Vlissides).Acestea pot fi vazute ca niste solutii generale, aplicabile ın mod repetat unorprobleme care tot apar ın designul de software.

Toate aceste sabloane de proiectare au la baza cateva idei foarte impor-tante:

1. Cand un anumit lucru variaza acel lucru trebuie ıncapsulat. Aceastaınseamna ca atunci cand ıntalnim o anumita parte a sistemului soft,care este foarte probabil sa se modifice ın viitor, aceasta ar trebui izo-lata ın sensul ın care sa se specifice o interfata cat mai stabila a ei,implementarea putand fi modificata ulterior.

2. Folosirea compozitiei ın dauna mostenirii. Chiar daca mostenirea esteun instrument foarte puternic, adesea se abuzeaza de ea, ın situatii ıncare ar fi mai bine daca nu ar fi folosita. Decizia de a folosi mostenireatrebuie sa fie o decizie bine argumentata luata numai dupa ce s-austudiat si alternativele.

3. In general este mai bine sa lucram pe interfete nu pe implementari.Acest lucru este necesar deoarece daca la un moment dat se alege sa selucreze cu o alta implementare si ne-am bazat pe prima implementare,va trebui sa schimbam codul. De asemenea, lucrul pe interfete ın daunamostenirii favorizeaza utilizarea polimorfismului.

Page 39: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

3.3. SOLUTII PENTRU UTILIZAREA EFICIENTA A PRINCIPIILOR POO35

O alta idee extrem de sugestiva este cea enuntata de cunoscutul infor-matician Bertrand Meyer si care poarta numele de Principiul Open-Closed :

Toate entitatile software trebuie sa fie deschise pentru extensie si ınchisepentru modificare.

Atunci cand o schimbare ıntr-o aplicatie conduce la numeroase alte schimbariın cascada ın alte zone ale aplicatiei, aceste este un semn ca avem de-a facecu un design slab. Programul devine fragil, greu de stapanit si imprevizibil.

Acest principiu spune ca trebuie sa construim module care nu se schimba,ın sensul ın care daca vrem sa adaugam noi facilitati putem scrie cod nou,dar fara a modifica codul deja existent.

In mod evident, nu se poate ca un modul sa fie complet ınchis. In anu-mite situatii este necesar sa modificam cod existent. Totusi aplicatia trebuiegandita astfel ıncat sa permita acest lucru ıntr-un mod cat mai flexibil sipremeditat.

Exista ınca doua principii importante referitoare la designul modulelorıntr-o aplicatie (ele fac parte dintr-o suita mai mare de astfel de sfaturi carepoarta numele GRASP - General Responsabilities Assignmnet Software Pat-terns):

1. Intre componentele unui modul (clasa, pachet, etc.) trebuie sa existeo coeziune ınalta. Aceasta ınseamna ca nu este bine, spre exemplu, caıntr-o clasa sa avem mai multe informatii si metode ıntre care nu existalegaturi stranse. Exista metrici specializate pentru masurarea acesteicaracteristici.

2. Intre diversele parti componente ale unei aplicatii trebuie sa existe ocuplare slaba. Aceasta ınseamna ca atunci cand modificam un modul,modificarile asupra lui sa nu genereze modificari ın cascada asupra altormodule.

In final vom spune cateva cuvinte despre un alt principiu foarte importantreferitor la programarea obiect orientata si anume principiul numit Inversionof Control (IoC). Acesta este un principiu abstract care descrie un anumitaspect referitor la designul sistemelor soft ın care fluxul evenimentelor esteinvers fata de cursul normal ıntr-o aplicatie traditionala.

El a fost asemanat cu principiul numit ”Hollywood Principle”: don’t callus, we’ll call you.

Se poate spune ca IoC este un mod de a scrie software ın care un codgeneric si reutilizabil poate fi aplicat la diverse probleme.

Exista doua moduri de lucru care au la baza principiul IoC:

• programarea orientata pe evenimente (event-driven programming)

Page 40: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

36 CAPITOLUL 3. CONCEPTE SI PRINCIPII IN POO

• injectarea de dependenta (dependency injection) - aceasta din urmaınseamna, spre exemplu, ca avem o componenta care deja are definitun schelet de utilizare, dar care pentru a fi utila are nevoie ca noi sa”injectam” un anumit comportament.

Page 41: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

CAPITOLUL 4

Obiecte si clase

In limbajul Java pentru a crea pana si cea mai simpla aplicatie este nevoiesa cream macar o clasa.

Dupa cum vom vedea ın continuare o aplicatie Java este alcatuita, ınprincipiu, din mai multe clase care colaboreaza ıntre ele. De obicei exista oclasa care contine si o metoda main() si care constituie punctul de intrare ınaplicatie, clasa care foloseste alte clase la rularea aplicatiei.

Se poate ıntampla ca o aplicatie sa aiba mai multe metode main(),situatie ın care, la rularea programului putem specifica care este clasa acarei metoda se va executa.

4.1 Definirea unei clase

Pentru definirea unei clase se foloseste urmatoarea sintaxa:

[modificatori] class NumeClasa [extends ClasaBaza]

[implements Interfata1[, Interfata2...]]

{//definire atribute clasa

//definire constructori

//definire metode clasa

}

37

Page 42: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

38 CAPITOLUL 4. OBIECTE SI CLASE

Modificatorii aplicabili unei clase sunt urmatorii: public, abstract, finalsi static.

Modificatorul public poate fi folosit pentru a specifica ca o clasa poatefi folosita peste tot ın aplicatie daca este inclus pachetul ın care ea estedeclarata sau clasa care o foloseste face parte din acelasi pachet. Daca acestmodificator lipseste atunci ınseamna ca avem vizibilitate la nivel de pachet(numai clasele din acelasi pachet pot utiliza aceasta clasa).

Modificatorul abstract specifica faptul ca avem de-a face cu o clasa ab-stracta. Acest lucru ınseamna ca nu se poate instantia aceasta clasa (nu sepot crea obiecte de acest tip). Vom discuta mai mult despre acest modificatorın contextul mostenirii.

Modificatorul final aplicat unei clase specifica faptul ca aceasta clasa numai poate fi derivata.

Modificatorul static nu se poate aplica decat ın contextul claselor imbri-cate. Vom studia acest lucru ıntr-o sectiune special dedicata acestor clase.

Despre folosirea lui extends si implements vom discuta atunci cand vomprezenta mostenirea si modul ın care o clasa poate implementa interfete.

4.2 Declararea atributelor unei clase

In primul rand trebuie facuta clar distinctia ıntre atribute si variabilelocale.

O variabila locala este definita ın interiorul unei metode sau a unui con-structor.

Un atribut al clasei este definit ın afara oricarei metode. Dupa cum vomvedea ın continuare atributele pot fi de doua feluri: statice (atribute aleclasei) si nestatice (atribute ale instantei).

Un exemplul din care se poate vedea acest lucru este urmatorul:

class Stiva

{public final static int MAX=100; //atribut static

private int nrElemente; //atribut nestatic

public void push(Object o)

{int a=0; //variabila locala

....

}}

Page 43: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4.2. DECLARAREA ATRIBUTELOR UNEI CLASE 39

Pentru a declara (si eventual initializa explicit) un atribut ın Java sefoloseste urmatoarea sintaxa:

[modificatori] tip numeAtribut[=val implicita][,...]

Daca nu initializam ın mod explicit un atribut el are niste valori implicite:0 pentru tipurile ıntregi, 0.0 pentru tipurile reale, boolean pentru caracteresi null pentru obiecte.

Modificatorii aplicabili atributelor ın Java sunt: public, private, pro-tected, final, static, transient si volatile.

4.2.1 Modificatorii de vizibilitate

Modificatorul public aplicat unui atribut semnifica faptul ca acel atributeste accesibil de oriunde, folosind notatia cu punct, ca ın exemplul urmator:

class Complex

{public double re;

public double im;

public Complex(double r, double i)

{re=r;

im=i;

}//alte atribute si metode

}

class UseComplex

{public static void main(String args[])

{Complex c=new Complex(3,4);

c.re=6; //se poate folosi atributul din afara clasei

}}

Modificatorul private semnifica faptul ca un atribut este accesibil numaidin interiorul clasei ın care este definit. Astfel, exemplul anterior de folosirea atributului nu ar fi functionat daca s-ar fi declarat atributul ca fiind privat.

Page 44: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

40 CAPITOLUL 4. OBIECTE SI CLASE

Modificatorul protected specifica faptul ca un atribut este vizibil atat ınclasele derivate din clasa ın care este declarat cat si ın toate clasele care facparte din acelasi pachet cu clasa ın care a fost declarat atributul.

Daca nu este folosit nici un modificator de vizibilitate se presupune im-plicit ca avem vizibilitate la nivel de pachet (package). Acest lucru ınseamnaca acel atribut este accesibil doar ın interiorul pachetului ın care este definitaclasa respectiva.

4.2.2 Modificatorul final

Un atribut care este declarat ca final nu mai poate sa-si schimbe valoareaıntr-o atribuire ulterioara.

Acest lucru ınseamna pentru tipurile primitive ca valoarea lor este con-stanta, iar pentru tipurile referinta ca nu se mai poate modifica adresa catreobiectul catre care pointeaza.

Iata si cateva exemple:

class Test

{final int a=100;

final String s="test";

final int[] b={2, 4, 5};

void metoda()

{//genereaza eroare deoarece nu se poate modifica un atribut de

//un tip primitiv declarat constant

a=1000;

//va genera eroare deoarece cand se modifica valoarea unui

//obiect de tip String automat se aloca memorie pt un nou sir

s="alt test";

//functioneaza deoarece nu se modifica adresa retinuta de sir

b[2]=4;

//nu functioneaza deoarece se modifica adresa retinuta de sir

b=new int[5];

}}

Page 45: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4.2. DECLARAREA ATRIBUTELOR UNEI CLASE 41

4.2.3 Modificatorul static

In mod implicit, daca modificatorul static nu este folosit asupra unuiatribut, acel atribut poate avea valori diferite pentru obiecte diferite. Astfel,daca avem definita o clasa Persoana care are un atribut nume, acest atributva avea valori diferite pentru fiecare obiect de tipul Persoana.

Modificatorul static aplicat unui atribut ınseamna ca pentru acel atributse aloca memorie o singura data indiferent cate obiecte de tipul clasei avem.Spunem despre acel atribut ca este un atribut al clasei, practic acea valoareunica nu tine de obiecte ci de clasa.

Prezentam si un exemplu din care se poate vedea modul ın care se potfolosi atributele statice si nestatice. Remarcati faptul ca un atribut staticpoate fi accesat si prin intermediul numelui clasei, mai degraba decat prinnumele unui obiect.

class Test

{public static int atributStatic;

public int atributNestatic;

}

public class ExempluStatic

{public static void main(String args[])

{Test t1=new Test();

Test t2=new Test();

t1.atributNestatic=3;

t2.atributNestatic=6;

System.out.println(t1.atributNestatic+" "+t2.atributNestatic);

//afiseaza valorile 3 si 6

t1.atributStatic=1;

t2.atributStatic=2;

System.out.println(t1.atributStatic+" "+Test.atributStatic);

//afiseaza valorile 2 si 2

}}

Page 46: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

42 CAPITOLUL 4. OBIECTE SI CLASE

4.2.4 Modificatorii transient si volatile

Modificatorul transient aplicat unui atribut specifica faptul ca acel atributnu este un atribut care ar trebui pastrat pe suport extern atunci cand se vaserializa o instanta a clasei.

Modificatorul volatile este folosit pentru atribute care pot fi accesatesimultan din mai multe fire de executie. Acest modificator avertizeaza com-pilatorul ca asupra lor nu trebuie facute anumite optimizari si ca de fiecaredata trebuie calculata valoarea lor actualizata.

4.3 Declararea metodelor unei clase

Declararea unei metode ın Java are urmatoarea sintaxa:

[modificatori] tip returnat numeMetoda( parametri)

[throws Exceptie1[, Exceptie2[...]]]

{//corpul metodei

}

Ca o prima observatie importanta, trebuie spus ca o clasa poate avea maimulte metode cu acelasi nume. Totusi este evident nevoie ca metodele sadifere macar prin tipul sau numarul parametrilor transmisi la metoda.

Modificatorii aplicabili metodelor ın Java sunt: public, private, protected,final, static, abstract, native si synchronized.

Nu vom mai prezenta ın cele ce urmeaza modificatorii de vizibilitatepublic, private si protected deoarece ei au aceeasi semnificatie ca si ın cazuldeclararii atributelor.

Modificatorul final aplicat unei metode specifica faptul ca acea metodanu mai poate fi redefinita ıntr-o clasa derivata. Mai multe despre acest lucruın capitolul dedicat mostenirii.

Modificatorul abstract aplicat unei metode specifica faptul ca acea metodaexista pentru tipul respectiv, dar nu se cunoaste ınca implementarea ei. Eava fi implementata ıntr-o clasa derivata.

Modificatorul synchronized aplicat unei metode specifica faptul ca apelulasupra acelei metode trebuie sincronizat. Acest lucru se foloseste ın cazulaplicatiilor care utilizeaza fire de executie.

Vom prezenta ın subsectiunea urmatoare rolul modificatorului static asuprametodelor.

Nu vom prezenta deocamdata facilitatile care tin de tratarea exceptiilor.

Page 47: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4.3. DECLARAREA METODELOR UNEI CLASE 43

4.3.1 Modificatorul static

Prin specificarea unei metode ca fiind o metoda statica, practic, ıi co-municam calculatorului ca acea metoda nu a fost creata pentru apelarea eiasupra obiectelor ci mai degraba avem o metoda a unei clase, care poatefolosi numai atribute si metode statice ale clasei.

Acesta este motivul pentru care pana acum, de fiecare data cand scriamo metoda trebuia ca acea metoda sa fie statica (din metoda main() care estestatica nu se pot apela decat metode statice).

Prezentam ın continuare un exemplu de clasa pentru care are sens sadefinim metode statice:

class Mathematica

{private Mathematica()

{}

public static int max(int a, int b)

{return a>=b?a:b;

}

public static int abs(int a)

{return a>=0 ? a : -a;

}}

public class Testare

{public static void main(String args[])

{System.out.println(Mathematica.max(3,4));

}}

4.3.2 Transmiterea parametrilor la metode

In limbajul Java toti parametri care se transmit unei metode setransmit prin valoare.

Page 48: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

44 CAPITOLUL 4. OBIECTE SI CLASE

Acest lucru ınseamna ca modificarile asupra lor nu se pastreaza. Totusieste important de ınteles ce se transmite de fapt unei metode.

In cazul ın care se transmite o variabila de un tip primitiv se transmitede fapt valoarea ei si modificarile asupra acesteia nu se pastreaza.

Daca se transmite un sir, matrice sau un alt obiect, atunci de fapt setransmite adresa obiectului respectiv. Acest lucru ınseamna ca acea adresanu se poate modifica. Totusi modificarile asupra continutului aflat laaceea adresa se pastreaza.

4.4 Declararea constructorilor unei clase

Un rol foarte important atunci cand lucram cu clase si obiecte ıl auconstructorii. Putem sa ne gandim la un constructor ca la o metoda mai spe-ciala (nu se poate zice ca este chiar metoda deoarece pentru un constructornu se specifica tipul returnat).

Acestia intervin ın momentul ın care dorim sa creem noi obiecte, folosindinstructiunea new().

Daca scriem codul:

String s=new String("Rodica");

atunci, pentru variabila s se va apela un constructor al clasei String careva realiza initializarea tuturor atributelor obiectului s.

Constructorii respecta doua caracteristici importante:

1. Au ıntotdeauna acelasi nume cu clasa pentru care se declara.

2. Pentru un constructor nu se specifica nici un tip returnat.

Observatii:

• Se poate ıntampla ca un constructor sa fie privat, ca ın exemplul prezen-tat la sectiunea precedenta. In acel exemplu, dupa cum am putut ob-serva este imposibila crearea obiectelor de tipul Mathematica.

• Daca nu avem nici un constructor definit, nu ınseamna ca acel con-structor lipseste. Specificatia Java prevede faptul ca daca nu definimnici un constructor, automat este creat unul care initializeaza toateatributele cu valorile lor implicite (0, 0.0, false si null). Acesta senumeste constructorimplicit. Acest constructor implicit, dar si oricealt constructor apeleaza chiar daca nu este specificat, constructorul faraparametri din clasa de baza.

Page 49: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4.4. DECLARAREA CONSTRUCTORILOR UNEI CLASE 45

• Daca pentru o clasa este specificat un constructor, atunci nu va mai figenerat constructorul implicit. Acest lucru se ıntampla indiferent detipul parametrilor constructorului creat de programator.

• O clasa poate avea mai multi constructori. Acest lucru va fi prezentatın exemplul urmator.

Prezentam ın continuare un exemplu de definire partiala a unei claseComplex care ar permite lucrul cu numere complexe:

public class Complex

{private double re, im;

/*public Complex(double r, double i)

{re=r;

im=i;

}*/

public Complex(double re, double im)

{this.re=re;

this.im=im;

}

public Complex(double re)

{this(re, 0);

}

public Complex()

{this(0);

}

//alte metode...

public static void main(String args[])

{Complex c1=new Complex(3, 4); //retine pe 3+4i

Complex c2=new Complex(6); //retine pe 6+0i

Page 50: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

46 CAPITOLUL 4. OBIECTE SI CLASE

Complex c3=new Complex(); //retine pe 0+0i

}}

Observatii:

• Daca ıntr-o metoda numele unui parametru al metodei este acelasi cunumele atributului clasei, atunci pentru a se putea face distinctia ıntrecele doua se foloseste cuvantul cheie this pentru a specifica un atributal clasei.

• Se poate ca dintr-un constructor sa se apeleze un alt constructor alaceleiasi clase. Am facut acest lucru cu ajutorul cuvantului cheie this,care primeste ın paranteza parametri catre acel constructor. Apelulacesta trebuie sa fie prima instructiune din cadrul constructorului apelant.

4.5 Initializatorul static al unei clase

Initializatorul static al unei clase este codul care este executat prima oaracand se foloseste o clasa. Acesta este marcat prin cuvantul cheie static urmatde acolade ıntre care se specifica codul de executat.

Iata si un exemplu:

class Test

{static int max=10;

static

{max=100;

System.out.println("In initializatorul static");

}}

public class FolosireInitializatorStatic

{public static void main(String args[])

{Test t=new Test();

}}

Page 51: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4.6. PROBLEME REZOLVATE 47

4.6 Probleme rezolvate

Problema 1 Sa se construiasca o clasa pentru lucrul cu numere complexe(constructori, metode get/set, implementarea modulului unui numar com-plex, adunarea, ınmultirea, ımpartirea si scaderea). Sa se citeasca de latastatura n numere complexe. Sa se rezolve urmatoarele subprobleme:

• Sa se sorteze crescator elementele sirului ın functie de modulul lor si sase afiseze pe ecran.

• Sa se calculeze suma elementelor sirului.

public class Complex

{private double re, im;

public Complex(double re, double im)

{this.re=re;

this.im=im;

}

public Complex(double re)

{this(re, 0);

}

public Complex()

{this(0);

}

public double getRe()

{return re;

}

public void setRe(double re)

{this.re=re;

}

Page 52: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

48 CAPITOLUL 4. OBIECTE SI CLASE

public double getIm()

{return im;

}

public void setIm(double im)

{this.im=im;

}

public double getModul()

{return Math.sqrt(re*re+im*im);

}

public Complex adunare(Complex c)

{return new Complex(re+c.re, im+c.im);

}

public Complex inmultire(Complex c)

{return new Complex(re*c.re-im*c.im, re*c.im+im*c.re);

}

public static Complex scadere(Complex c1, Complex c2)

{return new Complex(c1.re-c2.re, c1.im-c2.im);

}

public static Complex impartire(Complex c1, Complex c2)

{//de implementat :-) (de catre studenti)

return null;

}

public String toString()

{if(im<0)

return re+""+im+"*i";

Page 53: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4.6. PROBLEME REZOLVATE 49

return re+"+"+im+"*i";

}}

import java.util.*;

public class TestComplex

{public static void main(String args[])

{Scanner s=new Scanner(System.in);

System.out.print("n=");

int n=s.nextInt();

Complex[] c=new Complex[n];

for(int i=0;i<c.length;i++)

{System.out.print("partea reala: ");

double re=s.nextDouble();

System.out.print("partea imaginara: ");

double im=s.nextDouble();

c[i]=new Complex(re, im);

}sortare(c);

afisare(c);

System.out.println("Suma elementelor sirului: "+suma(c));

}

static void sortare(Complex[] c)

{for(int i=0;i<c.length-1;i++)

for(int j=i+1; j<c.length;j++)

if(c[i].getModul()>c[j].getModul())

{Complex aux=c[i];

c[i]=c[j];

c[j]=aux;

}}

Page 54: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

50 CAPITOLUL 4. OBIECTE SI CLASE

static void afisare(Complex[] c)

{for(Complex nr: c)

System.out.print(nr+" ");

System.out.println();

}

static Complex suma(Complex[] c)

{Complex sum=new Complex();

for(int i=0;i<c.length;i++)

sum=sum.adunare(c[i]);

return sum;

}}

Problema 2 Sa se implementeze o clasa pentrul lucrul cu o stiva carecontine numere ıntregi si sa se foloseasca aceasta clasa ıntr-un program sim-plu.

Codul pentru aceasta problema ar putea arata astfel:

public class Stack

{private int[] elemente;

private int top;

public Stack(int dim)

{top=0;

elemente=new int[dim];

}

public Stack()

{this(10);

// implicit se creeaza o stiva care are exact

// 10 elemente

}

private void expandare()

Page 55: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4.6. PROBLEME REZOLVATE 51

{int[] newElemente=new int[2*elemente.length];

System.arraycopy(elemente, 0, newElemente, 0, elemente.length);

elemente=newElemente;

}

private boolean isFull()

{return top==elemente.length;

}

public boolean isEmpty()

{return top==0;

}

public void push(int x)

{if(isFull())

expandare();

elemente[top++]=x;

}

public int top()

{return elemente[top-1];

}

public int pop()

{return elemente[--top];

}

public static void main(String args[])

{Stack s=new Stack();

s.push(3);

s.push(2);

System.out.println(s.top());

}}

Page 56: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

52 CAPITOLUL 4. OBIECTE SI CLASE

Problema 3 Sa se creeze o clasa care sa simuleze jocul Spanzuratoarea.Aceasta clasa trebuie sa fie o clasa cat mai generica pentru a permite reuti-lizarea ei ın mai multe situatii, indiferent daca avem o aplicatie grafica sauın linie de comanda.

Pentru inceput scriem codul care va folosi aceasta clasa:

import java.util.Scanner;

public class TestSpanzuratoare

{private static void afisare(char[] c)

{for(int i=0;i<c.length-1;i++)

System.out.print(c[i]+" ");

System.out.println(c[c.length-1]);

}

public static void main(String args[])

{Scanner s=new Scanner(System.in);

Spanzuratoare joc=new Spanzuratoare();

while(!joc.isOver())

{System.out.print("Cuvantul de ghicit: ");

afisare(joc.cuvantCurent());

System.out.print("Introduceti o litera: ");

char c=s.nextLine().charAt(0);

if(joc.ghiceste(c))

System.out.println("BRAVO!!! Ai ghicit !");

else

System.out.println("GRESEALA!!! Mai ai "+joc.incercariRamase()+" incercari");

}if(joc.isWinner())

System.out.println("AI CASTIGAT!!!");

else

System.out.println("AI PIERDUT!!!");

}}

Page 57: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4.6. PROBLEME REZOLVATE 53

Dupa cum se poate usor observa, metodele si constructorii necesari pentruaceasta clasa sunt:

Spanzuratoare

---------------------------

public Spanzuratoare()

public char[] cuvantCurent()

public boolean ghiceste(char c)

public int incercariRamase()

public boolean isOver()

public boolean isWinner()

Avand interfata clasei, adica metodele publice ale clasei, putem scrie co-dul pentru aceasta:

import java.util.*;

public class Spanzuratoare

{private String[] cuvinteDeAles={"abecedar", "calculator", "masina"};private char[] cuvantCurent;

private char[] cuvantAles;

private int nrGreseli;

private String ghicite;

private final static int MAX_NR_GRESELI=5;

public Spanzuratoare()

{Random r=new Random();

cuvantAles=cuvinteDeAles[r.nextInt(cuvinteDeAles.length)].toCharArray();

cuvantCurent=cuvantAles.clone();

char c1=cuvantAles[0];

char c2=cuvantAles[cuvantCurent.length-1];

cuvantCurent[0]=c1;

cuvantCurent[cuvantCurent.length-1]=c2;

for(int i=0;i<cuvantAles.length;i++)

if(cuvantAles[i]==c1 || cuvantAles[i]==c2)

cuvantCurent[i]=cuvantAles[i];

else

Page 58: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

54 CAPITOLUL 4. OBIECTE SI CLASE

cuvantCurent[i]=’_’;

ghicite=""+c1+c2;

}

public char[] cuvantCurent()

{return cuvantCurent.clone();

}

public boolean isOver()

{if(nrGreseli==MAX_NR_GRESELI)

return true;

for(int i=0;i<cuvantCurent.length;i++)

if(cuvantCurent[i]==’_’)

return false;

return true;

}

public boolean ghiceste(char c)

{if(ghicite.indexOf(c)>=0)

return false;

ghicite+=c;

boolean gasit=false;

for(int i=0;i<cuvantAles.length;i++)

if(cuvantAles[i]==c)

{cuvantCurent[i]=c;

gasit=true;

}if(!gasit)

nrGreseli++;

return gasit;

}

public int incercariRamase()

{return MAX_NR_GRESELI-nrGreseli;

}

Page 59: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4.6. PROBLEME REZOLVATE 55

public boolean isWinner()

{return isOver() && nrGreseli<5;

}}

Problema 4 Sa se construiasca o clasa MyStringTokenizer care sa lucrezeıntr-un mod asemanator cu clasa StringTokenizer.

Pentru a construi aceasta clasa ne gandim, ın primul rand cum ar trebuiea sa fie folosita ıntr-un program. Codul poate arata ın felul urmator:

public class TestMyStringTokenizer

{public static void main(String args[])

{MyStringTokenizer mst=new MyStringTokenizer("Ce mai faci? Eu sunt aici."

," ?!.");

System.out.println("Avem "+mst.countTokens()+" tokeni");

while(mst.hasMoreTokens())

{String str=mst.nextToken();

System.out.println(str);

}}

}

Se poate observa destul de usor ca aceasta clasa trebuie sa aiba urmatoarelemetode:

MyStringTokenizer

---------------------------

public MyStringTokenizer(String str, String sep)

public MyStringTokenizer(String str)

public String getSep()

public void setSep(String sep)

public int countTokens()

public boolean hasMoreTokens()

public String nextToken()

Codul pentru aceasta clasa poate arata astfel:

Page 60: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

56 CAPITOLUL 4. OBIECTE SI CLASE

public class MyStringTokenizer

{private String s;

private String sep;

public MyStringTokenizer(String s, String sep)

{this.s=s;

this.sep=sep;

}

public MyStringTokenizer(String s)

{this(s," \t\n\r\f");

}

public String getSep()

{return sep;

}

public void setSep(String sep)

{this.sep=sep;

}

private boolean isSeparator(char c)

{return sep.indexOf(c)>=0;

}

public int countTokens()

{int i=0, tokens=0;

while(i<s.length() && isSeparator(s.charAt(i)))

i++;

for(int j=i;j<s.length();j++)

if(j==0 || !isSeparator(s.charAt(j)) && isSeparator(s.charAt(j-1)))

tokens++;

return tokens;

}

Page 61: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4.6. PROBLEME REZOLVATE 57

public boolean hasMoreTokens()

{for(int i=0;i<s.length();i++)

if(sep.indexOf(s.charAt(i))<0)

return true;

return false;

}

public String nextToken()

{int i=0;

while(i<s.length() && isSeparator(s.charAt(i)))

i++;

if(i==s.length())

return null;

int j=i+1;

while(j<s.length() && !isSeparator(s.charAt(j)))

j++;

String cuv=s.substring(i,j);

s=s.substring(j);

return cuv;

}}

Problema 5 Sa se construiasca o clasa Queue cu ajutorul careia sa se poatalucra cu o coada de elemente numere ıntregi, alocata folosind liste ınlantuite.

Codul care ar folosi aceasta clasa ar putea arata astfel. Mentionam caam folosit ın continuare tratarea exceptiilor chiar daca ea va fi prezentataıntr-un capitol urmator:

import com.mihai.datastructures.*;

public class TestQueue

{public static void main(String args[])

{Queue q=new Queue();

q.push(3);

q.push(5);

Page 62: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

58 CAPITOLUL 4. OBIECTE SI CLASE

q.push(7);

try

{System.out.println("In varful cozii: "+q.top());

q.pop();

System.out.println("Continutul cozii: "+q);

}catch(EmptyQueueException e)

{System.out.println("Coada goala !!!");

}}

}

Dupa cum se poate usor observa vom avea nevoie de doua clase: Queue

si EmptyQueueException.Clasa Queue are urmatoarea interfata:

Queue

---------------------------

public Queue()

public void push(int x)

public int top()

public int pop()

public boolean isEmpty()

public String toString()

Clasele necesare acestei aplicatii arata astfel:

package com.mihai.datastructures;

public class EmptyQueueException extends Exception{

}

----------------------------------------

package com.mihai.datastructures;

class Node {private int value;

Page 63: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4.6. PROBLEME REZOLVATE 59

private Node next;

Node(int value)

{this.value=value;

this.next=null; //putea lipsi

}

Node(int value, Node next) {this.value = value;

this.next = next;

}

int getValue() {return value;

}

void setValue(int value) {this.value = value;

}

Node getNext()

{return next;

}

void setNext(Node next)

{this.next=next;

}}

----------------------------------------

package com.mihai.datastructures;

public class Queue {private Node first, last;

public boolean isEmpty()

{return first==null;

Page 64: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

60 CAPITOLUL 4. OBIECTE SI CLASE

}

public void push(int x)

{Node node=new Node(x);

if(isEmpty())

first=node;

else

last.setNext(node);

last=node;

}

public int top() throws EmptyQueueException

{if(isEmpty())

throw new EmptyQueueException();

return first.getValue();

}

public int pop() throws EmptyQueueException

{if(isEmpty())

throw new EmptyQueueException();

int value=first.getValue();

first=first.getNext();

return value;

}

public String toString()

{StringBuffer sb=new StringBuffer("[");

Node current=first;

if(!isEmpty())

{while(current.getNext()!=null)

{sb.append(current.getValue()+",");

current=current.getNext();

}sb.append(current.getValue());

}

Page 65: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4.6. PROBLEME REZOLVATE 61

sb.append("]");

return sb.toString();

}}

Problema 6 Sa se construiasca o clasa HeapMin care sa ne permita salucram cu heapuri minime.

Ea ar trebui sa poata fi folosita ıntr-unul din modurile urmatoare:

import java.util.Random;

public class TestHeapMin

{public static void main(String args[])

{/*Random r=new Random();

int[] a={0, 2, 4, 8, 7};

HeapMin heap=new HeapMin(a);

for(int i=0;i<3;i++)

heap.add(r.nextInt(10));

System.out.println(heap);

while(!heap.isEmpty())

System.out.print(heap.extractMin()+" ");*/

Random r=new Random();

HeapMin heap=new HeapMin();

for(int i=0;i<5;i++)

heap.add(r.nextInt(10));

System.out.println(heap);

System.out.print("Elementul minim: "+heap.getMin());

}}

Page 66: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

62 CAPITOLUL 4. OBIECTE SI CLASE

Interfata acestei clase arata astfel:

HeapMin

---------------------------

public HeapMin(int[] a)

public HeapMin()

public void add(int x)

public void add(int[] a)

public int extractMin()

public int getMin()

public boolean isEmpty()

public String toString()

Implementarea ei propriu-zisa poate arata ca ın exemplul urmator:

public class HeapMin

{private int count;

private int[] elements;

public HeapMin()

{elements=new int[3];

}

public HeapMin(int[] a)

{elements=new int[a.length+5];

System.arraycopy(a, 0, elements, 1, a.length);

count=a.length;

construiesteHeap();

}

private void expand()

{int newSize;

if(elements.length<10)

newSize=elements.length*2;

Page 67: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4.6. PROBLEME REZOLVATE 63

else

newSize=elements.length*4/3;

int[] newElements=new int[newSize];

System.arraycopy(elements, 1, newElements, 1, elements.length-1);

elements=newElements;

}

private boolean isFull()

{return count==elements.length-1;

}

public void add(int x)

{if(isFull())

expand();

elements[++count]=x;

int j=count;

while(j!=1 && elements[j/2]>elements[j])

{int aux=elements[j];

elements[j]=elements[j/2];

elements[j/2]=aux;

j=j/2;

}}

public void add(int[] a)

{for(int x:a)

add(x);

}

private void construiesteHeap()

{for(int i=count/2;i>=1;i--)

reconstituieHeap(i);

}

private void reconstituieHeap(int i)

{

Page 68: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

64 CAPITOLUL 4. OBIECTE SI CLASE

int left=2*i, right=2*i+1, minim;

if(left<=count && elements[left]<elements[i])

minim=left;

else

minim=i;

if(right<=count && elements[right]<elements[minim])

minim=right;

if(minim!=i)

{int aux=elements[i];

elements[i]=elements[minim];

elements[minim]=aux;

reconstituieHeap(minim);

}}

public int extractMin()

{int min=elements[1];

elements[1]=elements[count--];

reconstituieHeap(1);

return min;

}

public int getMin()

{return elements[1];

}

public boolean isEmpty()

{return count==0;

}

public String toString()

{StringBuffer sb=new StringBuffer("");

for(int i=1;i<=count;i++)

sb.append(elements[i]+" ");

return sb.toString();

}

Page 69: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

4.7. PROBLEME PROPUSE 65

}

4.7 Probleme propuse

Propunem spre rezolvare urmatoarele probleme:

1. Sa se construiasca o clasa pentru lucrul cu fractii, ın mod asemanatorcu cea pentru lucrul cu numere complexe si sa se foloseasca ıntr-unprogram.

2. Sa se construiasca o clasa Polinom si sa se implementeze operatiilepentru polinoame.

3. Sa se creeze o clasa Punct care contine coordonatele unui punct ın plan.Se citesc de la tastatura n puncte ın plan. Sa se rezolve urmatoarelesubprobleme:

• Sa se determine 2 puncte ıntre care avem distanta minima.

• Sa se verifice daca ın sir avem 3 puncte coliniare.

• Sa se afiseze toate punctele situate cel mai la nord.

4. Sa se construiasca o clasa Matrice pentru lucrul cu matrici.

5. Sa se construiasca o clasa Queue care sa simuleze modul de functionareal unei cozi. Elementele cozii vor fi retinute cu ajutorul vectorilor.Putem folosi chiar si vectori circulari.

Page 70: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

66 CAPITOLUL 4. OBIECTE SI CLASE

Page 71: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

CAPITOLUL 5

Mostenirea ın Java

5.1 Notiuni generale

Unul din cele mai importante concepte folosite ın programarea obiectorientata este conceptul de mostenire. Folosirea mostenirii ıncurajeaza:

• refolosirea claselor deja existente

• tratarea ın mod uniform a unor obiecte care sunt de tipuri diferite(ıncurajeaza polimorfismul)

Modul de lucru ın Java seamana oarecum cu ceea ce cunoastem deja dinlimbajul C++, numai ca ın Java sintaxa este mult mai usoara. In plus,ın Java nu exista conceptul de mostenire multipla (ın Java o clasa poate fiderivata dintr-o singura alta clasa).

Pentru a indica faptul ca o clasa este derivata din alta clasa folosimcuvantul cheie extends, ca ın exemplul urmator:

class ClasaDerivata extends ClasaBaza

{...

}

Clasa din care se deriveaza se numeste clasa de baza (sau clasa parinte,superclasa) iar clasa care este derivata din ea se numeste clasa derivata (sauclasa copil sau subclasa).

67

Page 72: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

68 CAPITOLUL 5. MOSTENIREA IN JAVA

O subclasa descrie obiecte care au aceleasi proprietati ca si cele ale su-perclasei si care, eventual, au si alte atribute sau metode.

Atributele si metodele din superclasa sunt accesibile si ın subclasa, cuexceptia atributelor si metodelor care sunt declarate private ın superclasa.De multe ori, atributele private din superclasa pot fi accesate prin intermediulunor metode din superclasa.

Reamintim ca ın limbajul Java exista modificatorul de vizibilitate pro-tected care are urmatoarea semnificatie: acele atribute sau metode cu aceastavizibilitate sunt vazute oriunde ın subclase precum si ın toate clasele din pa-chetul curent.

Dupa cum stim si din C++, atunci cand avem mostenire, trebuie sa putemapela din constructorul unei clase constructorul clasei de baza. Acest lucruse poate face cu ajutorul cuvantului cheie super. Apelul constructorului dinclasa de baza trebuie sa fie prima instructiune din constructor.

Un astfel de exemplu este prezentat ın continuare:

public class Profesor extends Persoana

{private String gradDidactic;

public Profesor(String nume, String prenume, String grad)

{super(nume, prenume);

this.gradDidactic=grad;

}...

}

Observatie: Daca nu apelam dintr-un constructor dintr-o clasa derivataun constructor din clasa de baza, atunci automat se apeleaza constructorulfara parametri din clasa de baza. De aceea, trebuie sa fim atenti, pentru caın situatia ın care avem doar constructori cu parametri ın clasa de baza siın constructorul din clasa derivata nu apelam pe niciunul din ei, vom obtineeroare.

5.2 Exemplu de aplicatie folosind mostenirea

In cele ce urmeaza vom prezenta un program care ilustreaza principiileprezentate anterior.

Exemplul 1 Sa se scrie un program care citeste de la tastatura informatiidespre n persoane (numele si prenumele). Persoanele sunt de 2 tipuri: profe-sori si studenti. Pentru fiecare profesor se cunoaste ın plus gradul didactic pe

Page 73: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

5.2. EXEMPLU DE APLICATIE FOLOSIND MOSTENIREA 69

care-l are, iar pentru fiecare student se cunoaste daca este bursier sau nu. Sase sorteze crescator sirul de persoane dupa nume si sa se afiseze sirul obtinut.

In primul rand definim o clasa Persoana astfel:

public class Persoana

{private String nume;

private String prenume;

public Persoana(String nume, String prenume)

{this.nume = nume;

this.prenume = prenume;

}

public String getNume()

{return nume;

}

public void setNume(String nume)

{this.nume = nume;

}

public String getPrenume()

{return prenume;

}

public void setPrenume(String prenume)

{this.prenume = prenume;

}

public String toString()

{return nume + " " + prenume;

}}

Definim o clasa Profesor derivata din clasa Persoana:

Page 74: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

70 CAPITOLUL 5. MOSTENIREA IN JAVA

public class Profesor extends Persoana

{private String gradDidactic;

public Profesor(String nume, String prenume, String gradDidactic)

{//daca nu apelez constructorul din clasa de baza

//am eroare

super(nume, prenume); //apel constructor din clasa de baza

this.gradDidactic=gradDidactic;

}

public String getGradDidactic()

{return gradDidactic;

}

public void setGradDidactic(String gradDidactic)

{this.gradDidactic = gradDidactic;

}

//suprascriere metoda din clasa de baza

public String toString()

{//apel metoda din clasa de baza

return super.toString()+" este "+gradDidactic;

}}

Clasa Student se construieste asemanator cu clasa Profesor:

public class Student extends Persoana

{private boolean bursier;

public Student(String nume, String prenume, boolean bursier)

{super(nume, prenume);

this.bursier = bursier;

}

Page 75: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

5.2. EXEMPLU DE APLICATIE FOLOSIND MOSTENIREA 71

public boolean isBursier()

{return bursier;

}

public void setBursier(boolean bursier)

{this.bursier = bursier;

}

public String toString()

{if(bursier)

return super.toString()+" este bursier";

return super.toString()+" nu este bursier";

}}

In cele din urma prezentam si codul pentru aplicatia care va folosi claselecreate anterior:

import java.util.Scanner;

public class TestPersoane

{public static void main(String[] args)

{Scanner s=new Scanner(System.in);

System.out.print("n=");

int n=Integer.parseInt(s.nextLine());

Persoana[] p=new Persoana[n];

for(int i=0;i<n;i++)

{System.out.print("Numele: ");

String nume=s.nextLine();

System.out.print("Prenumele: ");

String prenume=s.nextLine();

Page 76: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

72 CAPITOLUL 5. MOSTENIREA IN JAVA

System.out.print("Profesor sau student (p/s)");

char tip=s.nextLine().charAt(0);

if(tip==’p’)

{System.out.print("Gradul didactic: ");

String gradDidactic=s.nextLine();

p[i]=new Profesor(nume, prenume, gradDidactic);

}else

{System.out.print("Bursier? (d/n)");

if(s.nextLine().charAt(0)==’d’)

p[i]=new Student(nume, prenume, true);

else

p[i]=new Student(nume, prenume, false);

}}

sort(p);

afisare(p);

}

private static void sort(Persoana [] p)

{for(int i=0;i<p.length-1;i++)

for(int j=i+1;j<p.length;j++)

if(p[i].getNume().compareToIgnoreCase(p[j].getNume())>0)

{Persoana aux=p[i];

p[i]=p[j];

p[j]=aux;

}}

private static void afisare(Persoana [] p)

{for(Persoana pers:p)

System.out.println(pers); //POLIMORFISM !!!!

}}

Page 77: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

5.3. POLIMORFISMUL 73

Trebuie remarcat ca ın metoda de afisare, atunci cand se parcurge sirulde obiecte de tipul Persoana, ın functie de tipul obiectelor, Profesor sauStudent se apeleaza metoda toString() corecta.

Acest mecanism poarta numele de polimorfism.Solutia acestei probleme poate fi prezentata sub forma diagramei UML

din figura 5.1.

Figura 5.1: Diagrama de clase a aplicatiei cu persoane

5.3 Polimorfismul

Polimorfismul se refera la faptul ca atunci cand se apeleaza o metodaasupra unui obiect care la prima vedere pare de un tip mai generic, de faptse apeleaza metoda corespunzatoare clasei efective a obiectului.

Acest lucru este posibil deoarece ın Java se foloseste apelul dinamic almetodelor.

Atunci cand se apeleaza o metoda asupra unui obiect, se parcurg urmatoriipasi:

• In lista de metode ale clasei se identifica acele metode care se potrivescca nume cu metoda apelata.

Page 78: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

74 CAPITOLUL 5. MOSTENIREA IN JAVA

• Intre aceste metode se cauta o metoda pentru care parametrii acesteiasa se potriveasca cu parametri metodei apelate (overloading resolution).Daca nu se gaseste o astfel de metoda atunci se genereaza o eroare.

• Daca avem de-a face cu o metoda privata, statica, finala sau un con-structor, atunci compilatorul stie exact care este metoda care trebuieapelata. In acest caz, avem de-a face cu legarea statica la momentulrularii.

• Daca nu suntem ın una din aceste situatii, atunci metoda apelata sealege la momentul rularii de catre masina virtuala Java. In primul randse cauta o metoda ın clasa curenta, dupa care ın clasa ei de baza, sitot asa pana cand se gaseste o clasa ın care metoda este implementata.De fapt, ın realitate lucrurile nu se ıntampla chiar asa, ci mai degraba,pentru fiecare clasa se construieste cate un tabel cu metodele care sepot apela din clasa respectiva si doar se face o cautare ın acea tabela.

De exemplu, pentru clasa Profesor o tabela de metode ar putea arataastfel:

PROFESOR

getNume() => Persoana.getNume()

setNume() => Persoana.setNume()

getPrenume() => Persoana.getPrenume()

setPrenume() => Persoana.setPrenume()

getGradDidactic() => Profesor.getGradDidactic()

setGradDidactic() => Profesor.setGradDidactic()

toString() => Profesor.toString()

Daca se apeleaza o metoda polimorfic, atunci se parcurg urmatorii pasi:

• In primul rand masina virtuala obtine tabela cu metode corespunzatoaretipului actual al obiectului.

• Masina virtuala parcurge lista cu metode si identifica metoda core-spunzatoare.

• In final este rulata metoda.

Observatie: Atunci cand suprascriem ıntr-o clasa derivata o metoda carea fost declarata ıntr-o clasa de baza, aceasta noua metoda trebuie sa aiba unnivel de vizibilitate cel putin cat era ın clasa de baza, altfel se obtine eroare.

Page 79: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

5.4. METODE SI CLASE FINALE 75

5.4 Metode si clase finale

Atunci cand vrem ca o clasa sa nu mai poata fi derivata, putem precizaacest lucru compilatorului prin folosirea modificatorului final, ca ın exemplulurmator:

public final class Utils

{...

}

Pentru a nu mai permite suprascrierea unei metode ıntr-o clasa derivata,putem marca acea metoda ca metoda finala cu ajutorul modificatorului final.Daca programatorul ıncearca suprascrierea metodei, atunci compilatorul vagenera o eroare de compilare.

5.5 Operatia de casting

Se poate sa cream obiecte care sa fie retinute printr-o referinta la un tipde baza al lor si sa fie de un tip derivat. Urmatoarele instructiuni sunt valide:

Persoana s=new Student("Ion","Ion",true);

s.setNume("Ionescu");

//urmatoarea instructiune nu functioneaza pentru ca nu putem apela

//asupra obiectului decat metode ale clasei Persoana

//s.setBursier(false);

Si ın Java, la fel ca ın toate limbajele moderne de programare este supor-tata operatia de cast.

Putem avea nevoie de operatia de ea, de exemplu, atunci cand avem unsir de obiecte de un tip mai generic si vrem sa folosim anumite facilitati par-ticulare ale unui obiect care este de un tip mai specializat. Iata un exemplu:

for(int i=0;i<p.length;i++)

if(p[i] instanceof Profesor)

{Profesor prof=(Profesor)p[i];

prof.setGradDidactic("profesor universitar");

}

Cu ajutorul operatorului instanceof am verificat daca obiectul p[i] estede tipul Profesor, si daca este am retinut acel obiect ıntr-un obiect de tip

Page 80: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

76 CAPITOLUL 5. MOSTENIREA IN JAVA

profesor. Acest lucru a fost posibil deoarece am facut o operatie de cast.In general nu este bine sa scriem programe care sa foloseasca cast-uri, dacaacest lucru nu este neaparat necesar.

Observatie: Chiar daca un obiect p[i] este de tipul efectiv Profesor,asupra lui nu se pot apela decat metodele corespunzatoare tipului sirului. Afost nevoie de cast pentru a putea apela o metoda specifica subclasei.

5.6 Clase abstracte

Cu cat aplicatiile noastre devin mai complexe cu atat vom remarca ca sinumarul de nivele la care avem mostenire se poate mari. La un moment datvom ajunge la clase care sunt atat de generice, ıncat e si greu sa implementamanumite functionalitati pentru ele.

Cel mai bine vom ıntelege necesitatea utilizarii claselor abstracte printr-un exemplu. Sa consideram urmatoarea problema pe care dorim sa o re-zolvam:

Exemplul 2 Se citesc de la tastatura informatii despre n figuri ın plan.Fiecare figura geometrica are o culoare. Figurile geometrice sunt de 2 tipuri:cercuri si dreptunghiuri. Pentru un cerc, ın plus fata de culoare mai cunoastemsi raza lui, iar pentru un dreptunghi mai cunoastem lungimea si latimea. Sedoreste ordonarea celor n figuri geometrice crescator dupa arie si afisarea lorpe ecran.

In primul rand definim o clasa Figura care va arata astfel:

public abstract class Figura

{private String culoare;

public Figura(String culoare)

{this.culoare=culoare;

}

public String getCuloare()

{return culoare;

}

public void setCuloare(String culoare)

{this.culoare = culoare;

Page 81: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

5.6. CLASE ABSTRACTE 77

}

public abstract double aria();

public abstract double perimetru();

}

Observam ca aceasta clasa este abstracta si ca ea are doua metode ab-stracte, cele care calculeaza aria si respectiv perimetrul unei figuri geometrice.

O clasa abstracta este o clasa care nu poate fi instantiata ın mod direct.O metoda abstracta a unei clase este o metoda care are sens pentru aceaclasa dar a carei implementare nu poate fi oferita la momentul respectiv.

O clasa care are o metoda abstracta automat trebuie sa fie abstracta. Pede alta parte, putem avea clase abstracte care nu au nici o metoda abstracta.

Prima afirmatie este foarte naturala, deoarece ar fi greu de imaginat saputem crea instante ale unei clase care are niste metode neimplementate. Insituatia ın care programatorul ar apela acele metode compilatorul nu ar stiice trebuie sa faca.

In cele ce urmeaza ne definim clasele Cerc si Dreptunghi care suntderivate din clasa Figura. Ele arata astfel:

public class Cerc extends Figura

{private double raza;

public Cerc(String culoare, double raza)

{//apel constructor din clasa de baza

super(culoare);

this.raza=raza;

}

public double getRaza()

{return raza;

}

public void setRaza(double raza)

{this.raza = raza;

}

Page 82: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

78 CAPITOLUL 5. MOSTENIREA IN JAVA

public double aria()

{return Math.PI*Math.pow(raza, 2);

}

public double perimetru()

{return 2*Math.PI*raza;

}

public String toString()

{return "Cerc cu raza "+raza+" si de culoarea "+super.getCuloare();

}}

public class Dreptunghi extends Figura

{private double lungime, latime;

public Dreptunghi(String culoare, double lungime, double latime)

{super(culoare);

this.lungime = lungime;

this.latime = latime;

}

public double getLungime()

{return lungime;

}

public void setLungime(double lungime)

{this.lungime = lungime;

}

public double getLatime()

{return latime;

Page 83: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

5.6. CLASE ABSTRACTE 79

}

public void setLatime(double latime)

{this.latime = latime;

}

public double aria()

{return lungime*latime;

}

public double perimetru()

{return 2*(lungime+latime);

}

public String toString()

{return "Dreptunghi de lungime "+lungime+", latime de "+

latime+"si culoare: "+super.getCuloare();

}}

Observam ca ın exemplul de mai sus clasele prezentate implementeazametodele aria() si perimetru() care erau declarate abstracte ın clasa Figura.Daca macar una din cele doua metode nu era implementata ar fi trebuit caclasa care nu o implementa sa fie abstracta (conform regulii care zice ca oclasa care are metode abstracte este obligatoriu abstracta).

Programul care foloseste cele 3 clase reprezentate anterior este prezentatın cele ce urmeaza:

import java.util.Scanner;

public class TestFiguri

{public static void main(String[] args)

{Scanner s=new Scanner(System.in);

System.out.print("Numarul de figuri geometrice: ");

int n=Integer.parseInt(s.nextLine());

Page 84: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

80 CAPITOLUL 5. MOSTENIREA IN JAVA

Figura[] f=new Figura[n];

for(int i=0;i<n;i++)

{System.out.print("Tipul figurii? (c/d)");

if(s.nextLine().charAt(0)==’c’)

{System.out.print("Culoarea: ");

String culoare=s.nextLine();

System.out.print("Raza: ");

double raza=Integer.parseInt(s.nextLine());

f[i]=new Cerc(culoare, raza);

}else

{System.out.print("Culoarea: ");

String culoare=s.nextLine();

System.out.print("Lungime: ");

double lungime=Integer.parseInt(s.nextLine());

System.out.print("Latime: ");

double latime=Integer.parseInt(s.nextLine());

f[i]=new Dreptunghi(culoare, lungime, latime);

}}

sortare(f);

afisare(f);

}

private static void sortare(Figura[] f)

{for(int i=0;i<f.length-1;i++)

for(int j=i+1;j<f.length;j++)

if(f[i].aria()>f[j].aria())

{Figura aux=f[i];

f[i]=f[j];

f[j]=aux;

}

Page 85: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

5.6. CLASE ABSTRACTE 81

}

private static void afisare(Figura[] f)

{for(Figura fig:f)

System.out.println(fig);

}}

Putem remarca ca ın acest exemplu metoda aria() este tratata polimorfic,deoarece ın metoda main() ea este utilizata ıntr-un asa mod ıncat nu se poatespune la momentul compilarii care metoda se va apela.

Solutia acestei probleme se poate reprezenta cu ajutorul diagramei declase reprezentata ın figura 5.2.

Figura 5.2: Solutia problemei cu figuri geometrice

S-ar putea ca unii cititori sa se ıntrebe de ce este necesar ca metodelearia() si perimetru() sa fie abstracte.

Acest lucru este destul de simplu. Faptul ca ele sunt definite ın clasaFigura ımi permite sa le apelez uniform pentru toate obiectele din sirul de

Page 86: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

82 CAPITOLUL 5. MOSTENIREA IN JAVA

figuri geometrice. Totusi, nu puteam sa le definesc ın cazul clasei Figuradeoarece nu stiu cum sunt implementate. Din acest motiv, metodele au fostdeclarate ca abstracte.

5.7 Clasa Object

In Java, chiar daca acest lucru nu este vizibil ın mod direct, toate claselesunt derivate din clasa Object. Acest lucru ınseamna ca ele au deja o anumitafunctionalitate deja definita, si ca au, de asemenea, anumite metode pe carele pot suprascrie.

Metodele clasei Object sunt sintetizate ın diagrama de clase din figura5.3.

Figura 5.3: Metodele clasei Object

Faptul ca toate obiectele sunt derivate din clasa Object ınseamna caurmatorul cod este perfect valabil:

String s="test";

Object o=s;

s=(String)o;

Se poate observa ca pentru a transforma o referinta la un tip mai general,catre o referinta la un tip specializat, trebuie sa facem o operatie de cast.

Faptul ca toate clasele sunt derivate direct sau indirect din clasa Object

ne permite sa scriem clase pentru colectii care sa retina elemente de tipreferinta de orice tip. Aceasta modalitate de lucru a fost folosita foarte multınainte de aparitia lucrului cu tipuri generice ın Java.

Page 87: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

5.7. CLASA OBJECT 83

5.7.1 Metoda toString()

Metoda toString() poate fi implementata pentru o clasa pentru a puteaobtine cu ajutorul ei o reprezentare folosind un sir de caractere a unui obiect.

Aceasta reprezentare poate fi foarte usor folosita pentru realizarea operatieide logging.

In general nu este bine sa ne bazam ın interfata grafica pe metoda toString()ci mai degraba sa avem propriile noastre metode care sa realizeze afisarea.

Este deja binecunoscut ca atunci cand pentru un obiect apelam metodaprintln(), ca ın exemplul urmator, de fapt pentru afisarea obiectului se folosestemetoda toString().

Complex c=new Complex(3,4);

// automat se apeleaza metoda toString()

System.out.println(x);

5.7.2 Metoda equals()

Metoda equals() a clasei Object testeaza daca doua obiecte au aceeasistare. Cateodata nu are sens sa comparam doua obiecte, motiv pentru careaceasta metoda poate sau nu sa fie implementata. Totusi, daca avem obiectecare pot fi comparate pentru egalitate, este important sa o scriem.

Este important, de asemenea, sa scriem aceasta metoda deoarece, dacafolosim clase pentru lucrul cu colectii ın Java, aceasta metoda este folositaatunci cand se cauta un anumit element ıntr-o colectie.

De exemplu, putem scrie metoda equals() pentru clasa Complex ın felulurmator:

class Complex

{// alte atribute si metode

public boolean equals(Object otherObject)

{if (this == otherObject)

return true;

if (otherObject == null)

return false;

if (getClass() != otherObject.getClass())

return false;

Page 88: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

84 CAPITOLUL 5. MOSTENIREA IN JAVA

Complex other = (Complex) otherObject;

return re==other.re && im==other.im;

}}

Implementarea metodei equals() este destul de ”tricky” atunci cand avemde-a face cu compararea unor obiecte care fac parte din aceeasi ierarhie deobiecte. In anumite situatii, ın locul apelului metodei getClass() se preferafolosirea operatorului instanceof.

Pentru ıntelegerea mai buna a modului ın care se lucreaza cu metodaequals() este recomandata studierea ın amanunt a documentatiei Java.

5.7.3 Metoda hashCode()

Metoda hashCode() returneaza un numar ıntreg care este folosit ın situatiaın care un obiect este retinut ıntr-o tabela de dispersie. Este recomandabil ca,pe cat posibil, la valori diferite ale continutului obiectelor si valorile returnatede metoda sa fie diferite.

De cele mai multe ori, metoda returneaza o valoare bazata pe valorilecampurilor care sunt continute de clasa.

Iata si un exemplu:

class Persoana

{private String nume, prenume;

//alte atribute si metode

public int hashCode()

{return 3*nume.hashCode()+5*prenume.hashCode();

}}

Observatie: Daca doua obiecte prin folosirea metodei equals() sunt egale,atunci si metodele lor hashCode() trebuie sa returneze aceleasi valori.

5.7.4 Metoda clone()

Metoda clone() este folosita pentru a crea o copie a unui obiect. Trebuieca atunci cand realizam copia unui obiect sa creem un nou obiect care nupartajeaza absolut nimic cu vechiul obiect.

In primul rand trebuie spus ca exista situatii ın care nu vrem ca o instantaa unui obiect sa poata fi clonata. Daca suntem ın aceasta situatie nu trebuie

Page 89: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

5.8. IMPLEMENTAREA COLECTIILOR GENERICE FOLOSIND OBJECT85

sa facem nimic, pentru ca aceasta este implementarea implicita ın Java. Dacatotusı vrem sa putem

Daca obiectul initial are numai campuri de tipuri primitive atunci estesuficient sa copiem campurile din vechiul obiect ın cel nou. La fel se ıntamplasi ın cazul campurilor de tip String, deoarece aceasta clasa este immutable.

Prezentam un exemplu ın cele ce urmeaza:

class Complex implements Cloneable

{private double re, im;

public Object clone()

{return new Complex(re, im);

}}

Totusi ın unele situatii nu este bine sa facem acest lucru. Acesta ar ficazul unei stive, ın care codul ar arata mai degraba astfel:

class Stack implements Cloneable

{private int[] elements;

private int count;

public Object clone()

{Stack clonedStack=new Stack();

clonedStack.elements=elements.clone();

clonedStack.count=count;

}}

5.8 Implementarea colectiilor generice folosind

Object

Datorita faptului ca toate clasele ın Java sunt derivate din clasa Object

se poate ca sa definim colectii care sa poata fi utilizate pentru a retine obiectede orice tip.

Acest lucru se face prin retinerea elementelor care alcatuiesc colectia ınstructuri bazate pe clasa Object.

Page 90: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

86 CAPITOLUL 5. MOSTENIREA IN JAVA

In cele ce urmeaza prezentam un astfel de exemplu. Clasa Queue este ceaprezentata anterior, ın plus adaugand doar faptul ca ea poate retine obiectede orice tip.

package com.mihai.datastructures;

public class EmptyQueueException extends Exception{

}

package com.mihai.datastructures;

class Node {private Object value;

private Node next;

Node(Object value)

{this.value=value;

this.next=null; //putea lipsi

}

Node(Object value, Node next) {this.value = value;

this.next = next;

}

Object getValue() {return value;

}

void setValue(Object value) {this.value = value;

}

Node getNext()

{return next;

}

void setNext(Node next)

{

Page 91: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

5.8. IMPLEMENTAREA COLECTIILOR GENERICE FOLOSIND OBJECT87

this.next=next;

}}

package com.mihai.datastructures;

public class Queue {private Node first, last;

public boolean isEmpty()

{return first==null;

}

public void push(Object x)

{Node node=new Node(x);

if(isEmpty())

first=node;

else

last.setNext(node);

last=node;

}

public Object top() throws EmptyQueueException

{if(isEmpty())

throw new EmptyQueueException();

return first.getValue();

}

public Object pop() throws EmptyQueueException

{if(isEmpty())

throw new EmptyQueueException();

Object value=first.getValue();

first=first.getNext();

return value;

}

public String toString()

{

Page 92: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

88 CAPITOLUL 5. MOSTENIREA IN JAVA

StringBuffer sb=new StringBuffer("[");

Node current=first;

if(!isEmpty())

{while(current.getNext()!=null)

{sb.append(current.getValue()+",");

current=current.getNext();

}sb.append(current.getValue());

}sb.append("]");

return sb.toString();

}}

package com.mihai.main;

import java.util.StringTokenizer;

import com.mihai.datastructures.*;

public class TestQueue

{public static void main(String args[])

{Queue q=new Queue();

q.push("mihai");

q.push("ioana");

q.push("ana maria");

try

{System.out.println("In varful cozii: "+q.top());

String str=(String)q.pop();

System.out.println("Continutul cozii: "+q);

}catch(EmptyQueueException e)

{System.out.println("Coada goala !!!");

}

Page 93: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

5.9. UTILIZAREA COLECTIILOR GENERICE CU TEMPLATE-URI 89

}}

In exemplul anterior am vazut cum se poate implementa o colectie genericaavand la baza clasa Object.

Totusi aceasta abordare are anumite defecte, ceea ce a condus la imple-mentarea ın versiunile mai noi ale limbajului ale unor astfel de colectii cuajutorul template-urilor. Aceste defecte sunt:

• Se poate ca din greseala un anumit programator, care nu stie exact cetip au elementele dintr-o astfel de colectie sa introduca elemente de unalt tip.

• La parcurgerea apelul metodelor care obtin elemente din colectie, tre-buie facute casturi care pot sa genereze erori din cauza unor greseliprezentate anterior. In plus, acest mecanism de obtinere a elementelordintr-o colectie nu este elegant.

Practic, daca ne gandim mai bine o sa observam ca aceste colectii nuofera siguranta ın utilizare si pot produce erori care nu pot fi depistate lamomentul rularii.

Din acest motiv, s-au introdus colectiile care folosesc template-uri, caresunt prezentate pe scurt ın sectiunea urmatoare.

5.9 Utilizarea colectiilor generice cu template-

uri

Cel mai bine pentru a ıntelege cum se folosesc aceste liste, prezentam unexemplu de folosire a lor.

import java.util.*;

public class TestLista {

public static void main(String[] args) {List<String> lista=new LinkedList<String>();

lista.add("test1");

lista.add("test2");

lista.add("test3");

for(String s:lista)

Page 94: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

90 CAPITOLUL 5. MOSTENIREA IN JAVA

System.out.println(s);

System.out.println("-----------------------------");

Iterator<String> iterator=lista.iterator();

while(iterator.hasNext())

{String str=iterator.next();

System.out.println(str);

}

lista.remove("test2");

lista.add("test4");

System.out.println("-----------------------------");

for(int i=0;i<lista.size();i++)

{String str=lista.get(i);

System.out.println(str);

}

System.out.println("-----------------------------");

System.out.println("Rezultat contains: "+lista.contains("test2"));

}

}

Se poate testa faptul ca ın noua lista nu se mai pot introduce elementede alte tipuri decat cel declarat. Se poate observa, de asemenea, ca nu maieste nevoie de operatii de cast pentru a obtine un anumit obiect din colectie.

Deocamdata nu intram ın mai multe amanunte relativ la folosirea colectiilorın Java, urmand a reveni ın capitolul special dedicat colectiilor Java.

5.9.1 Boxing si unboxing ın Java

In mod normal ın colectii nu se pot retine decat obiecte. Acest lucru eravalabil la versiunile mai vechi de Java. In versiunile mai noi s-a introdusconceptul de boxing care face posibil urmatorul cod:

ArrayList<Integer> lista=new ArrayList<Integer>();

Page 95: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

5.9. UTILIZAREA COLECTIILOR GENERICE CU TEMPLATE-URI 91

lista.add(3);

lista.add(4);

for(int x:lista)

System.out.print(x+" ");

Acest cod este posibil deoarece atunci cand este apelata metoda add()parametrul transmis este automat convertit la un obiect de tip Integer (box-ing).

Exact opusul se ıntampla atunci cand realizam afisarea, ın acest cazputand afirma ca avem de-a face cu conceptul de unboxing.

Cel mai bine se poate vedea acest lucru pe urmatorul cod:

Integer intObject = 100;

//echivalent cu apelul Integer intObject = new Integer(100);

int x = intObject;

//echivalent cu apelul int x = intObject.getValue();

Observatie: La fel ca si clasa String, clasa Integer este o clasa immutable(nu ısi poate schimba niciodata valoarea).

Page 96: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

92 CAPITOLUL 5. MOSTENIREA IN JAVA

Page 97: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

CAPITOLUL 6

Tratarea exceptiilor ın Java

Unul din cele mai importante lucruri pentru orice programator care folosesteprogramarea obiect orientata este ıntelegerea mecanismului care sta la bazalucrului cu exceptii.

Evident, ar fi de dorit ca ın practica sa nu apara exceptii, dar dupa cumfiecare dintre noi a observat, acest lucru este imposibil. Astfel, este importantsa le tratam corespunzator.

Mecanismul de lucru cu exceptii ın Java seamana foarte mult cu mecan-ismul pe care deja ıl cunoastem din C/C++.

In momentul ın care apare o exceptie, cel care utilizeaza programul sauprogramatorul trebuie sa fie ınstiintat pentru a o putea trata corespunzator.Astfel, aplicatia trebuie sa fie capabila sa faca unul din urmatoarele doualucruri:

• Sa termine aplicatia ıntr-un mod civilizat (cu salvarea eventual a lu-crurilor care trebuie salvate, ınchiderea conexiunilor care se folosesc ınaplicatie)

• Sa permita utilizatorului sa se ıntoarca la o stare din care sa poatacontinua aplicatia (de exemplu, daca o citire nu reuseste, trebuie sa mise permita sa reiau acest pas sau sa tratez altfel aceasta situatie).

Teoretic, chiar daca acest lucru este mult mai complicat si mai putin ele-gant, se pot ıncerca si alte abordari ale tratarii exceptiilor decat cele folositeın limbajul Java. Astfel, se poate de exemplu, ca fiecare metoda sa returnezeun anumit cod, care sa ne spuna daca metoda a reusit sau nu.

93

Page 98: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

94 CAPITOLUL 6. TRATAREA EXCEPTIILOR IN JAVA

Totusi, pe termen lung, aceasta abordare este greu de utilizat pentruprogramator. Ea mai are un mare dezavantaj, si anume faptul ca are caefect amestecarea codului care prezinta cazul de dorit ın care totul mergebine cu codul care se ocupa de tratarea erorii.

Mai mult, unele erori ar fi greu de tratat folosind aceasta metoda.Din aceasta cauza, vom vedea ca limbajul Java acorda o mare importanta

tratarii erorilor. Astfel, avem o ıntreaga ierarhie de clase destinata acestuiscop.

6.1 Clasificarea exceptiilor

Exceptiile care pot fi ıntalnite ıntr-un program Java sunt de doua feluri:

• unchecked exceptions - sunt acele exceptii care apar la momentul rulariidar pe care programatorul nu este obligat sa le ”vaneze” (sa le tratezeın mod explicit). Exemple de astfel de exceptii sunt: ArrayIndexOut-OfBoundsException, DivisionByZeroException etc.

• checked exceptions - exceptiile pe care programatorul este obligat sa leia ın considerare (el trebuie sa fie constient de faptul ca acestea potaparea ıntr-un anumit loc). Astfel de exceptii sunt: FileNotFoundEx-ception, IOException etc.

Cele mai importante clase care sunt folosite ın Java pentru tratareaexceptiilor sunt Throwable, Exception, Error si RuntimeException. Elese afla ın relatiile prezentate ın figura 6.1.

Figura 6.1: Diagrama claselor pentru tratarea exceptiilor

Page 99: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

6.2. CREAREA CLASELOR EXCEPTIE 95

Toate exceptiile sunt derivate din clasa Throwable care se comporta pen-tru exceptii in modul ın care Object se comporta pentru toate clasele. Avemdoua tipuri derivate din Throwable si anume Error (erori care apar din cauzamasinii virtuale si care ın principiu sunt foarte greu de tratat; tot ceea cese poate face este sa ıncheiem programul ıntr-un mod elegant) si Exception(erori care apar din cauze care nu tin de implementarea masinii virtuale).

Un caz mai deosebit de erori sunt cele de tipul RuntimeException caresunt erorile unchecked de tipul Exception. Aceste erori sunt acele erori carenu tin de masina virtuala ci mai degraba de programator si care daca ar trebuitratate de fiecare data ar ıngreuna foarte mult scrierea codului. Astfel,ar figreu daca de fiecare data cand folosim un sir sau o matrice am verifica dacanu cumva se foloseste un element din afara matricii.

Totusi, ın aceste situatii se poate trata o eroare de acest tip.

Erorile de tip Exception care nu sunt de tipul RuntimeException sunterori care trebuie neaparat tratate ıntr-un fel de programator (checked er-rors).

6.2 Crearea claselor exceptie

Pentru a crea o noua exceptie ın Java, trebuie sa scriem o clasa care estederivata direct sau indirect din clasa Exception.

De exemplu, pentru a crea o exceptie de tipul checked exception putemscrie urmatorul cod:

class MatriciIncompatibileException extends Exception

{public MatriciIncompatibileException()

{}

public MatriciIncompatibileException(String message)

{super(message);

}}

Noua clasa pentru tratarea unei exceptii poate fi derivata si dintr-o altaclasa de tipul exceptie.

Daca dorim crearea unei exceptii unchecked derivam clasa exceptie dinRuntimeException sau dintr-o clasa derivata din aceasta:

Page 100: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

96 CAPITOLUL 6. TRATAREA EXCEPTIILOR IN JAVA

class StackEmptyException extends RuntimeException

{public StackEmptyException()

{}public StackEmptyException(String message)

{super(message);

}}

6.3 Aruncarea exceptiilor

Pentru a arunca o exceptie procedam ın felul urmator folosim cuvantulcheie throw dupa care trebuie sa folosim un obiect de tip exceptie:

public int pop()

{if(isEmpty())

throw new StackEmptyException();

//codul pentru eliminarea unui element din stiva

}

Observatie: Daca avem de-a face cu o exceptie de tipul ”checked excep-tion” trebuie sa specificam ca aceasta metoda arunca o astfel de exceptie:

public static Matrice adunare(Matrice m1, Matrice m2)

throws MatriciIncompatibileException

{if ((m1.noLines()!=m2.noLines()) ||

((m1.noCols()!=m2.noCols()))

throw new MatriciIncompatibileException();

//continua codul pentru aceasta metoda

}

Daca o metoda poate arunca mai multe exceptii de tipul ”checked” atunciacestea trebuie scrise toate ın sectiunea throws separate prin virgula.

6.4 Prinderea exceptiilor

Prinderea exceptiilor ın Java respecta urmatoarea sintaxa:

Page 101: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

6.4. PRINDEREA EXCEPTIILOR 97

try {instr1;

instr2;

....

}catch(Exception1 e){

//tratare exceptie 1

}catch(Exception2 e){

//tratare exceptie 2

}finally{

//aici am cod care se executa mereu

//indiferent daca a aparut exceptie sau nu

}

Daca ıntre instructiunile din blocul try nu apare nici o eroare atunci seexecuta toate aceste instructiuni dupa care se executa toate instructiuniledin blocul finally.

Daca la un moment dat apare eroare cand se executa o instructiune ınblocul try atunci executia instructiunilor din acel bloc se opreste si se executainstructiunile doar din primul catch care prinde eroarea potrivita, dupa carese executa instructiunile din blocul finally.

Dupa cum se poate observa se poate sa avem mai multe blocuri catchdar un singur bloc finally. Trebuie remarcat, de asemenea, ca blocul finallypoate lipsi.

In momentul ın care scriem cod ın care la un moment dat poate aparea oexceptie de tipul ”checked” putem sa rezolvam problema ın unul din urmatoarelemoduri:

• Daca nu stim cum sa tratam eroarea si vrem ca ea sa fie tratata ınalta parte, putem sa aruncam eroarea mai departe. Pentru acest lucrutrebuie sa specificam ca acea metoda poate arunca eroarea respectivaın clauza throws.

• Daca nu stim cum sa tratam eroarea dar vrem sa aruncam mai departeo alta eroare, putem folosi un bloc try-catch ın care pe ramura de catchcorespunzatoare exceptiei sa aruncam o alta exceptie.

• Putem trata exceptia direct ın sectiunea catch corespunzatoare.

Page 102: PROGRAMARE OBIECT ORIENTATA 2 - horatiuvlad.com · Aplicat˘ii pe mobil (se realizeaz a cu ajutorul unei distribut˘ii Java numit a J2ME - Java 2 Microedition). Accentul ^ n continuare

98 CAPITOLUL 6. TRATAREA EXCEPTIILOR IN JAVA

6.5 Indicatii referitoare la utilizarea exceptiilor

Atunci cand se lucreaza cu tratarea exceptiilor este bine sa se urmezeregulile prezentate ın continuare:

• Tratarea exceptiilor nu trebuie sa ınlocuiasca testele care verifica dacase poate efectua o operatie (motive de eficienta, ın primul rand)

• Nu trebuie sa separam codul ıntr-o serie de blocuri try-catch atuncicand este mai bine ca ele sa fie ın acelasi bloc try.

• Nu trebuie sa se foloseasca numai exceptii de tipul RuntimeException.Trebuie de fiecare data sa identificam exceptia corecta si sa derivamdin acea exceptie.

• Nu trebuie sa ınabusim tratarea unei exceptii prin prinderea ıntr-unbloc catch care trateaza direct o exceptie de tipul Exception.

• Nu toate exceptiile trebuie tratate ın blocuri catch. In unele situatiieste de dorit sa se arunce mai departe acea exceptie.

6.6 Exemple