P. 1
Programare in Java

Programare in Java

|Views: 1,437|Likes:
Published by your_alien2

More info:

Published by: your_alien2 on Jan 30, 2011
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

07/03/2013

pdf

text

original

UNIVERSITATEA TITU MAIORESCU FACULTATEA DE INFORMATICA

Programarea in Java
suport curs -

Lector univ. drd. Dascalescu Ana Cristina

- 2010 1

Cuprins

Capitolul 1 Introducere in limajul Java................................................................................................................................................. 3 1.1Caracteristici de baza ale limbajului Java ................................................................................................................................... 3 1.2 Tehnologia Java si componentele sale...................................................................................................................................... 4 1.2.2 Platforme de lucru Java ........................................................................................................................................................ 4 1.2.3 Tipuri de programe implementate de Java............................................................................................................................. 5 1.2.3Etapele dezvoltarii unei aplicatii Java..................................................................................................................................... 6 1.2 Structura lexicala a limbajului Java .............................................................................................................................................. 7 1.3 Tipuri de date si variabile in Java ................................................................................................................................................. 8 1.4 Expresii si operatori....................................................................................................................................................................11 1.5 Controlul executiei ......................................................................................................................................................................14 1.6 Siruri de caractere........................................................................................................................................................................17 Capitolul 2 Clase si obiecte .................................................................................................................................................................19 2.1 Ciclul de viata al unui obiect .......................................................................................................................................................20 2.1.1 Crearea obiectelor.................................................................................................................................................................20 2.2 Crearea claselor ...........................................................................................................................................................................22 2.2.1 Corpul unei clase ..................................................................................................................................................................23 2.2.2 Constructorii unei clase ........................................................................................................................................................24 2.2.3 Declararea variabilelor..........................................................................................................................................................25 2.3 Implementarea metodelor ............................................................................................................................................................27 2.3.1 Declararea metodelor............................................................................................................................................................27 2.3.2 Metode de instanta si metode de clasa ..................................................................................................................................29 2.3.3 Domeniul de vizibilitate (acces) al metodelor unei clase. Modificatori de acces..................................................................29 Capitolul 3 Extinderea claselor. Polimorfismul in Java.......................................................................................................................33 3.1 Mostenirea - concept fundamental al programarii orientata obiect..............................................................................................33 3.2 Caracteristicile unei ierarhi de clase ............................................................................................................................................35 3.3 Mostenirea simpla in Java ...........................................................................................................................................................35 3.4 Supraincarcarea (overloading) metodelor. Redefinirea (override) metodelor..............................................................................37 3.5 Implementarea polimorfismului .................................................................................................................................................39 3.6 Metode si clase abstracte .............................................................................................................................................................42 Capitolul 4 Interfete Java...................................................................................................................................................................50 4.1 Interfete .......................................................................................................................................................................................50 4.2 Crearea si folosirea interfetelor Java ...........................................................................................................................................50 4.3 Implementarea unei interfete .......................................................................................................................................................51 4.4 Implementarea unor interfete multiple.........................................................................................................................................52 Capitolul 5 Tratarea exceptiilor............................................................................................................................................................57 5.1 Tratarea erorilor...........................................................................................................................................................................57 5.2 Ierarhia de exceptii predefinite de platforma Java .......................................................................................................................58 5.3 Crearea si semnalarea propriilor exceptii ....................................................................................................................................64 Capitolul 6 Intarari si iesiri...................................................................................................................................................................68 6.1 Tipuri de fluxuri de intrare/iesire Java.........................................................................................................................................68 6.2 Fluxuri de octeti si clase predefinite Java ....................................................................................................................................69 6.3 Fluxuri de caractere si clase predefinite Java utilizate.................................................................................................................81

Capitolul 1 Introducere in limajul Java

Obiective:

- implementarea firmei Sun a limbajului Java: Platforma J2SE (Java 2 Platform, Standard Edition); - tipuri de programe implementate de Java; - etapele dezvoltarii unei aplicatii Java; structura unei aplicatii Java; metoda main( ); - utilizarea claselor de obiecte din pachetele predefinite (pachete API) Java; directiva import ; instructiunea package; - elemente de baza ale limbajului Java: identificatori, variabile, tipuri primitive de date; constant,operatori, controlul executiei; - afisarea datelor pe ecran: metodele print, println, readLine, read.

1.1 Caracteristici de baza ale limbajului Java
Scurt istoric Inceptul limbajului Java este in toamna anului 1991, cand firma Sun Microsystems a finantat un proiect cu numele Green condus de James Gosling. Tehnologia propusa a avut un impact remarcabil asupra intregii comunitati a dezvoltatorilor de software, impunandu-se prin calitati deosebite cum ar fi simplitate, robustete si nu in ultimul rand portabilitate. Dupa patru ani de lucru, echipa Green finalizeaza specificatiile limbajului Java, astfel ca in anul 1995 firma Sun Microsystems vinde licenta firmelor IBM, Microsoft, Silicon Graphic, Adope si Netscape. Incepand cu anul 1998, cand a aparut versiunea 2 a limbajului (Java 2 Platform), Java a fost extins, acoperind si mai multe directii de dezvoltare: programarea aplicatiilor enterprise (aplicatii de tip server) precum si a celor adresate dispozitivelor cu resurse limitate, cum ar fi telefoanele mobile, pager-e sau PDA-uri (mici dispozitive de calcul, de dimensiuni putin mai mari decat ale unui telefon mobil, cu facilitati de agenda si capabile sa execute aplicatii intr-un mod relativ asemanator cu cel al unui PC). Caracteristicile de baza ale limbajului Java: - Java este un limbaj simplu de folosit. Aceasta caracteristica poate fi considerata ca o reactie directa la complexitatea considerabila a limbajului C/C++. Au fost indepartate din Java aspectele cele mai derutante din C++ precum supraincarcarea operatorilor, mostenirea multipla sau pointerrii. - Java este independent de arhitectura calculatorului pe care lucreaza si foarte portabil. Compilatorul Java genereaza o secventa de instructiuni ale unei masini virtuale Java. Executia aplicatiilor Java este interpretata. Singura parte din mediul de executie Java (JRE) care trebuie portata de pe o arhitectura pe alta cuprinde interpretorul Java si o parte din bibliotecile standard care depind de sistem. In acest fel aplicatii Java compilate pe o arhitectura SPARC de exemplu, pot fi
3

rulate fara recompilare pe un sistem bazat pe procesoare Intel. De altfel, mediul de executie Java (JRE) este scris in C ceea ce il face foarte portabil. - Interpretorul Java este gandit sa lucreze pe masini mici (memorie mica de ordinul sutelor de KB), precum ar fi procesoarele cu care sunt dotate aparatele casnice si telefoanele mobile. - Limbajul Java este orientat obiect. Cu el se pot crea clase de obiecte si instante ale acestora, se pot incapsula informatiile, se pot mosteni variabilele si metodele de la o clasa la alta etc. Singura caracteristica care lipseste este mostenirea multipla, dar pentru a suplini aceasta lipsa, Java ofera o facilitate mai simpla, numita interfata, care permite definirea unui anumit comportament pentru o clasa de obiecte, altul decat cel definit de clasa de baza. In Java orice element este un obiect, in afara de datele primare. Din Java lipsesc functiile si variabilele globale. - Limbajul Java este distribuit, avand implementate biblioteci pentru lucrul in retea. - Limbajul Java este un limbaj cu securitate ridicata. - Java are inclus suport nativ pentru aplicatii care lucreaza cu mai multe fire de executie (programare paralela si concurenta). Acest suport este independent de sistemul de operare.

1.2 Tehnologia Java si componentele sale
In tehnologia Java sunt cuprinse patru componente: 1. Masina virtuala, denumita JVM (Java Virtual Machine) care interpreteaza fisierele cu extensia .class ce contine “bytecode”. “Bytecode” reprezinta cod compilat care este procesat de un program, denumit masina virtuala, si nu cod executabil care ruleaza pe masina reala ce dispune de un procesor harwarde. “Bytecode” este format din instructiuni generice care sunt convertite (transformate) de masina virtuala in instructiuni specifice procesorului masinii reale. De aceea se spune ca aplicatiile Java sunt independente de platforma (hardware si software). Masina virtuala Java mai este denumita si interpretor Java. 2. Limbajul Java propriu-zis. Limbajul Java este orientat pe obiecte si se aseamana din punct de vedere al sintaxei cu C++. 3. Un compilator care genereaza fisiere cu extensia .class. Compilatorul Java traduce instructiunile scrise in limbajul Java (stocate in fisiere cu extensia .java) in instructiuni generice “bytecode”(stocate in fisiere cu extensia .class) care sunt “intelese” de masina virtuala. 4. Biblioteca de clase Java, denumita si Java API. Aceasta biblioteca contine un set de componente utile care pot fi reutilizate de programatori in diverse aplicatii informatice. 1.2.1 Platforme de lucru Java Limbajul de programare Java a fost folosit la dezvoltarea unor tehnologii dedicate rezolvarii unor probleme din cele mai diverse domenii. Aceste tehnologii au fost grupate in asa numitele platforme de lucru, ce reprezinta seturi de librarii scrise in limbajul Java, precum si diverse programe utilitare, folosite pentru dezvoltarea de aplicat¸ii sau componente destinate unei anume categorii de utilizatori.

pagini JSP.com”. Standard Edition) in diverse versiuni pe care le scoate firma si care este livrat gratuit (este un soft liber). Acest tip de programe Java sunt denumite applet-uri. 1. Acest tip de programe Java sunt denumite aplicatii de sine statatoare. etc.sun. Standard Edition) Produsul informatic (software-ul) care implementeaza platforma J2SE si care este folosit pentru dezvoltarea de aplicatii specifice acesteia este J2SDK (Java 2 Software Development Kit. platforma de lucru J2ME oferind suportul necesar scrierii de program dedicate acestui scop. oferind cea mai comoda solutie pentru distributia si actualizarea aplicatiilor Java. Programe Java care se executa individual prin intermediul unui interpretor Java. dintr-un document HTML. utilitare bazate pe text. din lina de comanda a sistemului de operare. biblioteca de clase Java API etc). Pachetul Java 2 SDK este un set de programe care ruleaza.java . aici este inclusa si tehnologia JavaWeb Start ce furnizeaza o modalitate extrem de facila pentru lansarea si instalarea locala a programelo scrise in Java direct de peWeb. etc. . bazate pe componente cum ar fi servleturi. Acestea se incadreaza in programele “clasice” scrise in diverse limbaje de programare.interpretorul Java. . cum ar fi:C/C++. Principlala caracteristica a acestui tip de aplicatie este incapsularea in cadrul unei clase principale a unuei functii main() asemanatoare cu cea folosita in limbajul C. cu urmatoarea signatura: 5 . formate din componente ce trebuie sa ruleze in sisteme eterogene. De asemenea. cu informatiile memorate in baze de date distribuite.folosit pentru testarea applet-urilor (aplicatii care ruleaza dintr-un navigator de internet). Tot aici gasim si suportul necesar pentru crearea de aplicatii si servicii Web. Platforma J2SE (Java 2 Platform. J2EE (Enterprise Edition) Aceasta platforma ofera API-ul necesar dezvoltarii de aplicatii complexe. programarea dispozitivelor mobile este extrem de simpla. Cele mai importante unelte incluse in J2SDK sunt: .appletviewer .com. O aplicatie de sine statatoare este un program Java care se executa in afara browswer-ului Web .compilatorul Java.sun. 3.2 Tipuri de programe implementate de Java Cu ajutorul limbajului Java se pot dezvolta trei tipuri de programe: 1. 2. Toate distributiile Java sunt oferite gratuit si pot fi descarcate de pe Internet de la adresa ”http://java. Produsul J2SDK include uneltele de creare a programelor Java (compilatorul si alte unelte necesare pentru dezvoltare de programe) si unelte de executie ale acestora (masina virtuala.javac . Pascal etc.2. care nu au nevoie de o interfata grafica pentru utilizator.J2SE (Standard Edition) Este platforma standard de lucru ce ofera suport pentru crearea de aplicatii independente si appleturi. Aplicatii care se executa pe partea de server numite serveturi. Pentru a fi la curent cu ultimele versiuni ale produsului J2SDK se poate accesa adresa de internet http://java. Programe Java care se executa in interiorul unui navigator Internet. J2ME (Micro Edition) Folosind Java.

compilatorul traduce acest program in codul masina pentru masina virtuala Java (un fel de calculator intr-un alt calculator).Un dezavantaj poate fi considerat timpul mai mare de executie. care are extensia .o secventa de instructiuni de asamblare pentru masina virtuala Java. Procesul de complilare si executie poate fi reprezentat ca in figura 1. iar rezultatul este trimis programului solicitant. Fisierul “bytecode” nu depinde de masina gazda si de sistemul de operare pe care va fi executat programul. de catre interpretorul Java. 1. In acest mod este asigurata portabilitatea si independenta de platforma. Rezultatul compilarii este unul sau mai multe fisiere de tip “bytecode”. Daca programul nu contine erori sintactice. semnaland eventualele erori. Conversia are loc la lansarea executiei si anume instructiune cu instructiune. Extensia fisierului “bytecode” rezultat in urma compilarii are extensia . scrisa in java.java.3 Etapele dezvoltarii unei aplicatii Java 1.public static void main(String args[] ) Aplicatiile care se executa pe partea de client sunt cele incarcate de pe un server si apoi executate de programe speciale cum ar fi navigatoarele Web. si care poate interactiona cu diferiti clienti folosind o implementare a paradigmei cerere/raspuns bazata pe protocolul HTTP. a instructiunilor “bytecode” in instructiuni inteligibile masinii gazda care apoi sunt executate. O aplicatie care se executa pe partea de server este o aplicatie care este rulata de server ca urmare a unei cererei primate de acesta. Conversia (transformarea). Compilatorul analizeaza textul sursa al programului din punct de vedere sintactic. . 2.2. de obicei a unui server HTTP. Un applet este un program Java care respecta o multime de reguli astfel incat sa poata rula in cadrul unui navigator Web.Editarea setului de instructiuni de programare cu ajutorul unui editor de texte. Servturile extend functionalitatea unui server. Pentru aceasta operatie se lanseaza in executie un program special. Compilarea programului. 3. In acest fel este creat un fisier sursa. Masina virtuala mai este cunoscuta si ca interpretor Java sau executor (runtime) Java. denumit compilator Java.class. Un servlet este o componenta Web.

Arabic. intalniti si sub denumirea de nume simbolice. trebuie sa existe o clasa care sa contina o metoda statica avand numele main. referirea la celelalte facandu-se prin \uxxxx. 9. spre deosebire de ASCII..\u0039 : cifre ISO-Latin 0 . unde era posibila reprezentarea a doar 256 de caractere. In grupul de clase.) • \u4e00 .org” Identificatori Identificatorii. Acesta este un standard international care inlocuieste vechiul set de caractere ASCII si care foloseste pentru reprezentarea caracterelor 2 octeti.} } Observatie: Tipul parametrilor metodei (functiei) main cat si tipul metodei.9 • \u03B1 .2 Structura lexicala a limbajului Java Setul de caractere Limbajului Java lucreaza in mod nativ folosind setul de caractere Unicode. Currency.\u9fff : litere din alfabetul Han (Chinez.\u22FF : simboluri matematice (8. Musical. O alta caracteristica a setului de caractere Unicode este faptul ca intreg intervalul de reprezentare a simbolurilor este divizat in subintervale numite blocuri. 1. Primele 256 caractere Unicode corespund celor ASCII. static void. 7 . Japonez. . unde xxxx reprezinta codul caracterului.9 • \u0660 . masina virtuala va cauta si invoca automat metoda statica avand numele main.println(“Primul program Java”).O aplicatie Java este compusa din una sau mai multe clase care interactioneaza intre ele prin intermediul metodelor. care formeaza o aplicatie Java.\u03C9 : simboluri grecesti _ − ! • \u2200 .\u0669 : cifre arabic-indic 0 . • \u0030 . Arrows. Greek.out. Atunci cand se executa o aplicatie Java. ceea ce inseamna ca se pot reprezenta 65536 de semne. cateva exemple de blocuri fiind: Basic Latin. etc.unicode. Cel mai simplu program Java (care nu face nimic) arata astfel: class aplicatie { public static void main (String [ ] args) {System. Mai jos sunt oferite cateva exemple de caractere Unicode. etc. clase metode etc. Observatie: Metoda main poate fi considerata ca fiind echivalentul Java a functiei main din C/C++. variabile. Coreean) Mai multe informatii legate de reprezentarea Unicode pot fi obtinute la adresa ”http://www. Gothic. Mathematical. sunt obligatorii. au rolul de a denumi elemente ale programului Java: constante.

’). Ea poate fi modificata pe parcursul executiei programului. . o valoare initiala care se atribuie variabilei.caracterul punct si virgula (‘. . La declararea variabilei trebuie specificat numele simbolic al variabilei. Pentru utilizarea unei variabile intr-un program Java trebuie ca aceasta sa fie declarata.3 Tipuri de date si variabile in Java Variabila este o zona temporara de stocare. tipul acesteia si.o succesiune de caractere pe mai multe linii care tin de documentatie. . TAB (‘\t’).caracterul apostrof (‘). modul de reprezentare a acestora in memorie. de exemplu. adica face diferenta intre literele mici si literele mari. in Java exista variabile care isi pot modifica valoarea si variabile care nu si-o pot modifica. variabilele Java devin independente de platforma hardware si software pe care lucreaza. . Asupra variabilelor finale vom reveni ulterior dupa intelegerea conceptelor de clasa de obiecte. care pot fi utilizati numai in constructii sintactice in care sunt specificati. identificatorii sunt diferiti in functie daca sunt scrisi cu litere mici si mari. primul caracter fiind obligatoriu o litera (inclusiv ‘_’). .Delimitatorii sunt folositi.’). incadrate intre /** si */. dar au rolul de a explicita si de a face mai lizibil pentru programator anumite secvente de program. 1. . Un tip de date defineste multimea de valori pe care variabila poate sa le stocheze. care are un nume simbolic (identificator) si stocheaza un anumit tip de date.a delimita sfarsitul unei instructiuni sau al unei declaratii .Ca separatori “generali” se utilizeaza caracterele albe: spatiu (‘ ‘). eventual. de exemplu. De aceea. pentru: . pentru a separa unele constructii sintactice: variabilele sunt separate prin caracterul virgula (‘. Alti separatori specifici sunt ( ) { } [ ] . Comentarii Comentariile sunt texte care vor fi ignorate de compilator. numite variabile finale. In acest fel. Toate cuvintelecheie se scriu numai cu litere mici. Limbajul Java este “case-sensitive”. Cuvintele-cheie (keywords) sunt identificatori speciali. In Java exista trei tipuri de comentarii: . cu inteles predefinit.o succesiune de caractere incadrata intre /* si */ . aceste comentarii pot fi formate din mai multe linii.Separatorii specifici sun folositi. . sfarsit de linie (‘\n’) si comentariile. textul dintre cele doua secvente este automat mutat in documentatia aplicatiei de catre generatorul automat de documentatie (javadoc).a delimita o constanta de tip caracter . De exemplu: if. ca si setul de operatii pe care programul poate sa le realizeze cu aceste date.o succesiune de caractere care incepe cu // si se termina la sfarsitul unei singure linii.Din punct de vedere sintactic. In ciuda denumirii.a delimita constantele sir de caractere(ghilimelele). Separatori Separatorii au rolul de a separa unitatile sintactice: . while etc. un identificator este constituit dintr-o succesiune nelimitata de litere si cifre Unicode. In limbajul Java a fost exact definita modalitatea de reprezentare a tipurilor primitive de date in memorie. rezidenta in memoria RAM.

147.De asemenea.483. 32767] Intreg pe 2 bytes int [2. Orice variabila de tip caracter nou creata primeste automat ca valoare implicita caracterul null al codului Unicode. Tipurile de date intregi sunt folosite pentru memorarea unor valori intregi cu semn.147. long. Orice variabila booleana nou creata primeste automat valoarea implicita false. 10308] coduri Unicod Virgula mobila pe 8 bytes char Pe 2 byte boolean false sau true Pe un bit Tipul boolean este folosit pentru memorarea unei valori de adevar sau fals. Java defineste o valoare implicita pentru fiecare tip de date. Limbajul Java accepta urmatoarele tipuri de baza: byte.483. in cazul in care variabila de un anumit tip nu a primit nici o valoare de la utilizator. float. Este o practica buna insa aceea ca programele sa nu depinda niciodata de aceste initializari implicite. 2. Tipurile de date intregi sunt: byte. Tip Valori Reprezentare in memorie byte [-128.648] Intreg pe 4 bytes long [-263. Orice variabila de tip intreg (byte. 9 . int. Tabelul de mai jos prezinta o descrie generala a tipurilor primitive de date utilizate de Java. Tipul char este folosit pentru a reprezenta caractere de tip Unicode. 127] Intreg pe 1 byte short [-32768. short. int si long) nou creata primeste automat valoarea implicita 0. 1038] Virgula mobila pe 4 bytes double 15 cifre semnificative [10-324. 263 -1] Intreg pe 8 bytes float 6 cifre semnificative [10-46. “\u0000’. double. Regula ar fi deci urmatoarea: nici o declararie fara initializare. long. int. boolean. short.648. char. void. Conventia folosita de Java pentru valorile intregi cu semn este reprezentarea in complement fata de doi. In Java aceste doua valori le vom nota prin constantele (literali) true si respectiv false. short.

java.lang. Constantele reale care se pot reprezenta in memoria calculatorului sunt numere rationale din intervalele specificate la tipurile float si double.pentru tipul double. POSITIVE_INFINITY. Caracterele care au reprezentare grafica pot fi scrise intre apostroafe. Constantele reale pot fi specificate in notatia obisnuita sau in format stiintific. Constantele lungi se recunosc prin faptul ca se termina cu sufixul l sau L.lang. Constantele de tip caracter sunt utilizate pentru a reprezenta caracterele Unicode. Constantele intregi pot fi intregi normale sau lungi. Numele constantelor este: NaN. valoarea implicita este de tip double. Valoarea implicita pentru variabilele de tip float este 0.Double. .lang.Long . Valori folosite pe post de infinit pozitiv si negativ. Pentru tipurile intregi si intregi lungi. functiile de scriere vor transforma acest numar in caracterul corespunzator.0.Tipurile de date reale sunt folosite pentru memorarea unor valori reale sub forma de mantisa si caracteristica.Float .0f. pentru care multimea valorilor este vida. Sufixul care indica tipul float poate fi f sau F iar sufixul care indica tipul double poate fi d sau D. Constante O constanata este folosita pentru a exprima in program o valoare pe care o poate lua tipurile primitive de date si tipul sir de caractere. fie o secventa escape. Valorile descrise la pct. cum a fost cazul metodei main ().Integer . se folosesc secventele escape sau secventele escape predefinite prezentate deja.java. NEGATIVE_INFINITY. Tipul void Tipul void este un tip special. precum si pentru tipurile flotante exista definite clase in ierarhia de clase predefinite Java si anume: . Pentru a reprezenta o constanta intreaga in baza 8 trebuie sa se adauge prefixul 0 (cifra zero) in fata numarului. . iar pentru variabilele de tip double este 0. Acest tip se utilizeaza cand este necesar sa se specifice absenta oricarei valori. Java interpreteaza constantele de tip caracter ca pe un numar (codul Unicode al caracterului respectiv).Double .lang. .pentru tipul float. Reprezentarea se face fie folosind o litera sau o cifra.0d.pentru tipul int.lang. de exemplu 0. Daca nu este specificat nici un sufix.Float si respectiv in clasa java. De exemplu: pentru tipul de data a metodelor care nu intorc nici un rezultat. 16 sau 8.pentru tipul long. Pentru a reprezenta o constanta intreaga in baza 16 trebuie sa se adauge prefixul 0x sau 0X in fata numarului. . 2. Ulterior. Tipurile de date reale sunt: float si double.java. Aceste valori pot rezulta in urma unor calcule. 1 si 2 sunt definite sub forma de constante si in ierarhia de clase predefinite Java.java. Pentru cele care nu au reprezentare grafica. Constantele intregi pot fi reprezentate in baza 10.0 / 0. si anume in clasa java. In fiecare dintre clase numerice prezentate sunt definite doua constante care reprezinta valorile minime si maxime pentru tipurile respective.Valoarea NaN (Not a Number) se obtine atunci cand se efectueaza o operatie a carei rezultat nu este definit. Aceste doua constante se numesc in mod uniform MIN_VALUE si MAX_VALUE. Intern. In Java sunt definite cateva valori reale speciale: 1.lang.

. b=3. legati prin operatori. Locul unde este declarata o variabila determina domeniul de vizibilitate si semnificatia ei. Daca cel putin unul 11 . Modul cum se face definirea constantelor va fi prezentata intr-o lectie separata destinata descrieri atributelor statice. Exemple de declaratii de variabile ce pot fi folosite intr-un program: int a. Vom reveni asupra sirurilor de caractere intr-o lectie separata. unde: .6. O variabila trebuie sa fie declarata imediat inainte de a fi folosita. Sintaxa folosita pentru declararea de variabile este: <tip> <nume_v1> [= <expresie>] [. Operatorul ‘/’ poate fi aplicat atat operanzilor intregi. Observatii: 1. … . fata de operanzii reali.restul impartirii intregi. <nume_v2> [= <expresie2>] … ]. ‘%’ .4 Expresii si operatori O expresie este compusa dintr-o succesiune de operanzi.Constantele de tip sir de caractere sunt cuprinse intre ghilimele. separand numele lor prin virgula. o instanta a clasei de obiecte String declarata standard in pachetul java.lang. identificatorii). Daca cei doi operanzi sunt numere intregi. Operatorii aritmetici Operatorii aritmetici sunt: ‘*’ .<expresie1>. <nume_v2>.<tip> . ‘+’ adunarea. un apel de metoda. sunt optionale si sunt folosite pentru a atribui unor variabile anumite valori initiale. . dar functioneaza diferit pentru operanzii intregi. Operatorul ‘%’ nu poate fi aplicat decat operanzilor intregi. 2. precum si operatorul unar ‘+’ (plus) (introdus pentru simetrie). Observatie: Se pot declara simultan mai multe variabile de acelasi tip.specifica tipul de data al variabilelor. … . float x=b*5. o expresie incadrata intre paranteze rotunde. atunci se foloseste secventa escape \n in sirul de caractere respectiv. Un operand poate fi o constanta. <expresie2>. o variabila. de fapt. Daca se doreste introducerea de caractere terminatoare de linie intr-un sir de caractere. Operatorii desemneaza operatiile care se executa asupra operanzilor si pot fi grupati pe categorii. A. y. Caracterele care formeaza sirul de caractere pot fi caractere grafice sau secvente escape ca cele prezentate la constantele de tip caracter. char g. Observatie: Un sir de caractere este.inmultirea. expresia trebuie sa fie evaluabila in momentul declararii.specifica numele simbolic al variabilelor care se declara (adica. c=4.impartirea. Operatorii limbajului Java sunt unari (se aplica unui singur operand) sau sunt binari (se aplica asupra a doi operanzi). in functie de tipul operatiilor realizate. operandul ‘/’ are ca rezultat catul impartirii intregi (fara parte fractionara).<nume_v1>.specifica o expresie de initializare. ‘/’ . ‘-’ . cat si operanzilor reali. De asemenea este folosit operatorul unar ‘-’ (minus) pentru schimbarea semnului. Limbjul Java permite si definirea de constante.scaderea. 1.

Operatorii de incrementare/decrementare Operatorul de incrementare este ‘++’. limbajul Java va utiliza mai intai valoarea variabilei intr-o alta expresie si apoi va efectua operatia de incrementare / decrementare. <=. >=. Sunt operatori binari si arata relatia de egalitate (==) sau inegalitate (!=).disjunctie logica (sau) reprezentata cu | | . De exemplu. C.dintre cei doi operanzi este un numar real. . In cazul cand se foloseste operatorul de incrementare / decrementare in forma prefixata (inaintea operandului). Exista trei operatori logici globali: . Operatori relationali Operatorii relationali sunt operatori binari si desemneaza relatia de ordine in care se gasesc cei doi operanzi: <. expresiile logice: 5 == 2+3 are ca rezultat valoarea true. Limbajul Java permite doua forme pentru operatorii de incrementare / decrementare: forma prefixata (inaintea operandului) si forma postfixata (dupa operand). Rezultatul aplicarii unui operator de egalitate este true. Operatorii de incrementare / decrementare pot fi aplicati operanzilor intregi.evaluarea expresiei 3 * ++x conduce la rezultatul 18. E. Rezultatul aplicarii unui operator relational este true daca cei doi operanzi sunt in relatia indicata de operator. 5 != 2+3 are ca rezultat valoarea false. . Operatori de egalitate Operatorii de egalitate sunt folositi pentru testarea unei egalitati sau inegalitati intre doua valori. D. operandul ‘/’ furnizeaza rezultatul impartirii reale (cu parte fractionara). De exemplu. si false. expresiile logice: 4 > 6 are ca rezultat valoarea false. Operatori logici se aplica asupra unor operanzi de tip boolean. . Operatorul de decrementare este ‘--’. daca valoarea curenta a lui x este 5. dupa care valoarea lui x va fi in ambele cazuri 6. operanzilor in virgula mobila si operanzilor de tipul char.5 se pot construi urmatoarele expresii: b%2 =1. In cazul cand se foloseste operatorul de incrementare / decrementare in forma postfixata (dupa operand). 8 <= 3+13 are ca rezultat valoarea true.conjunctie logica (si) reprezentata cu &&. B. b=7 float x=3.evaluarea expresiei 3 * x++ conduce la rezultatul 15.negatia logica (not) reprezentata cu !. De exemplu. . altfel. a/2=2. limbajul Java va incrementa / decrementa mai intai valoarea variabilei si apoi va utiliza variabila intr-o alta expresie. atunci: . daca cei doi operanzi sunt in relatia indicata de operator si false altfel. De exemplu pentru declaratiile de variabile: int a=5. >. Acesti operatori sunt unari si au ca efect marirea (respectiv micsorarea) valorii operandului cu 1.

<<. 3. operatorii “vecini” actioneaza conform regulilor de asociativitate prezentate in tabelul de mai sus. Carcterele din sirul rezultat sunt caracterele din primul sir. Observatie : <expresie> poate fi la randul ei o expresie de atribuire. apoi se atribuie variabilei <nume_variabila> valoarea expresiei.F. acesta este convertit la un sir de caractere care sa reprezinte valoarea operandului. /. >>. &. La prioritate egala. Efectul aplicarii operatorilor de atribuire compusi este echivalent cu instructiunea: <nume_variabila> = <nume_variabila> <operator_binar> <expresie>. urmate de cele dintr-al doilea sir in ordine. |. <nume_variabila1> = <nume_variabila2> = … = <nume_variabilan> = <expresie>. b = a* = 2. +. caz in care se realizeaza o atribuire multipla. G. Daca cel de-al doilea operand este un tip primitiv de data. sunt echivalente cu: total+ =100. prin inlocuirea in expresie a fiecarei variabile cu valoarea ei si a fiecarei functii cu valoarea returnata de functia respectiva si efectuarea operatiilor specificate de operatori. Operatori de atribuire Operatorii de atribuire sunt operatori binari care permit modificarea valorii unei variabile. De exemplu: total = 0. jumatate = jumatate/2. jumatate/ =2. -. de asociativitate si de prioritatea operatorilor: 1. In cadrul unei expresii fara paranteze. 13 .<operator_binar> . %. 2.este din multimea {*. el atribuie valorile de la dreapta la stanga. Atunci cand compilatorul intalneste o operatie de atribuire multipla. lungimea sirului rezultat este suma lungimii sirurilor care intra in operatie. De exemplu: “Acesta este” + “un sir” este echivalent cu “Acesta este un sir” “Variabila a are valoarea ” + 3 este echivalent cu “Variabila are valoarea 3” Evaluarea unei expresii presupune calculul valorii expresiei. O varianta de sintaxa folosita este: <nume_variabila> = <expresie> Efectul aplicarii operatorului este: Se evalueaza <expresie>. unde: . Se foloseste atunci cand se doreste sa se atribuie aceeasi valoare mai multor variabile. folosind atribuirea multipla rezulta: total = suma = a = 0 O alta varianta de sintaxa folosita este: <nume_variabila> <operator_binar> = <expresie>. Operatorul de concatenare ( + ) de siruri de caractere este un operator binar folosit pentru lipirea mai multor siruri de caractere La concatenarea sirurilor de caractere. a = 0. De exemplu instructiunile: total = total + 100. In timpul evaluarii expresiei se tine cont de existenta parantezelor. suma = 0. ^}. Utilizarea parantezelor rotunde este mai puternica decat prioritatea operatorilor. b = a = a*2. se efectueaza operatiile in ordinea prioritatii operatorilor. Exista un operator de atribuire simplu (=) si 10 operatori de atribuire compusi cu ajutorul operatorului ‘=‘ si al unui alt operator binar (aritmetic sau logic pe biti).

continue. while. InputStreamReader isrx = new InputStreamReader(System. z.readLine().<expresie> . Structuri alternative (de decizie) Instructiunea de decizie if Sintaxa instructiunii este: if (<expresie>) <instructiune_1>.out. s = brz. aria. System.parseDouble(s).4 Controlul executiei Instruct¸iunile Java pentru controlul executiei sunt foarte asemanatoare celor din limbajul C si pot fi impartite in urmatoarele categorii: Instructiuni de decizie: if-else. s = brx. altfel se executa <instructiune_2>.print ("Introduceti x= "). System. unde: . adica instructiunile if pot fi incluse (imbricate) in alte instructiuni if.specifica expresia de evaluat.java) testeaza daca trei numere pot forma laturile unui triunghi si daca da calculeaza aria triunghiului folosind formula lui Heron.readLine().io.print ("Introduceti y= "). A. y. p.<instructiune_1>. se executa <instructiune_1>. BufferedReader bry = new BufferedReader(isry). InputStreamReader isry = new InputStreamReader(System. System. do-while Instructiuni pentru tratarea except¸iilor: try-catch-finally. public class arie_triunghi { public static void main(String[] args) throws IOException { double x.in). /** Utilizarea instructiunii if pentru determinarea ariei triunghiului*/ import java. switch-case Instructiuni de salt: for. throw Alte instructiuni: break. .parseDouble(s). <instructiune_2> . BufferedReader brx = new BufferedReader(isrx). Semantica: se evalueaza <expresie> si daca valoarea expresiei este true.parseDouble(s). x = Double. BufferedReader brz = new BufferedReader(isrz). y = Double. label. . return.in). urmatorul program (denumit arie_triunghi. Nota: Instructiunea if poate sa faca parte dintr-o alta instructiune if sau else.1.in).out. String s.*.print ("Introduceti z= "). De exemplu. [else <instructiune_2>].readLine(). InputStreamReader isrz = new InputStreamReader(System. s = bry.out.specifica instructiunile (simple sau compuse) de executat. z = Double.

else if (x+y<=z || x+z<=y || y+z<=x) System. … case <constanta_n> : <grup_de_instructiuni_n>.println("Numerele introduse nu sunt laturi ale unui triunghi"). 2. 15 . care permite selectarea unei alternative din maximum doua posibile. } } } Instructiunea switch Sintaxa instructiunii este: switch (<expresie>) { case <constanta_1> : <grup_de_instructiuni_1>.println("Aria triunghiului = " + aria).<constanta_1>.daca valoarea expresiei este false se iese din ciclul while. se executa secventa de instructiuni din alternativa default (alternativa implicita sau prestabilita). pana la intalnirea instructiunii break sau pana la intalnirea acoladei inchise (}) care marcheaza sfarsitul instructiunii switch.sqrt(p*(p-x)*(p-y)*(p-z)).println("Numerele introduse nu sunt laturi ale unui triunghi"). switch permite selectarea unei alternative din maximum n+1 posibile. unde: . Observatii: 1.if (x<=0 || y<=0 || z<=0) System.out.] } unde: .out. se executa secventa de instructiuni corespunzatoare si toate secventele de instructiuni care urmeaza.daca nici una dintre valorile constantelor din alternativa case nu coincide cu valoarea expresiei. [default: <grup_de_instructiuni_n+1>. Semantica: se evalueaza <expresie>. B. System. <constanta_n> din alternativele case: .daca se intalneste o constanta din alternativa case cu valoarea expresiei.specifica variabila sau expresia de evaluat. Spre deosebire de if-else.<expresie> . . <constanta_2>.specifica valorile constantelor cu care se face compararea rezultatului evaluarii expresiei. . in timp ce in instructiunea switch se executa si toate secventele de instructiuni ale alternativelor case urmatoare. <constanta_2>. case <constanta_2> : <grup_de_instructiuni_2>. Structuri repetitive (iterative) Instructiunea while Sintaxa instructiunii este: while (<expresie>) <instructiune>.out. ….<expresie> .specifica expresia de testat. . <constanta_n> . In instructiunea if-else se executa instructiunea (instructiunile) corespunzatoare valorii expresiei si atat. … . aria = Math. Semantica: se evalueaza <expresie>: . se compara succesiv valoarea expresiei cu valorile constantelor <constanta_1>.o instructiune sau un grup de instructiuni care se executa in cazul in care o alternativa case se potriveste.<grup_de_instructiuni_1>. else { p = (x+y+z)/2. ….

. <valoare_increment>) <instructiune>. 1. Daca stream-ul este de iesire. Daca stream-ul este de intrare. Instructiunea do-while Sintaxa instructiunii este: do <instructiune>.daca valoarea expresiei este true.* Conceptul fundamental in operatiile de intrare/iesire in limbajul Java este fluxul de intrare/iesire (stream).o instructiune simpla de executat. . . catre ecran). Sintaxa instructiunii este: for (<valoare_initiala>. de fiecare data. Instructiunea for foloseste. Java ofera trei fluxuri predefinite pentru operatii I/O standard: . valoarea de incrementare sau decrementare poate fi diferita de 1. Instructiunea for Este folosita pentru efectuarea unor prelucrari de un anumit numar de ori. care.daca valoarea expresiei este false se iese din ciclul do-while. valoarea 1 la variabila de control. succesiunea de biti “curge” dinspre exterior (in acest caz.err pentru fluxul de erori.sectiunea <instructiune> reprezinta instructiunea (sau instructiunile) care se doreste (doresc) a fi repetata (repetate). .daca valoarea expresiei este true se executa instructiunea (din ciclul do-while) atita tip cat valoarea expresiei este adevarata. while (<expresie>).System. Orice program care foloseste rutinele de intrare/iesire trebuie sa cuprinda instructiunea: import java.sectiunea <valoare_initiala> atribuie variabilei de control o valoare initiala. este 0 sau 1.out pentru iesirea standard la ecranul calculatorului.System. dupa ce se executa instructiunea din corpul ciclului.<instructiune> . .io.System.sectiunea <conditie_sfarsit> testeaza valoarea variabilei de control pentru a stabili daca programul a executat instructiunea de atatea ori cat s-a dorit.io. se executa instructiunea atita tip cat valoarea expresiei este true. Aceste operatii se realizeaza prin intermediul unor metode existente in pachetele API ale limbajului. secventa de biti “curge” dinspre memoria calculatorului catre exterior (in acest caz. o variabila denumita variabila de control care indica de cate ori s-a executat instructiunea (<instructiune>) din corpul ciclului.<expresie> . de la tastatura) catre memoria calculatorului.6 Afisarea datelor pe ecran In limbajul Java nu exista instructiuni specializate pentru citirea/scrierea datelor. . de obicei. <conditie_sfarsit>. de obicei.specifica expresia de testat (de evaluat).sectiunea <valoare_increment> adauga (scade). de cele mai multe ori. . unde: . Semantica: se executa instructiunea si apoi se evalueaza expresia: .in pentru intrarea standard de la tastatura. Intrarea si iesirea in Java se realizeaza cu ajutorul claselor de obiecte din pachetul predefinit java. .. Instructiunea for contine patru sectiuni: .

cum ar fi: append.out. cea mai folosita modalitate de a lucra cu siruri este prin intermediul clasei String. daca nu toti operanzii din expresie sunt siruri de caractere. Efectul apelului metodei print este acela ca se realizeaza afisarea la ecran a variabilei data ca parametru si nu se face salt la o linie noua.<expresie> . Observatie: String-urile sunt obiecte Java care descriu sirurile de caractere si le vom studia separat intr-o lectie viitoare. ci alte tipuri primitive de date atunci Java face o conversie temporara la tipul String. adica in forma: System. unde: . in cazul ¸sirurilor de tip StringBuffer. Sintaxa folosita la apelul metodei println este: System. Clasa StringBuffer va fi utilizata predominant in aplicatii dedicate procesarii textelor cum ar fi editoarele de texte.print (<expresie>).out. Diferenta principala intre aceste clase este ca StringBuffer pune la dispozitie metode pentru modificarea continutului sirului. Operatorul de concatenare a doua siruri de caractere folosit de Java este semnul + (plus). insert. Sa retinem ca prin concatenarea a doua siruri se obtine un nou sir de caractere care uneste cele doua siruri initiale. Concatenarea ¸sirurilor de caractere se face prin intermediul operatorului + sau. altfel va fi declarat de tip StringBuffer. 17 . Sintaxa folosita la apelul metodei print este: System. ’b’. Efectul apelului metodei println este acela ca se realizeaza afisarea la ecran a variabilei data ca parametru si se face salt la o linie noua. delete. String s1 = "abc" + "xyz".5 Siruri de caractere In Java. ’c’}. folosind metoda append.out. Exemple echivalente de declarare a unui sir: String s = "abc". un sir de caractere poate fi reprezentat printr-un vector format din elemente de tip char. unde: . String s = new String("abc"). Uzual. String s = new String(data). reverse.este numele unei variabile de un tip de data sau este o expresie care foloseste operatorul de concatenare pentru siruri de caractere. Metoda println se poate apela si fara parametrii.este numele unei variabile de un tip de data sau este o expresie care foloseste operatorul de concatenare pentru siruri de caractere. Daca un ¸sir de caractere este constant (nu se doreste schimbarea continutului sau pe parcursul executiei programului) atunci el va fi declarat de tipul String. Spre deosebire de C/C++ care dispun de un numar foarte mare de optiuni de formatare. 1. String s2 = "123". un obiect de tip String sau un obiect de tip StringBuffer. afisarea in Java se face exclusiv prin concatenare de String-uri fara nici o optiune de formatare. char data[] = {’a’.<expresie> . care are ¸si unele particularitati fata de restul claselor menite sa simplifice cat mai mult folosirea sirurilor de caractere. caz in care se face numai un salt la o linie noua fara sa se afiseze nimic. String s3 = s1 + s2.Pentru afisarea datelor la ecranul calculatorului se folosesc metodele print si println.println (<expresie>).println( ).

"Ana"}.print("21 "). C. operatorul de concatenare + este extrem de flexibil. 1.length + " elemente"). String x = "a" + 1 + "b" Teste de control: 1.In Java.out.length. }} public static void main(String []args){ for(int i=0.print("i ").out. case 4:case5: System."Matei". Programul se compileaza si la executie afiseaza i 1 21 21 26 26 i. C. D. }} Care afrmatii sunt false? A.1 Fie urmatoarea declaratie Java: public private int h. deoarece se ia in considerare ultimul modicator de acces.3 Fie urmatorul program Java: public class Program{ static void f(int k){ switch(k){ default: System. B. deoarece se ia in considerare primul modicator de acces. String []names={"Andreea". in sensul ca permite concatenarea sirurilor cu obiecte de orice tip care au o reprezentare de tip ¸sir de caractere. A.out.i++) System. B. D.2 Ce rezulta din urmatorul fragment de cod Java? int x=1. 1. B.println(names[i]).print("1 ").i++) f(i). Output-ul include Matei.out.print("26 "). names[--x]+=".print("Vectorul v are" + v. Mai jos. Output-ul include Ana. Variabila h va fi accesata in mod public. Programul se compileaza si la executie afiseaza i 1 21 26 . case 2:case3: System. break.i<names. D.out. case1: System.". break. Programul se compileaza si la executie afiseaza i 1 21 21 26 26 . for(int i=0. sunt cateva exemple: System. Eroare la compilare.i<6. . Variabila h va fi accesata in mod private. Output-ul include Andreea. C. Nici una din variantele de mai sus. Nimic din cele de mai sus. Care armatii sunt adevarate: A. break. Va fi o eroare la compilare deoarece o variabila nu poate fi in acelasi timp accesata public si private.out.

-5.println(“suma”+suma). Programul produce eroare la compilare. Programul se compileaza si la executie afiseaza i 1 23 45 .print("23 ").out.}} Afisează la execuţie: a).i++) f(i).print("1 "). Programul se compileaza si la executie afiseaza i 1 23 23 45 45 .6 Secvenţa urmatoare: public class test { public static void main(String args[]) {int a=3. System. daca este integrat intr-un program Java? A. int b=(a=2)*a.suma=0.print("45 ").2}. break. Programul se compileaza si la executie afiseaza -4. case 2:case3: System. Va produce eroare la compilare. Ce se poate spune despre acest cod. a=3 b=6 c=30.print("i ").5 Fie urm¸atorul program Java: public class Program{ static void f(int k){ switch(k){ default: System. break.out. System.out. } } public static void main(String []args){ for(int i=0.println(b).-6. b). B.1. } } Care armatii sunt adevarate? A. C. C. a=2 b=5 c=25. c). D. 1. Programul se compileaza si la executie afiseaza i 1 23 23 45 45 i. a=2 b=5 c=20. int c=b*(b=5). d). a=2 b=4 c=20.i<6. Programul se compileaza si la executie afiseaza -3.i++) if(v[i]<-2) suma+=v[i]. 1.println(“a=”+a+”b=”+b+”c=”+c). System. D. for(i=0. 1. Va produce eroare la executie.i<5.7 Secvenţa uramatoare: public class test { public static void main(String args[]) {int v[ ]={-2. break.out. B.out.0.4 Fie urmatorul cod Java: byte b=-7 >>> 1. case 4:case5: System. case1: System.}} Afiseaza: 19 .out.out.4.

ca in orice limbaj de programare orientat-obiect. clasa ce descrie suprafete grafice rectangulare. Rectangle r1.a). Initializarea este de fapt parte integranta a procesului de instantiere. r2 = new Rectangle(0. respective inaltimea. crearea obiectelor se realizeaza prin instantierea unei clase si implica urmatoarele lucruri: Declararea Presupune specificarea tipului acelui obiect.1. 2. eroare la compilare. 0. r1 = new Rectangle(). in sensul ca imediat dupa alocarea memoriei ca efect al operatorului new este apelat constructorul specificat. Instantierea Se realizeaza prin intermediul operatorului new si are ca efect crearea efectiva a obiectului cu alocarea spatiului de memorie corespunzator. 200). Mai general. r2. d). instantierea si init¸ializarea apar sub forma: numeObiect = new NumeClasa([argumente constructor]). Sa consideram urmatorul exemplu. structura unei clase Java.1 Crearea obiectelor In Java. afiseaza -13. metode membre si constructori.1 Ciclul de viata al unui obiect 2. . b). Capitolul 2 Clase si obiecte Obiective: ciclul de viata al obiectelor. 100. Parantezele rotunde de dupa numele clasei indica faptul ca acolo este de fapt un apel la unul din constructorii clasei si nu simpla specificare a numelui clasei. c) afiseaza -11. afiseaza 0. definite de coordonatele coltului stanga sus (originea) ¸si latimea. definirea claselor. in care declaram si instantiem doua obiecte din clasa Rectangle. Initializarea Se realizeaza prin intermediul constructorilor clasei respective. cu alte cuvinte specificarea clasei acestuia NumeClasa numeObiect. numeObiect = new NumeClasa().

metoda([parametri]).setSize(200. y. Programarea orientata obiect descurajeaza folosirea directa a variabilelor unui obiect deoarece acesta poate fi adus instari inconsistente (ireale). Folosirea obiectelor Odata un obiect creat. De exemplu. height. 100). Fiecare clasa are un set de constructori care se ocupa cu initializare obiectelor nou create. //schimba originea Accesul la variabilele unui obiect se face in conformitate cu drepturile de acces pe care le ofer˘a variabilele respective celorlalte clase. patrat. //metoda setter //metoda setSize poate sa testeze daca noile valori sunt //corecte si sa valideze sau nu schimbarea lor Rolul operatorului new La folosirea operatorului new se executa urmatoarele: . 100. patrat. 21 . int y. Referirea valorii unei variabile se face prin obiect. //schimba dimensiunea Se observa ca valorile variabilelor pot fi modificate indirect prin intermediul metodelor sale.setSize(-100. patrat. width. schimbarea starii sale sau executarea unor actiuni. Acestea se numesc metode de accesare.width). int latime.se aloca memorie pentru aceasta instanta. int inaltime) public Rectangle(Point origine) public Rectangle(Point origine. origin.x = 10. respectiv prin apelarea metodelor sale. //schimba originea patrat. 300). Rectangle patrat = new Rectangle(0.width = -100. int inaltime) public Rectangle(Point origine.variabila De exemplu clasa Rectangle are variabilele publice x. Aceste lucruri se realizeaza prin aflarea sau schimbarea valorilor variabilelor sale. . clasa Rectangle are urmatorii constructori: public Rectangle() public Rectangle(int latime. //schimba originea patrat. int latime. 20).out. -200). System. respectiv getVariabila.getter si au numele de forma setVariabila. 0. 100. 100. initializarea se poate face si cu anumiti parametri.println(patrat. sau metode setter . Dupa cum observam in al doilea caz. Dimension dimensiune) Declararea. . int inaltime) public Rectangle(int x.In primul caz Rectangle() este un apel catre constructorul clasei Rectangle care este responsabil cu init¸ializarea obiectului cu valorile implicite. el poate fi folosit in urmatoarele sensuri: aflarea unor informatii despre obiect. 20). In schimb. Apelul unei metode se face prin obiect.origin = new Point(10. 200).setLocation(10. //afiseaza 100 patrat. //stare inconsistenta patrat. cu conditia sa existe un constructor al clasei respective care sa accepte parametrii respectivi.y = 20. 0. 200).se apeleaza o metoda speciala a clasei numita constructor. Aflarea valorilor acestor variabile sau schimbarea lor se face prin constructii de genul: Rectangle patrat = new Rectangle(0. 0.se creaza o noua instanta a clasei date. pentru fiecare variabil˘a care descrie starea obiectului trebuie sa existe metode care sa permita schimbarea/aflarea valorilor variabilelor sale. instantierea si initializarea obiectului pot aparea pe aceeasi linie (cazul cel mai uzual): Rectangle patrat = new Rectangle(0.

In Java programatorul nu mai are responsabilitatea distrugerii obiectelor sale intrucat. este de preferat ca numele clasei sa inceapa cu o litera majuscula si daca numele clasei contine in interior mai multe cuvinte. Declararea unei clase respecta urm˘atorul format general: [<modificatori_acces>] [<modificatori_clasa>] class <nume_clasa> [<clauze_s>] {<corpul_clasei>} unde: . modificatorul clasei este optional si poate fi: abstract.Constructorii reprezinta metode speciale pentru crearea si initializarea noilor instante ale claselor. modificatorul de acces este optional si poate fi: public. . Intr-o clasa pot fi definiti oricati constructori se doresc pentru a implementa comportamentul clasei. compilatorul va interzice instantierea acestei clase. Distrugerea obiectelor Multe limbaje de programare impun ca programatorul sa tina evidenta obiectelor create si sa le distruga in mod explicit atunci cand nu mai este nevoie de ele. Vom reveni intr-o lectie viitoare. prescurtat gc.2 Crearea claselor Clasele reprezinta o modalitate de a introduce noi tipuri de date intr-o aplicatie Java. Modificatorii pentru tipurile de clasa O clasa poate fi: .specifica domeniul de vizibilitate (folosire sau acces) al clasei. simultan cu interpretorul Java. In cazul in care declaram o clasa de obiecte ca fiind finala. numite la un loc membrii clasei. . cu alte cuvinte sa administreze singur memoria ocupata de obiectele sale. compilatorul va interzice ca pornind de la aceasta clasa sa se defineasca subclase. In cazul in care declaram o clasa de obiecte ca fiind abstracta. fiecare avand un numar diferit de argumente sau de tipuri.<modificatori_clasa> . Constructorii initializeaza noul obiect si variabilele sale.abstracta. Observatie: Continutul (corpul) unei clase nu este o succesiune de instructiuni. Intr-o clasa pot exista mai multe definitii de constructori.<modificatori_acces> . Cand se foloseste operatorul new. ruleaza si un proces care se ocupa cu distrugerea obiectelor care nu mai sunt folosite. despre aceste clauze vom vorbi intr-o lectie viitoare. se pot specifica diferite argumente in lista de argumente si va fi apelat constructorul corespunzator pentru acele argumente.finala.specifica tipul clasei definite. . adica nu se permite crearea de obiecte din aceasta clasa. . .specifica anumite clauze referitoare la pozitia pe care o ocupa clasa in ierarhia de clase din care face parte (clauza extends) sau daca aceasta clasa foloseste o interfata (clauza inplements).variabilele clasei (de instana si de clasa) si metodele care lucreaza cu acestea.<nume_clasa> . creaza orice alte obiecte de care are nevoie obiectul creat si realizeaza orice alte operatii de care obiectul are nevoie la initializarea sa. 2. Acest proces pus la dispozit¸ie de platforma Java de lucru se numeste garbage collector (colector de gunoi). final. caz in care folosim modificatorul abstract. in momentul rularii unui program.<clauze_s> . aceste cuvinte sa inceapa cu o litera majuscula.<corpul_clasei> . cealalta modalitate fiind prin intermediul interfetelor.specifica numele clasei de obiecte. . caz in care folosim modificatorul final.

2. dovedind un stil ineficient de progamare. aceasta modalitate de folosire a accesului de tip friendly nu este recomandata. Implementarea metodelor unei clase trebuie sa se faca obligatoriu in corpul clasei. Continutul acestuia este format din: Declararea si. Ca o consecinta. Acest lucru este insa total nerecomandat daca ne gandim din perspectiva lizibilitatii codului. // C++ class A { void metoda1(). Nota: Toate clasele care nu fac parte din nici un pachet. Spre deosebire de C++. accesul de tip friendly se aplica pentru toate aceste clase. care poate fi chiar numele clasei. sunt considerate automat ca facand parte din acelasi pachet implicit. urmand ca implementare sa fie facuta in afara ei. pentru ca cei doi modificatori se exclud.1 Corpul unei clase Corpul unei clase urmeaza imediat dupa declararea clasei si este cuprins intre acolade. in acelasi timp. atunci aceasta clasa poate fi folosita (accesata) si din exteriorul pachetului din care face parte. Acest tip de acces la o clasa se numeste package-friendly si este implicit in Java. eroarea va fi semnalata la compilare. int metoda2() { // Implementare } } A::metoda1() { // Implementare } // Java class A { void metoda1(){ // Implementare } void metoda2(){ // Implementare } } Variabilele unei clase pot avea acela¸si nume cu metodele clasei. o clasa de obiecte ca fiind abstracta si finala. Acesta este motivul pentru care vizibilitatea nu este afectata daca se omite modificatorul public pentru clasele care nu fac parte dintr-un pachet. Modificatorii de acces In cazul in care declaram o clasa de obiecte ca fiind publica. Daca o clasa nu este declarata ca fiind de tip public atunci ea va putea fi folosita (accesata) doar de clasele din cadrul aceluiasi pachet. eventual. Totusi. 23 . Declararea unor clase imbricate (interne).2.Nota:In cazul in care se declara. initializarea variabilelor de instanta si de clasa (cunoscute impreuna ca variabile membre). Declararea ¸si implementarea constructorilor. nu este permisa doar declararea metode in corpul clasei. Declararea ¸si implementarea metodelor de instanta si de clasa (cunoscute impreuna ca metode membre). fara a exista posibilitatea aparitiei vreunei ambiguitati din punctul de vedere al compilatorului.

h=0. } } Constructorii sunt apelat¸i automat la instant¸ierea unui obiect.out. double y1. double y1. w=w1. double h1) { // Implementam doar constructorul cel mai general x=x1. h. w.println("Instantiere dreptunghi"). } Dreptunghi() { // Constructor fara argumente x=0. fara repeta aceleasi secvente de cod in toti constructorii (cum ar fi afisarea mesajului ”Instantiere dreptunghi”). in functie de numarul parametrilor cu care este apelat constructorul.out. double h1) { // Constructor cu doua argumente x=0. class Dreptunghi { double x. Sa consideram ca exemplu declararea unei clase care descrie notiunea de dreptunghi ¸si trei posibili constructori pentru aceasta clasa. double w1. h=h1. w=0. y=y1. y=y1. Dreptunghi(double x1.2. double w1. System.println("Instantiere dreptunghi"). System.println("Instantiere dreptunghi"). void A() {}. care apeleaza constructorul corespunzator (ca argumente) al clasei respective. h. Dreptunghi(double x1. Aceasta metoda este folosita atunci cand sunt implementati mai multi constructori pentru o clasa. w.out. System. y. w=w1. class NumeClasa { [modificatori] NumeClasa([argumente]) { // Constructor}} O clasa poate avea unul sau mai mult¸i constructori care trebuie insa sa difere prin lista de argumente primite. double h1) { // Cel mai general constructor x=x1. y. y=0. In cazul in care dorim sa apelam explicit constructorul unei clase folosim expresia this( argumente ).println("Instantiere dreptunghi").class A { int A. . In felul acesta sunt permise diverse tipuri de init¸ializ˘ari ale obiectelor la crearea lor. } Dreptunghi(double w1.2 Constructorii unei clase Constructorii unei clase sunt metode speciale care au acelasi nume cu cel al clasei. w=w1. h=h1.out. nu returneaza nici o valoare si sunt folositi pentru initializarea obiectelor acelei clase in momentul instantierii lor. Mai eficient. System. pentru a nu repeta secventele de cod scrise deja la constructorii cu mai multe argumente (mai generali). h=h1. // Corect pentru compilator // Nerecomandat ca stil de programare } 2. clasa de mai sus poate fi rescrisa astfel: class Dreptunghi { double x. y=0.

atunci constructorul implicit (fara nici un argument) nu va mai fi furnizat implicit de catre sistem. • implicit : doar in clasele din acelasi pachet se pot crea instante ale clasei respective. desi acest lucru nu este impus de catre compilator.2. 100). care are mai mult de un argument. w. w1. // Apelam constructorul cu 2 argumente } } Constructorul implicit Constructorii sunt apelati automat la instant¸ierea unui obiect. class NumeClasa { // Declararea variabilelor 25 . r..3 Declararea variabilelor Variabilele membre ale unei clase se declara de obicei inaintea metodelor. Deci prezenta constructorilor in corpul unei clase nu este obligatorie.} Dreptunghi(double w1. } S˘a consider˘am acum dou˘a instant¸ieri ale claselor de mai sus: Dreptunghi d = new Dreptunghi(). // Corect (a fost generat constructorul implicit) Cerc c. Daca insa scriem un constructor pentru o clasa. • private :in nici o alta clasa nu se pot instantia obiecte ale acestei clase. sistemul ii creeaza automat un constructor implicit. controland in felul acesta diverse aspecte legate de instant¸ierea clasei respective. private si cel implicit. y. O astfel de clasa poate contine metode publice care s˘a fie responsabile cu crearea obiectelor. // Nici un constructor } class Cerc { double x. ca exemplu. urmatoarele declaratii de clase: class Dreptunghi { double x. // Eroare la compilare ! c = new Cerc(0. care nu primeste nici un argument si care nu face nimic. // Varianta corecta Constructorii unei clase pot avea urmatorii modificatori de acces: public. In cazul in care scriem o clasa care nu are declarat nici un constructor. 0. 0. c = new Cerc(). double y. • protected : doar in subclase pot fi create obiecte de tipul clasei respective. }. // Apelam constructorul cu 4 argumente } Dreptunghi() { this(0. 0). Sa consideram. y.. 2. h. double r) { . double h1) { this(0. h1). • public: in orice alta clasa se pot crea instante ale clasei respective. // Constructor cu 3 argumente Cerc(double x. protected.

• final Indica faptul ca valoarea variabilei nu mai poate fi schimbata. • unul din cuvintele rezervate: static. int variabilaInstanta . fiind vizibile in toate metodele respectivei clase. transient. volatile. Exemple de declaratii de variabile membre: class Exemplu { double x. PI = 3. unde un modificator poate fi : • un modificator de acces : public. Folosirea lui final aduce o flexibilitate sporita in lucrul cu constante. cu alte cuvinte este folosit pentru declararea constantelor.// Declararea metodelor } Variabilele membre ale unei clase se declara in corpul clasei si nu in corpul unei metode. private. protected static int n. class Test { final int MAX. final static long MAX = 100000L. ci poate fi specificata ¸si ulterior intr-un constructor. // Eroare la compilare ! } } . public String s = "abcd". // Eroare la compilare ! Prin conventie..14 .141. private Point p = new Point(10. final double PI = 3. Test() { MAX = 100. } Modificatori: • static Prezenta lui declara ca o variabila este variabila de clasa si nu de instanta. protected. dupa care ea nu va mai putea fi modificata. numele variabilelor finale se scriu cu litere mari. // Corect MAX = 200. Variabilele declarate in cadrul unei metode sunt locale metodei respective. .. final. in sensul ca valoarea unei variabile nu trebuie specificata neaparat la declararea ei (ca in exemplul de mai sus). o variabila se declara astfel: [modificatori] Tip numeVariabila [ = valoareInitiala ]. static int variabilaClasa. Declararea unei variabile presupune specificarea urm˘atoarelor lucruri: • numele variabilei • tipul de date al acesteia • nivelul de acces la acea variabila din alte clase • daca este constanta sau nu • daca este variabila de instanta sau de clasa • alti modificatori Generic. 10).

} class StudentInformatica extends Student { float calcMedie(float note[]. Intrucat Java este un limbaj de programare complet orientat-obiect. } . o metoda se declara astfel: [modificatori] TipReturnat numeMetoda ( [argumente] ) [throws TipExceptie1. indiferent de facultatea la care sunt. } }// Eroare la compilare ! 27 . synchronized.. . De exemplu...00. O metoda abstracta este o metoda care nu are implementare si trebuie obligatoriu sa faca parte dintr-o clasa abstracta.3 Implementarea metodelor 2.1 Declararea metodelor Metodele sunt responsabile cu descrierea comportamentului unui obiect. Acest lucru este util daca respectiva metoda are o implementare care nu trebuie schimbata sub nici o forma in subclasele ei.3.. void metodaInstanta(). studentilor unei universitati trebuie sa li se calculeze media finala. class Student { . metodele se pot gasi doar in cadrul claselor. native. abstract Permite declararea metodelor abstracte. in functie de notele obtinute la examene. private ( • unul din cuvintele rezervate: static. final float calcMedie(float note[].. Generic. final. float ponderi[]) { return 10.. protected. TipExceptie2. in aceeasi maniera. Modificatorii care pot fi specificati pentru o metoda: static Prezenta lui declara ca o metoda este de clasa si nu de instanta. fiind critica pentru consistent starii unui obiect.2. float ponderi[]) { . final Specifica faptul ca acea metoda nu mai poate fi supradefinita in subclasele clasei in care ea este definita ca fiind finala.. abstract..] { // Corpul metodei } unde un modificator poate fi : • un specificator de acces : public. static void metodaClasa().

Apelul metodelor Apelul unei metode definita intr-o clasa de obiecte se realizeaza in mai multe moduri: .length.println("]").out.creareTablou(1.prin crearea si utilizarea unei instante a clasei in care a fost definita metoda sau a unei subclase a clasei respective (ca regula generala de invocare a unei metode). Acesta preia doua numere naturale (o limita inferioara si una superioara) si creaza un tablou unidimensional care contine toate numerele naturale aflate intre cele doua limite. return tabl.out.inf) +1]. i < tablou.java si ClasaTablou2.print(tablou[i] + " "). ). in stanga acestuia punandu-se numele clasei in care a fost definita. ).println("]").print("Tabloul: [ "). int sup) { int [] tabl = new int[(sup . for (int i = 0. i < tablou. i < tabl.length.out.out. System. deoarece metoda este definita si apelata in aceeasi clasa. i++) System.out. System. System. in cazul in care clasa in care este apelata metoda este aceeasi cu clasa in care a fost definita. inclusiv aceste limite. iar in dreapa acestuia punandu-se numele metodei. iar in dreapta acestuia punandu-se numele metodei.prin folosirea operatorului punct ( . int sup) { int [] tabl = new int[(sup . } public static void main(String args[]) { ClasaTablou1 unTablou = new ClasaTablou1(). for (int i = 0 .prin simpla folosire a numelui sau. Varianta de apel a unei metode prin crearea si utilizarea unei instante a clasei in care a fost definita metoda. in acest caz se foloseste operatorul punct ( .inf) +1].print(tablou[i] + " "). aceasta modalitate este folosita numai daca metoda este definita ca metoda de clasa. i++) tabl[i] = inf++.} } Varianta de apel a unei metode prin simpla folosire a numelui metodei. public class ClasaTablou2 { static int [] creareTablou(int inf. } public static void main(String args[]) { int [] tablou = creareTablou(1.java) prezinta un exemplu de creare a unei clase care defineste o metoda numita creareTablou. . in stinga acestuia punandu-se numele instantei. fie numai metode de clasa. aceasta modalitate este folosita daca atat metoda apelanta cat si metoda apelata sunt fie numai metode de instanta. Totusi metoda creareTablou trebuie sa fie declarata ca metoda de clasa (modificatorul static) pentru a putea fi apelata dintr-o alta metoda de clasa. Programele urmatoare (ClasaTablou1.length. int [] tablou = unTablou.print("Tabloul: [ ").10). System.out. i < tabl. for (int i = 0. . .10). return tabl. public class ClasaTablou1 { int [] creareTablou(int inf.length. for (int i = 0 . i++) System. i++) tabl[i] = inf++.

Modificatorii de acces (vizibilitate) ai metodelor unei clase In Java exista trei modificatori de vizibilitate ai variabilelor unei clase: . 29 . aceste metode.modificatorul public.modificatorul private. Metodele de clasa sunt disponibile oricarei instante a clasei. definite intr-o clasa. Modificatorul protected face ca metoda respectiva sa fie accesibila in orice clasa din pachetul careia ii apartine clasa in care a fost definita. Metode de clasa Dupa cum stim deja. Modificatorul public face ca metoda respectiva sa fie accesibila oriunde este accesibila clasa din care face parte metoda.3 Domeniul de vizibilitate (acces) al metodelor unei clase. Metodele de instanta sunt aplicate unui anume obiect. Astfel de metode se numesc metode ale instantelor clasei. Pentru a fi apelate. Majoritatea metodelor definite intr-o clasa sunt metode de instanta. cauta mai sus in ierarhia de clase pana cand gaseste o definitie. In mod similar exista si metode de clasa sau metode statice.3.3.2 Metode de instanta si metode de clasa Metode de instanta Ca regula generala. . Modificatorul private face ca metoda respectiva sa fie accesibila doar in interiorul clasei in care a fost definita. Atunci cand se apeleaza metoda unui obiect. Modificatori de acces O metoda este accesibila (apelabila) daca este definita in clasa din care este apelata sau intr-una din subclasele acesteia. In acelasi timp. este nevoie sa avem drepturile de acces necesare (date de modificatorii de acces).} } 2. In acelasi timp pentru a “vedea” o metoda si pentru a o putea apela. Daca nu o gaseste. Aceasta se datoreaza faptului ca metoda lucreaza cu o serie de variabile ale clasei care sunt memorate in interiorul instantei si care au valori diferite in instante diferite (numite variabile de instanta). Aceste variabile pot fi accesate fara a avea nevoie de o instanta a clasei in care au fost declarate. . nu au nevoie sa fie creata o instanta a clasei respective sau a subclasei derivata din clasa respectiva.modificatorul protected. chiar daca ele apartin altor pachete. 2. nu unei clase intregi. metoda este accesibila in toate subclasele clasei date. Java cauta definitia metodei respective in clasa obiectului. o metoda definita intr-o clasa se poate apela prin crearea unei instante a clasei respective sau a unei subclase a clasei respective. exista si un alt tip de variabile si anume variabilele de clasa sau variabilele statice care sunt comune tuturor instantelor clasei respective.

getRaza()). accesul la aceasta variabila (pentru examinare si modificare) se face numai prin intermediul metodelor setRaza si getRaza care sunt publice. final) si apoi semnatura metodei. numele fisierului trebuie sa fie identic cu numele clasei publice. In clasa Cerc variabila de instanta este raza care este vizibila numai in clasa in care a fost declarata (are modificatorul private).x. Metoda poate folosi variabilele de instanta ale obiectului curent sau poate transmite obiectul curent ca parametru unei alte metode. urmeaza apoi modificatorii care determina felul metodei (static.resetRaza(this). class Cerc { private double raza. System.PI * raza. dar nu este accesibila in subclasele clasei date daca acestea apartin altor pachete. ne putem referi atat la variabilele de instanta.out. abstract. precum si al metodelor de instanta. definita in clasa curenta si // transmite obiectul curent return this. adica obiectul a carei metoda a fost apelata.setRaza(10). altfel compilarea nu se va face cu succes. cerculMeu.java) ilustreaza modul de folosire al variabilelor de instanata. } public double arie() { return Math. } } public class TestCerc { public static void main(String[] args) { Cerc cerculMeu = new Cerc(). // variabila de instanta x pentru acest obiect this. System. Nota: Modificatorii de acces (public. // returneaza obiectul curent In cele mai multe cazuri nu este nevoie sa se foloseasca explicit cuvantul-cheie this.println("Lungimea=" + cerculMeu.arie()). // apeleaza metoda resetRaza.PI * raza * raza. De exemplu. Iata cateva exemple de folosire a cuvantului this: t = this. cat si la apelurile de metode . } public double lungime() { return 2 * Math. private) sunt plasati primii in definitia metodei. } } Observatie: Deoarece fisierul-sursa TestCerc. Intr-un fisier-sursa nu se poate defini decat o singura clasa publica. Urmatorul program (TestCerc.out.lungime()). O metoda friendly este accesibila in pachetul din care face parte clasa in interiorul careia a fost definita. De aceea. protected.out. Referinta this Cuvantul-cheie this se refera la obiectul curent. public void setRaza(double r) { raza = r.java contine o clasa publica.println("Aria=" + cerculMeu. atunci metoda respectiva devine package-friendly. TestCerc. deoarece este presupus. } public double getRaza() { return raza.Daca pentru o metoda a unei clase nu se precizeaza nici un modificator de acces din cei descrisi mai sus.println("Raza=" + cerculMeu. System.

Va aparea eroare la compilare deoarece metoda suprascrisa f() din clasa C2 intoarce un tip diferit de void. C. int f(int x){ super. Aceste aspecte au fost explicate la paragraful referitor la domeniul de vizibilitate al variabilelor clasei. Va aparea eroare la compilare deoarece in clasa C2 s-a suprascris gresit atributul x din clasa C1. Nota: Deoarece this este o referinta a instantei curente a clasei. D.x=x. obiect.definite in clasa curenta prin simpla folosire a numelui lor.} float getX_C2(){ return x. Metodele de clasa. System.3 Ce putet i spune despre urmatorul program Java? public class Test{ public static void main(String []args){ C1 obiect =new C1().f(4). D. Programul este corect si va afisa la executie 5 4.f((int)x).getX_C2() + " "). relatia de mostenire dintre clase. // variabila de instanta x pentru acest obiect resetRaza(this). comportamentul obiectelor pe care le instantiaza. De aceea. primele doua exemple se pot rescrie astfel: t = x. declarate cu modificatorul static.0 4. } int getX_C1(){ Return x.print(obiect. a obiectului curent.0f.3). o metoda prin care poate fi accesat de toate tipurile din Java sau de tipuri mostenite din tipul care contine membrul in discutie.}} Class C2 extens C1{ float x=5. Teste de control 2.out. care trebuie sa fi identic cu numele clasei. void f(int x){ this. trebuie sa se foloseasca doar in corpul unei definitii de metoda de instanta. 31 .}} A.getX_C1()). C.1 Declararea constructorilor trebuie sa tina cont de: A. deoarece this este implicit folosit de aceste referinte.}} public class Test{ public static void main(String []args){ C2 obiect = new C2(). System. 2. // apeleaza metoda resetRaza.out. parametrii cu acelasi nume ca cel al unei variabile de instanta. B.2 Ce puteti spune despre urmatorul program Java? class C1{ int x=1.f(4. B. numele constructorului. nu pot folosi this. obiect. definita in clasa curenta Nu se omite cuvantul-cheie this daca in domeniul de vizibilitate al obiectului curent au fost definite variabile locale cu acelasi nume ca cel al unei variabile de instanta sau au fost transmisi unei metode.println(obiect. Programul este corect si va afisa la executie 4. 2.

System. final int yy){ int a=xx+yy. System. Va aparea eroare la compilare deoarece in metoda g() nu putem accesa variabila locala a din metoda f().0 4.4 Ce putet»i spune despre urm¸atorul program Java? class C1{ int x=1. } } Class C2 extens C1{ float x=5.out. Va aparea eroare la compilare. Programul este correct si va afisa la executie 4.out. .print(obiect. } int getX_C1(){ Return x. int f(int x){ super. D.f(4).out. Va aparea eroare la compilare deoarece nu se creeaza in clasa Test un obiect de tip C1. System. B.getX_C2() + " "). C. Va aparea eroare la compilare deoarece metoda suprascrisa f() din clasa C2 intoarce un tip diferit de void. b=3.println(obiect.f((int)x).}} A. final int b=xx-yy.0f. obiect2.}} class C1{ public void f(int xx.x=x. class C2{ public void g(){ System. deoarece clasa C2 nu poate fi defnita in metoda f() din clasa C1.out.C2 2. } } C2 obiect2 = new C2(). void f(int x){ this. } float getX_C2(){ return x. }} A. Va aparea eroare la compilare deoarece in clasa C2 s-a suprascris gresit atributul x din clasa C1. B. b= "+b).getX_C1()).g(). D. Programul este corect si va afisa la executie 5 4.print(". Programul este corect si va afisa la executie a=4.print("a= "+a). obiect. C. } } public class Subiect9{ public static void main(String []args){ C2 obiect = new C2().

. Polimorfismul in Java Obiective: . Mostenirea este un mecanism care permite unei clase sa mosteneasca atributele si comportamentul unei alte clase cu care este inrudita. controlul accesului si mostenirea. superclase si subclase. iar noua clasa de obiecte se va numi subclasa a clasei din care deriva.Capitolul 3 Extinderea claselor. din care provine). operatia de definire a unei noi clase de obiecte pe baza uneia deja existente se numeste derivare. ierarhie de clase. a polimorfismului. metode si clase abstracte.exemplu de folosire a mostenirii.1Mostenirea . prin mostenire o clasa noua dobandeste toate atributele si comportamentul unei clase existente (clasa originala). Practic. 33 . Din acest motiv. . Uneori. sintaxa pentru derivarea unei clase dintr-o superclasa. De exemplu. Intr-o relatie de tip ESTE-UN. Clasa originala (mai generala) se va numi superclasa a noii clase. redefinirea (override) metodelor. 3.polimorfism: caracteristicile polimorfismului. a claselor si metodelor finale si abstracte. metode-constructor pentru clase derivate si cuvantul-cheie super. Mostenirea este mecanismul fundamental pentru refolosirea codului. De exemplu. spunem despre o clasa nou creata ca ESTE-O variatiune a unei clase existente (originala.concept fundamental al programarii orientata obiect Conceptul de mostenire este folosit in Java la organizarea claselor si a comportamentului acestora. in loc de derivare se foloseste termenul de extindere. Termenul vine de la faptul ca o subclasa isi extinde superclasa cu noi variabile si metode. legarea statica si legarea dinamica. Mostenirea modeleaza relatii de tipul ESTE-UN (sau ESTE-O). clasa Object. Aceasta relatie nu este o relatie de mostenire. Observatie importanta: Un alt tip de relatie intre obiecte este relatia ARE-UN sau ESTECOMPUS-DIN. mostenire simpla si multipla.metode si clase finale. putem extinde clasa Masina la MasinaStraina (pentru care se plateste vama) si MasinaAutohtona (pentru care nu se plateste vama) etc. Datorita relatiilor de mostenire clasele de obiecte sunt organizate intr-o ierarhie bine precizata. De exemplu. Masina ESTE-UN Vehicul. . Masina ARE-UN volan. In cadrul ierarhiei claselor de obiecte.mostenire: derivare. supraincarcarea (overloading) metodelor. noua clasa poate fi creata prin simpla specificare a diferentelor fata de clasa originala din care provine.

D si E sunt subclase ale clasei B. Aceste concepte generale devin din ce in ce mai concrete. In cadrul ierarhiei claselor de obiecte. mai particularizate. noua clasa se integreaza corect in ierarhia claselor Java. Observatie importanta: Un alt tip de relatie intre obiecte este relatia ARE-UN sau ESTECOMPUS-DIN. Datorita relatiilor de mostenire clasele de obiecte sunt organizate intr-o ierarhie bine precizata. . iar noua clasa de obiecte se va numi subclasa a clasei din care deriva. care defineste atributele si comportamentul (metodele) mostenite de toate clasele din biblioteca de clase Java. Object reprezinta clasa initiala. In varful ierarhiei de clase Java se afla clasa Object. atunci ea mosteneste direct clasa Object. Clasa B este subclasa a clasei A. Java presupune ca noua clasa mosteneste direct clasa Object. De exemplu. care se creaza. ci este de agregare. sa-i spunem clasa de obiecte generice. daca se defineste o clasa care nu specifica o superclasa. Cand clasa nou creata defineste un comportament complet nou si nu este o subclasa a unei alte clase. Clasa originala (mai generala) se va numi superclasa a noii clase. Componentele care pot fi agregate devin simple campuri (atribute) de tip private ale clasei nou create. o data cu “coborarea” spre subclasele de pe nivelele de mai jos in ierarhie. Aceasta relatie nu este o relatie de mostenire. De asemenea. De exemplu. se poate construi o ierarhie Om care deriva direct din clasa generica Object si are doua clase derivate: clasa barbatilor (Barbat) si clasa femeilor (Femeie). foarte generale.ci este de agregare. Uneori. operatia de definire a unei noi clase de obiecte pe baza uneia deja existente se numeste derivare. putem extinde clasa Masina la MasinaStraina (pentru care se plateste vama) si MasinaAutohtona (pentru care nu se plateste vama) etc. Termenul vine de la faptul ca o subclasa isi extinde superclasa cu noi variabile si metode. Componentele care pot fi agregate devin simple campuri (atribute) de tip private ale clasei nou create. D si E. Astfel. Clasele C. iar toate clasele de obiecte. sunt derivate din aceasta unica superclasa. Clasele definite in exemplele de pana acum au mostenit direct clasa Object. in loc de derivare se foloseste termenul de extindere. Clasa B este superclasa pentru clasele C. Masina ARE-UN volan. Clasa A este superclasa a clasei B. In varful ierarhiei se definesc concepte (clase) abstracte. De exemplu.

care permit folosirea repetata a acestora pentru toate clasele aflate pe nivelele mai joase din ierarhie. superclase sau nu ale clasei Om. subclasele acestora si asa mai departe.clasa derivata poate sa adauge noi atribute si metode si poate modifica semnificatia metodelor mostenite (prin polimorfism. care trebuie duplicat pe diferite “ramuri” ale ierarhiei de clase (nu pe aceeasi ramura a ierarhiei). ceea ce inseamna ca o variabila referinta de tipul superclasei poate referi un obiect al clasei derivate. Acest lucru complica semnificativ definitia clasei si a codului necesar acesteia. Mostenirea simpla poate fi restrictiva. despre care vom vorbi mai incolo in acesta lectie). omul poate fi privit ca un mamifer care naste pui vii sau poate fi privit ca un obiect spatio-temporal care are propria lui forma si pozitie in functie de timp. Dar. Interfetele vor fi prezentate in totalitate intr-o lectie viitoare.superclasa nu este afectata in nici un fel de modificarile aduse in clasele derivate.2 Caracteristicile unei ierarhi de clase Organizarea unei aplicatii informatice intr-o ierarhie de clase presupune o planificare atenta. 3. Sintaxa folosita pentru a deriva o clasa noua dintr-o superclasa 35 . deoarece fiecare clasa de obiecte Java nou creata poate fi derivata dintr-o singura superclasa (poate avea o singura superclasa). dar nu si invers.o clasa derivata este compatibila ca tip cu superclasa. deoarece acestea primesc noile informatii prin mostenire. clasele derivate dintr-o superclasa nu sunt compatibile ca tip. De alegerea claselor si de proiectarea arborelui acestor clase depinde eficienta si flexibilitatea aplicatiei. Mostenirea multipla inseamna ca o clasa nou creata pot fi derivata din doua sau mai multe superclase. nu trebuie modificat si recompilat nimic in clasele aflate pe nivelurile inferioare. Declaratiile de metode si atribute comune mai multor clase de obiecte care nu sunt mostenite de la superclasele lor poarta denumirea de interfeta. Proiectarea arborelui de clase de obiecte necesare rezolvarii unei anumite probleme este un talent pe care fiecare programator trebuie sa si-l descopere si sa si-l cultive cu atentie. Aceasta inseamna ca trebuie sa dam definitii de metode despre ce inseamna faptul ca un obiect poate fi privit ca un mamifer sau ca un obiect spatio-temporal. . toate aceste caracteristici vor fi mostenite si de clasele derivate din clasa Om. Java foloseste interfetele. Mostenire multipla (multiple inferitance) ofera mijloace de creare a unor clase care cuprind aproape orice comportament imaginabil. si anume clasa barbatilor si cea a femeilor.modificarile efectuate in superclasa se reflecta automat in toate subclasele ei. Pentru rezolvarea problemei mostenirii multiple. Principalele caracteristici ale unei ierarhie de clase sunt: . mostenind variabilele si metodele combinate din toate aceste superclase. . 3.Daca la nivelul clasei de obiecte Om am definit forma bipeda a acestuia si capacitatea de a vorbi si de a intelege.atributele si metodele comune mai multor clase pot fi definite in superclase. mai ales atunci cand exista un comportament similar.3 Mostenirea simpla in Java Forma de mostenire folosita in Java este denumita mostenire simpla (single inheritance). Putem sa gasim o multime de clase de obiecte ale caror instane pot fi privite ca obiecte spatiotemporale dar care sa nu aiba mare lucu in comun cu omul (de exemplu clasa Minge). . . aceste definitii de metode sunt comune nu numai clasei de obiecte Om dar si altor clase de obiecte derivate sau nu din clasa Om. Fiecare din aceste clase de obiecte derivate isi vor defini propriile lor proprietati si operatii pentru a descrie diferenta dintre ele si clasa originala. De exemplu.

astfel: [<modificatori_acces>] [<modificatori_clasa>] class <nume_subclasa> extends <nume_superclasa> {<corpul_clasei} unde: . modificatorul de acces poate fi: public.java prezentat in capitolul 2. Folosirea metodelor “accesori” si “modificatori” este foarte raspandita in programarea orientata obiect. cum ar fi setRaza() din programul TestCerc. sa redefineasca metode ale superclasei sau sa adauge noi metode. Fiecare clasa derivata este o clasa complet noua. . folosind operatorul “punct” sau direct numele membrului) in clasa derivata.specifica numele clasei derivate dintr-o superclasa. apoi .specifica numele unei superclase din care deriva subclasa.<modificatori_clasa> . Daca nu se defineste nici un constructor. De asemenea.variabilele clasei si metodele care lucreaza cu acestea. protejata sau prietenoasa) din superclasa.va apela automat constructorul implicit (fara parametrii) al superclasei (aflata pe nivelul imediat superior) pentru membrii care au fost mosteniti. Clasa derivata poate apoi sa adauge noi atribute. Acest constructor implicit al clasei derivate: . Orice metoda neprivata (adica publica. final. De asemenea.O clasa derivata (numita si subclasa) mosteneste toate atributele (variabilele de instanta si de clasa) superclasei din care provine. cu exceptia constructorilor. membrii de tip private ai superclasei sunt mosteniti. este mostenita nemodificat. Metode-constructor pentru clase derivate si cuvantul-cheie super Metodele-constructor nu se mostenesc. .<nume_subclasa> . protected. <nume_superclasa> . dar acestia nu sunt accesibili in mod direct (adica.<modificatori_acces> . “modificatori”. Metodele speciale care examineaza si modifica valoarea fiecarui atribut de tip private sunt denumite “accesori” si. Observatii: 1. Fiecare clasa derivata trebuie sa isi defineasca propriile metode-constructor. modificatorul clasei poate fi: abstract. Metoda poate fi apoi apelata ca si cum ar face parte din clasa derivata. evitand folosirea lui necorespunzatoare.specifica tipul subclasei definite.java prezentat in capitolul 2. care nu este redefinita (suprascrisa) in clasa derivata. . Java va genera un constructor implicit (fara parametri). public sau fara modificator de acces. 2.<corpul_clasei> . Controlul accesului si mostenirea Ca regula generala. respectiv. cum ar fi getRaza() din programul TestCerc. se foloseste conventia ca numele metodelor “modificator” sa inceapa cu set. Se foloseste conventia ca numele metodelor “accesor” sa inceapa cu get. Pentru a declara o clasa derivata se foloseste clauza extends.specifica domeniul de vizibilitate (folosire sau acces) al subclasei. adaugate sau redefinite in subclasa . ci prin intermediul altor metode publice mostenite de la superclasa care fac posibil accesul. toti membrii de tip public ai superclasei devin membrii de tip public ai clasei derivate. Clasa derivata contine atribute si metode suplimentare (fata de cele mostenite din superclasa) care pot fi declarate: private. Acest mod de abordare mareste gradul de reutilizare a codului.

- va aplica initializarea implicita pentru atributele adaugate in clasa derivata (adica 0/false pentru tipurile primitive numerice/booleene si null pentru tipurile referinta). Asadar, construirea unui obiect al unei clase derivate are loc prin construirea prealabila a portiunii mostenite (constructorul clasei derivate apeleaza automat constructorul superclasei aflata pe nivelul imediat superior). Acest lucu este normal, deoarece mecanismul incapsularii afirma ca partea mostenita este un “intreg”, iar constructorul superclasei ne spune cum sa initializam acest “intreg”. Metodele-constructor ale superclasei pot fi apelate explicit in clasa derivata prin metoda super(). Metoda super poate sa apara doar in prima linie dintr-o metoda-constructor. Apelul unei metode-constructor a superclasei dintr-o clasa derivata, folosind super se face astfel: super(<arg1>, <arg2>, <arg3>, …) unde: - <arg1>, <arg2>, <arg3>, … - specifica parametrii metodei-constructor a superclasei. De exemplu, sa presupunem ca o superclasa (ClasaSuper) are un constructor cu doi parametri de tip int. Constructorul clasei derivate va avea, in general, forma: public class ClasaDerivata extends ClasaSuper { public ClasaDerivata(int x, int y); { super(x, y); // alte instructiuni } … } Observatie: Daca in superclasa este definit explicit cel putin un constructor, atunci trebuie apelat explicit (prin super) constructorul superclasei respective din interiorul constructorului clasei derivate. Altfel se obtine eroare de compilare.

3.4 Supraincarcarea (overloading) metodelor. Redefinirea (override) metodelor
Supraincarcarea metodelor permite existenta in interiorul aceleiasi clase a mai multor metode cu acelasi nume, dar cu lista diferita de parametrii (ca numar si tip), deci cu semnatura diferita. Supraincarcarea metodelor este permisa si daca unele dintre metode sunt definite intr-o superclasa si altele in clasele derivate din superclasa respectiva. De exemplu, putem avea o metoda int max(int a, int b) si o metoda int max(int a, int b, int c), ambele in cadrul aceleasi clase sau putem defini prima metoda in cadrul unei superclase si cea de a doua metoda in cadrul unei clase derivate din superclasa. Atunci cand se face un apel al unei metode supraincarcate, compilatorul alege definitia de metoda examinand lista parametrilor de apel (adica, semnatura). Redefinirea (suprascriere) metodelor permite existenta in interiorul claselor derivate dintr-o superclasa a mai multor metode cu acelasi nume, tip de rezultat si aceeasi lista de parametrii, deci cu aceeasi semnatura. Atunci cand se face un apel al unei metode redefinite, compilatorul foloseste definitia metodei care este gasita prima (incepand din partea de jos a ierarhiei de clase si mergand in sus). Programul urmator (AfisareSubClasa.java) prezinta o clasa ce contine o metoda afisareDate(), care afiseaza numele clasei si valorile variabilelor de instanta. De asemenea, in acelasi fisier-sursa este inclusa si clasa denumita AfisareSubClasa derivata din clasa AfisareClasa. A fost creat un obiect de
37

tip AfisareSubClasa si a fost apelata metoda afisareDate(). Deoarece clasa AfisareSubClasa nu defineste aceasta metoda, Java o cauta in superclasele clasei AfisareSubClasa, incepand cu superclasa AfisareClasa, unde gaseste metoda afisareDate() si o executa. class AfisareClasa { int x = 0; int y = 1; void afisareDate() { System.out.println("x este " + x + ", y este " + y); System.out.println("Sunt un obiect al clasei " + this.getClass().getName()); } } class AfisareSubClasa extends AfisareClasa { int z = 3; public static void main(String [] args) { AfisareSubClasa ob = new AfisareSubClasa(); ob.afisareDate(); } } Rezultatul programului este: x este 0, y este 1 Sunt un obiect al clasei AfisareSubClasa Deoarece metoda afisareDate() a superclasei AfisareClasa nu afiseaza si variabila de instanta z specifica subclasei AfisareSubClasa, metoda afisareDate() va fi redefinita (suprascrisa) in interiorul subclasei. Iata noul program (AfisareSubClasa.java): class AfisareClasa { int x = 0; int y = 1; void afisareDate() { System.out.println("x este " + x + ", y este " + y); System.out.println("Sunt un obiect al clasei " + this.getClass().getName()); } } class AfisareSubClasa extends AfisareClasa { int z = 3; void afisareDate() { System.out.println("x este " + x + ", y este " + y + ", z este " + z); System.out.println("Sunt un obiect al clasei " + this.getClass().getName()); } public static void main(String [] args) { AfisareSubClasa ob = new AfisareSubClasa(); ob.afisareDate();} } Rezultatul programului este: x este 0, y este 1, z este 3 Sunt un obiect al clasei AfisareSubClasa Nota: Apelul de metoda: this.getClass().getName()); este folosit pentru aflarea numelui clasei din care face parte un obiect, in cazul de fata obiectul curent. Vom reveni cu amanunte in ce priveste obtinerea de informatii despre o clasa. Redefinirea partiala a unei metode

Redefinirea partiala inseamna ca metoda din clasa derivata nu redefineste complet metoda cu aceeasi semnatura din superclasa, ci extinde operatiile pe care aceasta le realizeaza. Cu alte cuvinte, metoda din clasa derivata face ceva in plus fata de cea originala din superclasa. Pentru a apela metoda din superclasa in interiorul metodei din clasa derivata se foloseste referinta super. Urmatorul program (AfisareSubClasa1.java) ilustreaza modul de redefinire partiala a metodei afisareDate() din subclasa AfisareSubClasa1 si apelul in cadrul acesteia a metodei afisareDate() din superclasa AfisareClasa. class AfisareClasa { int x = 0; int y = 1; void afisareDate() { System.out.println("Sunt un obiect al clasei " + this.getClass().getName()); System.out.println("x este " + x); System.out.println("y este " + y); } } class AfisareSubClasa1 extends AfisareClasa { int z = 3; void afisareDate() { super.afisareDate(); System.out.println("z este " + z); } public static void main(String [] args) { AfisareSubClasa1 ob = new AfisareSubClasa1(); ob.afisareDate(); } } Accesul la metodele din superclasa si redefinirea metodelor in clasele derivate Atunci cand se creaza o clasa derivata si se redefineste (suprascrie) o metoda declarata intr-o superclasa, trebuie sa se ia in considerare tipul de acces dat pentru metoda originala. Astfel, in cazul metodelor mostenite, pentru care se doreste redefinirea (suprascrierea) in clasa derivata se impun urmatoarele reguli: - metodele de tip public dintr-o superclasa trebuie sa fie, de asemenea, de tip public in toate clasele derivate; ele nu pot fi redefinite de tip private in clasele derivate; - metodele de tip protected dintr-o superclasa pot fi de tip protected sau de tip public in clasele derivate; ele nu pot fi redefinite de tip private in clasele derivate; - metodele de tip private dintr-o superclasa nu pot fi redefinite (suprascrise) in clasele derivate.

3.5

Implementarea polimorfismului

Polimorfismul reprezinta capacitatea unui obiect de a aparea sub diferite forme. De exemplu, in lumea reala, apa apare sub forma solida, sub forma lichida sau sub forma gazoasa. In Java, polimorfismul inseamna ca o singura variabila referinta x de tipul unei superclase poate fi folosita pentru a construi diferite obiecte (instante) ale claselor derivate, direct sau indirect din acea superclasa, in momente diferite ale executiei unui program. Cand variabila referinta x este folosita pentru a apela o metoda a unui obiect apartinand unei clase derivate, metoda adecvata care va fi
39

selectata depinde de tipul obiectului pe care variabila referinta x il indica in acel moment. Se spune ca variabila referinta este polimorfica. De exemplu, sa presupunem ca s-au definit clasele: AnimalDeCasa, Pisica, Caine. Se doreste sa se afiseze la ecran (programul Polimorfism.java) caracteristicile principale ale claselor Pisica si Caine, atunci cand instantele lor sunt infometate. class AnimalDeCasa { private boolean stareSuparare; public boolean flamand; protected void hranesc() { System.out.println("Nu se cunoaste"); } public void caracteristici() { System.out.println("Caracteristici necunoscute"); } public boolean getStare() { return stareSuparare; } public void setStare(boolean stare) { stareSuparare = stare; } } class Pisica extends AnimalDeCasa { public void caracteristici() { String starePisica; if (getStare() == true) starePisica = "miauna"; else starePisica = "nu miauna"; if (flamand == true) System.out.println("Pisica " + starePisica + ". Este flamanda."); else System.out.println("Pisica " + starePisica + ". Este satula."); } public void hranesc() { if (flamand==true) {System.out.println("Pisica mananca lapte."); flamand = false; setStare(false);} else System.out.println("Pisica a mancat deja.");} } class Caine extends AnimalDeCasa { public void caracteristici()

System.flamand = true. respectiv. intr-o superclasa numita AnimalDeCasa si in doua clase derivate numite Pisica si Caine care extind clasa AnimalDeCasa. a.out. a.out.println("Cainele mananca oase. a. a.hranesc().hranesc()."). tip valoare returnata si numar si tip parametrii) si trei metode cu numele hranesc() care au.out.println("Cainele " + stareCaine + ".println("Caracteristicile celui de al doilea animal de casa: "). a. a.caracteristici()."). flamand = false. setStare(false).caracteristici(). a.println("Cainele a mancat deja.{ String stareCaine.out.caracteristici(). a. de asemenea.setStare(true).println("Caracteristicile primului animal de casa: ").caracteristici(). a.out.} } public class Polimorfism { public static void main(String args[]) { AnimalDeCasa a = new Pisica().println("Cainele " + stareCaine + ". if (getStare() == true) stareCaine = "latra". aceeasi semnatura.} else System. Este satul. } public void hranesc() { if (flamand==true) {System. if (flamand == true) System."). a. Este flamand. a = new Caine(). Dar.caracteristici().").hranesc(). hranesc() din superclasa. else System.out.setStare(true). Spunem ca metodele caracteristici() si hranesc() din clasele derivate redefinesc (override) metodea caracteristici() si.flamand = true. Sa analizam acum instructiunea urmatoare: 41 . a. } } Ceeace este specific acestui program este ca el contine trei metode cu numele caracteristici() care au aceeasi semnatura (nume. else stareCaine = "nu latra". a. aceste metode se afla in clase diferite si anume. System.

pe de o parte. . 3. mostenirea permite tratarea unui obiect ca fiind de tipul propriu sau de tipul de baza (din care este derivat tipul propriu). Termenul este specific programarii orientate pe obiecte. In procesul de organizare a unei ierarhi de clase. dar similare (adica derivate din aceeasi superclasa: AnimalDeCasa). Acesta clasa se numeste clasa abstracta si este creata folosind modificatorul abstract. pentru ca toate legaturile se fac in mod static. uneori. Intr-o ierarhie de clase. polimorfismul permite unui tip de obiect sa exprime distinctia fata de un alt tip de obiect similar. doar ca loc de pastrare a unor metode si atribute pe care le folosesc in comun subclasele sale. O metoda abstracta este declarata cu modificatorul abstract. clasa Pisica si clasa Caine au doua atribute (stareSuparare si flamand) si doua metode setStare() si getStare() mostenite de la superclasa AnimalDeCasa din care deriva. In cazul din exemplul prezentat. in faza de compilare) spunem ca este vorba despre o legare statica(early binding). atata timp cat amandoua sunt derivate din aceeasi superclasa. Polimorfisul apare doar atunci cand are loc legarea tarzie a metodelor. Sa analizam si instructiunea: a = new Caine(). Cand legarea are loc inainte de rularea programului respectiv (adica. O clasa aflata ierarhic deasupra altor clase poate defini doar atributele si comportamentul comune celor aflate sub ea pe ramura respectiva a ierarhiei. Aceasta caracteristica permite mai multor tipuri (derivate din acelasi tip de baza) sa fie tratate ca si cum ar fi un singur tip.pe de alta parte. cu atat definirea sa este mai abstracta. se poate descoperi. In concluzie: .AnimalDeCasa a = new Pisica(). Variabila referinta a care este de tipul AnimalDeCasa desemneaza un obiect de tipul Pisica. Variabila a refera (la momente diferite de timp) obiecte de tipuri diferite.6 Metode si clase abstracte O metoda abstracta este o metoda din superclasa care are sens doar pentru clasele derivate direct din superclasa. cu cat clasa se afla pe un nivel mai inalt. care ESTE-UN AnimalDeCasa prin mostenire. Legarea statica si legarea dinamica Conectarea unui apel de metoda de un anumit corp de metoda poarta numele de legare (binding). spunem ca este vorba despre o legare tarzie (late binding) sau legare dinamica. ceea ce face ca aceeasi secventa de cod sa fie folosita de catre toate aceste tipuri. nu are implementare (nu are corp) ci numai antet. De fapt. metodele caracteristici() si hranesc() din clasa Pisica sau din clasa Caine). In programarea procedurala (vezi limbajul C sau Pascal) notiunea de legare statica nu exista. Cand legarea are loc in faza de executie a programului respectiv. Legarea tarzie permite determinarea in faza de executie a tipului obiectului referit de o variabila referinta si apelarea metodei specifice acestui tip (in exemplul prezentat. in superclasa si care in mod obligatoriu trebuie definita (completata cu corpul ei) in clasele derivate (altfel rezulta eroare de compilare). cate o clasa care nu se instantiaza direct (adica din ea nu se pot crea direct obiecte). . Distinctia este exprimata prin redefinirea (suprascrierea) metodelor care pot fi apelate prin intermediul unei variabile-referinta de tipul superclasei (in exemplul nostru este vorba despre metodele caracteristici() si hranesc()). aceasta serveste.

deriva clasa patratului ca un caz particular de dreptunghi. Ea este invarianta de-a lungul ierarhiei si de aceea a fost declarata cu tipul final. deoarece nu putem furniza nici un calcul implicit al ariei pentru o clasa derivata care nu isi defineste propria metoda de calcul a ariei. afisarea caracteristicilor formelor geometrice concrete (cerc. derivat din FormaGeo. de exemplu tipul formei geometrice. apoi. Astfel. a claselor si metodelor finale si abstracte Un exemplu simplu de clasa abstracta este clasa formelor geometrice. dreptunghi etc). este posibil sa folosim aceasta metoda pentru a compara aria obiectului curent (care poate fi. In consecinta.java) prezinta clasa abstracta FormaGeo. De fapt. Metoda cu numele arie() este o metoda abstracta. cum ar fi: Dreptunghi. inclusiv metodeleconstructor. metoda arie() va fi declarata ca abstracta. Cerc. Patrat. Metoda toString afiseaza numele formei geometrice si aria ei. o instanta a clasei Dreptunghi). deoarece subclasele lor pot avea nevoie sa mosteneasca aceste metode-constructor. calculul ariei unui obiect oarecare (dreptunghi. deoarece FormaGeo este o clasa abstracta. de aceea am declarat-o cu tipul final. Constructorul acestei clase nu va fi apelat niciodata direct. cum ar fi. o instanta a clasei Cerc) cu aria unui obiect de alt tip. definirea ei este invarianta de-a lungul ierarhiei. nu se va putea crea un obiect de tip FormaGeo. Figura de mai jos prezinta ierarhia de clase care rezulta: Clasa FormaGeo poate sa aiba membri care sa fie comuni pentru toate subclasele. de exemplu. Totusi. dreptunghi. deoarece ea poate fi aplicata la fel pentru toate clasele derivate. De asemenea. Variabila rhs poate sa refere orice instanta a unei clase derivate din FormaGeo (de exemplu. Deci. Fisierul-sursa urmator (FormaGeo. 43 . o referinta de tip FormaGeo poate sa refere orice forma concreta derivata.Clasele abstracte pot contine aceleasi tipuri de membri ca o clasa normala. a polimorfismului. Din clasa formelor geometrice pot deriva forme specifice cum ar fi: cerc. ci numai obiecte din clasele derivate. Se poate. Exemplu de folosire a mostenirii. de asemenea. Avem totusi nevoie de constructor. Clasele abstracte pot contine. Metoda maiMic() de comparatie a ariei unui obiect curent de tip FormaGeo cu un alt obiect de tip FormaGeo (preluat prin parametrul rhs) nu este abstracta. metode abstracte. Acesta este un exemplu de folosire a polimorfismului. cerc etc). cum ar fi. clasa poate defini metode care se aplica fiecarui obiect in parte. O clasa care are cel putin o metoda abstracta este o clasa abstracta. Nu se poate declara o metoda abstracta intr-o clasa non-abstracta. care sa fie apelat din clasele derivate pentru a initializa atributul nume de tip private care specifica tipul figurii geometrice. Clasa FormaGeo fiind abstracta nu se poate instantia.

In general. Mai intai. am definit o metoda toString care permite sa afisam un obiect oarecare de un tip derivat din clasa FormaGeo folosind instructiunea System.java).} . cerc * ------------------.Observatie: Vom face cateva precizari asupra folosirii metodei toString() in orice clasa in care se doreste afisarea starii instantelor unei clase. Definirea lor se face distinct in fisiere-sursa separate (Cerc. afisarea starii unui obiect se face utilizand metoda print() din clasa System. Pentru a putea face acest lucru. } final public String toString() { return nume + ". * ------------------. Astfel.arie(). cercuri) de la tastatura.metode publice --------------------* double arie() --> Intoarce aria (abstracta) * boolean maiMic --> Compara doua forme dupa arie * String toString --> Metoda uzuala pentru afisare */ abstract class FormaGeo { private String nume. Dreptunghi si Patrat. Aceasta metoda trebuie sa intoarca o valoare de tip String (reprezentand starea obiectului) care poate fi afisata. avand aria " + arie(). abstract public double arie(). Dreptunghi. } } Pe baza clasei abstracte FormaGeo definite ne propunem sa rezolvam urmatoarea problema: Se citesc N forme geometrice (patrate. } public double arie() { return Math.java. } final public boolean maiMic(FormaGeo rhs) { return arie() < rhs. dreptunghiuri. in cazul nostru. compilatorul Java apeleaza automat toString() pentru fiecare obiect care se afiseaza cu metoda print(). trebuie sa definim subclasele Cerc. trebuie ca in clasa obiectului care se doreste a fi afisat sa existe o metoda cu numele de toString().java si Patrat.out. /* Superclasa abstracta pentru forme FormeGeo * * CONSTRUIREA: nu este permisa.out. public FormaGeo(String numeForma) { nume = numeForma. Practic.PI * raza * raza.println(). /* clasa Cerc * derivata din FormaGeo * CONSTRUCTORI: cu raza ptr. public Cerc(double rad) { super("Cerc"). Sa se afiseze formele geometrice ordonate dupa arie.metode publice --------------------* double arie()-->Implementeaza metoda abstracta din FormaGeo */ public class Cerc extends FormaGeo { private double raza. FormaGeo fiind abstracta. * Constructorul cu un parametru este necesar ptr. raza = rad. clasele * derivate.

} /* clasa Dreptunghi. "Dreptunghi"). referinta la obiecte este apoi stocata in tabloul forme[]. patrat * ------------------. Patrat. 45 . Dreptunghi. Fisierul-sursa (TestForma. double lat) { this(lg. lungime = lg. Patrat) din tipul FormaGeo si returneaza o referinta catre obiectul creat. latura. dreptunghi * ------------------. } public double arie() { return lungime * latime. } } /* clasa Patrat * derivata din Dreptunghi * CONSTRUCTORI: cu latura ptr. Dreptunghi. Dreptunghi. } } Observatie: Clasa Patrat mosteneste de la clasa Dreptunghi metoda arie() si de aceea nu o mai defineste in interiorul ei. Patrat) ci numai referinte catre aceste obiecte.metode publice --------------------* double arie()-->Implementeaza metoda abstracta din FormaGeo */ public class Patrat extends Dreptunghi { public Patrat(double latura) { super(latura. pe baza unor optiuni care precizeaza tipul figurii. creaza un nou obiect de un tip derivat (Cerc. "Patrat"). * derivata din FormaGeo * CONSTRUCTORI: cu lungime si latime ptr.java) care realizeaza ordonarea si punerea in executie a aplicatiei se prezinta in continuare. se foloseste un tablou de tip FormaGeo cu numele forme[] cu o dimensiune citita de la tastatura. String nume) { super(nume). public Dreptunghi(double lg. Sa retinem ca tablou forme[] este un tablou de referinte de tip FormaGeo pentru care se aloca zona de memorie. private double latime. In metoda main().metode publice --------------------* double arie()-->Implementeaza metoda abstracta din FormaGeo */ public class Dreptunghi extends FormaGeo { private double lungime. } Dreptunghi(double lg. Acest tablou nu stocheaza obiecte din clasele derivate ale clasei FormaGeo (de tip Cerc. Metoda citesteForma() citeste de la tastatura atributele obiectelor de tipul Cerc. latime = lat. Pentru rezolvarea problemei ordonarii formelor geometrice dupa aria lor. lat. double lat.

charAt(0)) { case 'c': System.out.println("Sortarea dupa arie: ").out. import java.out. class TestForma { private static BufferedReader in.} //sortare si afisare sortare(forme).readLine()).readLine()).println("Lungimea si latimea " + " dreptunghiului pe linii separate: "). } while (s.parseInt( in. int numForme = Integer. String s. Metoda arie() este apelata prin intermediul metodei maiMic() care la randul ei este apelata in metoda sortare().out. lg = Integer.parseInt(in.println("Raza cercului: "). switch (s. System.readLine(). double lg. public static void main(String[] args) throws IOException { //Citeste numarul de figuri in = new BufferedReader(new InputStreamReader(System. rad = Integer.println(forme[i]). i < numForme. do { s = in.out. case 'd': System. . i < numForme.* .readLine()).out.length() == 0). 'p' sau 'd' pentru a indica forma. System.println("Latura patratului: "). //citeste formele FormaGeo[] forme = new FormaGeo[numForme].parseInt(in.println("Introduceti tipul formei: "). //utilizatorul introduce 'c'. ++i) {forme[i] = citesteForma().parseInt(in. lg = Integer. Functie de datele de intrare. return new Cerc(rad). apoi introduce dimensiunile //in caz de eroare se intoarce un cerc de raza 0 private static FormaGeo citesteForma() throws IOException { double rad. double lat. case 'p': System.in)). ++i) {System. for (int i = 0.io. for (int i = 0.Metoda sortare() este folosita pentru a sorta formele geometrice referite prin tabloul forme[] in functie de aria calculata a fiecarui tip de figura geometrica.} } //creaza un obiect adecvat de tip FormaGeo. return new Patrat(lg).readLine()).print("Numarul de figuri: ").out. System.

a[i] = a[j].length .3893421169302 47 .141592653589793 Dreptunghi. avand aria 452. i++) {for (int j = i+1. avand aria 8. return new Dreptunghi(lg. avand aria 6.0 Patrat.2.maiMic(a[i])) {temp = a[i]. j <= a. avand aria 78.53981633974483 Patrat. a[j] = temp. avand aria 3. for (int i = 0.class pe ecran se afiseaza: Sortarea dupa arie: Cerc.length .} }} } } Dupa executia programului TestForma. j++) {if (a[j]. lat).parseInt(in. avand aria 36. avand aria 314.lat= Integer.0 Cerc. p sau d: ").readLine()). avand aria 100. } } //sortare private static void sortare(FormaGeo [] a) { FormaGeo temp. default: System.1592653589793 Cerc.0 Dreptunghi.0 Cerc. i <= a.err. return new Cerc(0).1.println("Tastati c. avand aria 24.3893421169302 Cerc. avand aria 452.0 Dreptunghi.

1Ce puteti spune despre urmatorul program Java? class C1{ int x=1. } } A. Se foloseste cuvantul cheie abstract. Se foloseste mostenirea multipla. C. 3. Va aparea eroare la compilare deoarece in clasa C2 s-a suprascris gresit atributul x din clasa C1.getX_C2() + " "). O subclasa abstracta nu poate fi instantiata. Va aparea eroare la compilare deoarece metoda suprascrisa f() din clasa C2 intoarce un tip diferit de void. Programul este corect si va afisa la executie 5 4.0f. int f(int x){ super. obiect. void f(int x){ this. si furnizeaza implementari pentru toate acestea.f(4).f((int)x). D.2 O subclasa a unei clase abstracte poate fi instantiata numai daca: A.3 Secventa de cod: class x{ private int x=1. } float getX_C2(){ return x. } } Class C2 extens C1{ float x=5. } int getX_C1(){ Return x.println(obiect. B. .0 4.out. System. } } public class Test{ public static void main(String []args){ C2 obiect = new C2(). C.print(obiect.x=x. D. Programul este correct si va afisa la executie 4.getX_C1()). 3. Suprascrie fiecare metoda declarata abstracta in superclasa sa. System. B.out.Teste de control: 3.

d).x(). void x( ) { super.eroare la compilare: nu se poate defini un atribut si o metoda cu aceelasi nume (x) . b). System.println(x+” “). programul este corect si va afisa 1 2. eroare : nu este corect realizată moştenirea.eroare la compilare: nu se poate defini un atribut cu numele clasei (x) .}} class y extends x{ private int x=2. c).println(x).x(). 49 .out.} public class test { public static void main( ) { y obiect=new y( ).void x( ) { System. obiect.}} Determină: a).out.

interfata Java: crearea interfetelor. dar implementari diferite sau ar putea avea atribute cu acelasi nume. …]] { <corpul interfetei> . De exemplu. implementarea unor interfete multiple. Dificultatea rezolvarii unor astfel de probleme a facut ca Java sa nu permita mostenirea multipla. O clasa implementeaza o anumita interfata daca furnizeaza definitii pentru toate metodele abstracte din cadrul interfetei. Tehnic. <nume_interfata2>][. implementarea unei interfete.implementarea de componente generice: programarea generica. care pot fi combinate in orice clasa pentru a introduce in acea clasa comportamente care nu pot fi mostenite de la superclasa. O interfata Java este o colectie de comportamente abstracte. pot exista in ierarhie clase precum Student si Angajat.Capitolul 4 Obiective: Interfete Java . Din aceste doua clase ar putea fi derivata o clasa cu numele AngajatStudent care sa contina atribute si metode combinate din clasele Student si Angajat. cele doua superclase din care deriveaza subclasa ar putea contine metode care au aceeasi semnatura. derivarea interfetelor. .1 Mostenirea multipla. <nume_interfata3>].2 Crearea si folosirea interfetelor Java Sintaxa de definire a unei interfete este urmatoarea: [<modificatori] interface <nume_interfata> [extends <nume_interfata1> [. 4. interfata Java este cea mai abstracta clasa posibila. Mostenirea multipla poate conduce insa la dificultati de proiectare. De exemplu. Ea consta doar din metode publice abstracte si din atribute statice si finale. Alternativa oferita de Java pentru mostenirea multipla este folosirea interfetelor. O clasa care implementeaza o interfata se comporta ca si cand ar fi extins o clasa abstracta specificata de acea interfata. clase generice. folosirea interfetelor. Interfete In cazul mostenirii multiple o clasa este derivata din doua sau mai multe superclase. 4.

din acest motiv. folosind cuvantul-cheie implements in antetul sau. adica nu se poate crea o instanta a unei interfete. .<nume_interfata1>. Pentru a exemplifica implementarea unei interfete ne vom referi la clasa FormaGeo descrisa in lectia 6.sunt specificati prin cuvintele-cheie public si abstract. 4. public interface Compara { int comparaCu(Compara rhs).defineste implementari pentru toate metodele din interfata. . Implementarea metodei in clasa FormaGeo trebuie sa fie identica cu declaratia din interfata si. } Interfata Compara declara o metoda pe care orice clasa derivata din ea (in declaratia clasei se foloseste cuvantul-cheie implements) trebuie sa o implementeze.contine declaratii de variabile si declaratii de metode (numai antetul acestora). fara corp. metoda comparaCu() are ca parametru un obiect de tip 51 .specifica numele interfetei. . <nume_interfata2>.} unde: . Interfetele. interfetele pot importa interfete sau clase din alte pachete.<nume_interfata> . . Observatii: 1.declara ca implementeaza interfata. este de preferat ca numele interfetei sa respecte aceeasi conventie de numire ca si cea de numire a claselor. o interfata publica poate fi accesata si de alte pachete decat cel care a definit-o.3 Implementarea unei interfete O clasa implementeaza o interfata in doi pasi: . Metoda este implicit publica si abstracta si deci nu trebuie sa folosim modificatorii de acces public si de metoda abstract.specifica numele superinterfetelor din care poate deriva interfata. fiecare interfata este in mod implicit abstracta deci cuvantul-cheie abstract poate lipsi. Un exemplu de interfata este Compara. Interfetele trebuie sa posede o protectie de pachet sau publica. o interfata nu are o metoda constructor. ca si clasele. . Interfetele nu se pot instantia. Metodele sunt declarate in interfata numai cu antetul lor. acestea neputand fi folosite decat in clasele sau interfetele din acelasi pachet. trebuie sa definim si metoda comparaCu() din interfata Compara. Interfetele care nu contin modificatorul public nu-si vor converti automat metodele la accesul public si abstract si nici constantele la accesul public.<corpul_clasei> . deci. Metoda comparaCu () se va comporta similar cu metoda compareTo() din clasa String.. Aceasta clasa implementeaza interfata Compara si. Ele sunt implicit abstracte. . deci. O interfata nepublica are metode si constante nepublice. Nu pot exista implementari diferite pentru aceeasi metoda declarata in doua interfete.<modificatori> . prezentata mai jos: /* INTERFATA folosita de mai multe clase pentru comparatii * --------------------Metode publice--------------* int comparaCu --> Compara doua obiecte de tip Compara * metoda trebuie definita in clasa care o implementeaza */ package clasegenerice. De asemenea. Variabilele interfetei sunt implicit statice si finale si deci trebuie specificate valori initiale pentru acestea. 2. pot apartine unui pachet daca se foloseste instructiunea package in prima linie din fisierul-sursa.

atunci si clasa respectiva mosteneste interfata. O clasa care implementeaza o interfata poate sa extinda si o alta clasa. Retinem ca definirea metodelor declarate intr-o interfata trebuie obligatoriu sa fie facuta in fiecare clasa in parte.declara toate interfetele pe care le implementeaza.Compara si nu un obiect de tip FormaGeo. import clasegenerice. interfetele pot fi organizate intr-o ierarhie. avand aria " + arie(). else return 1. Derivarea interfetelor Ca si in cazul claselor.arie()) return 0. In acest caz in declaratia clasei se foloseste mai intai cuvantul-cheie extends urmat de numele clasei din care deriveaza si apoi cuvantul-cheie implements urmat de numele interfetei pe care o implementeaza.4 Implementarea unor interfete multiple O clasa poate sa implementeze mai mult decat o singura interfata. Folosirea unor interfete multiple poate crea totusi complicatii. . 4. folosind cuvantul-cheie implements in antetul sau urmat de numele tuturor interfetelor separate prin virgula. Atunci cand o interfata mosteneste o alta interfata. .arie()) return -1.java): /* Superclasa abstracta pentru forme */ package formegeometrice. O clasa poate implementa mai multe interfe in doi pasi: . } final public String toString() { return nume + ". 3. care implementeaza interfata respectiva. public abstract class FormaGeo implements Compara { private String nume. } public int comparaCu(Compara rhs) { if (arie() < ((FormaGeo) rhs). 2. Metodele interfetei definite in clasa care o implementeaza sunt mostenite de toate subclasele clasei respective. } } Nota: 1. Aceste metode pot fi redefinite (suprascrise) in subclase. Daca o clasa extinde o superclasa care implementeaza o interfata. public FormaGeo(String numeForma) { nume = numeForma.*. abstract public double arie(). else if (arie() == ((FormaGeo) rhs). 4. subinterfata primeste toate metodele si constantele definite in superinterfata. Codul clasei este ilustrat in continuare (FormaGeo.defineste implementari pentru toate metodele din toate interfetele pe care le implementeaza.

// Numarul curent de elemente din stiva public StackImpl1 (int max ) { // Constructor items = new Object [ max ]. public class StackImpl1 implements Stack { private Object items [].returneaza continutul stivei sub forma unui sir de caractere. vor trebui sa contina metodele: • push . clasa Object. O singura interfata poate mosteni oricate clase are nevoie. il vom defini prin intermediul unei interfete. public interface Stack { void push ( Object item ) throws StackException . indiferent de implementarea lor. Object peek () throws StackException .elimina elementul din varful stivei • peek . items [n++] = item . ambele solutii avand avantaje si dezavantaje.adauga un nou element in stiva • pop . length ) throw new StackException (" Stiva este plina !"). } // Implementarea stivei folosind un vector de obiecte . // Vectorul ce contine obiectele private int n=0. Interfetele pot exista independent sau pot mosteni o alta interfata. } public void push ( Object item ) throws StackException { if (n == items . String toString (). Vom vedea imediat avantajele acestei abordari. void pop () throws StackException . } 53 . care sa modeleze notiunea de stiva de obiecte. Deoarece nu dorim sa legam tipul de date Stack de o anumita implementare structurala. o stiva poate fi implementata folosind un vector sau o lista inlantuita. la fel ca in cazul definitiilor de clasa: public interface <nume_interfata> extends <nume_superinterfata> { …. } public StackImpl1 () { this (100) . in timp ce a doua este mai eficienta din punctul de vedere al folosirii memoriei. Din punctul de vedere al structurii interne. Ierarhia de interfete este cu mostenire multipla. } Nota: In cazul interfetelor nu exista o radacina comuna a arborelui de derivare asa cum exista pentru arborele de clasa.Pentru a deriva (extinde) o interfata se foloseste tot cuvantul-cheie extends.. Obiectelede tip stiva. Prima solutie este mai simplu de inteles. boolean empty (). Exemplu: implementarea unei stive Dorim sa implementam un nou tip dedate numit Stack.testeaza daca stiva este vida • toString .returneaza varful stivei • empty .

} public Object peek () throws StackException { if ( empty ()) throw new StackException (" Stiva este vida !"). return top. item . i --) s += items [i]. top = top . // informatia din nod Node link . link = link . } public Object peek () throws StackException { if ( empty ()) throw new StackException (" Stiva este vida !"). } public boolean empty () { return (n ==0) . link . item = item . } public boolean empty () { return (top == null ). Node link ) { this . // legatura la urmatorul nod Node ( Object item . top = node . } } // Implementarea stivei folosind o lista inlantuita . } public void pop () throws StackException { if ( empty ()) throw new StackException (" Stiva este vida !"). // Referinta la varful stivei public void push ( Object item ) { Node node = new Node (item . . for (int i=n -1. items [--n] = null . toString () + " ". public class StackImpl2 implements Stack { class Node { // Clasa interna ce reprezinta un nod al listei Object item . } } private Node top= null . i >=0. top). this . } public String toString () { String s="".public void pop () throws StackException { if ( empty ()) throw new StackException (" Stiva este vida !"). return items [n -1]. return s. } public String toString () { String s="".

} } In continuare este prezentata o mica aplicatie demonstrativa care foloseste tipul de date nou creat ¸si cele doua implementari ale sale: public class TestStiva { public static void afiseaza ( Stack s) { System . } } } 55 . push ("a"). item ). printStackTrace (). afiseaza (s2). err. while ( node != null ) { s += ( node . node = node . s2. println (" Continutul stivei este : " + s).Node node = top. toString () + " ". s2. Stack s2 = new StackImpl2 (). afiseaza (s1). link . s1. e. out.14) ). s1. push ("b"). push ( new Double (3. push ( new Integer (1)). } public static void main ( String args []){ try { Stack s1 = new StackImpl1 (). } return s. println (" Eroare la lucrul cu stiva !"). } catch ( StackException e) { System .

3f.println(“y=”+obiect.7.out. B. } public class Test implements I1{ public static void main(String [] args){ System.3f 2. class C1 (int y=4. D.3f. o clasa nu poate implementa o interfaţa. 4. 4. C.}} . c). } class c1 implements I1 {int y.7f. nu este corect definită interfaţa. La executie se va afisa: 2.print(x). } } A.3f 6. d).println(x+” “+y). System.out.Teste de control: 4.out. Va aparea eroare la compilare deoarece valoarea variabilei x nu se mai poate modifica.eroare la compilare: metoda abstactă nu este implementată.out.2 Secventa de cod : interface I1{int x=3.print(x+" ").7f. afiseaza y=5.} public class extends C1 implements I1 {public static void main(String args[]) { System.} interface I2 extends I1{ int y=3}.3 6. La executie se va afisa: 2. x=6. c1( int y) {{this.y). Secvenţa uramatoare: interface I1{ int x=2.1 Ce se va afisa la executia urmatorului program Java? interface I1{ float x=2. System. b). public void afisare( ).}} Determină: a).}} public class test { public static void main(String args[]) {c1 obiect=new c1(5).y=y. La executie se va afisa: 2.

explicit. verificarea consistentei exceptiilor Java. programul afiseaza 2 4.cum sa folosim exceptiile? 5. semnalarea (“aruncarea”) propriilor exceptii. c). exceptiile sunt evenimente anormale care au loc in timpul executiei unei aplicatii si care pot duce la intreruperea executiei normale a acesteia. 57 . inseamna ca a fost semnalata (thrown .crearea si semnalarea propriilor exceptii: definirea propriilor clase de exceptii. eroare la compilare: arbitrul y este ambiguu petru C1 si I2. in Java. fisiere care nu mai contin date corecte.1 Tratarea erorilor Erorile care apar in faza de executie a unei aplicatii informatice sunt produse din diverse cauze cum ar fi: . ca “a aparut o eroare”. Faptul ca o exceptie a fost semnalata inseamna.declararea metodelor care pot semnala (“arunca”) exceptii catre alte metode: clauza throws.“aruncata”) o exceptie. implicit. b). de aplicatia informatica realizata. Capitolul 5 Tratarea exceptiilor Obiective: -tratarea erorilor: exceptii Java.a). programul afiseaza 2 3. . Interceptarea unei exceptii inseamna tratarea situatiilor speciale (erorilor) astfel incat aplicatia informatica proiectata sa nu se mai termine anormal. instructiunea throw. Exceptiile pot fi semnalate. .existenta unor situatii aflate in afara controlului programatorului (date eronate primite de la utilizatori.programatorul nu a anticipat toate situatiile posibile in care ar putea ajunge aplicatia informatica. dispozitive hardware care nu mai functioneaza etc). d). ierarhia de exceptii predefinite de platforma Java. . Exceptii Java In Java. Exceptia poate fi si interceptata (caught . . de sistem sau. . Atunci cand aplicatia informatica isi interupe executia normala.interceptarea (“prinderea”) si tratarea exceptiilor in cadrul aceleiasi metode: blocul try … catch.“prinsa”). o interfata nu poate extinte o alta interfata.

tratate de aplicatie. Clasa Exception are multe subclase definite in cadrul pachetului java.io.lang.io. Aceste erori sunt rare si. tipul de exceptie ClassCastException (prezentat la inceputul acestei lectii) indica faptul ca aplicatia noastra a incercat sa faca o conversie explicita de tip pentru un obiect ce nu poate fi convertit la tipul specificat. . numite erori. de obicei. Aceste subclase indica diverse tipuri de exceptii care pot aparea in cadrul unei aplicatii Java.IOException si sunt definite in pachetul java. desi sunt anumite exceptii care nu pot fi tratate si atunci aplicatia va fi oprita din executie. In general.Error. De exemplu. reprezinta clasa de baza pentru intreaga familie de clase de exceptii. definita in pachetul java. care sunt. Clasa Throwable. Figura de mai jos ilustreaza ierarhia claselor de exceptii.ele nu pot fi interceptate de catre aplicatia informatica in care s-au produs si determina intreruperea executiei programului (de exemplu. Verificarea consistentei exceptiilor Java . Clasa Exception. deoarece ea este clasa de baza pentru exceptiile care apar in timpul executiei unui program. pornind de la clasa de baza Throwable si continuand cu cateva dintre subclasele cele mai importante. impreuna cu toate clasele derivate din ea. toate exceptiile I/O (de intrare/iesire) sunt derivate din clasa java. descrie exceptii grave. Nu toate exceptiile sunt definite in pahetul java. fatale. tipul de exceptie NoSuchFieldException semnaleaza ca programul a incercat sa foloseasca o variabila de instanta sau de clasa care nu exista.lang. Clasa RuntimeException este foarte des folosita de programatori. De exemplu. reprezinta exceptiile propriu-zise Java.2 Ierarhia de exceptii predefinite de platforma Java In Java. De exemplu. de cele mai mute ori. impreuna cu toate clasele derivate din ea. Clasa Throwable are doua subclase directe: . exceptiile sunt instante ale unor clase derivate din clasa Throwable.Exception. Java este cea care foloseste acest tip de erori daca are nevoie de ele.5. OutOfMemoryError).lang. Exceptiile semnalate descriu conditii anormale. Cand se semnaleaza (este “aruncata”) o exceptie este creata o instanta a unei clase de exceptii. Clasa Error.

partea care o intercepteaza si o trateaza. . In cazul exceptiilor neverificate de catre compilator. Exceptiile verificate sunt toate tipurile de exceptii derivate din clasa Exception (inclusiv clasa Exception). insa pana la urma ea va fi interceptata si tratata. programatorul poate decide daca “prinde” (semnaleaza) si trateaza exceptia sau trece cu vederea exceptia. In cazul exceptiilor neverificate de catre compilator. 59 . Exceptiile neverificate sunt de tipul clasei Throwable. Pentru a intercepta si trata o exceptie trebuie parcursi doi pasi: . Compilatorul Java cat si masina virtuala Java verifica daca aceste exceptii “aruncate” in cadrul unei metode sunt fie tratate in cadrul acelei metode. precum si de tipul clasei RuntimeException si al subclaselor ei. . programatorul poate decide daca “prinde” (semnaleaza) si trateaza exceptia sau trece cu vederea exceptia. Atunci cand se folosesc aceste metode in aplicatia Java. o metoda poate indica tipurile de exceptii pe care le poate semnala (“arunca”). O exceptie poate fi aruncata de la o metoda la alta de mai multe ori inainte de a fi interceptata. de tipul clasei Error si al subclaselor ei. De exemplu. mai putin clasa RuntimeException si subclasele ei. metodele care ciresc din fisiere sau de la tastatura pot “arunca” exceptii de tipul IOException. O exceptie poate fi aruncata de la o metoda la alta de mai multe ori inainte de a fi interceptata.gruparea codului care contine metoda ce poate semnala (“arunca”) exceptia in cadrul unui bloc try. insa pana la urma ea va fi interceptata si tratata. Exceptiile neverificate sunt de tipul clasei Throwable.partea care semnaleaza exceptia si . Interceptarea (“prinderea”) si tratarea exceptiilor in cadrul aceleiasi metode In fiecare situatie de exceptie exista doua parti: . Aceste tipuri de exceptii se numesc exceptii verificate. precum si de tipul clasei RuntimeException si al subclaselor ei. Interceptarea (“prinderea”) si tratarea exceptiilor in cadrul aceleiasi metode In fiecare situatie de exceptie exista doua parti: .partea care semnaleaza exceptia si .Compilatorul este cel care il obliga pe programator sa intercepteze si sa trateze exceptiile de tipul IOException. mai putin clasa RuntimeException si subclasele ei. fie specificate ca fiind “aruncate” de metoda respectiva la alte metode in care urmeaza a fi tratate. Exceptiile verificate sunt toate tipurile de exceptii derivate din clasa Exception (inclusiv clasa Exception).In Java.gruparea codului care contine metoda ce poate semnala (“arunca”) exceptia in cadrul unui bloc try. programatorul trebuie sa aiba grija sa intercepteze (“sa prinda”) si sa trateze exceptiile de tipul IOException. programatorul poate decide daca “prinde” (semnaleaza) si trateaza exceptia sau trece cu vederea exceptia.interceptarea si tratarea exceptiei in cadrul unui bloc catch.partea care o intercepteaza si o trateaza.interceptarea si tratarea exceptiei in cadrul unui bloc catch. de tipul clasei Error si al subclaselor ei. In cazul exceptiilor neverificate de catre compilator. Pentru a intercepta si trata o exceptie trebuie parcursi doi pasi: .

o exceptie de tip NumberFormatException.partea care semnaleaza exceptia si . “se pot intercepta”. Pentru a intercepta si trata o exceptie trebuie parcursi doi pasi: . insa pana la urma ea va fi interceptata si tratata. eventualele exceptii de tip IOException. intr-un bloc tray.specifica numele prin care poate fi referita instanta ce reprezinta exceptia tratata de blocul catch. Urmatorul exemplu (cireste un sir de caractere si “incearca”.specifica tipul de exceptie care poate fi tratat.<nume_variabila> . se executa in continuare urmatoarea linie de cod aflata dupa secventa catch. Instructiunile din blocul catch se executa doar daca instructiunile din blocul try genereaza exceptii si aceste exceptii sunt instante ale clasei cu numele <nume_clasa_de exceptii> precizat in antetul instructiunii catch. intr-un bloc try. Exceptiile neverificate sunt de tipul clasei Throwable.interceptarea si tratarea exceptiei in cadrul unui bloc catch. De asemenea. Dupa ce exceptia a fost tratata. . In caz de nereusita.<nume_clasa_de_exceptii> . intr-un bloc catch. precum si de tipul clasei RuntimeException si al subclaselor ei.gruparea codului care contine metoda ce poate semnala (“arunca”) exceptia in cadrul unui bloc try. care este “aruncata” de metoda Integer. aceasta variabila este recunoscuta si poate fi folosita doar in cadrul blocului catch. Interceptarea (“prinderea”) si tratarea exceptiilor in cadrul aceleiasi metode In fiecare situatie de exceptie exista doua parti: . mai putin clasa RuntimeException si subclasele ei. Tratarea acestui tip de eroare se face printr-un mesaj de avertizare si returnarea valorii implicite 0 pentru un numar intreg. tip dat de numele clasei de exceptie. de tipul clasei Error si al subclaselor ei. Blocurile catch de instructiuni sunt asociate cu un bloc try astfel: try {…} catch (…) { … } catch (…) { … } … Forma generala a unui bloc catch este: catch(<nume_clasa_de_exceptii> <nume_variabila>) unde: . atunci cand “se incearca” citirea sirului de caractere de la tastatura. sa il converteasca la un numar intreg.partea care o intercepteaza si o trateaza.Exceptiile verificate sunt toate tipurile de exceptii derivate din clasa Exception (inclusiv clasa Exception). care sunt “aruncate” .parseInt() atunci cand numarul introdus nu este un numar intreg. se “intercepteaza”. . in blocul catch. O exceptie poate fi aruncata de la o metoda la alta de mai multe ori inainte de a fi interceptata.

class TestCitesteNumere { public static void main(String[] args) { citesteDate valIntreg = new citesteDate(). package intrareiesire.out. import intrareiesire.println("Introduceti numarul de elemente ale sirului:").in)). i++) System.length. for (int i = 0.io. care trateaza un tip de exceptii va intercepta si trata si clasele de exceptii derivate din exceptia respectiva. } } } Programul urmator (TestCiesteNumere. i++) numere [i] = valIntreg. } } public static int citesteNrInt() { try { return Integer. Deoarece clasele de exceptii sunt organizate ierarhic. } catch(IOException ioe) { return null.parseInt(citesteString()). } } Exemplul.println ("Introduceti elementele sirului: ").*. } catch(NumberFormatException nfe) { System. System. /* cieste un sir de caractere si incerca sa il converteasca la tipul int */ public class CitesteDate { public static String citesteString() { BufferedReader br = new BufferedReader(new InputStreamReader(System.out.print(numere[i] + " ")."). (care semnaleaza. prezinta modul de interceptare a unui anumit tip de exceptie.println("Nu este numar intreg.*.readLine(). Tratarea acestui tip de eroare se face prin returnarea valorii implicite null pentru un String. for (int i = 0. exceptia creata de tipul NumberFormatException. i < numere. int n = valIntreg.println ("Sirul de numere introdus este: "). nu este necesar ca tipul de exceptie tratat de blocul catch si tipul de exceptie “aruncat” de o metoda din blocul try sa fie identice.out. se poate intercepta in blocul catch. Un bloc catch. i < numere. intercepteaza si trateaza erorile care apar in cadrul lor) pentru a citi un sir de numere de tastatura. codul ar putea arata astfel: public static int citesteNrInt() { try { 61 . int [] numere = new int [n].java) apeleaza metodele din clasa CitesteDate.de metoda readLine().citesteNrInt(). Astfel. import java. System. folosind clasa Exception care este superclasa pentru NumberFormatException.out. return 0.out.length.citesteNrInt(). descris mai sus. try { return br. System. In exemplul de fata.

iar celelalte ignorate. deci dinspre varful stivei spre baza stivei. Atunci cand programatorul decide ca o metoda. in blocul catch. am descris cazul in care exceptiile sunt interceptate (“prinse”) si tratate in cadrul aceleiasi metode. a unor tipuri foarte diferite de exceptii semnalate in blocul try. 2.return Integer. A doua posibilitate este aceea de a specifica exceptiile care nu sunt tratate in cadrul metodei respective. In final exceptia va trebui interceptata (“prinsa”) si tratata in cadrul unei metode. le semnaleaza (“le arunca”) mai departe metodei care o apeleaza."). Pentru a indica faptul ca o metoda poate semnala (“arunca”) o exceptie. utilizarea blocurilor catch specializate. catre alte metode care o apeleaza. si nu a celor generale. Daca se doreste interceptarea si tratarea. O folosire uzuala are metoda getMessage().println("Nu este numar intreg. care nu sunt inrudite prin mostenire. care la randul ei daca nu le intercepteaza si nu trateaza le semnaleaza (“le arunca”) mai departe unei alte metode care o apeleaza pe aceasta din urma si asa mai departe. sa nu intercepteze o anumita exceptie care poate fi semnalata de codul din interiorul ei. dar si clase de exceptii derivate din clasa Exception. blocul catch intercepteaza toate exceptiile Exception. pornind de la metoda in care a aparut exceptia. Observatii: 1. In timpul procesului de examinare.Exceptiile specificate in clauza throws nu trebuie sa fie interceptate (“prinse”) si tratate in cadrul metodei respective care foloseste clauza throws. Declararea metodelor care pot semnala (“arunca”) exceptii catre alte metode (transmiterea exceptiilor catre baza stivei de apel) In paragraful anterior. din aplicatia informatica.out. } catch(Exception nfe) { System.Semnalarea (“aruncarea”) exceptiilor incepe cu metoda originala care daca nu intercepteaza si nu trateaza exceptiile generate. care ofera mai multe detalii despre situatia de eroare. trebuie sa se precizeze ca metoda respectiva poate semnala (“arunca”) la randul ei exceptia respectiva catre alte metode care o apeleaza. return 0.parseInt(citesteString()). Nota: Toate clasele de exceptii mostenesc de la clasa Throwable cateva metode utile pentru aflarea de informatii despre situatia de eroare. atunci se asocieaza blocului try mai multe blocuri catch. } } } In aceasta situatie. masina virtuala Java cauta in stiva de apel metoda care intercepteaza si trateaza exceptia. cum este si cazul clasei de exceptii FormatNumberException. Astfel. se foloseste in antetul metodei respective clauza throws in care se specifica numele exceptiilor pe care le poate semnala (“arunca”) metoda respectiva. primul bloc catch care va corespunde exceptiei semnalate va fi executat. Blocurile catch sunt examinate in ordinea in care ele apar in fisierul sursa. . fiind semnalate (“aruncate”) mai departe catre alte metode care le vor intercepta (“prinde”) si le vor trata. Se prefera totusi. nefiind transmise altor metode care apeleaza metoda respectiva. Ea afiseaza un mesaj detaliat referitor la ce s-a intamplat.

care apoi sa le semnaleaza metodei main() din clasa TestCitesteNumereThrows (care reprezinta aplicatia Java). import java.*.io. de catre metoda readLine(). } public static int citesteNrInt() throws IOException { try { return Integer. } catch(NumberFormatException nfe) { System. daca metoda respectiva genereaza exceptii pe care nu le trateaza.citesteNrInt().out. Astfel.io. class TestCitesteNumereThrows { public static void main(String[] args) throws IOException { CitesteDateThrows valIntreg = new CitesteDateThrows(). 63 .readLine(). al clasei CitesteDate.Forma antetului metodei care specifica tipurile de exceptii semnalate (“aruncate”) de metoda este: [<modificatori_acces>] [<modificatori_metoda>] <tip_returnat> <nume_metoda> ([<param1>. return br. import java. s-a creat o noua clasa CitesteDateThrows care are definitia: package intrareiesire.println("Nu este numar intreg.*. deoarece compilatorul detecteaza aceasta “scapare” si o raporteaza ca eroare de compilare. System. } } } Clasa TestCitesteNumereThrows (care reprezinta programul principal) are definitia data de secventa de cod: import intrareiesire.").*. return 0. Exemplul prezentat anterior. propunand doua solutii: tratarea lor in cadrul metodei (prin blocuri try…catch) sau specificarea lor in clauza throws.println("Introduceti numarul de elemente ale sirului:").out. <nume_clasa_de_exceptii2>.parseInt(citesteString()). /* cieste un sir de caractere si incerca sa il converteasca la tipul int */ public class CitesteDateThrows { public static String citesteString() throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System. <param2>. …] Nota: Specificarea prin clauza throws a exceptiilor aruncate de metoda originala nu se poate omite. sa fie semnalate (“aruncate”) mai departe in metoda citesteNrInt(). int [] numere = new int [n]. …]) throws <nume_clasa_de_exceptii1>[.in)). poate fi modificat astfel incat exceptiile de tipul IOException care sunt semnalate (“aruncate”) in metoda citesteString (). int n = valIntreg.

out. se recomanda adaugarea la numele clasei a sufixului Exception. Clasele proprii de exceptii sunt clase Java obisnuite. Clasele proprii de exceptii sunt derivate (direct sau indirect) din clasa Throwable.println ("Sirul de numere introdus este: "). Aceste clase proprii de exceptii descriu situatii de exceptii particulare aplicatiei respective care nu exista in ierarhia de clase de exceptii oferita de platforma Java. i++) System.out.primul constructor nu primeste nici un parametru. doi constructori: . toate exceptiile sunt instante ale unei clase de exceptie oarecare.3 Crearea si semnalarea propriilor exceptii Pe langa exceptiile definite de platforma Java. Nota: In definirea noilor clase de exceptii. fie de programator. } } Clasa IndexException definita mai sus nu aduce practic nimic nou clasei Exception. mai intai. Pentru a semnala (“arunca”) un tip de exceptie definita de programator.length. public class IndexException extends Exception { public IndexException() { super(). definite fie in biblioteca Java standard. . pentru toate clasele derivate (direct sau indirect) din clasa Exception (de exemplu. .print(numere[i] + " "). deoarece defineste doar doi constructori care apeleaza constructorii superclasei Exception. de obicei. Clasele proprii de exceptii poseda. Definirea propriilor clase de exceptii De regula.System.citesteNrInt(). } public IndexException(String msg) { super(msg).println ("Introduceti elementele sirului: ").al doilea constructor primeste ca parametru un sir de caractere care reprezinta un mesaj ce evidentiaza situatia de eroare. System. } } 5. i < numere.out. i < numere. De regula. MyNewException).length. trebuie sa se creeze. programatorul poate defini propriile clase de exceptii. for (int i = 0. Semnalarea (“aruncarea”) propriilor exceptii Sa ne reamintim ca. for (int i = 0. i++) numere [i] = valIntreg. o instanta a sa. se creaza propriile clase de exceptii derivate din clasa Exception. o clasa proprie de exceptii este definita ca in exemplul de mai jos: package exceptii. tipul exceptiei in sine este important pentru ca ajuta programatorul sa intercepteze tip respectiv de exceptie atunci cand este necesar. Totusi.

i++) { s.Folosind definirea de clasa de exceptie prezentata. "). public class TestStiva1 { public static void main(String[] args) { Stiva1 s = new StivaArr(10). Iata codul-sursa in care se realizeaza acest lucru: /* Clasa de test simpla pentru o stiva.”.push(new Integer(i)).print("Continutul stivei este: "). interceptarea si tratarea exceptiei de tip IndexException este realizata in metoda main() a aplicatiei (clasa TestStiva1). Instructiunea throw are un singur argument. Odata creata o instanta a unei clase proprii de exceptii. //introducem elemente in stiva for (int i = 0. In cel de al doilea caz situatia de eroare transmite si o informatie. crearea unei instante a clasei de excepie IndexException poate fi facuta in doua moduri: new IndexException(). } Pentru transmiterea exceptiei semnalate (“aruncate”) in metoda topAndPop(). care trebuie sa fie o instanta a unei clase de exceptii derivate din clasa Exception. aceasta devine o exceptie Java si este semnalata (“aruncata”) folosind instructiunea throw. Forma instructiunii throw este: throw <instanta_clasa_de_exceptii>. In exemplul prezentatat. care adauga 10 numere * dupa care le extrage in ordine inversa */ import clasegenerice.*. } return elemStiva[pozitieVarf--]. eventual intercepta (“prinde”) si trata sau poate fi transmisa mai departe la o alta metoda apelanta. try { while (true) 65 .*. "). import exceptii. pentru semnalarea (“aruncarea”) unei exceptii din metoda topAndPop() (exceptie care poate fi generata cand o stiva este vida) se poate folosi urmatoarea secventa de cod: public Object topAndPop() throws IndexException { if (isEmpty()) { throw new IndexException("Stiva vida.out. } //scoatem elementele din stiva si le afisam System. De exemplu. new IndexException("Stiva vida. i < 10. care poate fi folosit de codul care trateaza exceptia aparuta pentru a afisa un mesaj informativ. In metoda apelanta exceptia IndexException se poate. cu ajutorul instructiunea throw. catre o alta metoda apelanta se foloseste clauza throws in antetul metodei topAndPop(). sub forma mesajului “Stiva vida.

aceasta metoda trebuie sa fie declarata folosind clauza throws.getMessage()). } } catch(IndexException ie) { System. atunci se pot semnala numai aceleasi tipuri de exceptii sau subclase ale exceptiilor respective. cat si pentru a o resemnala explicit folosind instructiunea throw.out. 2. Ca regula generala. System.print("Eroare: " + ie. Daca o metoda din aplicatia Java apeleaza o alta metoda in care s-a folosit clauza throws. Daca o metoda din aplicatia Java semnaleaza (“arunca”) propriile exceptii.println(). 2. daca apare o eroare. folosirea de clauze throws in propriile metode in scopul de a evita tratarea exceptiilor face ca utilizatorii acestor metode (adica obiectele aflate mai sus pe lantul de apeluri) sa fie nevoiti sa le trateze. Astfel metodele noastre se complica nejustificat. nu este recomandata utilizarea exceptiilor in cazul in care situatia este previzibila in aplicatia Java (de exemplu. .out. Sistemul de exceptii al Java a fost proiectat in asa fel incat.print(s.se realizeaza ambele metode descrise mai sus. folosind instructiunea throw. Daca metoda din aplicatia Java suprascrie metoda unei subclase care contine clauza throws. De asemenea.{ System.se trateaza exceptia folosind blocurile try si catch. 3. . avem trei posibilitati: .se transmite exceptia mai departe pe lant (spre baza stivei de apel). Erorile semnalate de compilator cu privire la exceptii au rolul de a ne atrage atentia asupra acestor probleme. iesirea din bucla while se realizeaza in momentul in care stiva devine vida si metoda topAndPop() semnaleaza (“arunca”) exceptia IndexException care este interceptata si tratata in blocul catch.topAndPop() + " ").out. Modul incorect de folosire a exceptiilor 1. sa fim avertizati in legatura cu aceasta. Concluzii privind folosirea eficienta a exceptiilor Cum sa folosim exceptiile? 1. adaugand in metoda respectiva clauza throws. . Ignorarea acestor avertismente si nerespectarea lor duce la posibila aparitie a unor erori fatale in cadrul aplicatiilor. Mai mult. nu se pot semnala alte tipuri de exceptii. depasirea dimensiunii unui tablou etc). exceptia trebuie semnalata explicit in corpul metodei. } } } Observatie: In secveta de mai sus. sfarsitul unui fisier. atat pentru a intercepta (“prinde”) si trata exceptia folosind blocurile try … catch.

publice. Propagarea unei erori pana la un analizor de exceptii corespunzator. C. Va produce eroare la executie din cauza impartirii la 0 (se arunca o except»ie: "ArithmeticExpetion").out. Va produce eroare la compilare din cauza impartirii la 0. if (double.1 Fie urm¸atorul cod Java: int x=0. C. Gruparea erorilor dupa tipul lor.Teste de control 5. Codul este corect si va afisa Infnit.2 Prin modalitatea sa de tratare a exceptiilor. Exista o metoda care se ocupa cu acest lucru.println("Infinit").println("2/0"). B. Ce puteti spune despre acest cod. else System. 67 . D.isInfinite(2/x)) System. Codul este corect si va afisa NaN 5. B. 5. exceptii. daca este integrat in cadrul unui program Java? A. Java are urmatoarele avantaje fata de mecanismul traditional de tratare a erorilor: A. dinamice. B. D.out. Separarea codului pentru tratarea unei erori de codul in care ea poate sa apara.3 Metodele care sunt apelate uzual pentru un obiect de tip exceptie sunt defnite in clasa Throwable si sunt: A. C. Declarate cu modicatorul de acces private. D.

fluxuri filtrate de intrare cu o zona tampon. . comunicatii Internet sau cod Java (bytecode) etc. fluxuri-filtre. .io. Un flux (stream) reprezinta o succesiune de octeti (bytes) sau de caractere transportat de la sau catre memoria RAM in care se afla programul Java. fluxuri filtrate cu date formatate. Java foloseste doua tipuri principale de fluxuri: . . . Un flux de intrare transporta datele de la o sursa externa (tastatura.fluxuri de caractere si clase predefinite Java utilizate: fluxuri nefiltrate de intrare care folosesc ca sursa un fisier.fluxuri de octeti. 6.1 Tipuri de fluxuri de intrare/iesire Java Toate datele din Java sunt scrise sau citite folosind fluxuri.255. Fluxurile de octeti pot pastra valori intregi din domeniul 0 .fluxuri de octeti si clase predefinite Java utilizate: fluxuri nefiltrate de intrare care folosesc ca sursa un fiser. Numarul claselor si a metodelor lor. System.in. fisier pe hard-disc etc) catre programul Java. Fluxurile de intrare/iesire in Java sunt create si manevrate cu ajutorul claselor din pachetul predefinit java. System. definite in pachetul java. . fluxuri nefiltrate de iesire care folosesc ca destinatie un fisier.io. fisier pe hard-disc etc). fluxuri de iesire cu o zona tampon.io. Din acest motiv orice program care executa operatii de intrare/iesire trebuie sa includa instructiunea: import java.err. In acest format pot fi reprezentate o multitudine de date. programe executabile. fluxuri de caractere. System.filtrarea fluxurilor de octeti si clase predefinite Java utilizate: zona tampon (“buffer”). fluxuri filtrate de intrare cu o zona tampon care tin evidenta numerelor de linie.out. este foarte mare. De aceea se recomanda programatorului sa consulte in permanenta documentatia ce insoteste versiunea de Java folosita.Capitolul 6 Intarari si iesiri Obiective: -tipuri de fluxuri de intrare/iesire Java: fluxuri de octeti. Un flux de iesire transporta datele din programul Java catre o destinatie externa (ecranul calculatorului. fluxuri filtrate cu date de tipuri primitive. fluxuri de intrare cu o zona tampon. cum ar fi: date numerice.fluxuri de caractere.*.

pentru fluxuri de caractere de intrare si .InputStream . paginile Web. citirea/scrierea datelor de la /in filtru si nu direct in flux. Dintre metodele clasei System.metoda setOut.OutputStream . referitoare la fluxurile predefinite descrise mai sus.System. un fisier pe disc). aceasta metoda are antetul: void setIn(InputStream <in>) .out . este necesar sa foloseasca fluxurile de caractere. Generic.pentru fluxuri de octeti de iesire.System. 6. Ele difera de fluxurile de octeti prin faptul ca setul de caractere Java suporta codificarea Unicode (cu doi octeti pe caracter).Reader . un fisier pe disc).in . acest flux este de tip PrintStream. care redirecteaza fluxul de intrare standard catre o alta sursa decat tastatura (de exemplu. cum ar fi fisierele text. la ecranul calculatorului sau pentru erori) care sunt campuri ale clasei System inclusa in pachetul java. 2.pentru fluxuri de octeti de intrare si .metoda setIn. mentionam: . Toate datele de tip text.pentru fluxuri de caractere de iesire.metoda setErr. fluxurile de octeti sunt subclase ale claselor abstracte predefinite: . aceasta metoda are antetul: void setOut(PrintStream <out>) .System. acest flux este de tip InputStream.2 Fluxuri de octeti si clase predefinite Java A. sau alte formate de text. .Writer . Fluxurile de caractere reprezinta un tip special de flux de octeti. . care redirecteaza fluxul de iesire standard catre o alta destinatie decat ecranul calculatorului (de exemplu. aceasta metoda are antetul: void setErr(PrintStream <out>) Asocierea fluxului de intrare sau de iesire cu un filtru Majoritatea claselor Java folosite in prezent permit realizarea de operatii de intrare/iesirmai performante prin asocierea fluxului cu un filtru.reprezinta iesirea standard (implicit.reprezinta fluxul standard de iesire pentru mesaje de eroare (implicit.lang: .Generic. acest flux este de tip PrintStream. crarea (deschiderea) unui flux de tip filtru asociat cu fluxul deschis la pasul 1. un fisier pe disc). tastatura calculatorului). ecranul calculatorului). care se folosesc numai pentru date de tip text (tiparibile). care redirecteaza fluxul de iesire standard al mesajelor de eroare catre o alta destinatie decat ecranul calculatorului (de exemplu. Java ofera trei fluxuri predefinite pentru operatii de I/O standard (de la tastatura. 3. fluxurile de caractere sunt subclase ale claselor abstracte predefinite: . crearea (deschiderea) unui flux asociat cu sursa de date sau cu destinatia datelor. Un filtru este un tip de flux care schimba modul in care se lucreaza cu un flux existent. Fluxuri nefiltrate de octeti si clase predefinite utilizate 69 . Procedura de folosire a unui filtru pentru un flux presupune urmatorii pasi: 1. ecranul calculatorului).reprezinta intrarea standard (implicit.err . inainte de a citi sau scrie date.

nr de octeti sariti in fluxul de intrare. Daca s-a detectat sfarsitul de fisier. Fluxuri nefiltrate care folosesc ca sursa un fisier de octeti de intrare Sunt folosite pentru transferul de date de la fisierele aflate pe hard-discuri. . .<poz_ini> . Daca fisierul nu poate fi deschis. urmatoarea instructiune deschide un flux de intrare de la fisierul “test. atunci este lansata exceptia FileNotFoundException. rezultatul intors este -1.<b> . Metoda read cu trei parametrii are forma: read (byte [] <b>.numarul de octeti care se vor citi din fluxul de intrare repetand metoda read fara parametri. Dupa deschiderea fluxului de intrare din fisier se pot folosi metodele acestui flux pentru realizarea diverselor operatii de intrare. .<sir> . De exemplu. Rezultatul intors de metoda este numarul de pozitii peste care s-a trecut efectiv. si eventual calea. Descriem cateva dintre ele. care are forma: FileInputStream(String <sir>) unde: .pozitia elementului din cadrul tabloului unde se va stoca primul octet de date. de la inceput. Metoda skip avanseaza cu n pozitii (octeti) in fluxul de intrare.<lungime> . Metoda skip are forma: skip(long <n>) unde : <n> .In schema de mai jos se prezinta doar o parte a structurii de clase ce poate fi folosita in operatiile cu fluxuri de intrare si iesire nefiltrate. Metoda returneaza un intreg care reprezinta numarul de octeti cititi sau -1 daca. int <poz_ini>. fluxul de intrare este la sfarsitul sau. int <lungime>) unde: . nedepasind bineinteles sfarsitul fluxului. rezultatul intors este un intreg din intervalul 0 255. Metoda read() citeste un octet din fluxul de intrare. Crearea (deschiderea) unui flux de intrare de la un fisier se realizeaza cu ajutorulconstructorului clasei FileInputStream. la specificarea caii fisierului trebuie sa se foloseasca doua caractere backslash pentru a nu se confunda cu o secventa escape.dat”: FileInputStream fis = new FileInputStream(“test.reprezinta numele. pe CD-ROM sau pe alte dispozitive de stocare (ce pot fi referite printr-o cale de director si un nume) catre aplicatia Java. Metoda available() este folosita pentru a returna numarul de octeti ce mai pot fi cititi la momentul curent din fluxul de intrare.un tablou de octeti in care se vor memora datele citite. fisierului.dat”).

reprezinta numele.read(). la specificarea caii fisierului trebuie sa se foloseasca doua caractere backslash pentru a nu se confunda cu o secventa escape." + e. octet = fis.out. public class CitesteFisierOcteti { public static void main(String [] args) { try { FileInputStream fis = new FileInputStream("test. programul “CitesteFiserOcteti . pentru inchiderea fluxului de intrare se foloseste metoda close(). index++.read(). si eventual calea.close(). Crearea (deschiderea) unui flux de iesire catre un fisier se realizeaza cu ajutorul constructorului clasei FileOutputStream.<sir> . int index = 0.out. } } } Dupa executia programului va fi afisat fiecare octet din fisierul “test.java” citeste octeti dintr-un flux de intrare al unui fisir cu numele “test. System.doc”. Fluxuri nefiltrate de octeti de iesire care folosesc ca destinatie un fisier Sunt folosite pentru transferul de date de la aplicatia Java catre fisierele aflate pe hard-discuri. import java.dat").println("Eroare . Dupa citirea ultimului octet din fisier. 71 . Fisierul de intrare cu numele “test. fisierului. care are forma: FileOutputStream(String <sir>) unde: .Metoda close() inchide fluxul de intrare respectiv si elibereaza resursele sistem asociate cu acesta. urmat de numarul total de octeti cititi.out.print(octet + " "). ca mai jos: 48 49 50 51 52 53 54 55 56 57 13 10 73 111 110 101 115 99 117 32 70 108 111 114 105 110 Octeti cititi: 26 Observatie: Se observa ca valorile octetilor afisati sunt codurile ASCII ale caracterelor din cele doua linii existente in fisier.io.dat”. } fis.println("\nOcteti cititi: " + index).*. Aceasta operatie trebuie realizata pentru a elibera resursele sistemului asociate fisierului deschis. De exemplu. } catch (IOException e) { System. int octet = fis. pe CD-ROM sau pe alte dispozitive de stocare (ce pot fi referite printr-o cale de director si un nume). while (octet != -1) { System.dat” din care se citesc date in forma binara contine doua linii: 0123456789 Ionescu Florin Acest fisier a fost creat cu utilitarul Notepad.getMessage()).

Aceasta metoda are forma: write(int <b>) unde: <b> . 0. 0. pentru inchiderea fluxului de iesire se foloseste metoda close(). 128. 57. Metoda write cu un parametru scrie un octet in fluxul de iesire. caz in care nu se face adaugarea de date la sfarsitul fisierului ci suprascrierea datele existente. urmatoarea instructiune deschide un flux de iesire catre fisierul “test1.length octeti.<lungime> . caz in care se face adaugarea datelor la sfarsitul fisierului. Constructorul cu doi parametrii are forma: FileOutputStream(String <sir>. Daca se foloseste numele unui fisier deja existent. import java. . 0. Metoda write cu trei parametrii are forma: write (byte [] <b>.<poz_ini> . Urmatoarea instructiune deschide un flux de iesire catre fisierul “test1. Metoda write cu doi parametrii scrie un tablou de octeti in fluxul de iesire si are forma: write (byte [] <b>) unde: . Dupa scrierea ultimului octet in fisier.dat”: FileOutputStream fis = new FileOutStream(“test1. Aceasta operatie trebuie realizata pentru a elibera resursele sistemului asociate fisierului deschis. boolean <adauga>) unde: . 0. atunci este lansata exceptia FileNotFoundException. int <poz_ini>. Dupa deschiderea fluxului de iesire din fisier se pot folosi metodele acestui flux pentru realizarea diverselor operatii de iesire. Programul urmator (ScrieFisierOcteti. sau poate avea valoarea false. .specifica un tablou de octeti care va fi scris in fluxul de iesire.<b> . true).specifica un tablou de octeti care va fi scris in fluxul de iesire. 0.<b> .poate avea valoare true. 111.<adauga> . . si eventual calea. int <lungime>) unde: .pozitia elementului din cadrul tabloului de la care se incepe scrierea in fluxul de iesire. la specificarea caii fisierului trebuie sa se foloseasca doua caractere backslash pentru a nu se confunda cu o secventa escape. 0.reprezinta numele. 97.io. . 111. acesta va fi sters definitiv. 44. fisierului. 15.dat” pentru a adauga octeti la sfarsitul fisierului: FileOutputStream fis = new FileOutStream(“test1. in fisier vor fi scrisi b.dat”. daca fisierul nu poate fi deschis.numarul de octeti care se vor scrie in fluxul de iesire. 0. 0.dat”). De exemplu. odata cu inceperea scrierii datelor.*. 73. 111. Descriem cateva dintre ele. Metoda close() inchide fluxul de iesire respectiv. 0.variabila care contine octetul de scris in fluxul de iesire.gif”. 56.Trebuie sa se aiba o grija deosebita atunci cand se specifica numele fisierului in care se scrie.java) scrie un tablou de octeti intr-un flux de iesire intr-un fisier date cu numele “test1. 15. public class ScrieFisierOcteti { public static void main (String [] args) { int [] octeti = { 71. 70. 0.<sir> .

getMessage()). for (int i = 0. } catch(IOException e) { System. 0. 169. Fluxurile FilterInputStream si FilterOutputStream nu realizeaza in mod direct nici un fel de operatie de filtrare. 155. 26. } } } B. 154. 105. 228. 127. 145." + e. 112. 84.1 Fluxuri de octeti cu o zona tampon (“buffer”) Un tampon (“buffer”) reprezinta o zona de memorie RAM in care se pot pastra date din fluxul de intrare sau de iesire pana la momentul citirii sau scrierii lor intr-o aplicatie Java. try { FileOutputStream fis = new FileOutputStream("test1. modifica informatia transmisa printr-un flux existent (de tip InputStream sau OutputStream). 200. 200. 73 . Dar. 102. 0. 0. 0. 15. 35.length.out. 201. astfel. Filtrarea fluxurilor de octeti si clase predefinite Java utilizate Fluxurile filtrate sunt fluxuri care selecteaza si. 205. 142. 0. Acestea sunt create folosind subclase ale claselor FilterInputStream si FilterOutputStream. 165. Prin folosirea unui tampon se pot accesa (citi sau scrie) date fara a folosi sursa originala (fisierul) sau destinatia originala (fisierul) de date. 200. BufferedInputStream) care sunt folosite pentru anumite tipuri de filtrari. 200. 200. 0. Zona tampon este folosita ca o zona intermediara pentru citirea/ scrierea datelor din/in fluxul de intrare/iesire.println("Eroare . i < octeti. 200. 185. in acest mod micsorandu-se timpul de lucru al aplicatiei Java. 15. 33. 175. Pentru memoria tampon se mai foloseste si termenul de “memorie de lucru”. 132.gif"). 25.0. 2. 128. din ele deriveaza subclase (de exemplu. In schema de mai jos se prezinta doar o parte a structurii de clase ce poate fi folosita in operatiile cu fluxuri de intrare si iesire filtrate. 200 } . 241. Aceasta tehnica este mai eficienta intrucat utilizarea zonei tampon evita accesarea fisierului pentru fiecare citire/scriere. B. 161. 81. i++) fis. 33.close().write(octeti[i]). fis.

Metoda skip are forma: skip(long <n>) unde : <n> . Metoda close() inchide fluxul de intrare cu tampon si elibereaza resursele sistem asociate cu acesta.<b> . cat si din fluxul de intrare. int <lg_buffer>) unde: . Crearea (deschiderea) unui flux de intrare cu tampon se realizeaza cu ajutorul constructorilor clasei BufferedInputStream. Metoda read() citeste un octet din fluxul de intrare cu tampon. Metoda available() este folosita pentru a returna numarul de octeti ce mai pot fi cititi la momentul curent atat din zona tampon. acestea sunt cautate mai intai in zona tampon si apoi in sursa originala de intrare. Fluxurile de octeti de intrare cu tampon folosesc clasa BufferedInputStream.<poz_ini> .<in> . Metoda read cu trei parametrii are forma: read (byte [] <b>. care sa intercepteze aceasta exceptie. Dupa deschiderea fluxului de intrare cu tampon se pot folosi metodele acestui flux pentru realizarea diverselor operatii de intrare. Cand este deschis un flux de intrare cu tampon se creaza si o zona tampon. Metoda returneaza un intreg care reprezinta numarul de octeti cititi sau -1 daca. de la inceput.<lungime> . toate operatiile legate de fluxuri se incadreaza in blocuri try … catch. int <poz_ini>. atasata acestuia. bineinteles.un tablou de octeti in care se vor memora datele citite.reprezinta lungimea zonei tampon a fluxului de intare. sub forma unui tablou de octeti.255. fluxul de intrare este la sfarsitul sau. rezultatul intors este un intreg din intervalul 0 . Daca s-a detectat sfarsitul de fisier.nr de octeti sariti in fluxul de intrare si descarcati din fluxul de intare. Fluxuri de octeti de intrare cu o zona tampon Un flux de intrare cu tampon poseda un tampon cu date din care se face citirea. .Nota: Deoarece fluxurile de intrare/iesire cu tampon semnaleaza exceptia IOException la aparitia unei erori.pozitia elementului din cadrul tabloului unde se va stoca primul octet de date.numarul de octeti care se vor citi din fluxul de intrare cu tampon repetand metoda read fara parametri. rezultatul intors este -1. Constructorii clasei BufferedInputStream au una din formele: a) BufferedInputStream(InputStream <in>) unde: . b)BufferedInputStream(InputStream <in>.<lg_buffer> .reprezinta fluxul original de tip InputStream. Nota: Zona tampon are o lungime care este aleasa implicit (automat). . int <lungime>) unde: .reprezinta fluxul original de tip InputStream. Cand aplicatia Java citeste date. . Metoda skip avanseaza cu n pozitii (octeti) in fluxul de intrare cu tampon si descarca n octeti din flux. Fluxuri de octeti de iesire cu o zona tampon . Descriem cateva dintre ele. sfarsitul fluxului. nedepasind. Rezultatul intors de metoda este numarul de pozitii peste care s-a trecut efectiv.<in> .

atasata acestuia. . . Cu ajutorul acestei metode se realizeaza golirea zonei tampon chiar daca aceasta nu s-a umplut inca.java) scrie o serie de octeti intr-un flux de iesire cu tampon asociat cu un fisier pe disc.pozitia elementului din cadrul tabloului de la care se incepe scrierea in fluxul de iesire cu tampon.specifica un tablou de octeti care va fi scris in fluxul de iesire cu tampon.reprezinta fluxul de iesire de tip OutputStream. Atunci cand datele sunt directionate intr-un flux de iesire cu tampon. Limita inferioara si limita superioara din seria de numere sunt specificate in doua argumente transmise prin linia de comanda.<out> . sub forma unui tablou de octeti.<lungime> . programul deschide un flux de intrare cu tampon si citeste octetii scrisi in fisier. Crearea (deschiderea) unui flux de iesire cu tampon se realizeaza cu ajutorul constructorilor clasei BufferedOutputStream. public class IOBinarTampon { public static void main (String [] args) { int limInf = 0. int <lg_buffer>) unde: .reprezinta lungimea zonei tampon a fluxului de iesire.255.variabila care contine octetul de scris in fluxul de iesire cu tampon. import java. Metoda flush() transmite (scrie) continutul zonei tampon la destinatia fluxului de iesire original chiar daca aceasta zona tampon nu s-a umplut inca. Dupa deschiderea fluxului de iesire cu tampon se pot folosi metodele acestui flux pentru realizarea diverselor operatii de iesire. daca se incearca scrierea unei valori care este mai mare decat 255 va fi stocat numai restul impartirii acestei valori la 256. int <lungime>) unde: .*.reprezinta fluxul de iesire de tip OutputStream. Urmatorul program (IOBinarTampon. Cand este deschis un flux de iesire cu tampon se creaza si o zona tampon.<poz_ini> .numarul de octeti care se vor scrie in fluxul de iesire cu tampon. int <poz_ini>. implicit limita inferioara este 0 iar limita superioara este 255.io. Dupa scrierea in fisier. continutul acestuia nu va fi transmis catre destinatie decat dupa ce zona tampon atasata s-a umplut.Un flux de iesire cu tampon poseda un tampon cu date care nu au fost inca scrise in destinatia originala a fluxului.<b> . Constructorii clasei BufferedOutputStream au una din formele: a) BufferedOuputStream(OutputStream <out>) unde: . Metoda write cu un parametru scrie un octet in fluxul de iesire cu tampon.<lg_buffer> . .<out> . 75 . b)BufferedOutputStream(OutputStream <out>. valoarea acestei variabile trebuie sa apartina intervalului 0 . Fluxurile de octeti de iesire cu tampon folosesc clasa BufferedOutputStream. ca in exemplul urmator: java IOBinarTampon 2 30 Daca nu se transmit argumente prin linia de comanda. Metoda write cu trei parametrii are forma: write (byte [] <b>. Descriem cateva dintre ele. Metoda close() inchide fluxul de iesire cu tampon si elibereaza resursele sistem asociate cu acesta. Nota: Zona tampon are o lungime care este aleasa implicit (automat). Aceasta metoda are forma: write(int <b>) unde: <b> .

dat")).parseInt(args[0]). boolean succesCiteste = fo. boolean succesScrie = fo.dat")). FluxOcteti fo = new FluxOcteti(limInf. } } } class FluxOcteti { private int inceput = 0.getMessage()).println("\nCiteste: "). } } boolean citesteFlux() { try { BufferedInputStream fluxTampon = new BufferedInputStream( new FileInputStream("numere.citesteFlux(). } else if(args.print(" " + i).out.length > 1) { limInf = Integer. int i = 0. return true.close().parseInt(args[1]). for (int i = inceput.int limSup = 255.out.length > 0) limInf = Integer.out. System. } catch(NumberFormatException nfe) { System.println("\nScrie: ").out. this. } catch(IOException e) { System.println("Eroare: " + "Nu ati introdus un numar intreg"). i <= sfarsit.inceput = inceput. public FluxOcteti(int inceput. limSup).parseInt(args[0]). } fluxTampon.sfarsit = sfarsit.print("Eroare: " + e. limSup = Integer.scrieFlux().write(i). try { if (args. } boolean scrieFlux() { try { BufferedOutputStream fluxTampon = new BufferedOutputStream( new FileOutputStream("numere. System. private int sfarsit = 255. System. do { . return false. i++) { fluxTampon.out. int sfarsit) { this.

atunci argumentele sunt separate prin spatii. atunci argumentele sunt separate prin spatii. argumentele din linia de comanda sunt preluate de metoda main() sub forma unui tablou de siruri: public static void main(String [] args) { //corpul metodei } Argumentele din linia de comanda sunt stocate in tabloul de siruri de caractere incepand cu primul element din tablou (care are indexul 0). Argumentele trebuie adaugate la executie dupa numele programului si daca sunt mai multe decat unul.print("Eroare: " + e. ci ca succesiuni de date primitive. Deci. 77 . in tabloul de siruri de caractere al metodei main() nu se preia si numele programului ca la C/C++. B2. In cadrul aplicatiei Java. Deci.read(). posibilitatea ca fluxurile sa nu mai fie privite strict la nivel de octet.i = fluxTampon.print(" " + i). Modul de transmitere a unor argumente la aplicatii Java depinde de platforma pe care se executa Java. Observatie: Aplicatia Java prezentata mai sus poate primi unul sau doua argumente atunci cand este lansata. Fluxuri filtrate cu date de tipuri primitive Clasele DataInputStream si DataOutputStream ofera. return true. in tabloul de siruri de caractere al metodei main() nu se preia si numele programului ca la C/C++. argumentele din linia de comanda sunt preluate de metoda main() sub forma unui tablou de siruri: public static void main(String [] args) { //corpul metodei } Argumentele din linia de comanda sunt stocate in tabloul de siruri de caractere incepand cu primul element din tablou (care are indexul 0). Prin aceasta. In Windows si Unix se pot transmite argumente prin intermediul liniei de comanda. } catch(IOException e) { System. if (i != -1) System.out. fluxTampon.close().getMessage()). } } } Observatie: Aplicatia Java prezentata mai sus poate primi unul sau doua argumente atunci cand este lansata. In Windows si Unix se pot transmite argumente prin intermediul liniei de comanda. Modul de transmitere a unor argumente la aplicatii Java depinde de platforma pe care se executa Java.out. In cadrul aplicatiei Java. return false. } while (i != -1). ca facilitate suplimentara. Argumentele trebuie adaugate la executie dupa numele programului si daca sunt mai multe decat unul.

care sa intercepteze aceasta exceptie.specifica fluxul de intrare existent. . Urmatorul program (IODataTampon. .readBoolean(). Observatii: 1. writeFloat(float <v>). Urmatoarea lista prezinta metodele de citire si de scriere ce pot fi folosite pentru fluxurile de tipul DataInputStream. un flux de iesire cu tampon sau un flux de iesire in fisier. de exemplu. dupa cum parametrul <v> este true sau false.<out> . de exemplu. Constructorul are forma: DataInputStream(InputStream <in>) unde: . . .readInt().readDouble().specifica fluxul de iesire existent. De exemplu.readChar(). metoda writeBoolean() scrie intr-un octet valoarea 1 sau valoarea 0.readShort(). writeDouble(double <v>). Fiecare dintre metodele de citire prezentate incearca sa citeasca un numar de octeti egal cu lungimea pe care sunt reprezentate tipurile respective indicate in numele metodei. implicit limita inferioara este 0 iar limita superioara este 255. writeLong(long <v>). writeShort(short <v>). Limita inferioara si limita superioara din seria de numere reale sunt specificate in doua argumente transmise prin linia de comanda.<in> . ca in exemplul urmator: java IOBinarTampon 2 30 Daca nu se transmit argumente prin linia de comanda.readLong(). toate operatiile legate de fluxuri se incadreaza in blocuri try … catch.datele vor fi scrise in fluxul de iesire intr-un format independent de modul de reprezentare al datelor in sistemul pe care se lucreaza. De exemplu. writeBoolean(boolean <v>). . . Constructorul clasei DataOutputStream creaza un nou flux de iesire ce suprapune pe cel existent primit ca argument. Fiecare dintre metodele de scriere prezentate incearca sa scrie un numar de octeti egal cu lungimea pe care sunt reprezentate tipurile respective indicate in numele metodei. metoda readBoolean() citeste un octet si returneaza true daca octetul citit este diferit de zero. Constructorul are forma: DataOutputStream(OutputStream <out>) unde: .readFloat(). writeChar(char <v>). Deoarece fluxurile filtrate de intrare/iesire cu date de tipuri primitive semnaleaza exceptia IOException la aparitia unei erori. un flux de intrare cu tampon sau un flux de intrare din fisier. si respectiv de tipul DataOutputStream: . writeInt(int <v>).java) scrie o serie de valori de tip float intr-un flux de iesire DataOutputStream cu tampon asociat cu un fisier pe disc. 2. In astfel de cazuri se semnaleaza exceptia EOFException care indica faptul ca s-a ajuns la sfarsitul fluxului de intrare. . Datele citite folosind metodele clasei DataInputStream trebuie sa fi fost scrise in fisier cu metodele complementare ale clasei DataOutputStream. Constructorul clasei DataInputStream creaza un nou flux de intrare ce suprapune pe cel existent primit ca argument. Nu toate metodele de citire dintr-un flux de tip DataInputStream returneaza o valoare ce poate indica faptul ca s-a ajuns la sfarsitul fluxului.

return true.scrieFlux(). i <= sfarsit. } catch(IOException e) { System.parseFloat(args[1]). limSup). boolean succesCiteste = fd.out.sfarsit = sfarsit. try { if (args.close(). float sfarsit) { this.io. 79 .out. return false.inceput = inceput. for (float i = inceput.dat"))).println("Eroare: " + "Nu ati introdus un numar real"). private float sfarsit = 255.getMessage()).5) fluxDate. System.Dupa scrierea in fisier. float limSup = 255. } } boolean citesteFlux() { try { DataInputStream fluxDate = new DataInputStream( new BufferedInputStream(new FileInputStream("numere. FluxDatePrimitive fd = new FluxDatePrimitive(limInf.out.*.println("\nCiteste: ").length > 1) { limInf = Float. } catch(NumberFormatException nfe) { System. } boolean scrieFlux() { try { DataOutputStream fluxDate = new DataOutputStream( new BufferedOutputStream(new FileOutputStream("numere. programul deschide un flux de intrare cu tampon si citeste datele de tip float scrise in fisier.writeFloat(i). } else if(args.length > 0) limInf = Float.dat"))). i+=0.citesteFlux(). public class IODataTampon { public static void main (String [] args) { float limInf = 0.parseFloat(args[0]). } } } class FluxDatePrimitive { private float inceput = 0. fluxDate. float i = 0. this. limSup = Float. import java.parseFloat(args[0]). public FluxDatePrimitive(float inceput. boolean succesScrie = fd.print("Eroare: " + e.

String si alte tipuri de obiecte in format text. Metodele acestei clase nu semnaleaza niciodata exceptia IOException. Prezentam doi dintre constructorii acestei clase: PrintStream(OutputStream <out>) PrintStream(OutputStream <out>.out. pe care l-am folosit aproape in toate lectiile de pana acum pentru afisarea mesajelor la ecranul calculatorului. este de fapt un flux de tip PrintStream. <auto_golire> . clasa PrintStream converteste numarul la caracterele “4” si “2” si apoi transmite caracterele mai departe in flux. Fluxuri filtrate cu date formatate Clasa PrintStream furnizeaza un flux filtru de iesire care permite afisarea de numere. Metoda readFloat() citeste valorile intregi din flux. valori boolean.se creaza un flux de iesire in fisier.dat”.out. atunci cand programul afiseaza valoarea intreaga 42. System.getMessage()). asociat cu fisierul “numere. boolean <auto_golire>) unde: . } return true. fluxul PrintStream da posibilitatea (optional) de a goli automat zona tampon dupa ce a fost scris un tablou de octeti sau un octet egal cu ‘\n’. return false.print(" " + i). } } catch(EOFException eof) { fluxDate. De exemplu. . Fluxul System.se asociaza fluxului de iesire cu tampon un flux de tip DataInputStream.close().se asocieaza fluxului de fisier un flux de iesire filtrat cu tampon. Fluxul filtrat este construit in trei etape: . .specifica fluxul de iesire existent. pentru ca la un moment dat va fi atins sfarsitul fluxului si va fi semnalata o exceptie EOFException. Mentionam cateva metode ale acestei clase: .out. } } } Aplicatia prezentata este un exemplu de suprapunere a mai multor filtre peste un flux original de tip FileInputStream. In plus.<out> .print (String <s>) . B3.try { while (true) { i = fluxDate. Instructiunea while(true) din metoda citesteFlux() creaza un ciclu infinit in aparenta.readFloat(). } catch(IOException e) { System.specifica daca se goleste automat zona tampon dupa ce a fost scris un tablou de octeti sau un octet egal cu ‘\n’ (daca valoarea este true). Filtrul de iesire PrintStream converteste numerele si alte tipuri de date la reprezentari text. inainte de transmiterea datelor la fluxul de iesire.print("Eroare: " + e.

txt”. ps. urmatoul program (PrintStreamFile.print (char <c>) .print (float <f>) .valueOf(x).close(). inclusiv un fisier text ASCII. “print.print(nr2). In plus.PI). Un flux PrintStream nu are ca destinatie numai ecranul calculatorului ci orice destinatie de flux.5. public class PrintStreamFile { public static void main(String [] args) { double nr1 = 234. care adauga caracterul ‘\n’ in fluxul de iesire.java) afiseaza un String. Metodele print si println scriu argumentul lor intr-un format de tip text si anume identic cu cel produs de apelurile metodei String.txt")).io. } catch(IOException e) { System.getMessage()). int nr2 = 120. ps. un intreg si un numar in virgula mobila intr-un fisier. ps. De exemplu. documentele HTML sau fisiere care contin cod sursa Java.print(nr1). ps.3 Fluxuri de caractere si clase predefinite Java utilizate Fluxurile de caractere se folosesc pentru lucrul cu orice text reprezentat in format ASCII sau Unicode (set de caractere international care include si ASCII). Fluxuri de caractere de intrare nefiltrate si filtrate 81 .print (char <c>) .. } } } 6. try { PrintStream ps = new PrintStream(new FileOutputStream("print. care scrie doar caracterul de sfarsit de linie ‘\n’.println(Math. Ele opereaza asupra sirurilor de caractere si tablourilor de caractere.print(' '). exista si metoda println fara parametrii.println ("Date pentru testarea fluxului PrintStream").out. Exemple de fisiere cu care putem lucra prin intermediul fluxurilor de caractere sunt fisierele de text simplu. import java.println("Eroare la scrierea fisierului: " + e.print (boolean <b>) .println(). ps.print (double <d>) Pentru fiecare metoda print exista si perechea ei println. ps.*. ps. A.print (long <l>) .print (int <i>) .

<poz_ini> .un tablou de caractere in care se vor memora datele citite.numarul de caractere care se vor citi din fluxul de intrare repetand metoda read fara parametri.65535. toate operatiile legate de fluxuri se incadreaza in blocuri try … catch. int <poz_ini>. care citeste un flux de octeti si ii converteste in valori intregi corespunzatoare caracterelor Unicode. Este indicat sa folosim clasa Reader pentru lucru cu text si nu fluxuri de octeti. Daca fisierul nu poate fi deschis. Nota: Deoarece fluxurile de intrare semnaleaza exceptia IOException la aparitia unei erori. Descriem cateva dintre ele. Metoda read() citeste un caracter din fluxul de intrare.In schema de mai jos se prezinta doar o parte a structurii de clase ce poate fi folosita in operatiile cu fluxuri de caractere de intrare nefiltrate si filtrate. care are forma: FileReader(String <sir>) unde: . Crearea (deschiderea) unui flux de intrare de la un fisier se realizeaza cu ajutorul constructorului clasei FileReader. la specificarea caii fisierului trebuie sa se foloseasca doua caractere backslash pentru a nu se confunda cu o secventa escape. si eventual calea. pe CD-ROM sau pe alte dispozitive de stocare (ce pot fi referite printr-o cale de director si un nume) catre aplicatia Java. Principala clasa folosita pentru citirea de fluxuri de caractere dintr-un fisier este FileReader. Metoda read cu trei parametrii are forma: read (char [] <c>.doc”: FileReader document = new FileReader(“test. A.1 Fluxuri nefiltrate de caractere de intrare care folosesc ca sursa un fisier Sunt folosite pentru transferul de date de la fisierele aflate pe hard-discuri. Dupa deschiderea fluxului de caractere de intrare din fisier se pot folosi metodele acestui flux pentru realizarea diverselor operatii de intrare. fisierului. . Aceasta clasa mosteneste clasa InputStreamReader.<sir> . care sa intercepteze aceasta exceptie. urmatoarea instructiune deschide un flux de intrare de la fisierul “test.<c> .pozitia elementului din cadrul tabloului unde se va stoca primul caracter de date. Daca s-a detectat sfarsitul de fisier. Clasa Reader este o clasa abstracta si din ea deriveaza toate celelalte clase care creaza fluxuri de caractere de intrare si realizeaza operatii de intrare pe aceste fluxuri. atunci este lansata exceptia FileNotFoundException.<lungime> .doc”). rezultatul intors este un intreg din intervalul 0 . rezultatul intors este -1. int <lungime>) unde: . De exemplu.reprezinta numele. . .

de la inceput. Daca dupa citirea primului sir. in zona tampon mai exista caractere necitite (ceea ce inseamna ca s-a introdus un sir de lungime mai mare de 20) atunci acestea vor fi sarite din fluxul de intrare pentru a permite eliberarea zonei tampon si citirea de la tastatura a celui de al doilea sir.*. Metoda skip avanseaza cu n pozitii (caractere) in fluxul de intrare. nedepasind bineinteles sfarsitul fluxului. Dintr-un flux de caractere cu tampon se poate citi folosind metodele read() si read (char [] <c>. b) BufferedReader(Reader <in>.2 Fluxuri filtrate de caractere de intrare cu o zona tampon (“buffer”) Fluxurile de caractere cu o zona tampon (“buffer”) permit utilizarea unei zone tampon pentru cresterea eficientei operatiilor de citire. class CitesteSiruri { public static void main(String[] args) 83 . ready() si close() sunt asemanatoare celor descrise pentru clasa FileReader.reprezinta fluxul original de tip Reader. Constructorii clasei BufferedReader au una din formele: a) BufferedReader(Reader <in>) unde: . Rezultatul intors de metoda este numarul de pozitii peste care s-a trecut efectiv. . int <lungime>) . Fiecare caracter poseda un cod numeric care reprezinta pozitia sa in setul de caractere Unicode. int <lg_buffer>) unde: . Metodele skip().<in> .io. Metoda skip are forma: skip(long <n>) unde : <n> . Metoda ready() specifica daca acest flux de caractere este disponibil pentru a fi citit. Nota: Deoarece metoda read() a unui flux de caractere returneaza o valoare intreaga.reprezinta lungimea zonei tampon a fluxului de intare. Un flux de caractere dintr-un fisier este disponibil pentru a fi citit daca zona tampon de intrare nu este goala (in caz ca ea exista) sau daca exista octeti disponibili de a fi cititi de la fluxul de octeti de tip InputStreamReader. Valoarea intreaga citita din flux reprezinta chiar acest cod numeric. trebuie sa se converteasca explicit prin cast aceasta valoare inainte de a o afisa sau de a o salva intr-un tablou de caractere.nr de caractere sarite in fluxul de intrare. Nota: Zona tampon are o lungime care este aleasa implicit (automat). Metoda close() inchide fluxul de intrare respectiv si elibereaza resursele sistem asociate cu acesta.<lg_buffer> . int <poz_ini>. Crearea (deschiderea) unui flux de caractere cu tampon se realizeaza cu ajutorul constructorilor clasei BufferedReader. fluxul de intrare este la sfarsitul sau. import java.Metoda returneaza un intreg care reprezinta numarul de caractere citite sau -1 daca.reprezinta fluxul original de tip Reader.<in> . A. asemanatoare celor descrise pentru clasa FileReader. Fluxurile de caractere de intrare cu tampon folosesc clasa BufferedReader.java) citeste doua siruri de caractere de la tastatura si le stocheaza intr-un tablou de caractere de lungime 20. Programul urmator (CitesteSiruri.

skip (1). 0. import java. String sir2 = new String(caractere2). i <=19. fara a include si caracterul (sau caracterele) care reprezinta sfarsitul de linie. } catch(IOException e) { System. if (rezultat ==true) System. System.read(caractere1. Ca exemplu. 20). System.io. putem ilustra deschiderile de flux de intare cu tampon si citirile de linii de text de la tastatura.‘\r’). public class CitesteLiniiFisier { public static void main (String [] args) { try { . for (int i=0. i++) caractere2[i] = ' '.println ("siruri egale"). daca se foloseste un flux de caractere cu tampon de tip BufferedReader suprapus peste un flux de tip FileReader.ready() ) br. while (br.read(caractere2. br.println ("Introduceti primul sir"). String sir1 = new String(caractere1).un caracter de retur de car (carriage return . for ( int i=0. Programul urmator (CitesteLiniiFisier. System.{ char[] caractere1 = new char[20]. si nu caracter cu carecter. i++) caractere1[i] = ' '. 20). Dintr-un fisier se poate citi o intreaga linie de text. try { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)).println(sir1).out. Metoda returneaza un obiect de tip String care contine linia de text citita din flux .getMessage()).java”).out. .out. folosind un flux de caractere cu zona tampon. Sfarsitul de linie este indicat astfel: .println(sir2). Daca se ajunge la sfarsitul fluxului. boolean rezultat = false.un retur de car urmat de o linie noua.println ("siruri diferite").equals(sir2). .println ("Introduceti al doilea sir").out. 0.println ("Eroare la sirul citit" + e. } } } Metoda readLine() citeste din fluxul de intrare o linie de text.out. i <=19.‘\n’).*.out.out.un caracter de linie noua (newline . br.java) ilustreaza modul de citire linie cu linie dintr-un fisier care contine instructiuni Java (numit “CitesteLiniiFisier. valoarea sirului returnat va fi null. facute in aproape toate programele Java prezentate pana acum. else System. System. char[] caractere2 = new char[20]. rezultat = sir1.

<in> .java")). Dintr-un fisier se poate citi o intreaga linie de text si se poate tine evidenta numerelor citite daca se foloseste un flux de caractere cu tampon de tip LineNumberReader suprapus peste un flux de tip FileReader.reprezinta fluxul original de tip Reader. .reprezinta fluxul original de tip Reader. b) LineNumberReader(Reader <in>. boolean eof = false.println(linie).BufferedReader fisier = new BufferedReader( new FileReader("CitesteLiniiFisier.reprezinta lungimea zonei tampon a fluxului de intare. Programul urmator (CitesteLiniiFisier.io. testarea unui flux de intrare cu tampon sunt mostenite de la clasa BufferedReader si ele au fost prezentate deja.<in> . } fisier.java”).out. aceasta clasa ofera metoda getLineNumber() care este folosita pentru a obtine numarul liniei curente din fluxul de intrare atunci cand acesta este citit cu metoda readLine().close(). In plus. Metoda returneaza un intreg care reprezinta numarul liniei curente din flux.getMessage()). inchiderea. import java. int <lg_buffer>) unde: . folosind un flux de caractere cu zona tampon tip LineNumberReader. else System. Acest filtru al fluxului de intrare urmareste numarul de linie pe masura citirii din fluxul de intrare. 85 . if (linie == null) eof = true. while(!eof) { String linie = fisier. Constructorii clasei LineNumberReader au una din formele: a) LineNumberReader(Reader <in>) unde: . Crearea (deschiderea) unui flux de caractere cu tampon care tin evidenta numerelor de linie se realizeaza cu ajutorul constructorilor clasei LineNumberReader. Metodele pentru citirea.readLine().3 Fluxuri filtrate de caractere de intrare cu o zona tampon care tin evidenta numerelor de linie Fluxurile de caractere de intrare cu tampon care tin evidenta numerelor de linie dintr-un fisier folosesc clasa LineNumberReader. } } } A. Nota: Zona tampon are o lungime care este aleasa implicit (automat).<lg_buffer> .*.println("Eroare: " + e.java) afiseaza numerele liniilor citite dintr-un fisier care contine instructiuni Java (numit “CitesteLiniiFisier1.out. } catch(IOException e) { System.

getMessage()).out.println("Eroare: " + e.public class CitesteLiniiFisier1 { public static void main (String [] args) { try { LineNumberReader fisier = new LineNumberReader(new FileReader("CitesteLiniiFisier1. else System. boolean eof = false. } fisier.out.readLine(). if (linie == null) eof = true.println(fisier. } catch(IOException e) { System. } } } .java")).close(). while(!eof) { String linie = fisier.getLineNumber() + " " + linie).

Fractia retinuta de un obiect trebuie sa fie ireductibila.realizati o clasa extinsa automobil_leasing cu data membra rata si definiti doua obiecte din aceasta clasa. Obiectele de tip stiva contin metodele (adaugare.construiti 2 obiecte din clasa definita mai sus. 3. salariul si cel putin doi constructori pentru intitializarea obiectelor.(setarea valorilor. . extragere. . calculul modului unui numar complex. . -construiti doua obiecte rationale si afisati suma lor in fisierul “date. cu un parametru. afisare. capcitate. Scrieti metode pentru prelucrarea obiectelor de tip complex (adunarea a doua numere complexe.Aplicatii propuse : 1. Implementati o clasa punct_plan care defineste un punct in plan cu atributele abcisa.construiti doua obiecte punct_plan si afisati distanta dintre ele in fisierul “date. .Implementati tipul rational cu atributele numarator si numitor si trei constructori : implicit. functie. Construiti tipul automobil definit prin datele membre : marca. cu un parametru si cu doi parametrii. afisare. Scrieti metode pentru setarea datelor de la tastatura. Construiti doua obiecte de tip angajat si afisati datele lor in fisierul “date.construiti doua obiecte de tip complex si afisati in fisierul ”date. testare daca stiva este vida).in” modulele si suma lor. cu un parametru si cu doi parametrii. afisarea datelor. extragere. . doi parametrii. testare daca stiva este vida). Implementati o clasa pentru numere complexe cu atributele real si imaginar si trei constructori : implicit.Implementati o clasa angajat cu atributele nume. Scrieti metode care prelucreaza puncte_plan cu date trimise de la tastatura. .construiti o interfata care modeleaza notiunea de stiva de obiecte. ordonata si trei constructori : implicit. Introduceti in clasa cel putin doi constructori pentru initializarea obiectelor de tip automobil. . setarea datelor unui obiect de tip complex cu date trimise de la tastatura). Scrieti o metoda pentru adunarea a doua numere rationale. 5. Extineti clasa definita mai sus la clasa angajat_determinat cu data membra perioada si construiti doua obiecte de acest tip.in”.construiti o interfata care modeleaza notiunea de stiva de obiecte. 2. afisare. 4. an_fabricatie. testare daca stiva este vida). 87 .construiti o stiva care contine obiecte de tip punct_plan.Construiti o stiva cu numere rationale.in”. . .conversie String). Obiectele de tip stiva contin metodele (adaugare. extragere.construiti o stiva cu numere complexe.construiti o interfata care modeleaza notiunea de stiva de obiecte. .in”. calculul distantei intre doua puncte. Obiectele de tip stiva contin metodele (adaugare.

about. http://java. “Thinking in Java.2002. http://java. 3rd ed. Cristian Olaru.Bibliografie 1. Stefan Andrei. Revision 4. 2. The Java™ Tutorials. Thinking in Java. Stefan Tanasa.sun. Editura Polirom 2007. Horia Georescu.0. Java Programming Tutorial.com/docs/books/tutorial/java/TOC. 3rt Edision”. “JAVA de la 0 la expert”. Editura Prentice – Hall.htm 3. Bruce Eckel. “Introducere in universul Java”. Doina Logofatu. . Bruce Eckel. 7. Sun Microsystems. Kevin Taylor. 2003. 6.com/od/beginningjava/a/beginjavatutor. Editura Polirom. Aplicatii “. 2002. Editura Tehnica. “Algoritmi fundamentali in Java.ro/mirrors/eckelbooks/TIJ3/TIJ3. http://arh.htm 4.html 5.pub.

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->