Sunteți pe pagina 1din 41

1. Introducere in tehnologia Java 2. Obiecte si clase 3.

Exceptii

Fluxuri (Intrari / Iesiri) 4. Interfete Pachete Organizarea fisierelor .java si .class Serializarea obiectelor Colectii 5. Interfata grafica 6. Desenarea si tiparirea Swing 7. Fire de executie 8. Programarea n retea 9. Applet-uri 10. Lucrul cu baze de date pe platforma Java 11. Lucrul dinamic cu clase Java Web Start 12. Introducere in Java ME / EE

Introducere in Java

Ce este Java ? Crearea unei aplicatii simple Crearea unui applet simplu Structura lexicala a limbajului Java o Setul de caractere o Cuvinte cheie o Identificatori o Literali o Separatori o Operatori o Comentarii Tipuri de date Variabile Controlul executiei Vectori Siruri de caractere Folosirea argumentelor de la linia de comanda

Ce este Java ?
Limbajul de programare Java Java este un limbaj de programare de nivel nalt, dezvoltat de JavaSoft, companie n cadrul firmei Sun Microsystems. Dintre caracteristicile principale ale limbajului amintim:

simplitate, elimina suprancarcarea operatorilor, mostenirea multipla si toate "facilitatile" ce pot provoca scrierea unui cod confuz. robustete, elimina sursele frecvente de erori ce apar in programare prin eliminarea pointerilor, administrarea automata a memoriei si eliminarea fisurilor de memorie printr-o procedura de colectare a 'gunoiului' care ruleaza n fundal. Un program Java care a trecut de compilare are proprietatea ca la executia sa nu "crapa sistemul". complet orientat pe obiecte - elimina complet stilul de programare procedural usurinta in ceea ce priveste programarea in retea

securitate, este cel mai sigur limbaj de programare disponibil n acest moment, asigurnd mecanisme stricte de securitate a programelor concretizate prin: verificarea dinamica a codului pentru detectarea secventelor periculoase, impunerea unor reguli stricte pentru rularea programelor lansate pe calculatoare aflate la distanta, etc este neutru din punct de vedere arhitectural portabililtate, cu alte cuvinte Java este un limbaj independent de platforma de lucru, aceeasi aplicatie ruland, fara nici o modificare, pe sisteme diferite cum ar fi Windows, UNIX sau Macintosh, lucru care aduce economii substantiale firmelor care dezvolta aplicatii pentru Internet. compilat si interpretat asigura o performanta ridicata a codului de octeti permite programarea cu fire de executie (multitheaded) dinamicitate este modelat dupa C si C++, trecerea de la C, C++ la Java facndu-se foarte usor. permite creearea unor documente Web mbunatatite cu animatie si multimedia.

Java : un limbaj compilat si interpretat In functie de modul de executie al programelor, limbajele de programare se mpart n doua categorii :

interpretate : instructiunile sunt citite linie cu linie de un program numit interpretor si traduse n instructiuni masina; avantaj : simplitate; dezavantaje : viteza de executie redusa compilate : codul sursa al programelor este transformat de compilator ntr-un cod ce poate fi executat direct de procesor; avantaj : executie rapida; dezavantaj : lipsa portabilitatii, codul compilat ntr-un format de nivel scazut nu poate fi rulat dect pe platforma pe care a fost compilat.

Programele Java sunt fi att interpretate ct si compilate. Codul de octeti este diferit de codul masina. Codul masina este reprezentat de o succesiune de 0 si 1; codurile de octeti sunt seturi de instructiuni care seamana cu codul scris n limbaj de asamblare. Codul masina este executat direct de catre procesor si poate fi folosit numai pe platforma pe care a fost creat; codul de octeti este interpretat de mediul Java si de aceea poate fi rulat pe orice platforma care foloseste mediul de executie Java.
Cod sursa Java -> (compilare) -> Cod de octeti -> (interpretare)

Crearea unei aplicatii simple


1. Scriererea codului sursa
2. class FirstApp { 3. public static void main( String args[]) { 4. System.out.println("Hello world"); 5. } 6. }

Toate aplicatiile Java contin o clasa principala(primara) n care trebuie sa se gaseasca metoda main. Clasele aplicatiei se pot gasi fie ntr-un singur fisier, fie n mai multe. 7. Salvarea fisierelor sursa Se va face n fisiere cu extensia .java Fiserul care contine codul sursa al clasei primare trebuie sa aiba acelasi nume cu clasa primara a aplicatiei (clasa care contine metoda main) Obs: Java face distinctie ntre literele mari si mici.
C:/java/FirstApp.java

8. Compilarea aplicatiei Se foloseste compilatorul Java, javac Apelul compilatorului se face pentru fisierul ce contine clasa principala a aplicatiei. Compilatorul creeaza cte un fisier separat pentru fiecare clasa a programului; acestea au extensia .class si sunt plasate n acelasi director cu fisierele sursa.
javac FirstApp.java -> FirstApp.class

9. Rularea aplicatiei

Se face cu interpretorul java, apelat pentru unitatea de compilare corespunzatoare clasei principale, fiind nsa omisa extensia .class asociata acesteia.
java FirstApp

Rularea unei aplicatii care nu foloseate interfata grafica, se va face ntr-o fereastra sistem.

Crearea unui applet


Crearea structurii de fisere si compilarea applet-urilor sunt identice ca n cazul aplicatiilor. Difera n schimb structura programului si modul de rulare al acestuia. 1. Scrierea codului sursa si salvarea n fisier
2. import java.awt.* ; 3. import java.applet.* ; 4. public class FirstApplet extends Applet { 5. Image img; 6. public void init() { 7. img = getImage(getCodeBase(), "taz.gif"); 8. } 9. public void paint (Graphics g) { 10. g.drawImage(img, 0, 0, this); 11. g.drawOval(100,0,150,50); 12. g.drawString("Hello! My name is Taz!", 110, 25); 13. } 14. }

Salvarea se va face n fisierul FirstApplet.java 15.Compilarea applet-ului


javac FirstApplet.java -> FirstApplet.class

16.Rularea applet-ului Applet-urile nu ruleaza independent. Ele pot fi rulate doar prin intermediul unui browser : Internet Explorer, Netscape sau printr-un program special cum ar fi appletviewer-ul din setul JDK. 1. Creearea unui fisier HTML pentru miniaplicatie (exemplu.html)
2. 3. 4. 5. 6. 7. 8. 9. 10. <html> <head> </head> <body> height=400> </body> </html> <title>First Java Applet</title> <applet code=FirstApplet.class width=400 </applet>

11.Vizualizarea appletului
appletviewer exemplu.html

Structura lexicala a limbajului


Setul de caractere Limbajului Java lucreaza n mod nativ folosind setul de caractere Unicode. Acesta este un standard international care nlocuieste vechiul set de caractere ASCII si care foloseste pentru reprezentarea caracterelor 2 octeti, ceea ce nseamna ca se pot reprezenta 65536 de semne, spre deosebire de ASCII, unde era posibila reprezentarea a 256 de caractere. Primele 256 caractere Unicode corespund celor din ASCII, referirea la celelate facndu-se prin \uxxxx, unde xxxx reprezinta codul caracterului. Ex:
\u0030 - \u0039 : cifre ISO-Latin 0 - 9

\u0660 - \u0669 : cifre arabic-indic 0 - 9 \u4e00 - \u9fff : litere din alfabetul Han (Chinez, Japonez, Coreean)

Cuvinte cheie Cuvintele rezervate n Java sunt cele din C++, cu cteva exceptii Identificatorii Sunt secvente nelimitate de litere si cifre Unicode, ncepand cu o litera. Identificatorii nu au voie sa fie identici cu cuvintele rezervate. Literalii (constantele) Literalii pot fi de urmatoarele tipuri

literali ntregi Sunt acceptate 3 baze de numeratie : baza 10, baza 16 (ncep cu caracterele 0x) si baza 8 (ncep cu cifra 0) si pot fi de doua tipuri: o normali, (se reprez pe 4 octeti - 32 biti) o lungi (8 octeti - 64 biti) : se termina cu caracterul L (sau l). literali flotanti Pentru ca un literal sa fie considerat flotant el trebuie sa aiba cel putin o zecimala dupa virgula, sa fie n notatie exponentiala sau sa aiba sufixul F sau f pentru valorile normale (reprez. pe 32 biti), respectiv D sau d pentru valorile duble (reprez. pe 64 biti) literali logici true : valoarea booleana de adevar false : valoarea booleana de fals Atentie: spre deosebire de C++, literalii ntregi 1 si 0 nu mai au rolul de adevarat si false literali caracter Un literal de tip caracter este utilizat pentru a exprima caracterele codului Unicode. Reprezentarea se face fie folosind o litera, fie o secventa escape scrisa ntre apostrofuri. Secventele escape permit reprezentarea caracterelor care nu au reprezentare grafica si reprezentarea unor caractere speciale precum backslash, caracterul apostrof, etc. Secvente escape predefinite n Java:
Cod Secventa Escape Caracter \u0008 '\b' Backspace(BS) \u0009 '\t' Tab orizontal (HT)

\u000a \u000c \u000d \u0022 \u0027 \u005c

'\n' '\f' '\r' '\"' '\'' '\\'

Linie noua - linefeed (LF) Pagina noua - formfeed (FF) Inceput de rand (CR) Ghilimele Apostrof Backslash

literali siruri de caractere Un literal sir de caractere este format din zero sau mai multe caractere ntre ghilimele. Caracterele care formeaza sirul de caractere pot fi caractere grafice sau secvente escape ca cele definite la literalii caracter. Daca sirul este prea lung el poate fi scris ca o concatenare de subsiruri de dimensiune mai mica. Concatenarea sirurilor se face cu operatorul + ("Ana " + " are " + " mere "). Sirul vid este "". Dupa cum vom vedea, orice sir este de fapt o instanta a clasei String, definita n pachetul java.lang.

Separatori Un separator este un caracter care indica sfrsitul unei unitati lexicale si nceputul alteia. In Java separatorii sunt urmatorii: ( ) { } [ ] ; , . Instructiunile unui program se separa cu punct si virgula Operatori

atribuirea: = operatori matematici: +, -, *, /, % Este permisa notatia prescurtata de forma lval op= rval (ex: n += 2) Exista operatorii pentru autoincrementare si autodecrementare (post si pre)
ex: x++, ++x, n--, --n

Observatie: evaluarea expresiilor logice se face prin metoda scurtcircuitului (evaluarea se opreste n momentul n care valoarea de adevar a expresiei este sigur determinata) operatori logici: &&(and), ||(or), !(not) operatori relationali: <, <=, >, <=, ==, != operatori pe biti: & (and), |(or), ^(xor), ~(not) operatori de translatie <<, >>, >>> (shift la dreapta fara semn) operatorul if-else: expresie_logica ? val_pt_true : val_pt_false operatorul , (virgula) folosit pentru evaluarea secventiala a operatiilor int x=0, y=1, z=2; operatorul + pentru concatenarea sirurilor:
String s="abcd"

int x=100; System.out.println(s + " - " + x);

operatori pentru conversii (cast) : (tip_de_data)


int i = 200; long l = (long)i; //widening conversion - conversie prin extensie long l2 = (long)200; int i2 = (int)l2; //narrowing conversion - conversie prin contractie

Comentarii In Java exista trei feluri de comentarii:


Comentarii pe mai multe linii, nchise ntre /* si */. Comentarii pe mai multe linii care tin de documentatie, nchise ntre /** si */. Textul dintre cele dou secvente este automat mutat n documentatia aplicatiei de catre generatorul automat de documentatiejavadoc. comentarii pe o singura linie care ncep cu //.

Observatii: 1. nu putem sa scriem comentarii n interiorul altor comentarii. 2. nu putem introduce comentarii n interiorul literalilor caracter sau sir de caractere. 3. secventele /* si */ pot sa apara pe o linie dupa secventa // dar si pierd semnificatia; la fel se ntmpl cu secventa // n comentarii care ncep cu /* sau /**.

Tipuri de date
In Java tipurile de date se mpart n doua categorii: tipuri primitive de date si tipuri referinta. Java porneste de la premiza ca "orice este un obiect". Asadar tipurile de date ar trebui sa fie de fapt definite de clase si toate variabilele ar trebui sa memoreze de fapt instante ale acestor clase (obiecte). In principiu acest lucru este adevarat, nsa, pentru usurinta programarii, mai exista si asa numitele tipurile primitivede date, care sunt cele uzuale :

aritmetice o ntregi: byte

(1 octet), short (2), int (4), long (8)

reale: float (4 octeti), double caracter : char (2 octeti) logic : boolean (true si false)
o

(8)

In alte limbaje formatul si dimensiunea tipurilor primitive de date folosite ntrun program pot depinde de platforma pe care ruleaza programul. In Java acest lucru nu mai este valabil, orice dependenta de o anumita platforma specifica fiind eliminata. Vectorii, clasele si interfetele sunt tipuri referinta. Valoarea unei variabile de acest tip este, n contrast cu tipurile primitive, o referinta (adresa de memorie) catre valoarea sau multimea de valori reprezentata de variabila respectiva. Exista trei tipuri de date C care nu sunt suportate de limbajul Java. Acestea sunt: pointer, struct si union. Pointerii au fost eliminati din cauza ca erau o sursa constanta de erori, locul lor fiind luat de tipul referinta, iar struct si union nu si mai au rostul att timp ct tipurile compuse de date sunt formate n Java prin intermediul claselor.

Variabile
Variabilele pot avea ca tip fie un tip primitiv de data, fie o referinta la un obiect.
Declararea variabilelor Tip nume_variabila Initializarea variabilelor Tip nume_variabila = valoare Declararea constantelor final Tip nume_variabila

Conventia de notare a variabilelor in Java este data de urmatoarele criterii: 1. variabilele finale (constante) se scriu cu majuscule 2. variabilele normale se scriu astfel : prima litera cu litera mica, daca numele variabilei este format din mai multi atomi lexicali, atunci primele litere ale celorlalti atomi se scriu cu majuscule, de exemplu:
3. 4. 5. 6. final double PI = 3.14; int valoare = 100; long numarElemente = 12345678L; String bauturaMeaPreferata = "apa";

In functie de locul n care sunt declarate variabile se mpart n urmatoatele categorii:

1. Variabile membre, declarate n interiorul unei clase, vizibile pentru

toate metodele clasei respective si pentru alte clase n functie de nivelul lor de acces (vezi "Declararea variabilelor membre") 2. Variabile locale, declarate ntr-o metoda sau ntr-un bloc de cod, vizibile doar n metoda/blocul respectiv 3. Parametri metodelor, vizibili doar n metoda respectiva 4. Parametrii de la tratarea exceptiilor

Obs: variabilele declarate ntr-un for pentru controlul ciclului, ramn locale corpului ciclului.
for(int i=0; i<100; i++) { } int i; //ok n Java, eroare n C++

Obs: Spre deosebire de C++ nu este permisa ascunderea unei variabile :


int x=12; { int x=96; //ilegal }

Controlul executiei

Instructiunile Java pentru controlul executiei sunt asemanatoare celor din C.


Instructiuni de decizie Instructiuni de salt Instructiuni pt. tratarea exceptiilor Alte instructiuni Instructiuni de decizie
if-else if-else, switch-case for, while, do-while try-catch-finally, throw break, continue, label: , return

if (exp_booleana) { /*...*/} if (exp_booleana) { /*...*/} else { /*...*/} switch (variabila) { case val1 : /* ... */ break; case val2 : /* ... */ break; /*...*/ default : /*...*/ }

switch-case

Instructiuni de salt
for(initializare; exp_booleana; pas_iteratie) Ex: for(int i=0, j=100 ; i<100 && j>0; i++, j--) {/* ... /*}

for

Obs: att la initializare ct si n pasul de iteratie pot fi mai multe instructiuni despartite prin virgula.
while while (exp_booleana) { /*...*/ } do { /*...*/ } while (exp_booleana) ;

do-while

Instructiuni pentru tratarea exceptiilor


try-catchfinally, throw

(vezi "Tratarea exceptiilor") paraseste fortat corpul iteratiei curente termina fortat iteratia curenta
return [valoare];

Alte instructiuni
break continue return label:

Termina o metoda Defineste o eticheta

Atentie: In Java nu exista goto. Se pot nsa defini etichete de forma nume_eticheta:, folosite n expresii de genul: break nume_eticheata sau continue nume_eticheta
Exemplu: i=0; eticheta: while (i<10) {

System.out.println("i="+i); j=0; while (j<10) { j++; if (j==5) continue eticheta; if (j==7) break eticheta; System.out.println("j="+j); } i++;

Vectori
Crearea unui vector 1. Declararea vectorului
2. Tip[] numeVector; sau 3. Tip numeVector[]; 4. Ex: int[] intregi; 5. String adrese[];

6. Instantierea

Se realizeaza prin intermediul operatorului new si are ca efect alocarea memoriei pentru vector, mai precis specificarea numarului maxim de elemente pe care l va avea vectorul;
7. numeVector = new Tip[dimensiune]; 8. Ex: v = new int[10]; //se aloca spatiu pentru 10 intregi 9. adrese = new String[100];

Obs: declararea si instantierea unui vector pot fi facute simultan astfel:


Tip[] numeVector = new Tip[dimensiune];

10. Initializarea (optional)

Dupa declararea unui vector, acesta poate fi initializat, adica elementele sale pot primi niste valori initiale, evident daca este cazul pentru asa ceva. In acest caz instantierea lipseste, alocarea memoriei facndu-se automat n functie de numarul de elemente cu care se initializeaza vectorul.
11. Ex: 12. String culori[] = {"Rosu", "Galben", "Verde"}; int []factorial = {1, 1, 2, 6, 24, 120};

Observatii: Primul indice al unui vector este 0, deci pozitiile unui vector cu n elemente vor fi cuprinse ntre 0 si n-1

Nu sunt permise constructii de genul Tip numeVector[dimensiune], alocarea memoriei facndu-se doar prin intermediul opearatorului new.
Ex: int v[10]; //ilegal int v[] = new int[10]; //corect

Vectori multidimensionali In Java tablourile multidimensionale sunt de fapt vectori de vectori.


Ex: int m[][]; m = new int[5][10]; m[1], ..., m[5] //declararea unei matrici //cu 5 linii, 10 coloane

Obs: m[0],

sunt vectori de intregi cu 10 elemente

Dimensiunea unui vector Cu ajutorul cuvntului cheie length se poate afla dimensiunea unui vector.
int []a = new int[5]; a.length are valoarea 5 int m = new int[5][10]; m[0].length are valoarea 10

Copierea vectorilor Copierea unui vector n alt vector se face cu ajutorul metodei System.arraycopy:
int x[] = {1, 2, 3, 4}; int y[] = new int[4]; System.arraycopy(x,0,y,0,x.length);

Vectori cu dimensiune variabila Implementarea vectorilor cu numar variabil de elemente este oferita de clasa Vector din pachetul java.util. Un obiect de tip Vector contine numai elemente de tip Object.

Siruri de caractere
In Java, un sir de caractere poate fi reprezentat printr-un vector format din elemente de tip char, un obiect de tip String sau un obiect de tip StringBuffer. Declararea unui sir Daca un sir de caractere este constant atunci el va fi declarat de tipul String, altfel va fi declarat cu StringBuffer. (vezi "Clasele String, StringBuffer") Exemple echivalente de declarare a unui sir:
String str = "abc";

char data[] = {'a', 'b', 'c'}; String str = new String(data); String str = new String("abc");

Concatenarea sirurilor Concatenarea sirurilor de caractere se face prin intermediul operatorului +.


String str1 = "abc" + "xyz"; String str2 = "123"; String str3 = str1 + str2;

In Java, operatorul de concatenare + este extrem de flexibil n sensul ca permite concatenarea sirurilor cu obiecte de orice tip care au o reprezentare de tip sir de caractere.
System.out.print("Vectorul v are" + v.length + " elemente")

Folosirea argumentelor de la linia de comanda


O aplicatie Java poate primi oricte argumente de la linia de comanda n momentul lansarii ei. Aceste argumente sunt utile pentru a permite utilizatorului sa specifice diverse optiuni legate de functionarea aplicatiei sau sa furnizeze anumite date initiale programului. Atentie: Programele care folosesc argumente de la linia de comanda nu sunt 100% pure Java deoarece unele sisteme de operare cum ar fi Mac OS nu au n mod normal linie de comanda. Argumentele de la linia de comanda sunt introduse la lansarea unei aplicatii, fiind specificate dupa numele aplicatiei si separate prin spatiu. De exemplu, sa presupunem ca aplicatia Sort ordoneaza lexicografic liniile unui fisier si primeste ca argument numele fisierului pe care sa l sorteze. Pentru a ordona fisierul "persoane.txt" lansarea aplicatiei se va face astfel:
java Sort persoane.txt

Asadar, formatul general pentru lansarea unei aplicatii care primeste argumente de la linia de comanda este:
java NumeAplicatie [arg1 arg2 . . . argn]

In cazul n care sunt mai multe, argumentele trebuie separate prin spatii iar daca unul dintre argumente contine spatii, atunci el trebuie pus ntre ghilimele. Evident, o aplicatie poate sa nu primeasca nici un argument sau poate sa ignore argumentele primite de la linia de comanda. In momentul lansarii unei aplicatii interpretorul parcurge linia de comanda cu care a fost lansata aplicatia si, n cazul n care exista, transmite aplicatiei argumentele specificate sub forma unui vector de siruri. Acesta este primit de

aplicatie ca parametru al metodei main. Reamintim ca formatul metodei main din clasa principala este:
public static void main ( String args[])

Vectorul primit ca parametru de metoda main va contine toate argumentele transmise programului de la linia de comanda. In cazul apelului java Sort persoane.txt vectorul args va contine un singur element args[0]="persoane.txt". Numarul argumentelor primite de un program este dat deci de dimensiunea vectorului args si acesta poate fi aflat prin intermediul atributului length al vectorilor:
numarArgumente = args.length ;

Spre deosebire ce C/C++ vectorul primit de metoda main nu contine pe prima pozitie numele aplicatiei, ntruct n Java numele aplicatiei este numele clasei principale, adica a clasei n care se gaseste metoda main. Exemplu: afisarea argumentelor primite la linia de comanda
public class Echo { public static void main (String[] args) { for (int i = 0; i < args.length; i++) System.out.println(args[i]); } }

Un apel de genul java


Drink Hot Java

Echo Drink Hot Java va

produce urmatorul rezultat:

(aplicatia Echo a primit 3 argumente). Una apel de genul java Echo "Drink Hot
Drink Hot Java

Java"

va produce urmatorul rezultat:

(aplicatia Echo a primit un singur argument). Argumente numerice la linia de comanda Argumentele de la linia de comanda sunt primite sub forma unui vector de siruri (obiecte de tip String). In cazul n care unele dintre acestea reprezinta valori numerice ele vor trebui convertite din siruri n numere. Acest lucru se realizeaza cu metode de tipul parseXXX aflate n clasa corespunzatoare tipului n care vrem sa facem conversia: Integer, Float, Double, etc. Sa consideram, de exemplu, ca aplicatia Power ridica un numar real la o putere ntreaga, argumentele fiind trimise de la linia de comanda:
java Power "12.1" "3" //ridica 12.1 la puterea 3

Conversia celor doua argumente n numere se va face astfel:


double numar; int putere; numar = Double.parseDouble(args[0]); putere = Integer.parseInt(args[1]);

Metodele de tipul parseXXX pot produce exceptii (erori) de tipul NumberFormatException n cazul n care sirul primit ca parametru nu reprezinta un numar de tipul respectiv.

Obiecte si clase in Java

Ciclul de viata al unui obiect o Crearea obiectelor o Folosirea obiectelor o Distrugerea obiectelor Crearea claselor o Declararea claselor o Corpul unei clase o Constructorii unei clase o Declararea variabilelor membre o Implementarea metodelor o Specificatori de acces pentru membrii unei clase o Membri de instanta si membri de clasa Clase imbricate Clase si metode abstracte Clasa Object

Ciclul de viata al unui obiect


Crearea obiectelor In Java obiectele sunt create prin instantierea unei clase, cu alte cuvinte prin crearea unei instante a unei clase.Crearea unui obiect presupune trei lucruri: 1. Declararea obiectului
2. 3. NumeClasa numeObiect; Ex: Rectangle patrat;

4. Instantierea

5.

Se realizeaza prin intermediul operatorului new si are ca efect crearea efectiva a obiectului cu alocarea spatiului de memorie corespunzator.
patrat = new Rectangle();

6. Initializarea

Se realizeaza prin intermediul constructorilor clasei respective. Rectangle() este un apel catre constructorul clasei Rectangle care este responsabil cu initializarea obiectului. Initializarea se poate face si cu anumiti parametri, cu conditia sa existe un constructor al clasei respective care sa accepte parametrii respectivi;
7. patrat = new Rectangle(0, 0, 100, 200);

Fiecare clasa are un set de constructori care se ocupa cu initializare obiectelor nou create. De exemplu clasa Rectangle are urmatorii constructori:
public public public public Rectangle(Point p) Rectangle(int w, int h) Rectangle(Point p, int w, int h) Rectangle()

(vezi "Constructorii unei clase") Declararea, instantierea si initializarea obiectului pot aparea pe aceesi linie (cazul cel mai uzual):
Rectangle patrat = new Rectangle(0, 0, 100, 200);

Este posibila si crearea unor obiecte anonime care servesc doar pentru initializarea altor obiecte, caz n care etapa de declarare a obiectului nu mai este prezenta:
patrat.origin = new Point(0, 0); //se creeaza un obiect anonim de tip Point care, //dupa executarea atribuirii este automat distrus de catre

sistem

Atentie Spatiul de memorie nu este pre-alocat Declararea unui obiect nu implica alocarea de spatiu de memorie pentru acel obiect.
Rectangle patrat; patrat.x = 10; //EROARE!

Alocarea memoriei se face doar la apelul instructiunii new ! Folosirea obiectelor

Odata un obiect creat, el poate fi folosit n urmatoarele sensuri: aflarea unor informatii despre obiect, schimbarea starii sale sau executarea unor actiuni. Aceste lucruri se realizeaza prin:

aflarea sau schimbarea valorilor variabilelor sale apelarea metodelor sale.

Referirea valorii unei variabile se face prin obiect.variabila De exemplu clasa Rectangle are variabilele publice x, y, width, height, origin. Aflarea valorilor acestor variabile sau schimbarea lor se face prin constructii de genul:
Rectangle patrat = new Rectangle(0, 0, 100, 200); System.out.println(patrat.width); //afiseaza 100 patrat.x = 10; patrat.y = 20; //schimba originea patrat.origin = new Point(10, 20); //schimba originea

Obs: Accesul la variabilele unui obiect se face n conformitate cu drepturile de acces pe care le ofera variabilele respective celorlalte clase. (vezi "Specificatori de acces pentru membrii unei clase") Apelul unei metode se face prin obiect.metoda([parametri])
Rectangle patrat = new Rectangle(0, 0, 100, 200); patrat.setLocation(10, 20); //schimba originea patrat.setSize(200, 300); //schimba dimensiunea

Se observa ca valorile variabilelor pot fi modificate indirect prin intermediul metodelor. Programarea orientata obiect descurajeaza folosirea directa a variabilelor unui obiect deoarece acesta poate fi adus n stari inconsistente (ireale). In schimb, pentru fiecare variabila a obiectului trebui sa existe metode care sa permita aflarea/schimbarea valorilor variabilelor sale.
patrat.width = -100; //stare inconsistenta patrat.setSize(-100, -200) //metoda setSize poate sa testeze daca valorile sunt corecte si //valideze sau nu schimbarea lor

sa

Distrugerea obiectelor Multe limbaje de programare impun ca programatorul sa tina evidenta obiectelor create si sa le distruga n mod explicit atunci cnd nu mai este nevoie de ele, cu alte cuvinte sa administreze singur memoria ocupata de obiectele sale. Practica a demonstart ca aceasta tehnica este una din principala furnizoare de erori ce duc la functionarea defectuoasa a programelor. In Java programatorul nu mai are responsabilitatea distrugerii obiectelor sale ntruct, n momentul rularii unui program, simultan cu interpretorul Java

ruleaza si un proces care se ocupa cu distrugerea obiectelor care nu mai sunt folosite. Acest proces pus la dispozitie de platforma Java de lucru se numeste garbage collector (colector de gunoi), prescurtat gc. Un obiect este elimnat din memorie de procesul de colectare atunci cnd nu mai exista nici o referinta la acesta. Referintele (care sun de fapt variabile) sunt distruse n mod :

natural, atunci cnd variabila respectiva iese din domeniul sau, de exemplu la terminarea unei metode explicit, daca atribuim variabilei respective valoare null.

Cum functioneaza colectorul de gunoaie ? GC este un proces de prioritate scazuta care se executa periodic si care scaneaza dinamic memoria ocupata de programul Java aflat n executie si marcheaza acele obiecte care au referinte directe sau indirecte. Dupa ce toate obiectele au fost parcurse cele care au ramas nemarcate sunt eliminate din memorie. Procesul gc poate fi fortat sa se execute prin metoda gc a clasei System. Finalizare Inainte ca un obiect sa fie eliminat din memorie, procesul gc da acelui obiect posibilitatea "sa curete dupa el", apelnd metoda de finalizare a obiectului respectiv. Uzual, n timpul finalizarii un obiect si nchide fisierele si socketurile folosite, distruge referintele catre alte obiecte (pentru a usura sarcina colectorului de gunoaie), etc. Codul pentru finalizare unui obiect trebuie scris ntr-o metoda speciala numitafinalize a clasei ce descrie obiectul respectiv. De exemplu, clasa Rectangle are urmatorul cod pentru finalizarea obiectelor sale:
class Rectangle { ... protected void finalize() throws Throwable { origin = null; super.finalize(); } }

Crearea claselor
Declararea claselor
Declararea unei clase

[public][abstract][final] class NumeClasa [extends NumeSuperclasa] [implements Interfata1 [, Interfata2 ... ]] { //corpul clasei }

Asadar, prima parte a declaratie o ocupa modificatorii clasei. Acestia sunt:


Modificatorii unei clase Implicit, o clasa poate fi folosita doar de clasele aflate n acelasi pachet cu clasa respectiva (daca nu se specifica un anume pachet, toate clasele din directorul public curent sunt considerate a fi n acelasi pachet). O class declarata cu public poate fi folosita de orice clasa, indiferent de pachetul n care se gaseste. Declara o clasa abstracta (sablon). O clasa abstracta nu poate fi instantiata, fiind abstract folosita doar pentru a crea un model comun pentru o serie de subclase; (vezi "Clase si metode abstracte") Declara ca respectiva clasa nu poate avea subclase. Declarare claselor finale are doua scopuri:
final

securitate : unele metode pot astepta ca parametru un obiect al unei anumite clase si nu al unei subclasei, dar tipul exact al unui obiect nu poate fi aflat cu exactitate dect n momentul executiei; n felul acesta nu s-ar mai putea realiza obiectivul limbajului Java ca un program care a trecut compilarea nu mai este susceptibil de nici o eroare (nu "crapa sistemul"). programare n spririt orientat-obiect : "O clasa perfecta nu trebuie sa mai aiba subclase"

Dupa numele clasei putem specifica, daca este cazul, faptul ca respectiva clasa este subclasa a unei alte clase cu numele NumeSuperclasa sau/si ca implementeaza una sau mai multe interfete, ale caror nume trebuie separate prin virgula. Se observa ca, spre deosebire de C++, Java permite doar mostenirea simpla, asadar o clasa poate avea un singur un singur parinte (superclasa). Evident o clasa poate avea oricti mostenitori (subclase). Extinderea unei clase se realizeaza deci astfel:
class B extends A {...} //A este superclasa clasei B

Corpul unei clase

Urmeaza declararea clasei si este cuprins ntre acolade. Contine:


declararea variabilelor de instanta si de clasa (cunoscute mpreuna ca variabile membre) declararea si implementarea metodelor de instanta si de clasa (cunoscute mpreuna ca metode membre)

Spre deosebire de C++, nu este permisa doar declararea metodei n corpul clasei, urmnd ca implementare sa fie facuta n afara ei. Implementarea metodelor unei clase trebuie sa se faca "inline" in corpul clasei.
In C++ In Java
class A { void metoda1(); int metoda2() { class A { //implementare void metoda(){ } //implementare } } A::metoda1() { } //implementare }

Obs: variabilele unei clase pot avea acelasi nume cu metodele clasei. Constructorii unei clase Constructorii unei clase sunt metode speciale care au acelasi nume cu cel al clasei, nu returneaza nici o valoare si sunt folositi pentru initializarea obiectelor acelei clase n momentul instantierii lor.
class Dreptunghi { Dreptunghi() { //constructor } }

O clasa poate avea unul sau mai multi constructori care trebuie nsa sa difere prin lista de argumente primite. In felul acesta sunt permise diverse tipuri de initializari ale obiectului la crearea sa, n functie de numarul parametrilor cu care este apelat constructorul.
class Dreptunghi { double x, y, w, h; Dreptunghi(double x0, double y0, double wo, double h0) { x=x0; y=y0; w=w0; h=h0; } Dreptunghi(double x0, double y0) { this(x0, y0, 0, 0); } Dreptunghi() { //initializare implicita

} }

this(0, 0, 100, 100);

Constructorii sunt apelati automat la instantierea unui obiect. In cazul n care dorim sa apelam explicit constructorul unei clase folosim metoda this( argumente ), care apeleaza constructorul corespunzator (ca argumente) al clasei respective. Aceasta metoda este folosita atunci cnd sunt implementati mai multi constructori pentru o clasa pentru a nu repeta secventele de cod scrise la constructorii cu mai putine argumente. Dintr-o subclasa putem apela si constructorii superclasei cu metoda super( argumente ).
class Patrat extends Dreptunghi { double size; Patrat(double x0, double y0, double s0) { super(x0, y0, s0, s0); //se apeleaza constructorul superclasei size = s0; } }

Constructorii sunt apelati automat la instantierea unui obiect. In cazul n care scrieti o clasa care nu are declarat nici un constructor, sistemul i creeaza automat un constructor implicit care nu primeste nici un argument si care nu face nimic. Deci prezenta constructorilor n corpul unei clase nu este obligatorie. Daca nsa ati scris un constructor pentru o clasa care are mai mult de un argument, atunci constructorul implicit (fara nici un argument) nu va mai fi furnizat implicit de catre sistem.
class Dreptunghi { //nici un constructor } ... Dreptunghi d; d=new Dreptunghi(); -> OK (a fost generat constructorul implicit) class Dreptunghi { double x, y, w, h; Dreptunghi(double x0, double y0, double wo, double h0) { x=x0; y=y0; w=w0; h=h0; } } ... Dreptunghi d; d=new Dreptunghi(); -> Eroare la compilare

Constructorii unei clase pot avea urmatorii specificatori de acces:


private

Specificatorii de acces ai constructorilor Nici o alta clasa nu poate instantia obiecte ale acestei clase. O astfel de clasa poate contine metode publice (numite "factory methods") care sa-si creeze propriile obiecte si sa le returneze altor clase, controlnd n felul acesta diversi

parametri legati de creare obiectelor sale. Doar subclasele pot crea obiecte de tipul clasei respective. public Orice clasa poate crea instante ale clasei respective implicit Doar clasele din acelasi pachet pot crea instante ale clasei respective
protected

Declararea variabilelor membre Variabilele se delara de obicei naintea metodelor, desi acest lucru nu este impus de compilator.
class NumeClasa { //declararea variabilelor //declararea metodelor }

Variabilele unei clase se declara n corpul clasei dar nu n corpul unei metode. Variabilele declarate n cadrul unei metode sunt locale metodei respective. Declararea unei variabile presupune specificarea urmatoarelor lucruri:

numele variabilei tipul de date nivelul de acces la acea variabila de catre alte clase daca este constanta sau nu daca este variabila de instanta sau de clasa
Declararea variabilelor membre
[modificatori] TipDeDate numeVariabila [ = valoareInitiala ] ;

Generic, o variabila se declara astfel: unde un modificator poate fi :


Ex:

un specificator de acces : public, protected, private (vezi "Specificatori de acces pentru membrii unei clase") unul din cuvintele rezervate: static, final, transient,
double x; protected static int n; public String s = "abcd"; private Point p = new Point(10, 10); final long MAX = 100000L;

volatile

static

Prezenta lui declara ca o variabila este variabila de clasa si nu de instanta: Declararea int x ; //variabila de instanta static int nrDeObiecteCreate; //variabila de clasa variabilelor de (vezi "Membri de instanta si membri de clasa") clasa

Indica faptul ca valoarea variabilei nu mai poate fi schimbata, cu alte cuvinte este folosit pentru declararea constantelor.
final double PI = 3.14 ; ... PI = 3.141 -> eroare la compilare

final

Declararea constantelor

Prin conventie numele variabilelor finale se scriu cu litere mari. Folosirea lui final aduce o flexibilitate sporita n lucrul cu constante, n sensul ca valoarea unei variabile nu trebuie specificata neaparat la declararea ei (ca n exemplul de mai sus), ci poate fi specificata si ulterior, dupa care ea nu va mai putea fi modificata.
class Test { final int MAX; Test() { MAX = 100; MAX = 200; compilare } }

// legal // ilegal -> eroare la

transient

volatile

Este folosit la serializarea obiectelor, pentru a specifica ce variabile membre ale unui obiect nu participa la serializare (vezi "Serializarea obiectelor") Este folosit pentru a semnala compilatorului sa nu execute anumite optimizari asupra membrilor unei clase. Este o facilitate avansata a limbajului Java.

Implementarea metodelor Metodele sunt responsabile cu descrierea comportamentului unui obiect. Generic, o metoda se declara astfel:
Declararea metodelor membre
[modificatori] TipReturnat numeMetoda ( [argumente] ) [throws TipExceptie] { //corpul metodei }

unde un modificator poate fi :


un specificator de acces : public, protected, private (vezi "Specificatori de acces pentru membrii unei clase") unul din cuvintele rezervate: static, abstract, final, native,
synchronized

static

Declararea

Prezenta lui declara ca o metoda este metoda de clasa si nu de instanta:


void metoda1() ; //metoda de instanta

metodelor de clasa (vezi "Membri de instanta si membri de clasa")


abstract

static void metoda2(); //metoda de clasa

Declararea metodelor abstracte


final

O metoda abstracta este o metoda care nu are implementare si trebuie sa faca parte dintr-o clasa abstracta.(vezi "Clase si metode abstracte") Specifica faptul ca acea metoda nu mai poate fi supradefinita n subclasele clasei n care ea este definita ca fiind finala. (vezi "Metode finale") In cazul n care aveti o librarie nsemnata de functii scrise n alt limaj de programare dect Java (C de exemplu), acestea pot fi refolosite din programele Java. Este folosit n cazul n care se lucreaza cu mai multe fire de executie iar metoda respectiva se ocupa cu partajarea unei resurse comune. Are ca efect construirea unui semafor care nu permite executarea metodei la un moment dat dect unui singur fir de executie. (vezi "Fire de executie")

native

synchronized

Tipul returnat de o metoda Metodele pot sau nu sa returneze o valoare (un obiect) la terminarea lor. Tipul returnat poate fi att un tip primitiv de date (int, double, etc.) sau o referinta la un obiect al unei clase. In cazul n care o metoda nu returneaza nimic atunci la rubrica TipReturnat trebuie obligatoriu sa apara cuvntul cheie void. (Ex: void
afisareRezultat() )

Daca o metoda trebuie sa returneze o valoare acest lucru se realizeaza prin intermediul instructiunii return, care trebuie sa apara n toate situatiile de terminare a functiei.
double radical(double x) { if (radical >= 0) return Math.sqrt(x); else System.out.println("Eroare - numar negativ!"); //Eroare la compilare - lipseste return pe aceasta ramura }

In cazul n care n declaratia functiei tipul returnat este un tip primitiv de date, valoarea returnata la terminarea functiei trebuie sa aiba obligatoriu acel tip, altfel va fi furnizata o eroare la compilare. Daca valoarea returnata este o referinta la un obiect al unei clase, atunci clasa obiectului returnat rebuie sa coincida sau sa fie o subclasa a clasei specificate la declararea metodei. De exemplu, fie clasaPoligon si subclasa acesteia Patrat.
Poligon metoda1( ) { Poligon p = new Poligon(); Patrat t = new Patrat(); if (...) return p; // legal else return t; // legal

} Patrat metoda2( ) { Poligon p = new Poligon(); Patrat t = new Patrat(); if (...) return p; // ilegal else return t; // legal }

Trimiterea parametrilor catre o metoda Signatura unei metode este data de numarul si tipul argumentelor primite de acea metoda:
metoda([tip1 argument1] [, tip2 argument2] ... )

Tipul de date al unui argument poate fi orice tip valid al limbajului, att tip primitiv de date ct si referinta la un obiect.
Ex: adaugarePersoana(String nume, int varsta, float salariu) String este tip referinta, int si float sunt tipuri primitive

Spre deosebire de alte limbaje, n Java nu pot fi trimise ca parametri ai unei metode referinte la alte metode (functii), nsa pot fi trimise obiecte care sa contina implementarea acelor metode, pentru a fi apelate. De asemenea, n Java o metoda nu poat primi un numar variabil de argumente, ceea ce nseamna ca apelul unei metode trebuie sa se faca cu specificarea exacta a numarului si tipurilor argumentelor. Numele argumentelor primite trebuie sa difere ntre ele si nu trebuie sa coincida cu numele nici uneia din variabilele locale ale metodei. Pot nsa sa coincida cu numele variabilelor membre ale clasei caz n care diferentierea se va face prin intermediul variabile this.
class Cerc { int x, y, raza; public Cerc(int x, int y, int raza) { this.x = x; this.y = y; this.raza = raza; } }

Atentie: In Java argumentele sunt trimise doar prin valoare (pass-by-value) Acest lucru nsemna ca metoda receptioneaza doar valorile variabilelor primite ca parametri. Cnd argumentul are tip primitiv de date metoda nu-i poate schimba valoarea dect local (n cadrul metodei); la revenirea din metoda variabila are aceeasi valoare ca la apelul inittial al metodei (modificarile facute n cadrul metodei sunt pierdute). Cnd argumentul este de tip referinta metoda nu poate schimba referinta obiectului nsa poate apela metodele acelui obiect si poate modifica orice variabila membra accesibila.

Asadar, daca dorim ca o metoda sa schimbe starea(valoarea) unui argument primit, atunci el trebuie sa fie neaparat de tip referinta (trebuie sa fie un obiect!). De exemplu, sa consideram clasa Cerc descrisa anterior si dorim sa implementam o metoda care sa returneze parametrii cercului: Varianta incorecta
... int x = -1, y = -1, r = -1; cerc.aflaParametri(x, y, r); System.out.println("x = " + x + ", y = " + y + ", raza = " + r); . . .

In acesct scop n clasa Cerc ar trebui sa avem o metoda de genul:

class Cerc { int x, y, raza; ... public void aflaParametri(int valx, int valy, int valr) { //metoda nu functioneaza cum ar trebui! valx = x; valy = y; valr = raza; } }

Aceasta metoda nsa nu va realiza lucrul propul ntruct ea primeste doar valorile variabilelor x, y si r adica (-1, -1, -1) si nu referinte la ele (adresele lor de memorie) astfel nct sa le poata modifica valoarea. In concluzie, metoda nu realizeaza nimic pentru ca nu poate schimba valorile unor variabile aflate n afara corpului ei. Varianta corecta Definim o clasa suplimentara care descrie parametrii pe care dorim sa-i aflam:
class CParam { public int x, y, raza; } class Cerc { int x, y, raza; public void aflaParametri(CParam param) { param.x = x; param.y = y; param.raza = raza; } } ... CParam p = new CParam(); cerc.aflaParametri(p); System.out.println("x = " + p.x + ", y = " + p.y + ", raza = " + p.raza);

Suprancarcarea si supradefinirea metodelor Sunt doua concepte extrem de utile ale POO si se refera la:

suprancarcarea (overloading) : n cadrul unei clase pot exista metode cu acelasi nume cu conditia ca signaturile lor sa fie diferite (lista de argumente primite sa difere fie prin numarul argumentelor, fie prin tipul lor) astfel nct la apelul functiei cu acel nume sa se poata stabili n mod unic care dintre ele se executa. Fenomenul de supradefinire a metodelor se mai numeste si polimorfism. supradefinirea (overriding): o subclasa a unei clase poate rescrie o metoda a clasei parinte, prin implementarea unei metode cu acelasi nume si aceeasi signatura ca ale superclasei.

Exemplificare:

class A { void metoda() { System.out.println("A: metoda fara parametru"); } //supraincarcare - polimorfism void metoda(int arg) { System.out.println("A: metoda cu un parametru"); } } class B extends A { //supradefinire void metoda() { System.out.println("B: metoda fara parametru"); } }

O metoda supradefinita poate sa:


ignore complet codul metodei corespunzatoare din superclasa (cazul de mai sus)
B b = new B(); b.metoda(); -> afiseaza "B: metoda fara parametru"

sa extinda codul metodei parinte, executnd nainte de codul propriu si functia parinte.
class B extends A { //supradefinire prin extensie void metoda() { super.metoda(); System.out.println("B: metoda fara parametru"); }

} . . . B b = new B(); b.metoda(); -> afiseaza : "A: metoda fara parametru" "B: metoda fara parametru"

Metode finale Specifica faptul ca acea metoda nu mai poate fi supradefinita n subclasele clasei n care ea este definita ca fiind finala. Acest lucru este util daca respectiva metoda are o implementare care nu trebuie schimbata sub nici o forma n subclasele ei, fiind critica pentru consistenta starii unui obiect. De exemplu studentilor unei universitati trebuie sa li se calculeze media finala n functie de notele obtinute la examene n aceeasi maniera, indiferent de facultatea la care sunt.
class Student { . . . final float calcMedie(int nrExamene, float note[], float ponderi[]) { ... } . . . } class StudentInformatica extends Student{ float calcMedie(int nrExamene, float note[], float ponderi[]) { return 10.00; } }//eroare la compilare!

Specificatori de acces pentru membrii unei clase Sunt cuvinte rezervate ce controleaza accesul celorlate clase la membrii unei clasei. Specificatorii de acces pentru variabilele si metodele unei clase sunt: public, protected, private si cel implicit (package), iar nivelul lor de acces este dat n tabelul de mai jos:
Specificator Clasa Subclasa Pachet Toti private X protected X X** X public X X X X package* X X

Exemple de declaratii:

private int secretPersonal; proteceted String secretDeFamilie; public Vector elemente;

long doarIntrePrieteni ;

-> package

private void metodaInterna(); public double calculeazaRezultat();

Obs1(*): Daca nu este specificat nici un modificator de acces, implicit nivelul de acces este la nivelul pachetului (package). Asadar, modificatorul "package" nu apare explicit n declararea unei variabile/metode (n cazul n care apare, compilatorul va furniza o eroare). Obs2(**): In cazul n care declaram un membru "protected" atunci accesul la acel membru din subclasele clasei n care a fost declarata variabila depinde si de pachetul n care se gaseste subclasa: daca sunt n acelasi pachet accesul este permis, daca nu sunt n acelasi pachet accesul nu este permis dect pentru obiecte de tipul subclasei. Membri de instanta si membri de clasa O clasa Java poate contine doua tipuri de variabile si metode :

de instanta: declarate fara modificatorul static, specifice fiecarei instante si de clasa: declarate cu modificatorul static, specifice clasei

Variabile Cnd declarati o variabila membra cum ar fi x n exemplul de mai jos:


class MyClass { int x ; //variabila de instanta }

se declara de fapt o variabila de instanta, cee ce nsemna ca la fiecare creare a unei instante a clasei MyClass sistemul aloca o zona de memorie separata pentru memorarea valorii lui x.
MyClass o1 = new MyClass(); o1.x = 100; MyClass o2 = new MyClass(); o2.x = 200; System.out.println(o1.x) -> afiseaza 100 System.out.println(o2.x) -> afiseaza 200

Asadar, fiecare obiect nou creat va putea memora valori diferite pentru variabilele sale de instanta. Pentru variabilele de clasa (statice) sistemul aloca o singura zona de memorie la care au acces toate instantele clasei respective, ceea ce nseamna ca daca un obiect modifica valoarea unei variabile statice ea se va modifica si pentru toate celelate obiecte.
class MyClass { int x ; //variabila de instanta static long n; //variabila de clasa

} . . . MyClass o1 = new MyClass(); MyClass o2 = new MyClass(); o1.n = 100; System.out.println(o2.n) -> afiseaza 100 o2.n = 200; System.out.println(o1.n) -> afiseaza 200

Metode Similar ca la variabile, metodele declarate fara modificatorul static sunt metode de instanta iar cele declarate cu static sunt metode de clasa (statice). Diferenta ntre cele doua metode este urmatoarea:

metodele de instanta opereaza att pe variabilele de instanta ct si pe cele statice ale clasei metodele de clasa opereaza doar pe variabilele statice ale clasei
class MyClass { int x ; //variabila de instanta static long n; //variabila de clasa void metodaDeInstanta() { n ++; //legal x --; //legal static void metodaStatica() { n ++; //legal x --; //ilegal }

Intruct metodele de clasa nu depind de starea obiectelor clasei respective, apelul lor se poate face astfel:
MyClass.metodaStatica(); MyClass obj = new MyClass(); obj.metodaStatica(); //legal, echivalent cu //legal

spre deosebire de metodele de instanta care nu pot fi apelate dect unei instante a clasei respective:
MyClass.metodaDeInstanta(), MyClass obj = new MyClass(); obj.metodaDeInstanta(); //ilegal //legal

Utilitatea membrilor de clasa (statici) Sunt folositi pentru a pune la dispozitie valori si metode independente de starea obiectelor dintr-o anumita clasa.
1. Declararea constantelor
2. 3. 4. class MyClass { final double PI = 3.14; //variabila finala de instanta }

La fiecare instantiere a clasei MyClass va fi rezervata zona de memorie pentru variabilele finale ale obiectului respectiv, ceea ce este o risipa ntruct aceste constante au aceleasi valori pentru toate instantele clasei. Declararea corecta a constantelor trebuie asadar facuta cu modificatorii static si final, pentru a le rezerva o singura zona de memorie, comuna tuturor obiectelor:
class MyClass { static final double PI = 3.14; //variabila finala de clasa }

5. Numararea obiectelor unei clase


6. 7. 8. class MyClass { static long nrInstante = 0; MyClass() { //constructorul este apelat la fiecare instantiere 9. nrInstante ++; 10. } 11. }

Folosind variabile statice putem controla diversi parametri legati de crearea obiectelor unei clase
12. Implementarea functiilor globale

13. 14.

Spre deosebire de C++, n Java nu putem avea functii globale definite ca atare, ntruct "orice este un obiect". Din acest motiv si metodele care au o functionalitate globala trebuie implementate n cadrul unei clase. Acest lucru se va face prin intermediul metodelor de clasa (globale), deoarece acestea nu depind de starea particulara a obiectelor din clasa respectiva. De exemplu, sa consideram functia globala sqrt care extrage radicalul unui numar si care se gaseste n clasa Math. Daca nu ar fi fost functie de clasa, apelul ei ar fi trebuit facut astfel (incorect, de altfel):
Math obj = new Math(); double rad121 = obj.sqrt(121);

ceea ce ar fi fost extrem de neplacut pentru programatori. Fiind nsa functie statica ea poate fi apelata prin: Math.sqrt(121) .

Initializarea variabilelor de clasa


Se poate face n momentul declararii lor :
class MyClass {

static final double PI = 3.14; static long nrInstante = 0; static final double EPS = 0.01;

sau prin intermediul unui bloc static de initializare:


class MyClass { static { final double PI = 3.14; long nrInstante = 0; final double EPS = 0.01; } }

Clase imbricate
O clasa imbricata este, prin definitie, o clasa membra a unei alte clase
class ClasaDeAcoperire{ . . . class ClasaImbricata { . . . } }

Folosirea claselor imbricate se face atunci cnd o alta clasa are nevoie n implementarea ei de o alta clasa si nu exista nici un motiv pentru care clasa imbricata sa fie declarata de sine statatoare (nu mai este folosita nicaieri).
public class Pachet { //clasa de acoperire class Continut { //clasa imbricata private String marfa; private float cantitate; Continut (String marfa, float cantitate) { this.marfa = marfa; this.cantitate = cantitate; } } class Destinatie { //clasa imbricata private String dest; private int termen; Destinatie(String undePleaca, int inCateZile) { dest = undePleaca; termen = inCateZile; } }

dest,

public void trimite(String marfa, float cant, String int termen) { Continut c = new Continut(marfa, cant); Destinatie d = new Destinatie(dest, termen); } public static void main(String[] args) { Pachet p = new Pachet(); p.trimite("banane", 100, "Romania", 7); }

Ca membra a unei clase, o clasa imbricata are un privilegiu special fata de celelalte clase: acces nelimitat la variabilele clasei de acoperire, chiar daca acestea sunt private. Clase interne Ca orice alta clasa o clasa imbricata poate fi declarata statica sau nu. O clasa imbricata nestatica se numeste clasa interna.
class ClasaDeAcoperire{ . . . static class ClasaImbricataStatica { . . . } class ClasaInterna { . . . } }

Diferentierea acestor denumiri se face deoarece:


o o

o "clasa imbricata" reflecta relatia sintactica a doua clase; codul unei clase apare n interiorul dodului altei clase; o "clasa interna" reflecta relatia dintre instantele a doua clase, n sensul ca o instanta a unei clase interne nu poate exista dect n cadrul unei instante a clasei de acoperire.

In general cele mai folosite clase imbricate sunt clasele interne Asadar, o clasa interna este o clasa imbricata ale carei instante nu pot exista dect n cadrul instantelor clasei de acoperire si care are acces direct la toti membrii clasei sale de acoperire. Identificarea claselor imbricate

Dupa cum stim orice clasa produce la compilare asa numitele "unitati de compilare", care sunt fisiere avnd numele clasei respective si extensia .class, si care contin toate informatiile despre clasa respectiva. Pentru clasele imbricate aceste unitati de compilare sunt denumite astfel: numele clasei de acoperire, urmat de simbolul '$' apoi de numele clasei imbricate.
class ClasaDeAcoperire{ class ClasaInterna1 {} class ClasaInterna2 {} }

Pentru exemplul de mai sus vor fi generate trei fisiere:


ClasaDeAcoperire.class ClasaDeAcoperire$ClasaInterna1.class ClasaDeAcoperire$ClasaInterna2.class

In cazul n care clasele imbricate au la rndul lor alte clase imbricate (situatie mai putin uzuala) denumirea lor se face dupa aceeasi metoda : adaugarea unui '$' si apoi numele clasei imbricate.

Clase si metode abstracte


Uneori n proiectarea unei aplicatii este necesar sa reprezentam cu ajutorul claselor concepte abstracte care sa nu poata fi instantiate si care sa foloseasca doar la dezvoltarea ulterioara a unor clase ce descriu obiecte concrete. De exemplu n pachetul java.lang exista clasa abstracta Number care modeleaza conceptul generic de "numar". Intr-un program nu avem nsa nevoie de numere generice ci de numere ntregi, reale, etc. Clasa Number serveste ca superclasa pentru clase cum ar fi Byte, Double, Float, Integer, Long si Short ce implementeaza obiecte pentru descrierea numerelor de un anumit tip. Asadar clasa Number reprezinta un concept abstract si nu vom putea instantia obiecte de acest tip:
Number numarGeneric = new Number(); //eroare

Declararea unei clase abstracte Se face folosind cuvntul rezervat abstract n declaratia clasei:
abstract class ClasaAbstracta { . . .

Daca vom ncerca sa instantiem un obiect al clasei ClasaAbstracta vom obtine o eroare la compilarea programului de genul:class ClasaAbstracta is an abstract class. It can't be instantiated. Metode abstracte Spre deosebire de clasele obisnuite care trebuie sa furnizeze implementari pentru toate metodele declarate o clasa abstracta poate contine metode fara nici o implementare. Metodele fara nici o implementare se numesc metode abstracte si pot aparea doar n clase abstracte. In fata unei metode abstracte trebuie sa apara cuvntul cheie abstract, altfel va fi furnizata o eroare de compilare.
abstract void metodaAbstracta(); //corect void metoda(); //incorect (Method metoda requires a method body; otherwisw declare it abstract)

In felul acesta o clasa abstracta poate pune la dispozitia subclaselor sale un model complet pe care trebuie sa-l implementeze, furniznd chiar implementarea unor metode comune tuturor claselor sau lasnd explicitarea unor metode fiecarei subclase n parte. Un exemplu elocvent de folosire a claselor si metodelor abstracte este descrierea obiectelor grafice ntr-o maniera orientata-obiect.
o o o

Obiecte grafice : linii, dreptunghiuri, cercuri, curbe Bezier, etc Stari comune : pozitia(originea), dimensiunea, culoarea, etc Comportament : mutare, redimensionare, desenare, colorare, etc.

Pentru a folosi starile si comportamentele comune acestor obiecte n avantajul nostru putem declara o clasa generica GraphicObject care sa fie superclasa pentru celelalte clase.

Metodele abstracte vor fi folosite pentru implementarea comportamentului specific fiecarui obiect, cum ar fi desenarea iar cele obisnuite pentru comportamentul comun tuturor, cum ar fi schimbarea originii. Implementarea clasei abstracte GraphicObject:
abstract class GraphicObject { int x, y; . . . void moveTo(int newX, int newY) { . . . } abstract void draw(); } ici o implementare

//metoda normala //metoda abstracta //n

Atentie: Orice subclasa non-abstracta a unei clase abstracte trebui sa furnizeze implementari ale metodelor abstracte din superclasa. Implementarea claselor pentru obiecte grafice ar fi:
class Circle extends GraphicObject { void draw() { . . . //obligatoriu implementarea } } class Rectangle extends GraphicObject { void draw() { . . . //obligatoriu implementarea } }

Observatii: O clasa abstracta poate sa nu aiba nici o metoda abstracta. O metoda abstracta nu poate aparea dect ntr-o clasa abstracta. Orice clasa care are o metoda abstracta trebuie declarata ca fiind abstracta.

Clasa Object
Orice clasa are o superclasa Dupa cum am vazut la crearea unei clase clauza "extends" specifica faptul ca acea clasa este o subclasa a altei clase, numita superclasa. O clasa poate avea o singura superclasa (Java nu suporta mostenirea multipla) si chiar daca nu specificati clauza "extends" la crearea unei

clase ea totusi va avea o superclasa. Cu alte cuvinte, in Java orice clasa are o superclasa si numai una.

Superclasa tuturor celorlalte clase este clasa Object, care este radacina ierarhiei de clase n Java. Clasa Object este si superclasa implicita a claselor care nu specifica o alta superclasa. Declaratiaclass MyClass {} este echivalenta cu class MyClass extends Object {}. Clasa Object Este cea mai generala dintre clase, orice obiect fiind, direct sau indirect, descendent al acestei clase. Defineste si implementeaza comportamentul comun al tuturor claselor Java cum ar fi:
o o o o

posibilitatea compararii obiectelor ntre ele specificarea unei reprezentari ca sir de caractere a unui obiect returnarea clasei din care face parte un obiect notificarea altor obiecte ca o variabila de conditie s-a schimbat, etc

Fiind sublcasa a lui Object, orice clasa poate supradefini metodele clasei Object care nu sunt finale. Metode care pot fi supradefinite sunt: clone, equals/hashCode, finalize ,toString
Acesasta metoda este folosita pentru duplicarea obiectelor (creearea unor clone). Clonarea unui obiect presupune crearea clone unui nou obiect de acelasi tip si care sa aiba aceeassi stare (aceleasi valori pentru variabilele sale) equals,hashCode Aceste metode trebuie supradefinite mpreuna. In metoda equals este scris codul pentru compararea a doua obiecte. Implicit (implementarea din clasa Object) aceasta

finalize

metoda compara referintele obiectelor. Uzual este redefinita pentru a testa daca starile obiectelor coincid sau daca doar o parte din variabilele lor coincid. Metoda hashCode returneaza un cod ntreg pentru fiecare obiect pentru a testa consistenta obiectelor: acelasi obiect trebuie sa returneze acelasi cod pe durata executiei programului. Daca doua obiecte sunt egale conform metodei equals atunci apelul metodei hashCode pentru fiecare din cele doua obiecte trebuie sa returneze acelasi ntreg. In aceasta metoda se scrie codul care "curata dupa un obiect" nainte de a fi eliminat din memorie de colectorul de gunoaie. (vezi "Distrugerea obiectelor") Este folosita pentru a returna o reprezentare ca sir de caractere a unui obiect. Este utila pentru concatenarea sirurilor cu diverse obiecte n vederea tiparirii.
MyObject obj = new MyObject(); System.ot.println("Obiect=" + obj); //echivalent cu System.ot.println("Obiect=" + obj.toString());

toString

Exemplu de supradefinire a metodelor clasei Object


class MyObject extends Object { //clasa in care este supradefinita metoda equals public int x; public boolean equals(Object obj) { if (obj == null) return false; if (!(obj instanceof MyObject)) return false; if ( ((MyObject) obj).x == x) return true; else return false; } public synchronized Object clone() { MyObject m = new MyObject(); m.x = x; return m; } public final synchronized String toString() { return "[" + x + "]"; } public void finalize() { System.out.println("Finalizare"); x = -1; } } class OtherObject { public int x; //clasa in care NU este supradefinita metoda equals }

class TestObject { //clasa principala - contine metoda main public static void main(String args[]) { OtherObject o1 = new OtherObject(); OtherObject o2 = new OtherObject(); o1.x = 1; o2.x = 1; if (o1.equals(o2)) System.out.println("test1: o1 == o2"); else System.out.println("test1: o1 != o2");//corect //Desi x=1 pt ambele obiecte egalitatea se obtine doar cand //adresele lor de memorie coincid deoarece nu este implementata //metoda equals o2 = o1; if (o1.equals(o2)) System.out.println("test2: o1 == o2");//corect else System.out.println("test2: o1 != o2"); ////////////////////////////////////////////// MyObject m1 = new MyObject(); MyObject m2 = new MyObject(); m1.x = 1; m2.x = 1; if (m1.equals(m2)) System.out.println("test3: m1 == m2");//corect else System.out.println("test3: m1 != m2"); //x=1 pt ambele obiecte -> metoda equals returneaza true MyObject m3; m3 = (MyObject) m1.clone(); System.out.println("Obiectul clonat: " + m3); //echivalent cu System.out.println("Obiectul clonat: " + m3.toString()); //Se tipareste: Obiectul clonat: [1] } }

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