Documente Academic
Documente Profesional
Documente Cultură
Curs 3 Java
Curs 3 Java
Curs 3
Cand scriem un program in Java proiectam si construim un set de clase . Atunci cand
programul ruleaza din aceste clase sunt create obiecte si apoi acestea sunt folosite .
Sarcina programatorului Java este de a crea seturile corecte de clase pentru ca
programul sa se comporte corespunzator .
In practica nici macar nu trebuie pornit de la zero cu constructia claselor . Fiecare
versiune de Java contine un grup de clase care implementeaza caracteristicile de baza
de care au in general nevoie programatorii . Aceste grupe de clase se numesc
biblioteci .
O biblioteca de clase este un grup de clase proiectate pentru a fi folosite impreuna cu
alte programe . Biblioteca de clase Java standard contine mai multe zeci de clase
( depinzand exact de versiunea limbajului ) .
Biblioteca standard Java se ocupa de mai multe sarcini uzuale , cum ar fi functii
matematice , lucru cu text , imagini , sunet interactiune cu utilizatorul si lucru in
retea . In multe cazuri bibliotecile Java sunt de ajuns pentru un program de nivel
scazut . In acest caz programatorul are ca sarcina doar crearea unei singure clase ,
folosite pentru a crea obiecte pronind de la clasele Java standard si pentru a administra
interactiunile dintre acestea .
Odata cu avansarea in programarea Java se poate crea un set complet nou de clase
care sa aiba definite anumite interactiuni intre ele ; acestea pot fi folosite pentru a se
alcatui eventual o biblioteca proprie de clase care poate fi reutilizata mai tarziu in alte
programe . Aceasta capacitate de reutilizare este unul dintre avantajele majore ale
programarii orientate obiect .
ATRIBUTE SI COMPORTAMENT
Atributele reprezinta parametrii individuali care diferentiaza o clasa de obiecte de o
alta si care determina modul de prezentare , starea si alte calitati ale clasei .
Intr-o clasa atributele sunt definite de variabile . Fiecare obiect poate avea valori
diferite ale variabilelor sale ; acestea se numesc variabile de instanta .
O vaziabila de instanta este un element de informatie care defineste atributul unui
anumit obiect . Clasa obiectului defineste ce fel de atribut este si fiecare instanta isi
pastreaza propria sa valoare pentru acel atribut . Variabilele de instanta mai sunt
denumite si variabilele obiectului .
Fiecarui atribut al unei clase ii corespunde o singura variabila ; putem schimba
atributul unui obiect modificand aceasta variabila .
Variabilele de instanta pot lua o valoare atunci cand se creeaza un obiect ce ramane
neschimbat pe toata durata lui de existenta sau pot lua diferite valori pe masura ce
obiectul este folosit .
Un alt atribut este folosit pentru descrierea intregii clase de obiecte , nu numai a unui
singur obiect al clasei . Aceste atribute sunt continute in variabile de clasa .
O variabila de clasa este un element de informatie care defineste atributul unei intregi
clase . Variabila se aplica insasi clasei si tuturor instantelor ei , deci este stocata o
singura valoare , indiferent cate obiecte ale clasei au fost create .
COMPORTAMENTUL UNEI CLASE DE OBIECTE
Comportamentul este modul in care clasele de obiecte pot face ceva cu ele insele sau
cu alte obiecte . Comportamentul unei clase determina ce obiecte ale clasei isi
modifica atributele , precum si ce fac ele atunci cand alte obiecte le cer sa faca ceva .
Comportamentul unei clase de obiecte este determinat cu ajutorul metodelor .
Metodele sunt grupuri de instructiuni dintr-o clasa de obiecte , care actioneaza asupra
acesteia sau asupra altor clase sau obiecte . Ele sunt folosite pentru a realiza diferite
sarcini , in acelasi fel in care in alte limbaje de programare se folosesc functiile .
Obiectele comunica unele cu altele folosind metodele . O clasa sau un obiect poate
apela metode dintr-o alta clasa sau obiect pentru mai multe motive :
-
if (flamand==true) {
System.out.println(Bun foame!);
Flamand=false;
} else
System.out.println(Nu murci am mancat!);
}
In continuare prezentam listingul celei de a doua metode pentru verificarea
atributelor :
void afisezAtribute() {
System.out.println(Acesta e un jabberwock +sex+ +culoare);
if (flamand==true) System.out.printl(Jabberwock-ul este flamand);
else System.out.println(Jabberwock-ul e satul);
}
In acest moment avem o clasa Jabberwock cu variabile si metode de instanta ce pot fi
folosite pentru a afisa si modifica variabilele .
Pentru a compila programul schimbam directorul curent in directorul care contine
fisierul nostru sursa si folosim comanda :
javac Jabberwock.java
In cazul in care incercam sa rulam fisierul ( cu comanda : java Jabberwock ) vom
obtine o eroare . Aceasta apare deoarece interpretorul Java presupune ca programul pe
care incercam sa il executam din linia de comanda este o aplicatie . Atunci cand se
executa o aplicatie punctul ei de lansare este metoda main() . Deoarece clasa noastra
nu poseda o metoda main() avem probleme .
Exista doua metode de a folosi clasa noastra :
1. Cream , separat , un applet sau o aplicatie java care sa foloseasca aceasta clasa
2. adaugam metoda main() in listingul nostru
Pentru a adauga metoda main() se introduc urmatoarele :
public static void main(String argumente[]){ }
Mai jos avem intregul listing al aplicatiei noastre :
class Jabberwock {
String culoare;
String sex;
boolean flamand;
void hranescJabberwock() {
if (flamand==true) {
System.out.println("Bun - vrea mancare");
flamand=false; }
else
System.out.println("Nu multumesc - am mancat deja");
}
void afisezAtribute () {
System.out.println("Acesta e un jabber " + sex + " " + culoare + " .");
if (flamand==true)
System.out.println("Jabber este flamand");
else
System.out.println("Jabber este satul");
}
public static void main (String argumente[] ) {
Jabberwock j=new Jabberwock();
j.culoare="portocaliu";
j.sex="mascul";
j.flamand=true;
System.out.println("Apelez afisezAtribute ...");
j.afisezAtribute();
System.out.println("___");
System.out.println("Hranesc Jabber-ul ...");
j.hranescJabberwock();
System.out.println("___");
System.out.println("Apelez afisezAtribute ...");
j.afisezAtribute();
System.out.println("---");
System.out.println("Hranesc Jabber-ul ... ");
j.hranescJabberwock();
}
}
ORGANIZAREA CLASELOR SI COMPORTAMENTUL ACESTORA
MOSTENIREA
Mostenirea reprezinta unul dintre cele mai importante concepte ale programarii OOP ,
avand un efect direct asupra modului de proiectare si scriere a claselor noastre Java .
Mostenirea este un mecanism care permite unei clase sa mosteneasca comportamentul
si stributele unei alte clase .
Prin mostenire , o clasa dobandeste imediat tot comportamentul unei clase existente .
Din acest motiv , noua clasa poate fi creata prin simpla specificare a diferentelor fata
de clasa existenta .
Prin mostenire toate clasele sunt aranjate intr-o ierarhie stricta cele pe care le cream
si cele provenite din biblioteca Java sau din alte biblioteci .
O clasa care mosteneste alta clasa este denumita subclasa iar clasa care isi ofera
mostenirea se numeste superclasa .
O clasa poate avea o singura superclasa , insa poate avea un numar nelimitat de
subclase . Subclasele mostenesc toate atributele si comportamentul superclaselor lor .
In varful ierarhiei de clase Java se afla clasa Object toate clasele mostenesc aceasta
unica superclasa . Object reprezinta cea mai generica clasa din ierarhie , care defineste
comportamentul si atributele mostenite de toate clasele din biblioteca Java . Fiecare
clasa aflata mai jos in ierarhie devine din ce in ce mai adaptata unui scop precis . O
ierarhie de clase defineste conceptele abstracte la varful ierarhiei ; aceste concepte
devin din ce in ce mai concrete odata cu coborarea spre subclase .
In mod normal , cand cream o noua clasa Java dorim ca ea sa prezinte toate
caracteristicile unei clase existente , cu unele modificari ; de exemplu putem dori o
versiune a butonului CommandButton care sa produca un zgomot la folosirea sa .
Pentru a mosteni toate caracteristicile clasei CommandButton fara effort vom defini
noua noastra clasa ca o subclasa a clasei CommandButton . Clasa noastra va mosteni
automat comportamentul si atributele superclasei . Tot ceea ce trebuie sa facem este sa
introducem diferenta fata de superclasa .
Subclasarea reprezinta crearea unei noi clase , care mosteneste o clasa existenta .
Singurul lucru care trebuie facut in subclasa este definirea diferentelor in
comportament si atribute fata de superclasa .
Cand clasa noastra defineste un comportament complet nou si nu este o subclasa
atunci ea mosteneste direct clasa Object . Acest lucru ii permite acesteia sa se
integreze corect in ierarhia claselor Java ; in practica , daca definim o clasa care nu
specifica o superclasa atunci Java presupune automat ca noua clasa mosteneste direct
clasa Object
Atunci cand cream un nou obiect Java pastreaza urma fiecarei variabile definite
pentru acel obiect si a fiecarei variabile definite pentru fiecare clasa a obiectului . In
acest fel , toate clasele se combina pentru a forma un model al obiectului curent , iar
fiecare obiect isi completeaza informatiile corespunzatoare acestei situatii .
Metodele se comporta in acelasi fel : noile obiecte au acces la toate metodele clasei si
superclaselor de care apartin . Acest lucru este determinat dinamic , atunci cand o
metoda este folosita intr-un program aflat in executie . Daca apelam o metoda a unui
anumit obiect , interpretorul Java verifica mai intai clasa obiectului , pentru a gasi
acea metoda . Daca metoda nu este gasita interpretorul o cauta in superclasa clasei si
asa mai departe pana la gasirea definitiei metodei .
Problema se complica atunci cand o subclasa defineste o metoda cu acelasi nume , tip
de rezultat si argumente care sunt definite si intr-o superclasa . In acest caz se
foloseste definitia metodei care este gasita prima ( incepand din partea de jos a
ierarhiei si mergand in sus ) . Atfel intr-o subclasa putem crea o metoda cu acelasi
nume , tip de rezultat si argumente ca ale metodei din superclasa ; aceasta procedura
se numeste anulare prin suprascriere sau simplu suprascriere .
MOSTENIREA SIMPLA SI MULTIPLA
Forma de mostenire folosita in Java este denumita mostenire simpla deoarece fiecare
clasa Java poate avea o singura superclasa .
In alte limbaje de programare si in C++ - clasele pot avea mai multe superclase ,
mostenind variabile si metode combinate din toate aceste superclase . Aceasta forma
de mostenire este denumita mostenire multipla si ofera mijloace de creare a unor clase
care cuprind aproape orice comportament imaginabil . Totusi , acest lucru complica
mult definitia clasei si a codului necesar pentru producerea acesteia . Java simplifica
acest concept permitand doar mostenirea simpla .
INTERFETE
Mostenirea simpla face ca relatiile intre clase si comportamentul pe care aceste clase
il implementeaza sa devina usor de inteles si de proiectat . Totusi ea poate fi restrictiva
mai ales atunci cand avem un comportament similar care trebuie duplicat pe diferite
ramuri ale ierarhiei de clase . Java rezolva aceasta problema a comportamentului
partajat prin folosirea interfetelor .
O interfata este o colectie de metode care indica faptul ca o clasa are un anumit
comportament suplimentar fata de ceea ce mosteneste de la superclasele sale .
Tehnic vorbind , o interfata Java nu contine nimic altceva decat definitii de metode
abstracte si constante fara variabile de instanta sau implementari de metode
( cuvantul cheie folosit pentru a semnala folosirea unei interfete este implements ) .
PACHETE
Pachetele in Java reprezinta o modalitate de a grupa clasele si interfetele inrudite .
Pachetele permit grupurilor de clase sa fie disponibile doar daca este nevoie de ele ,
eliminand potentialele conflicte intre numele claselor din diferite grupuri de clase .
Bibliotecile de clase Java sunt continute intr-un pachet denumit java . Clasele din
pachetul Java sunt disponibile garantat in orice implementare Java si sunt singurele
disponibile in diferite implementari . Pachetul Java contine pachete mai mici care
definesc seturi specifice ale caracteristicilor limbajului Java , cum ar fi caracteristicile
standard , manipularea fisierelor , multimedia , etc . Clasele din alte pachete , ca sun
sau netscape , pot fi disponibile doar in anumite implementari .
In mod prestabilit clasele noastre Java au acces doar la clasele din java.lang
( caracteristicile de baza ale limbajului ) . Pentru a folosi clasele din alte pachete
trebuie sa ne referim explicit la numele pachetului sau sa importam clasele in fisierul
nostru sursa .
Pentru a ne referi la o clasa din cadrul unui pachet trebuie sa introducem toate
pachetele care contin clasa , urmate de numele clasei , elementele fiind separate prin
puncte . De exemplu sa luam clasa Color . Ea este continuta in pachetul awt , care la
randul lui este continut in pachetul java . Pentru a referi clasa Color in program
trebuie folosita notatia java.awt.Color .
Prin crearea unei variabile de instanta care sa-l contina , am facut obiectul Font
disponibil tuturor metodelor din clasa noastra . Urmatorul pas in proiectul nostru este
de a crea o metoda care sa-l foloseasca .
Atunci cand scriem applet-uri , exista mai multe metode definite in superclasa Applet ,
care , de obicei , sunt anulate prin suprascriere . Printre acestea exista metode care
configureaza applet-ul inainte de a fi lansat in executie , care lanseaza applet-ul , care
raspund la evenimentele mouse-ului sau care elibereaza memoria cand applet-ul isi
inceteaza executia .
Una dintre aceste metode este paint() , care se ocupa de orice se intampla cand appletul este afisat pe pagina web . Metoda paint() mostenita de clasa Palindrom nu face
nimic este o metoda goala . Prin suprascrierea metodei paint() vom indica ce anume
dorim sa fie desenat in fereastra applet-ului , ori de cate ori este nevoie sa se afiseze
ceva , atunci cand programul ruleaza .
Sa adaugam la clasa noastra urmatoarele instructiuni :
public void paint(Graphics ecran) {
ecran.setFont(f);
ecran.setColor(Color.red);
ecran.drawString(Go hang a salami , Im a lasagna hog,5,40);
}
Metoda paint() este declarata public , ca si applet-ul ; acest lucru apare deoarece
metoda pe care o suprascrie este si ea publica . O metoda publica apartinand unei
superclase nu poate fi suprascrisa decat de o metoda publica , altfel apar erori la
compilare .
Metoda paint() preia un singur argument : o instanta a clasei Graphics , denumita
ecran . Clasa Graphics se ocupa cu reprezentarea fonturilor , culorilor si desenarea
liniilor si altor forme .
In metoda paint() se realizeaza trei lucruri :
-
am indicat obiectului Graphics faptul ca fontul pe care vrem sa-l folosim este
cel continut in variabila de instanta f
am indicat obiectului Graphics faptul ca culoarea pe care dorim sa o folosim
pentru text si alte operatii de desenare este o instanta a clasei Color pentru
culoarea rosu ( red ) .
in final am scris pe ecran un text la coordonatele x,y egale cu 5 si 40 .
}
In cazul in care incercam sa compilam acest fisier sursa vom obtine o serie de erori
de genul : Class not found
Aceste erori apar deoarece clasele Graphics , Font si Color apartin pachetului java.awt
, care nu este disponibil implicit . Am referit clasa Applet din prima linie a sursei prin
numele sau complet incluzand si numele pachetului din care face parte . In restul
programului am referit insa celelalte clase fara a folosi numele pachetului din care
acestea fac parte .
Exista doua metode pentru a rezolva problema :
-
Pentru o scriere mai usoara si mai rapida a codului sursa se foloseste de obicei a doua
varianta , fapt tradus in programul nostru prin inserarea liniilor :
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Font;
Pentru o si mai mare usurinta putem folosi simbolul * in locul unui anumit nume de
clasa . Putem astfel folosi instructiunea :
import java.awt.*;
Deoarece fisierul sursa contine o clasa publica , Palindrom , numele fisierului trebuie
sa fie identic cu numele clasei publice cu folosirea corecta a majusculelor si
minusculelor .
Pentru a putea vedea ce am realizat trebuie sa cream o pagina web care sa foloseasca
applet-ul nostru .
Vom crea o pagina web cu urmatorul continut :
<applet code=Palindrom.class width=600 height=100>
</applet>
-
In lipsa unui browser putem folosi pentru a vizualiza pagina noastra utilitarul
appletviewer din pachetul JDK , cu sintaxa :
appletviewer Palindrom.html
pentru acele argumente . La crearea unei clase putem defini oricati constructori avem
nevoie pentru implementarea comportamentului clasei .
GESTIONAREA MEMORIEI
Gestionarea memoriei in Java se face dinamic si automat . Atunci cand cream un
obiect nou Java aloca automat o zona de memorie de dimensiunea corespunzatoare
obiectului . Nu trebuie sa alocam explicit memorie pentru obiecte .
Deoarece gestionarea memoriei se face automat nu este nevoie sa dezalocam memoria
ocupata de obiect atunci cand am terminat de lucrat cu acesta . Atunci cand am
terminat lucrul cu obiectul acesta nu mai poseda nici o referinta activa catre el ( nu va
mai fi atribuit nici unei variabile pe care o folosim sau nu va mai fi stocat in vreun
tablou ) . Java poseda un garbage collector care cauta obiectele nefolosite si
recupereaza memoria ocupata de acestea . Nu trebuie sa eliberam explicit acea zona
de memorie .
ACCESAREA SI STABILIREA VARIABILELOR DE CLASA SI DE INSTANTA
Variabilele de clasa si de instanta se comporta in acelasi fel ca si variabilele locale .
Trebuie doar sa ne referim la ele intr-o modalitate usor diferita .
OBTINEREA VALORILOR
Pentru a obtine valoarea unei variabile de instanta vom folosi notatia cu punct . In
aceasta notatie variabila de instanta sau de clasa este formata din doua parti :
obiectul , in partea stanga a punctului si variabila , in partea dreapta .
De exemplu , daca avem un obiect atribuit variabilei clientulMeu si acel obiect poseda
o variabila denumita totalFactura atunci ne vom referi la aceasta variabila astfel :
clientulMeu.totalFactura;
Aceasta forma de accesare a variabilelor este o expresie ( deoarece intoarce o
valoare ) in care de ambele parti ale punctului se afla tot expresii . Acest lucru
inseamna ca putem insera mai multe variabile de instanta . Daca variabila totalFactura
refera ea insasi un obiect care poseda propria variabila de instanta numita rezervat ,
putem sa ne referim la aceasta astfel :
clientulMeu.totalFactura.rezervat;
Expresiile cu punct sunt evaluate de la stanga spre dreapta , asa incat se va incepe cu
variabila din clientulMeu , totalFactura , care refera un alt obiect cu variabila
rezervat . In final vom obtine valoarea variabilei rezervat .
MODIFICAREA VALORILOR
Atribuirea unei valori acelei variabile se face pur si simplu prin utilizarea operatorului
de atribuire :
clientulMeu.totalFactura.rezervat=true;
In continuare avem un exemplu simplu de accesare a variabilelor prin notatia cu punct
:
import java.awt.Point;
class DefinirePuncte {
public static void main(String argumente[]) {
Point pozitie=new Point(4,13);
System.out.println(Pozitia de inceput:);
System.out.println(X egal +pozitie.x);
System.out.println(Y egal +pozitie.y);
System.out.println(\nSe muta in (7,6));
pozitie.x=7;
pozitie.y=6;
System.out.println(Pozitia finala:);
System.out.println(X egal +pozitie.x);
System.out.println(Y egal +pozitie.y);
}
}
VARIABILE DE CLASA
Dupa cum am vazut in cursurile anterioare o variabila de clasa este definita si
memorata chiar in clasa respectiva . Valorile variabilelor de clasa se aplica clasei si
tuturor instantelor sale .
In cazul variabilelor de instanta fiecare noua instanta primea o copie a variabilelor de
instanta definite in clasa . Fiecare instanta poate modifica apoi valorile acestor
variabile fara a afecta alte instante . In cazul variabilelor de clasa exista o singura
copie a acesteia . Modificarea valorii sale este vizibila in toate instantele clasei .
Variabilele de clasa se definesc prin inserarea cuvantului cheie static inaintea numelui
variabilei . De exemplu , sa luam urmatoarea definitie de clasa :
class MembruFamilie {
static String numeFamilie=Popescu;
String prenume;
int varsta;
}
Instantele clasei noastre poseda propriile valori pentru prenume si varsta insa variabila
de clasa numeFamilie are o valoare comuna pentru toti membrii familiei . Daca se
modifica valoarea acestei variabile toate instantele clasei MembruFamilie vor fi
afectate .
System.out.println(Subsirul de la 9 la 11 : +str.substring(9,11));
System.out.println(Indexul caracterului u: +str.indexOf(u));
System.out.println(Indexul inceputului +subsirului \voi\ : +str.indexOf(voi));
System.out.println(Sirul scris cu litere mari : +str.toUpperCase());
}
}
METODE DE CLASA
Metodele de clasa , ca si variabilele de clasa , se aplica unei clase in intregul sau si nu
instantelor sale . Metodele de clasa sunt utilizate de obicei drept metode de uz
general , care nu pot opera direct asupra unei instante a clasei , dar se potrivesc
conceptual in cadrul clasei . De exemplu , clasa String contine o metoda numita
valueOf() , care poate prelua mai multe tipuri de argumente ( intregi , booleeni , alte
obiecte s.a.m.d. ) . Metoda valueOf() intoarce o noua instanta a clasei String , care
contine valoarea argumentului sub forma de sir . Aceasta metoda nu opereaza direct
asupra unei instante String insa obtinerea unui sir dintr-un alt tip de data este in mod
clar o operatie apartinand clasei String si are deci sens sa fie definita in clasa String .
Metodele de clase pot fi de asemenea folositoare pentru adunarea unor metode
generale intr-un singur loc ( o clasa ) . De exemplu , clasa Math , definita in
java.lang , contine un set larg de operatii matematice definite ca metode de clase nu
exista instante ale clasei Math si totusi putem folosi metodele sale impreuna cu
argumente booleene sau numerice . De exemplu sa luam metoda de clasa Math.max :
Int pretMaxim=Math.max(primulPret,alDoileaPret);
Ca si in cazul variabilelor de clasa accesarea metodelor de clasa se poate face folosind
in stanga punctului fie numele clasei fie numele de instanta .
Exemplul de mai jos va produce acelasi rezultat in ultimele sale doua linii :
String s,s2;
s=articol;
s2=s.valueOf(5);
s2=String.valueOf(5);