curs poo id

Upload: giurgiurubin

Post on 14-Jul-2015

218 views

Category:

Documents


1 download

TRANSCRIPT

FIFOR CARMEN

PROGRAMARE ORIENTAT OBIECTMaterial de studiu pentru nvmntul la distan

Specializarea: Informatic, Anul II

Arad, 2010

CuprinsPrefa .................................................................................................................................................. 3 I. Introducere n Java ............................................................................................................................ 5 1.1 Ce este Java ? ............................................................................................................................. 5 1.2 Primul program .......................................................................................................................... 7 1.3 Structura lexical a limbajului Java ........................................................................................... 8 1.4 Tipuri de date i variabile......................................................................................................... 11 1.5 Controlul execuiei ................................................................................................................... 13 1.6 Tipuri enumerate (enum).......................................................................................................... 16 1.7 Folosirea argumentelor de la linia de comand........................................................................ 17 II. Elemente de baz ale programarii orientate obiect........................................................................ 21 2.1 Clase i obiecte............................................................................................................................. 21 2.1.1 Crearea claselor ..................................................................................................................... 21 2.1.2 Clase imbricate ...................................................................................................................... 28 2.1.3 Crearea obiectelor ................................................................................................................. 30 2.1.4 Membri de instan i membri de clas ................................................................................. 32 2.1.5 Tablouri ................................................................................................................................. 33 2.1.6 iruri de caractere ................................................................................................................. 35 2.2 Motenirea .................................................................................................................................... 40 2.2.1 Ce este motenirea? ............................................................................................................... 40 2.2.2 Suprancrcarea i supradefinirea metodelor ........................................................................ 40 2.2.3 Clasa Object .......................................................................................................................... 41 2.2.4 Clase i metode abstracte ...................................................................................................... 43 2.2.5 Interfee ................................................................................................................................. 45 2.2.6 Adaptori ................................................................................................................................ 49 2.2.7 Polimorfism ........................................................................................................................... 49 2.3 Excepii ........................................................................................................................................ 54 2.3.1 Ce sunt excepiile ? ............................................................................................................... 54 2.3.2 Ierarhia claselor ce descriu excepii ...................................................................................... 55 2.3.3 Prinderea i tratarea excepiilor ......................................................................................... 55 2.3.4 Aruncarea excepiilor de ctre o metod ........................................................................... 57 2.3.5 Avantajele tratrii excepiilor................................................................................................ 58 2.3.6 Excepii la execuie ............................................................................................................... 58 2.3.7 Excepii definite de utilizator ................................................................................................ 58 2.4 Intrri i ieiri. Fluxuri ................................................................................................................. 60 2.4.1 Introducere ............................................................................................................................ 60 2.4.2 Fluxuri primitive ................................................................................................................... 62 2.4.3 Fluxuri de procesare .............................................................................................................. 62 2.4.4 Crearea unui flux ................................................................................................................... 63 2.4.5 Fluxuri pentru lucrul cu fiiere .............................................................................................. 64 2.4.6 Citirea i scrierea cu buffer ................................................................................................... 65 2.4.7 Clasele DataInputStream i DataOutputStream .................................................................... 66 2.4.8 Fluxuri standard de intrare i ieire ....................................................................................... 67 2.4.9 Intrri i ieiri formatate ........................................................................................................ 68

2.4.10 Clasa RandomAccesFile (fiiere cu acces direct) ............................................................... 70 2.4.11 Clasa File ............................................................................................................................ 72 2.5 Colecii ......................................................................................................................................... 75 2.5.1 Introducere ............................................................................................................................ 75 2.5.2 Interfee ce descriu colecii ................................................................................................... 75 2.5.3 Implementri ale coleciilor .................................................................................................. 78 2.5.4 Folosirea eficient a coleciilor ............................................................................................. 79 2.5.5 Algoritmi polimorfici ............................................................................................................ 80 2.5.6 Tipuri generice ...................................................................................................................... 80 2.5.7 Iteratori i enumerri ............................................................................................................. 81 III. Operatii speciale asupra claselor si obiectelor ...................................................................... 86 3.1 Serializarea obiectelor .................................................................................................................. 86 3.1.1 Folosirea serializrii .............................................................................................................. 86 3.1.2 Obiecte serializabile .............................................................................................................. 89 3.1.3 Personalizarea serializrii obiectelor .................................................................................... 90 3.2 Fire de execuie ............................................................................................................................ 95 3.2.1 Introducere ............................................................................................................................ 95 3.2.2 Crearea unui fir de execuie .................................................................................................. 96 3.2.3 Ciclul de via al unui fir de execuie ................................................................................... 99 3.2.4 Comunicarea prin fluxuri de tip pipe .............................................................................. 102 3.3 Organizarea claselor................................................................................................................... 105 3.3.1 Pachete ................................................................................................................................ 105 3.3.2 Organizarea fiierelor.......................................................................................................... 108 3.3.3 Arhive JAR ......................................................................................................................... 111 3.3.4 javadoc ................................................................................................................................ 112 Rspunsuri la testele de evaluare ..................................................................................................... 115

Programare orientat obiect Prefa

3

Ce nseamn Programarea orientat pe obiecte (POO)?Programarea orientat obiect este unul din cei mai importani pai fcui n evoluia limbajelor de programare spre o mai puternic abstractizare n implementarea programelor. ntrebarea este: la ce se refer aceast abstractizare cnd vine vorba de un limbaj de programare? Ea a aparut din necesitatea exprimarii problemei ntr-un mod mai natural fiinei umane. Astfel unitile care alctuiesc un program se apropie mai mult de modul nostru de a gndi dect modul de lucru al calculatorului. Pn la apariia programrii orientate obiect, programele erau implementate n limbaje de programare procedurale (C, Pascal) sau n limbaje care nici mcar nu ofereau o modalitate de grupare a instruciunilor n uniti logice (functii, proceduri) cum este cazul limbajului de asamblare (assembler). Altfel spus, o problem preluat din natur trebuia fragmentat n repetate rnduri, astfel nct s se identifice elementele distincte, implementabile ntr-un limbaj de programare. O mare problem a programrii procedurale era separarea datelor de unitile care prelucrau datele (subrutinele), ceea ce facea foarte dificil extinderea i ntreinerea unui program. Astfel, s-a pus problema ca aceste dou entiti (date i subrutine) s fie grupate ntr-un anumit mod, astfel nct subrutinele s "tie" n permanen ce date prelucreaz i, mai mult dect att, ele s formeze un modul, adic o unitate care separ implementarea de interfa, ceea ce implic posibilitatea refolosirii codului. A aparut astfel conceptul de clas. Clasa grupeaz datele i unitile de prelucrare a acestora ntr-un modul, unindu-le astfel ntr-o entitate mult mai natural. Dei tehnica se numete "Programare Orientata Obiect", conceptul de baz al ei este este Clasa. Clasa, pe lng faptul c abstractizeaz foarte mult analiza/sinteza problemei, are proprietatea de generalitate, ea desemnnd o mulime de obiecte care mpart o serie de proprieti comune. De exemplu: Clasa "floare" desemneaz toate plantele care au flori, precum clasa "Fruct" desemneaz toate obiectele pe care noi le identificam ca fiind fructe. Binenteles, n implementarea efectiv a programului nu se lucreaz cu entitati abstracte, precum clasele ci se lucreaz cu obiecte, care sunt "instanieri" ale claselor. Altfel spus, plecnd de la exemplul de mai sus, dac se construiete un program care s lucreze cu fructe, el nu va prelucra entitatea "fruct" ci va lucra cu entiti concrete ale clasei "fruct", adic "mr", "par", "portocal", etc. Odat identificate entitile (n spe clasele) ele nu rmn izolate; ele vor fi grupate n module, pachete, programe, etc., care vor stabili legaturi ntre ele. Aceste legturi reflect relaiile care se stabilesc ntre clasele/obiectele problemei pe care am preluat-o din natur. Ideea POO este de a vedea programele ca o colecie de obiecte, uniti individuale de cod care interacioneaz unele cu altele, n loc de simple liste de instruciuni sau de apeluri de proceduri. Principiile de baz ale POO: - Abstractizarea - ncapsularea - Polimorfismul - Motenirea Note

4

Programare orientat obiect

Note

Programare orientat obiect I. Introducere n Java

5

Obiective: Cunoaterea structurii lexicale a limbajului Java (identificatori, terea literali, cuvinte cheie) Cunoaterea operatorilor Java i a modului corect de folosire a terea i lor Cunoaterea tipurilor de date primitive terea Cunoaterea setului de instruc iuni de control si modul corect instruciuni de folosire a lor Cunoaterea modului de lucru cu argumentele transmise din terea linia de comand 1.1 Ce este Java ? Java este o tehnologie inovatoare lansat de compania Sun Microsystems lansat n 1995, care a avut un impact remarcabil asupra ntregii comunit comuniti a dezvoltatorilor de software, impunndu impunndu-se prin caliti deosebite cum ar fi i simplitate, robustee i nu n ultimul rnd portabilitate. Denumit iniial OAK, i Denumit ial tehnologia Java este format dintr dintr-un limbaj de programare de nivel nalt pe baza aj cruia sunt construite o serie de platforme destinate implement rii de aplica ruia implementrii aplicaii pentru toate segmentele industriei software.

1.1.1 Limbajul de programare JavaInainte de a prezenta n detaliu aspectele tehnice ale limbajului Java, sa amintim caracteristicile sale principale, care l l-au transformat ntr-un interval de un timp att de scurt ntr-una din cele mai populare op iuni pentru dezvoltarea de una opiuni aplicaii, indiferent de domeniu sau de complexitatea lor. ii, Simplitate - elimina suprancarcarea operatorilor, mo tenirea multipla toate motenirea i facilitaile ce pot provoca scrierea unui cod confuz. ile Uurina n crearea de aplicaii complexe ce folosesc programarea n reea, fire a aplicaii de execuie, interfaa grafica, baze de date, et a etc. Robustee - elimin sursele frecvente de erori ce apar n programare prin renunarea la pointeri, administrarea automat a memoriei i eliminarea area automat i pierderilor de memorie printr-o procedura de colectare a obiectelor care nu mai -o sunt referite, ce ruleaza n fundal (garbage collector). Complet orientat pe obiecte - elimin complet stilul de programare procedural. Securitate - este un limbaj de programare foarte sigur, furniznd mecanisme stricte de securitate a programelor concretizate prin: verificarea dinamica a verificarea codului pentru detectarea secven elor periculoase, impunerea unor reguli stricte secvenelor pentru rularea proceselor la distan etc. distana, Neutralitate arhitectural - comportamentul unei aplica ii Java nu depinde de aplicaii arhitectura fizic a mainii pe care ruleaz. inii Portabililtate - Java este un limbaj independent de platforma de lucru, aceea aceeai aplicaie rulnd fr nici o modificare i fr a necesita recompilarea ei pe sisteme de operare diferite cum ar fi Windows, Linux, Mac OS, Solaris, etc. lucru care aduce economii substaniale firmelor dezvoltatoare de aplica iale aplicaii. Este compilat i interpretat, aceasta fiind solu i soluia eficient pentru ob obinerea portabilitaii.

Note

6

Programare orientat obiect Performana - dei mai lent dect limbajele de programare care genereaz executabile native pentru o anumit platform de lucru, compilatorul Java asigur o performan ridicat a codului de octei, astfel nct viteza de lucru puin mai scazut nu va fi un impediment n dezvoltarea de aplicaii orict de complexe, inclusiv grafica 3D, animaie, etc. Este modelat dup C i C++, astfel trecerea de la C, C++ la Java facndu-se foarte uor.

1.1.2 Platforme de lucru JavaLimbajul de programare Java a fost folosit la dezvoltarea unor tehnologii dedicate rezolvarii unor probleme din cele mai diverse domenii. Aceste tehnologii au fost grupate n aa numitele platforme de lucru, ce reprezinta seturi de librarii scrise n limbajul Java, precum i diverse programe utilitare, folosite pentru dezvoltarea de aplicaii sau componente destinate unei anume categorii de utilizatori. J2SE (Standard Edition): Este platforma standard de lucru ce ofer suport pentru crearea de aplicaii independente i appleturi. De asemenea, aici este inclus i tehnologia JavaWeb Start ce furnizeaz o modalitate extrem de facil pentru lansarea i instalarea local a programelor scrise n Java direct de pe Web, oferind cea mai comod soluie pentru distribuia i actualizarea aplicaiilor Java. J2ME (Micro Edition): Folosind Java, programarea dispozitivelor mobile este extrem de simpl, platforma de lucru J2ME oferind suportul necesar scrierii de programe dedicate acestui scop. J2EE (Enterprise Edition): Aceast platform ofer API-ul necesar dezvoltrii de aplicaii complexe, formate din componente ce trebuie s ruleze n sisteme eterogene, cu informaiile memorate n baze de date distribuite, etc. Tot aici gsim i suportul necesar pentru crearea de aplicaii i servicii Web, bazate pe componente cum ar fi servleturi, pagini JSP, etc. Toate distribuiile Java sunt oferite gratuit i pot fi descarcate de pe Internet de la adresa http://java.sun.com. n continuare, vom folosi termenul J2SDK pentru a ne referi la distribuia standard J2SE 1.5 SDK (Tiger).

1.1.3 Java: un limbaj compilat i interpretatn funcie de modul de execuie a aplicaiilor, limbajele de programare se mpart n doua categorii: Interpretate: instruciunile sunt citite linie cu linie de un program numit interpretor i traduse n instruciuni main. Avantajul acestei soluii este simplitatea i faptul c, fiind interpretat direct sursa programului, obinem portabilitatea. Dezavantajul este viteza de execuie redus. Probabil cel mai cunoscut limbaj interpretat este limbajul Basic. Compilate: codul surs al programelor este transformat de compilator ntr-un cod ce poate fi executat direct de procesor, numit cod maina. Avantajul este execuia extrem de rapid, dezavantajul fiind lipsa portabilitaii, codul compilat ntr-un format de nivel scazut nu poate fi rulat dect pe platforma de lucru pe care a fost compilat. Limbajul Java combina soluiile amintite mai sus, programele Java fiind att interpretate ct i compilate. Aadar vom avea la dispoziie un compilator responsabil cu transformarea surselor programului n aa numitul cod de octei, precum i un interpretor ce va executa respectivul cod de octei. Codul de octei

Note

Programare orientat obiect este diferit de codul main. Codul main este reprezentat de o succesiune de instruciuni specifice unui anumit procesor i unei anumite platforme de lucru reprezentate n format binar astfel nct s poat fi executate fr a mai necesita nici o prelucrare. Codurile de octei sunt seturi de instruciuni care seamn cu codul scris n limbaj de asamblare i sunt generate de compilator independent de mediul de lucru. n timp ce codul main este executat direct de ctre procesor i poate fi folosit numai pe platforma pe care a fost creat, codul de octei este interpretat de mediul Java i de aceea poate fi rulat pe orice platforma pe care este instalata mediul de execuie Java. Prin maina virtuala Java (JVM) vom nelege mediul de execuie al aplicaiilor Java. Pentru ca un cod de octei s poat fi executat pe un anumit calculator, pe acesta trebuie s fie instalat o main virtual Java. Acest lucru este realizat automat de ctre distribuia J2SDK. 1.2 Primul program Crearea oricrei aplicaii Java presupune efectuarea urmtorilor pai: 1. Scriererea codului surs class FirstApp { public static void main(String args[]) { System.out.println("Hello world!"); } } Toate aplicaiile Java conin o clas principal(primar) n care trebuie s se gaseasc metoda main. Clasele aplicaiei se pot gasi fie ntr-un singur fiier, fie n mai multe. 2. Salvarea fiierelor surs Se va face n fiiere care au obligatoriu extensia java, nici o alt extensie nefiind acceptat. Este recomandat ca fiierul care conine codul surs al clasei primare s aib acelai nume cu cel al clasei, dei acest lucru nu este obligatoriu. S presupunem c am salvat exemplul de mai sus n fiierul C:\intro\FirstApp.java. 3. Compilarea aplicaiei Pentru compilare vom folosi compilatorul javac din distribuia J2SDK. Apelul compilatorului se face pentru fiierul ce conine clasa principala a aplicaiei sau pentru orice fiier/fiiere cu extensia java. Compilatorul creeaza cte un fiier separat pentru fiecare clasa a programului. Acestea au extensia .class i implicit sunt plasate n acelai director cu fiierele sursa. javac FirstApp.java n cazul n care compilarea a reuit va fi generat fiierul FirstApp.class. 4. Rularea aplicaiei Se face cu interpretorul java, apelat pentru unitatea de compilare corespunzatoare clasei principale. Deoarece interpretorul are ca argument de intrare numele clasei principale i nu numele unui fiier, ne vom poziiona n directorul ce conine fiierul FirstApp.class i vom apela interpretorul astfel: java FirstApp Rularea unei aplicaii care nu folosete interfaa grafica, se va face ntr-o fereastra sistem. Note

7

8 1.3 Structura lexical a limbajului Java

Programare orientat obiect

1.3.1 Setul de caractereLimbajului Java lucreaz n mod nativ folosind setul de caractere Unicode. Acesta este un standard internaional care nlocuiete vechiul set de caractere ASCII i care folosete pentru reprezentarea caracterelor 2 octei, ceea ce nseamn c se pot reprezenta 65536 de semne, spre deosebire de ASCII, unde era posibil reprezentarea a doar 256 de caractere. Primele 256 caractere Unicode corespund celor ASCII, referirea la celelalte fcndu-se prin \uxxxx, unde xxxx reprezint codul caracterului. O alta caracteristic a setului de caractere Unicode este faptul ca ntreg intervalul de reprezentare a simbolurilor este divizat n subintervale numite blocuri, cteva exemple de blocuri fiind: Basic Latin, Greek, Arabic, Gothic,Currency, Mathematical, Arrows, Musical, etc. Mai jos sunt oferite cteva exemple de caractere Unicode. \u0030 - \u0039 : cifre ISO-Latin 0 - 9 \u0660 - \u0669 : cifre arabic-indic 0 - 9 \u03B1 - \u03C9 : simboluri greceti \u2200 - \u22FF : simboluri matematice (,,, etc.) \u4e00 - \u9fff : litere din alfabetul Han (Chinez, Japonez, Coreean) Mai multe informaii legate de reprezentarea Unicode pot fi obinute la adresa http://www.unicode.org.

1.3.2 Cuvinte cheieCuvintele rezervate n Java sunt, cu cteva excepii, cele din C++ i au fost enumerate n tabelul de mai jos. Acestea nu pot fi folosite ca nume de clase, interfee, variabile sau metode. true, false, null nu sunt cuvinte cheie, dar nu pot fi nici ele folosite ca nume n aplicaii. Cuvintele marcate prin * sunt rezervate, dar nu sunt folosite. abstract boolean break byte case catch char class const* continue default do double else extends final finally float for goto* if implements import instanceof int interface long native new package private protected public return short static strictfp super switch synchronized this throw throws transient try void volatile while

ncepnd cu versiunea 1.5, mai exist i cuvntul cheie enum.

1.3.3 IdentificatoriSunt secvene nelimitate de litere i cifre Unicode, ncepnd cu o liter. Dup cum am mai spus, identificatorii nu au voie s fie identici cu cuvintele rezervate.

1.3.4 LiteraliNote Literalii pot fi de urmtoarele tipuri: ntregi

Programare orientat obiect Sunt acceptate 3 baze de numeraie : baza 10, baza 16 (ncep cu caracterele 0x) i baza 8 (ncep cu cifra 0) i pot fi de dou tipuri: normali - se reprezint pe 4 octei (32 bii) lungi - se reprezint pe 8 octei (64 bii) i se termin cu caracterul L (sau l). Flotani Pentru ca un literal sa fie considerat flotant el trebuie sa aiba cel puin o zecimala dup virgula, sa fie n notaie exponeniala sau sa aiba sufixul F sau f pentru valorile normale - reprezentate pe 32 bii, respectiv D sau d pentru valorile duble - reprezentate pe 64 bii. Exemple: 1.0, 2e2, 3f, 4D. Logici Sunt reprezentai de true - valoarea logic de adevar, respectiv false valoarea logic de fals. Atenie! Spre deosebire de C++, literalii ntregi 1 i 0 nu mai au semnificaia de adevarat, respectiv fals. Caracter Un literal de tip caracter este utilizat pentru a exprima caracterele codului Unicode. Reprezentarea se face fie folosind o liter, fie o secven escape scris ntre apostrofuri. Secvenele escape permit specificarea caracterelor care nu au reprezentare grafic i reprezentarea unor caractere speciale precum backslash, apostrof, etc. Secvenele escape predefinite n Java sunt: \b : Backspace (BS) \t : Tab orizontal (HT) \n : Linie noua (LF) \f : Pagina noua (FF) \r : Inceput de rnd (CR) \" : Ghilimele \ : Apostrof \\ : Backslash iruri de caractere Un literal ir de caractere este format din zero sau mai multe caractere ntre ghilimele. Caracterele care formeaz irul pot fi caractere grafice sau secvene escape. Dac irul este prea lung el poate fi scris ca o concatenare de subiruri de dimensiune mai mica, concatenarea irurilor realizndu-se cu operatorul +, ca n exemplul: "Ana " + " are " + " mere ". irul vid este "". Dup cum vom vedea, orice ir este de fapt o instan a clasei String, definita n pachetul java.lang.

9

1.3.5 SeparatoriUn separator este un caracter care indica sfritul unei unitai lexicale i nceputul alteia. n Java separatorii sunt urmatorii: ( ) [ ] ; , . . Instruciunile unui program se separa cu punct i virgula (;).

1.3.6 OperatoriOperatorii Java sunt, cu mici deosebiri, cei din C++: atribuirea: = operatori matematici: +, -, *, /, %, ++, -- . Este permisa notaia prescurtata de forma lval op= rval: Ex: x += 2; x=x+2; n*= 3;n=n*3; Note

10

Programare orientat obiect Exista operatori pentru autoincrementare i autodecrementare (post i pre): x++, ++x, x=x+1; n--, --n n=n-1; Aceti operatori, dac sunt folosii singuri, au acelai efect n forma post sau prefixat. Diferena dintre aceste dou forme se observ atunci cnd ei sunt folosii n expresii compuse cum ar fi: int x=2, n=5, s; s=(x++)*3; s=(--n)/2; Ordinea n care se vor efectua operaiile n cadrul atribuirilor de mai sus va fi urmtoarea: s=x*3; x++; --n; s=n/2; Astfel, n cazul formei postfixate, variabila este prima dat folosit i apoi modificat, iar n cazul formei prefixate, variabila este prima dat folosit i apoi modificat. n practic trebuie inut cont de acest fapt, pentru a nu aprea erori n calcule. n Java, evaluarea expresiilor logice se face prin metoda scurtcircuitului: evaluarea se oprete n momentul n care valoarea de adevar a expresiei este sigur determinata. operatori logici: &&(and), ||(or), !(not) operatori relaionali: > (shift la dreapta fr semn) operatorul if-else: expresie-logica ? val-true : val-false operatorul , (virgula) folosit pentru evaluarea secveniala a operaiilor: int x=0, y=1, z=2; operatorul + pentru concatenarea irurilor: String s1="Ana"; String s2="mere"; int x=10; System.out.println(s1 + " are " + x + " " + s2); operator pentru conversii (cast) : (tip-de-data) sau (clasa) Acest operator este folosit pentru a transforma valori de tip numeric dintr-un tip n altul sau pentru a a schimba tipul unui obiect de la o clas la alta. int a = (int)a; char c = (char)96; int i = 200; long l = (long)i; //conversie n sus (de la int la long) long l2 = (long)200; int i2 = (int)l2; //conversie n jos (de la long la int) n cazul obiectelor, dac se dorete conversia la o clas dintr-un nivel superior al ierarhiei de clase, nu este necesar folosirea operatorului de cast, ci doar cnd se dorete conversia la o clas de pe un nivel inferior al ierarhiei. Exemplu: Fie ierarhia de clase Object-FormaGeometric-Dreptunghi i un obiect obj din clasa FormaGeometric. n acest caz, am putea avea urmtoarele situaii: Object obj=new FormaGeometric(); Dreptunghi obj=(Dreptunghi)new FormaGeometric(); Note

Programare orientat obiect

11

1.3.7 Comentariin Java exista trei feluri de comentarii: Comentarii pe mai multe linii, nchise ntre /* i */. Comentarii pe mai multe linii care in de documentaie, nchise ntre /** i */. Textul dintre cele doua secvene este automat mutat n documentaia aplicaiei de ctre generatorul automat de documentaie javadoc. Comentarii pe o singura linie, care incep cu //. Observaii: Nu putem scrie comentarii n interiorul altor comentarii. Nu putem introduce comentarii n interiorul literalilor caracter sau ir de caractere. Secvenele /* i */ pot sa apara pe o linie dup secvena // dar i pierd semnificaia. La fel se ntampla cu secvena // n comentarii care incep cu /* sau */. 1.4 Tipuri de date i variabile

1.4.1 Tipuri de daten Java tipurile de date se impart n doua categorii: tipuri primitive i tipuri referina. Java pornete de la premiza ca orice este un obiect, prin urmare tipurile de date ar trebui sa fie de fapt definite de clase i toate variabilele ar trebui sa memoreze instane ale acestor clase (obiecte). n principiu acest lucru este adevarat, nsa, pentru usurina programarii, mai exista i aa numitele tipurile primitive de date, care sunt cele uzuale : aritmetice ntregi: byte (1 octet) -2727, short (2) -215215, int (4) -231231, long (8) 263263 reale: float (4 octeti), double (8) caracter: char (2 octei) poate reprezenta 65536 (216) caractere logic: boolean (true i false) n alte limbaje de programare formatul i dimensiunea tipurilor primitive de date pot depinde de platforma pe care ruleaza programul. n Java acest lucru nu mai este valabil, orice dependena de o anumita platforma specific fiind eliminat. Vectorii, clasele i interfeele sunt tipuri referin. Valoarea unei variabile de acest tip este, spre deosebire de tipurile primitive, o referina (adresa de memorie) ctre valoarea sau mulimea de valori reprezentata de variabila respectiva. Exista trei tipuri de date din limbajul C care nu sunt suportate de limbajul Java. Acestea sunt: pointer, struct i union. Pointerii au fost eliminai din cauza ca erau o sursa constanta de erori, locul lor fiind luat de tipul referina, iar struct i union nu i mai au rostul att timp ct tipurile compuse de date sunt formate n Java prin intermediul claselor.

1.4.2 VariabileVariabilele pot fi de tip primitiv sau referine la obiecte (tip referina). Indiferent de tipul lor, pentru a putea fi folosite variabilele trebuie declarate i, eventual, iniializate. Declararea variabilelor: Tip numeVariabila; Iniializarea variabilelor: Tip numeVariabila = valoare; Declararea constantelor: final Tip numeVariabila; Note

12

Programare orientat obiect Evident, exista posibilitatea de a declara i iniializa mai multe variabile sau constante de acelai tip ntr-o singura instruciune astfel: Tip variabila1[=valoare1], variabila2[=valoare2],...; Observatie: Convenia de numire a variabilelor n Java include, printre altele, urmatoarele criterii: variabilele finale (constante) se scriu cu majuscule; variabilele care nu sunt constante se scriu astfel: prima litera mica iar dac numele variabilei este format din mai muli atomi lexicali, atunci primele litere ale celorlali atomi se scriu cu majuscule. Exemple: final double PI = 3.14; final int MINIM=0, MAXIM = 10; int valoare = 100; char c1=j, c2=a, c3=v, c4=a; long numarElemente = 12345678L; String bauturaMeaPreferata = "apa"; n funcie de locul n care sunt declarate variabilele se mpart n urmtoatele categorii: a. Variabile membre, declarate n interiorul unei clase, vizibile pentru toate metodele clasei respective ct i pentru alte clase n funcie de nivelul lor de acces. b. Parametri metodelor, vizibili doar n metoda respectiva. c. Variabile locale, declarate ntr-o metoda, vizibile doar n metoda respectiva. d. Variabile locale, declarate ntr-un bloc de cod, vizibile doar n blocul respectiv. e. Parametrii de la tratarea excepiilor. Observatii: Variabilele declarate ntr-un for, ramn locale corpului ciclului: for(int i=0; ib) a=a-b; if (a0) { s=s+n; n--; } 5) do-while do { //Set de instructiuni } while (expresie-logica); Se repet executarea unui set de instruciuni, atta timp ct o expresie logic este adevrat. Diferena fa de instruciunea while const n faptul c expresia logic este testat dup executarea setului de instruciuni, astfel c, dac ea este fals de la nceput, n cazul instruciunii do-while el va fi totui executat o dat, ceea ce nu se va ntmpla la instruciunea while. Observaie: Instruciunea for poate fi scris ca i o instruciune while echivalent: for(initializare; expresie-logica; pas-iteratie) { //Set de instructiuni } poate fi scris ca i: initializare while (expresie-logica) { //Set de instructiuni pas-iteratie }

15

Note

16

Programare orientat obiect

1.5.3 Instruciuni pentru tratarea excepiilorInstruciunile pentru tratarea excepiilor sunt try-catch-finally, respectiv throw i vor fi tratate n capitolul Excepii.

1.5.4 Alte instruciuni break: parasete forat corpul unei structuri repetitive. continue: termina forat iteraia curenta a unui ciclu i trece la urmatoarea iteraie. return [valoare]: termina o metoda i, eventual, returneaza o valorare. numeEticheta: : definete o eticheta. Dei n Java nu exist goto, se pot defini totui etichete folosite n expresii de genul: break numeEticheata sau continue numeEticheta, utile pentru a controla punctul de ieire dintr-o structur repetitiv, ca n exemplul de mai jos: i=0; eticheta: while (i < 10) { System.out.println("i="+i); j=0; while (j < 10) { j++; if (j==5) continue eticheta; if (j==7) break eticheta; System.out.println("j="+j); } i++; } 1.6 Tipuri enumerate (enum) O noutate introdus cu varianta 1.5 este posibilitatea declarrii unor enumerri de elemente, facilitate existent n alte limbaje cum ar fi C i C++, ns care nu a existat de la nceput implementat n Java. Exemplu: public enum Zile_lucr { LUNI, MARTI, MIERCURI, JOI, VINERI } Prin convenie, deoarece elementele unei enumerri sunt constante, ele vor fi scrise cu majuscule. Cteva elemente care sunt implementate implicit pentru o enumerare sunt: metoda toString() care permite afiare unei valori din enumerare ca i ir de caractere metoda ordinal() care permite aflarea numrului de ordine a unei valori din enumerare (numerele de ordine ncep de la 0) metoda static values() care va genera un tablou cu elementele enumerrii Exemplu: public class ZileDeMunca { public static void main(String[] args) { for (Zile_lucr z : Zile_lucr.values() System.out.println (z + a + z.ordinal() + -a zi);

Note

Programare orientat obiect } } La rulare se va afisa: LUNI a 0-a zi MARTI a 1-a zi MIERCURI a 2-a zi JOI a 3-a zi VINERI a 4-a zi Un avantaj suplimetar oferit de tipul enumerat este faptul c va permite testarea valorilor de tip ir de caractere ntr-o instruciune switch, ceea ce altfel nu era posibil. Exemplu: Zile_lucr z; switch (z) { case LUNI: } 1.7 Folosirea argumentelor de la linia de comand

17

1.7.1 Transmiterea argumentelorO aplicaie Java poate primi oricte argumente de la linia de comanda n momentul lansrii ei. Aceste argumente sunt utile pentru a permite utilizatorului s specifice diverse opiuni legate de funcionarea aplicaiei sau s furnizeze anumite date iniiale programului. Argumentele de la linia de comand sunt introduse la lansarea unei aplicaii, fiind specificate dup numele aplicaiei i separate prin spaiu. Formatul general pentru lansarea unei aplicaii care primete argumente de la linia de comand este: java NumeAplicatie [arg0 arg1 . . . argn] n cazul n care sunt mai multe, argumentele trebuie separate prin spaii, iar dac unul dintre argumente conine spaii, atunci el trebuie pus ntre ghilimele. Evident, o aplicaie poate s nu primeasc nici un argument sau poate s ignore argumentele primite de la linia de comand.

1.7.2 Primirea argumentelorn momentul lansrii unei aplicaii interpretorul parcurge linia de comand cu care a fost lansat aplicatia i, n cazul n care exist, transmite programului argumentele specificate sub forma unui vector de iruri. Acesta este primit de aplicaie ca parametru al metodei main. Reamintim c formatul metodei main din clasa principal este: public static void main (String args[]) Vectorul args primit ca parametru de metoda main va conine toate argumentele transmise programului de la linia de comand. Vectorul args este instaniat cu un numr de elemente egal cu numrul argumentelor primite de la linia de comand. Aadar, pentru a afla numrul de argumente primite de program este suficient s aflm dimensiunea vectorului args prin intermediul atributului length: public static void main (String args[]) { int numarArgumente = args.length ; } n cazul n care aplicaia presupune existena unor argumente de la linia de comand, ns acestea nu au fost transmise programului la lansarea sa, vor

Note

18

Programare orientat obiect aprea excepii (erori) de tipul ArrayIndexOutOfBoundsException. Tratarea acestor excepii este prezentat n capitolul Excepii. Din acest motiv, este necesar s testm dac programul a primit argumentele de la linia de comand necesare pentru funcionarea sa i, n caz contrar, s afieze un mesaj de avertizare sau s foloseasc nite valori implicite, ca n exemplul de mai jos: public class Salut { public static void main (String args[]) { if (args.length == 0) { System.out.println("Numar insuficient de argumente!"); System.exit(-1); //termina aplicatia } String nume = args[0]; //exista sigur String prenume; if (args.length >= 1) prenume = args[1]; else prenume = ""; //valoare implicita System.out.println("Salut " + nume + " " + prenume); } } Spre deosebire de limbajul C, vectorul primit de metoda main() nu conine pe prima poziie numele aplicaiei, ntruct n Java numele aplicaiei este chiar numele clasei principale, adic a clasei n care se gasete metoda main(). S consider n continuare un exemplu simplu n care se dorete afiarea pe ecran a argumentelor primite de la linia de comand: public class Afisare { public static void main (String[] args) { for (int i = 0; i < args.length; i++) System.out.println(args[i]); } } Un apel de genul: java Afisare Hello Java va produce urmtorul rezultat (aplicaia a primit 2 argumente): Hello Java Apelul: java Afisare "Hello Java" va produce ns alt rezultat (aplicaia a primit un singur argument): Hello Java

1.7.3 Argumente numericeArgumentele de la linia de comand sunt primite sub forma unui vector de iruri (obiecte de tip String). n cazul n care unele dintre acestea reprezint valori numerice ele vor trebui convertite din iruri n numere. Acest lucru se realizeaz cu metode de tipul parseTipNumeric aflate n clasa corespunzatoare tipului n care vrem s facem conversia: Integer, Float, Double, etc. S considerm, de exemplu, c aplicaia Power ridic un numar real la o putere ntreag, argumentele fiind trimise de la linia de comand sub forma: java Power "1.5" "2" //ridica 1.5 la puterea 2 Conversia celor dou argumente n numere se va face astfel:

Note

Programare orientat obiect public class Power { public static void main(String args[]) { double numar = Double.parseDouble(args[0]); int putere = Integer.parseInt(args[1]); System.out.println("Rezultat=" + Math.pow(numar, putere)); } } Metodele de tipul parseTipNumeric() pot produce excepii (erori) de tipul NumberFormatException n cazul n care irul primit ca parametru nu reprezint un numar de tipul respectiv. Tratarea acestor excepii este prezentat n capitolul Excepii.

19

Test de autoevaluare: 1. Care sunt principiile de baz ale programrii orientate obiect?

2.

Care sunt caracterele valide cu care poate ncepe numele unei variabile n Java?

3.

Numii trei tipuri de date primitive din Java.

4.

Care sunt cele trei instruciuni de control repetitive?

5.

Ce tip implicit au datele transmise din linia de comanda?

Bibliografie : 1. Cristian Frsinaru Curs practic de Java 2. Bruce Eckel Thinking in Java 4th Edition, Ed. Prentice Hall, 2006, ISBN 0-13-187248-6 3. P. Niemeyer, J. Knudsen - Learning Java 3rd Edition, Ed. OReilly, 2005 4. .Tanas,.Andrei,C. Olaru Java de la 0 la expert, Ed.Polirom, 2007, ISBN 978-973-46-0317-6 5. D.Danciu, G.Mardale - Arta programrii n JAVA (Vol. I) Elemente-suport fundamentale, Ed. Albastr, 2005

Note

20

Programare orientat obiect

Note

Programare orientat obiect II. Elemente de baz ale programarii orientate obiect baz

21

2.1 Clase i obiecte

Obiective: Cunoaterea conceptului fundamental de clas terea clas Cunoaterea elementelor de baz care compun o clas terea baz Cunoaterea modificatorilor de acces de la diferite nivele terea (clas, atribut, metod , metod) nelegerea diferen dintre membrii de clas (statici) i cei de elegerea diferenei instan Declararea, ini iniializarea i utilizarea tablourilor Declararea, ini iniializarea i utilizarea irurilor de caractere Clasa este un concept de baz al programrii orientate obiect, domeniu n baz rii care reprezint structura care define te caracteristicile abstracte ale unui lucru definete (obiect), printre care caracteristicile acestuia (atributele sale, cmpuri sau proprieti), precum i comportamentele acestui lucru (lucrurile pe care le poate omportamentele face, sau metode, operaii sau propriet ii proprieti). Se poate spune c o clas este schia care descrie natura unui lucru. De clas a exemplu, clasa Cine va conine caracteristicile tuturor cinilor, precum ras sau ine ras culoarea prului (caracteristici), precum i capacitatea de a ltra i de a sta rului (comportament). Clasele asigur modularitatea i structura ntr-un program de calculator un orientat pe obiecte. O clas ar trebui s poat fi neleas de ctre o persoan care s tre nu tie programare dar cunosc toare a domeniului problemei, caracteristicile tie cunosctoare clasei ar trebui s aib sens n respectivul context. De asemenea, codul clasei ar trebui s fie auto-suficient (folosind n general ncapsularea). suficient n ansamblul lor, propriet proprietile i metodele definite printr-o clas sunt o numite membri. Pentru a da consisten atributelor este nevoie de cearea unui obiect ntr ntr-o clas. Astfel, un obiect se mai nume i instan a unei clase. . numete ncapsularea este termenul care define accesul la membrii unei clase. definete Un atribut sau o metod a unui obiect pot sau nu s fie accesate de ctre un obiect s tre exterior clasei. Se poate ntmpla ca o parte din membrii unei clase s poat fi s poat utilizai doar n interiorul clasei i s nu se permit accesul la ei dinafar Ca i dinafar. urmare, se spune c acetia vor fi ncapsula n interiorul clasei, fr a fi vizibili tia ncapsulai sau accesabili din exterior. Definirea accesului la un membru al unei clase se face prin intermediul specificatorilor de acces acces. 2.1.1 Crearea claselor a) Declararea claselor Clasele reprezint o modalitate de a introduce noi tipuri de date ntr ntr-o aplicaie Java, cealalt modalitate fiind prin intermediul interfe elor. Declararea interfeelor. unei clase respect urmtorul format general: torul [modificatori clasa] clasa]class NumeClasa [extends NumeSuperclasa] [implements Interfata1 [, Interfata2 ... ]]

Note

22

Programare orientat obiect { // Corpul clasei } Aadar, prima parte a declaraiei o ocup modificatorii clasei. Acetia sunt: public: Implicit, o clas poate fi folosit doar de clasele aflate n acelai pachet (librrie) cu clasa respectiv (dac nu se specific un anume pachet, toate clasele din directorul curent sunt considerate a fi n acelai pachet). O clas declarat cu public poate fi folosit din orice alt clas, indiferent de pachetul n care se gsete. abstract : Declar o clas abstract (ablon). O clas abstract nu poate fi instaniat, fiind folosit doar pentru a crea un model comun pentru o serie de subclase. final : Declar c respectiva clas nu poate avea subclase. Declarare claselor finale are dou scopuri: securitate: unele metode pot atepta ca parametru un obiect al unei anumite clase i nu al unei subclase, dar tipul exact al unui obiect nu poate fi aflat cu exactitate decat n momentul executiei; n felul acesta nu s-ar mai putea realiza obiectivul limbajului Java ca un program care a trecut compilarea s nu mai fie susceptibil de nici o eroare. programare n spririt orientat-obiect: O clasa perfect nu trebuie s mai aib subclase. Dup numele clasei putem specifica, dac este cazul, faptul c respectiva clas este subclas a unei alte clase cu numele NumeSuperclasa sau/i c implementeaz una sau mai multe interfee, ale cror nume trebuie separate prin virgul. b) Extinderea claselor Spre deosebire de alte limbaje de programare orientate-obiect, Java permite doar motenirea simpl, ceea ce nseamn c o clas poate avea un singur printe (superclas). Pe de alta parte, o clas poate avea oricti motenitori (subclase), de unde rezult c mulimea tuturor claselor definite n Java poate fi vazut ca un arbore, rdcina acestuia fiind clasa Object. Aadar, Object este singura clas care nu are printe, fiind foarte important n modul de lucru cu obiecte si structuri de date n Java. Extinderea unei clase se realizeaz folosind cuvntul cheie extends: class B extends A {...} // A este superclasa clasei B // B este o subclasa a clasei A O subclas motenete de la printele su toate atributele i metodele care nu sunt private. Pe lng acestea, clasa derivat poate aduga noi atribute i metode. Prin motenire, o clas poate fi reutilizat pentru a modela o alta clas, care va fi o subclas a sa (clas derivat). c) Corpul unei clase Corpul unei clase urmeaz imediat dup declararea clasei i este cuprins ntre acolade. Coninutul acestuia este format din: Declararea i, eventual, iniializarea variabilelor de instan i de clas (cunoscute mpreun ca variabile membre). Declararea i implementarea constructorilor. Declararea i implementarea metodelor de instana i de clas (cunoscute mpreun ca metode membre).

Note

Programare orientat obiect Declararea unor clase imbricate (interne). d) Constructorii unei clase Constructorii unei clase sunt metode speciale care au acelai nume cu cel al clasei, nu returneaz nici o valoare i sunt folosii pentru iniializarea obiectelor acelei clase n momentul instanierii lor. Constructorii nu sunt considerai ca fiind membrii ai clasei. class NumeClasa { [modificatori] NumeClasa([argumente]) { // Constructor } } O clas poate avea unul sau mai muli constructori care trebuie ns s difere prin lista de argumente primite. n felul acesta sunt permise diverse tipuri de iniializri ale obiectelor la crearea lor, n funcie de numrul parametrilor cu care este apelat constructorul. S considerm ca exemplu declararea unei clase care descrie noiunea de dreptunghi i trei posibili constructori pentru aceasta clas: class Dreptunghi { double x, y, w, h; Dreptunghi(double x1, double y1, double w1, double h1) { // Cel mai general constructor x=x1; y=y1; w=w1; h=h1; System.out.println("Instantiere dreptunghi"); } Dreptunghi(double w1, double h1) { // Constructor cu doua argumente x=0; y=0; w=w1; h=h1; System.out.println("Instantiere dreptunghi"); } Dreptunghi() { // Constructor fr argumente x=0; y=0; w=0; h=0; System.out.println("Instantiere dreptunghi"); } } Constructorii sunt apelai automat la instanierea unui obiect. n cazul n care dorim s apelm explicit constructorul unei clase folosim expresia this(argumente), care apeleaz constructorul corespunztor (ca argumente) al clasei respective. Aceast metod este folosit atunci cnd sunt implementai mai muli constructori pentru o clas, pentru a nu repeta secvenele de cod scrise deja la constructorii cu mai multe argumente (mai generali). Mai eficient, fr a repeta aceleai secvene de cod n toi constructorii (cum ar fi afiarea mesajului Instantiere dreptunghi), clasa de mai sus poate fi rescris astfel: class Dreptunghi { double x, y, w, h; Dreptunghi(double x1, double y1, double w1, double h1) { x=x1; y=y1; w=w1; h=h1; System.out.println("Instantiere dreptunghi"); }

23

Note

24 Dreptunghi(double w1, double h1) { this(0, 0, w1, h1); // Apelam constructorul cu 4 argumente } Dreptunghi() { this(0, 0); // Apelam constructorul cu 2 argumente }

Programare orientat obiect

} Atenie! Apelul explicit al unui constructor nu poate aprea dect ntr-un alt constructor si trebuie s fie prima instruciune din constructorul respectiv. Constructorul implicit: Constructorii sunt apelai automat la instanierea unui obiect. n cazul n care scriem o clas care nu are declarat nici un constructor, sistemul i creeaz automat un constructor implicit, care nu primete nici un argument i care nu face nimic. Deci prezena constructorilor n corpul unei clase un este obligatorie. Dac ns scriem un constructor pentru o clas, care are mai mult de un argument, atunci constructorul implicit (fr nici un argument) nu va mai fi furnizat implicit de ctre sistem. Constructorii unei clase pot avea urmtorii modificatori de acces: public: n orice alt clas se pot crea instane ale clasei respective. protected: Doar n subclase pot fi create obiecte de tipul clasei respective. private: n nici o alt clas nu se pot instania obiecte ale acestei clase. O astfel de clas poate conine metode publice (numite factory methods) care s fie responsabile cu crearea obiectelor, controlnd n felul acesta diverse aspecte legate de instanierea clasei respective. implicit: Doar n clasele din acelai pachet se pot crea instane ale clasei respective. e) Declararea variabilelor Variabilele membre ale unei clase se declar de obicei naintea metodelor, dei acest lucru nu este impus de ctre compilator. Variabilele membre ale unei clase se declar n corpul clasei i nu n corpul unei metode, fiind vizibile n toate metodele respectivei clase. Variabilele declarate n cadrul unei metode sunt locale metodei respective. Declararea unei variabile presupune specificarea urmtoarelor lucruri: numele variabilei tipul de date al acesteia nivelul de acces la acea variabila din alte clase dac este constant sau nu dac este variabil de instan sau de clas ali modificatori Generic, o variabil se declar astfel: [modificatori] TipDate numeVariabila [ = valoareInitiala ]; unde un modificator poate fi : un modificator de acces : public, protected, private unul din cuvintele rezervate: static, final, transient, volatile Exemple de declaraii de variabile membre: class Exemplu { double x; protected static int n; public String s = "abcd";

Note

Programare orientat obiect private Point p = new Point(10, 10); final static long MAX = 100000L; } S analizm modificatorii care pot fi specificai pentru o variabil: static: Prezena lui declar c o variabil este variabil de clas i nu de instan. Astfel, se va aloca o singur dat memorie pentru ea i apelul ei se va face prin intermediul clasei i nu printr-un obiect al clasei (instan). int variabilaInstanta; static int variabilaClasa; final: Indic faptul c valoarea variabilei nu mai poate fi schimbat, cu alte cuvinte este folosit pentru declararea constantelor. final double PI = 3.14 ; ... PI = 3.141; // Eroare la compilare ! Prin convenie, numele variabilelor finale se scriu cu litere mari. Folosirea lui final aduce o flexibilitate sporit n lucrul cu constante, n sensul c valoarea unei variabile nu trebuie specificat neaprat la declararea ei (ca n exemplul de mai sus), ci poate fi specificat i ulterior ntr-un constructor, dup care ea nu va mai putea fi modificat. class Test { final int MAX; Test() { MAX = 100; // Corect MAX = 200; // Eroare la compilare ! } } transient: Este folosit la serializarea obiectelor, pentru a specifica ce variabile membre ale unui obiect nu particip la serializare. volatile: Este folosit pentru a semnala compilatorului s nu execute anumite optimizri asupra membrilor unei clase. Este o facilitate avansat a limbajului Java. f) this i super Sunt variabile predefinite care fac referina, n cadrul unui obiect, la obiectul propriu-zis (this), respectiv la instana printelui (super). Sunt folosite n general pentru a rezolva conflicte de nume prin referirea explicit a unei variabile sau metode membre. Utilizate sub form de metode, au rolul de a apela constructorii corespunztori ca argumente ai clasei curente, respectiv ai superclasei. g) Implementarea metodelor Declararea metodelor Metodele sunt responsabile cu descrierea comportamentului unui obiect. Intruct Java este un limbaj de programare complet orientat-obiect, metodele se pot gsi doar n cadrul claselor. Generic, o metod se declar astfel: [modificatori] tipReturnat numeMetoda ( [argumente] ) [throws TipExceptie1, TipExceptie2, ...] { // Corpul metodei }

25

Note

26

Programare orientat obiect unde un modificator poate fi : un specificator de acces : public, protected, private unul din cuvintele rezervate: static, abstract, final, native, synchronized S analizm modificatorii care pot fi specificai pentru o metod: static: Prezena lui declar c o metod este de clas i nu de instan. n cazul acesta, apelul metodei se va face prin intermediul clasei i nu printr-un obiect al clasei (instan). n general, n cadrul metodelor statice se vor folosi atribute statice. abstract: Permite declararea metodelor abstracte. O metod abstract este o metod care nu are implementare i trebuie obligatoriu s fac parte dintr-o clas abstract. final: Specific faptul c acea metoda nu mai poate fi supradefinit n subclasele clasei n care ea este definit ca fiind final. Acest lucru este util dac respectiva metod are o implementare care nu trebuie schimbat sub nici o form n subclasele ei, fiind critic pentru consistena strii unui obiect. native: n cazul n care avem o librrie important de funcii scrise n alt limbaj de programare, cum ar fi C, C++ i limbajul de asamblare, acestea pot fi refolosite din programele Java. Tehnologia care permite acest lucru se numete JNI (Java Native Interface) i permite asocierea dintre metode Java declarate cu native i metode native scrise n limbajele de programare menionate. synchronized: Este folosit n cazul n care se lucreaz cu mai multe fire de execuie iar metoda respectiv gestioneaz resurse comune. Are ca efect construirea unui monitor care nu permite executarea metodei, la un moment dat, dect unui singur fir de execuie. Tipul returnat de o metod Metodele pot sau nu s returneze o valoare la terminarea lor. Tipul returnat poate fi att un tip primitiv de date sau o referin la un obiect al unei clase. n cazul n care o metod nu returneaz nimic atunci trebuie obligatoriu specificat cuvntul cheie void ca tip returnat. Dac o metod trebuie s returneze o valoare acest lucru se realizeaz prin intermediul instruciunii return, care trebuie s apar n toate situaiile de terminare a funciei. Exemplu: double radical(double x) { if (x >= 0) return Math.sqrt(x); else { System.out.println("Argument negativ !"); // Eroare la compilare // Lipseste return pe aceasta ramura } } n cazul n care n declaraia funciei, tipul returnat este un tip primitiv de date, valoarea returnat la terminarea funciei trebuie s aib obligatoriu acel tip sau un subtip al su, altfel va fi furnizat o eroare la compilare. Dac valoarea returnat este o referin la un obiect al unei clase, atunci clasa obiectului returnat trebuie s coincid sau s fie o subclas a clasei specificate la declararea metodei. De exemplu, fie clasa Poligon i subclasa acesteia Patrat. Poligon metoda1( ) { Poligon p = new Poligon();

Note

Programare orientat obiect Patrat t = new Patrat(); if (...) return p; // Corect else return t; // Corect } Patrat metoda2( ) { Poligon p = new Poligon(); Patrat t = new Patrat(); if (...) return p; // Eroare else return t; // Corect } Trimiterea parametrilor ctre o metod Signatura unei metode este dat de numarul i tipul argumentelor primite de acea metod. Tipul de date al unui argument poate fi orice tip valid al limbajului Java, att tip primitiv ct i tip referin. tipReturnat metoda([Tip1 arg1, Tip2 arg2, ...]) Exemplu: void adaugarePersoana(String nume, int varsta, float salariu) // String este tip referinta // int si float sunt tipuri primitive Spre deosebire de alte limbaje, n Java nu pot fi trimise ca parametri ai unei metode referine la alte metode (funcii), ns pot fi trimise referine la obiecte care s conin implementarea acelor metode, pentru a fi apelate. Pn la apariia versiunii 1.5, n Java o metod nu putea primi un numr variabil de argumente, ceea ce nseamna c apelul unei metode trebuia s se fac cu specificarea exact a numarului i tipurilor argumentelor. Numele argumentelor primite trebuie s difere ntre ele i nu trebuie s coincid cu numele nici uneia din variabilele locale ale metodei. Pot ns s coincid cu numele variabilelor membre ale clasei, caz n care diferenierea dintre ele se va face prin intermediul variabile this: class Cerc { int x, y, raza; public Cerc(int x, int y, int raza) { this.x = x; this.y = y; this.raza = raza; } } n Java argumentele sunt trimise doar prin valoare (pass-by-value). Acest lucru nseamn c metoda recepioneaz doar valorile variabilelor primite ca parametri. Cnd argumentul are tip primitiv de date, metoda nu-i poate schimba valoarea dect local (n cadrul metodei); la revenirea din metod variabila are aceeai valoare ca naintea apelului, modificrile fcute n cadrul metodei fiind pierdute. Note

27

28

Programare orientat obiect Cnd argumentul este de tip referin, metoda nu poate schimba valoarea referinei obiectului, ns poate apela metodele acelui obiect i poate modifica orice variabil membr accesibil. Aadar, dac dorim ca o metod s schimbe starea (valoarea) unui argument primit, atunci el trebuie s fie neaparat de tip referin. 2.1.2 Clase imbricate a) Definirea claselor imbricate O clas imbricat este, prin definiie, o clas membr a unei alte clase, numit i clas de acoperire. n funcie de situaie, definirea unei clase interne se poate face fie ca membru al clasei de acoperire - caz n care este accesibil tuturor metodelor, fie local n cadrul unei metode. class ClasaDeAcoperire{ class ClasaImbricata1 { // Clasa membru } void metoda() { class ClasaImbricata2 { // Clasa locala metodei } } } Folosirea claselor imbricate se face atunci cnd o clas are nevoie n implementarea ei de o alt clas i nu exist nici un motiv pentru care aceasta din urm s fie declarat de sine stttoare (nu mai este folosit nicieri). O clas imbricat are un privilegiu special fa de celelalte clase i anume acces nerestricionat la toate variabilele clasei de acoperire, chiar dac acestea sunt private. O clas declarat local unei metode va avea acces i la variabilele finale declarate n metoda respectiv. class ClasaDeAcoperire{ private int x=1; class ClasaImbricata1 { int a=x; } void metoda() { final int y=2; int z=3; class ClasaImbricata2 { int b=x; int c=y; int d=z; // Incorect } } } O clas imbricat membr (care nu este local unei metode) poate fi referit din exteriorul clasei de acoperire folosind expresia: ClasaDeAcoperire.ClasaImbricata Clasele membru pot fi declarate cu modificatorii public, protected, private pentru a controla nivelul lor de acces din exterior, ntocmai ca orice variabil sau metod membr a clasei. Pentru clasele imbricate locale unei metode nu sunt permii acesti modificatori. Toate clasele imbricate pot fi

Note

Programare orientat obiect declarate folosind modificatorii abstract i final, semnificaia lor fiind aceeai ca i n cazul claselor obinuite. b) Clase interne Spre deosebire de clasele obinuite, o clas imbricat poate fi declarat static sau nu. O clas imbricat nestatic se numete clasa intern. class ClasaDeAcoperire{ ... class ClasaInterna { ... } static class ClasaImbricataStatica { ... } } Diferenierea acestor denumiri se face deoarece: o clas imbricat reflect relaia sintactic a dou clase: codul unei clase apare n interiorul codului altei clase; o clas intern reflect relaia dintre instanele a dou clase, n sensul c o instana a unei clase interne nu poate exista decat n cadrul unei instane a clasei de acoperire. n general, cele mai folosite clase imbricate sunt cele interne. Aadar, o clas intern este o clas imbricat ale carei instane nu pot exista dect n cadrul instanelor clasei de acoperire i care are acces direct la toi membrii clasei sale de acoperire. c) Identificare claselor imbricate Dup cum tim orice clas produce la compilare aa numitele uniti de compilare, care sunt fiiere avnd numele clasei respective i extensia .class i care conin toate informaiile despre clasa respectiv. Pentru clasele imbricate aceste uniti de compilare sunt denumite astfel: numele clasei de acoperire, urmat de simbolul $ apoi de numele clasei imbricate. class ClasaDeAcoperire{ class ClasaInterna1 {} class ClasaInterna2 {} } Pentru exemplul de mai sus vor fi generate trei fiiere: ClasaDeAcoperire.class ClasaDeAcoperire$ClasaInterna1.class ClasaDeAcoperire$ClasaInterna2.class n cazul n care clasele imbricate au la rndul lor alte clase imbricate (situaie mai puin uzual) denumirea lor se face dup aceeai regul: adugarea unui $ i apoi numele clasei imbricate. d) Clase anonime Exist posibilitatea definirii unor clase imbricate locale, fr nume, utilizate doar pentru instanierea unui obiect de un anumit tip. Astfel de clase se numesc clase anonime i sunt foarte utile n situaii cum ar fi crearea unor obiecte ce implementeaz o anumit interfa sau extind o anumit clas abstract. Fiierele rezultate n urma compilrii claselor anonime vor avea numele de forma ClasaAcoperire.$1,..., ClasaAcoperire.$n

29

Note

30

Programare orientat obiect unde n este numrul de clase anonime definite n clasa respectiv de acoperire. 2.1.3 Crearea obiectelor a) Etape n Java, ca n orice limbaj de programare orientat-obiect, crearea obiectelor se realizeaz prin instanierea unei clase i implic urmtoarele lucruri: Declararea: Presupune specificarea tipului acelui obiect, cu alte cuvinte specificarea clasei acestuia (vom vedea c tipul unui obiect poate fi i o interfa). NumeClasa numeObiect; Instanierea: Se realizeaz prin intermediul operatorului new i are ca efect crearea efectiv a obiectului cu alocarea spaiului de memorie corespunztor. numeObiect = new NumeClasa(); Iniializarea: Se realizeaz prin intermediul constructorilor clasei respective. Iniializarea este de fapt parte integrant a procesului de instaniere, n sensul c imediat dup alocarea memoriei ca efect al operatorului new este apelat constructorul specificat. Parantezele rotunde de dup numele clasei indic faptul c acolo este de fapt un apel la unul din constructorii clasei i nu simpla specificare a numelui clasei. Pentru simplificarea scrierii, uzual, cei 3 pai se mai sus sunt adesea folosii mpreun: NumeClasa numeObiect = new NumeClasa([argumente constructor]); Fie clasa Rectangle o clas ce descrie suprafee grafice rectangulare, definite de coordonatele colului stnga sus (originea) i limea, respectiv nlimea i s presupunem c clasa Rectangle are urmtorii constructori: public Rectangle() public Rectangle(int origineX, int origineY, int latime, int inaltime) S considerm exemplul n care declarm i instaniem trei obiecte din clasa Rectangle: Rectangle r1, r2; r1 = new Rectangle(); r2 = new Rectangle(0, 0, 100, 200); Rectangle r3= new Rectangle(0, 0, 150, 150); n primul caz Rectangle() este un apel ctre constructorul clasei Rectangle care este responsabil cu iniializarea obiectului cu valorile implicite. n al doilea caz, iniializarea se poate face i cu anumii parametri, cu condiia s existe un constructor al clasei respective care s accepte parametrii respectivi. Pentru cel de-al treilea obiect, declararea, instanierea i iniializarea au fost fcute ntr-un singur pas. b) Folosirea obiectelor Odat un obiect creat, el poate fi folosit n urmtoarele sensuri: aflarea unor informaii despre obiect, schimbarea strii sale sau executarea unor aciuni. Aceste lucruri se realizeaza prin aflarea sau schimbarea valorilor variabilelor sale, respectiv prin apelarea metodelor sale. Referirea valorii unei variabile se face prin obiect.variabila. De exemplu clasa Rectangle are variabilele publice x, y, width, height. Aflarea valorilor acestor variabile sau schimbarea lor se face prin construcii de genul:

Note

Programare orientat obiect Rectangle patrat = new Rectangle(0, 0, 100, 100); System.out.println(patrat.width); //afiseaza 100 patrat.x = 10; patrat.y = 20; //schimba originea Accesul la variabilele unui obiect se face n conformitate cu drepturile de acces pe care le ofer variabilele respective celorlalte clase. Apelul unei metode se face prin: obiect.metoda([parametri]) Exemplu: Rectangle patrat = new Rectangle(0, 0, 100, 200); patrat.setLocation(10, 20); //schimba originea patrat.setSize(200, 300); //schimba dimensiunea Se observ c valorile variabilelor pot fi modificate indirect prin intermediul metodelor sale. Programarea orientat obiect descurajeaz folosirea direct a variabilelor unui obiect deoarece acesta poate fi adus n stri inconsistente (ireale). n schimb, pentru fiecare variabil care descrie starea obiectului trebuie s existe metode care s permit schimbarea/aflarea valorilor variabilelor sale. Acestea se numesc metode de accesare, sau metode setter - getter i au numele de forma setVariabila, respectiv getVariabila. Exemplu: patrat.width = -100; //stare inconsistenta patrat.setSize(-100, -200); //metoda setter //metoda setSize poate sa testeze dac noile valori sunt corecte si sa valideze sau nu schimbarea lor c) Distrugerea obiectelor Multe limbaje de programare impun ca programatorul s in evidena obiectelor create i s le distrug n mod explicit atunci cnd nu mai este nevoie de ele, cu alte cuvinte s administreze singur memoria ocupat de obiectele sale. Practica a demonstrat c aceast tehnic este una din principalele furnizoare de erori ce duc la funcionarea defectuoas a programelor. n Java programatorul nu mai are responsabilitatea distrugerii obiectelor sale ntruct, n momentul rulrii unui program, simultan cu interpretorul Java, ruleaz i un proces care se ocup cu distrugerea obiectelor care nu mai sunt folosite. Acest proces pus la dispoziie de platforma Java de lucru se numete garbage collector (colector de gunoi), prescurtat gc. Un obiect este eliminat din memorie de procesul de colectare atunci cnd nu mai exist nici o referin la acesta. Referinele (care sunt de fapt variabile) sunt distruse dou moduri: natural, atunci cnd variabila respectiv iese din domeniul su de vizibilitate, de exemplu la terminarea metodei n care ea a fost declarat; explicit, dac atribuim variabilei respective valoare null. Cum funcioneaz garbage collector? Garbage collector este un proces de prioritate scazut care se execut periodic, scaneaz dinamic memoria ocupat de programul Java aflat n execuie i marcheaz acele obiecte care au referine directe sau indirecte. Dup ce toate obiectele au fost parcurse, cele care au rmas nemarcate sunt eliminate automat din memorie. Apelul metodei gc din clasa System sugereaz mainii virtuale Java s depun eforturi n recuperarea memoriei ocupate de obiecte care nu mai sunt folosite, fr a fora ns pornirea procesului. Note

31

32

Programare orientat obiect Inainte ca un obiect s fie eliminat din memorie, procesul gc d acelui obiect posibilitatea s curee dup el, apelnd metoda de finalizare a obiectului respectiv. Uzual, n timpul finalizrii un obiect i inchide fisierele i socket-urile folosite, distruge referinele ctre alte obiecte (pentru a usura sarcina colectorului de gunoaie), etc. Codul pentru finalizarea unui obiect trebuie scris ntr-o metod special numit finalize a clasei ce descrie obiectul respectiv. 2.1.4 Membri de instan i membri de clas O clas Java poate conine dou tipuri de variabile i metode : de instan: declarate fr modificatorul static, specifice fiecrei instane create dintr-o clas i de clas: declarate cu modificatorul static, specifice clasei. a) Variabile de instan i de clas Cnd declarm o variabil membr fr modificatorul static, cum ar fi variabila x n exemplul de mai jos: class Exemplu1 { int x ; //variabila de instanta } se declar de fapt o variabil de instan, ceea ce nseamn c la fiecare creare a unui obiect al clasei Exemplu1 sistemul aloc o zon de memorie separat pentru memorarea valorii lui x. Exemplu1 o1 = new Exemplu1(); o1.x = 100; Exemplu1 o2 = new Exemplu1(); o2.x = 200; System.out.println(o1.x); // Afiseaza 100 System.out.println(o2.x); // Afiseaza 200 Aadar, fiecare obiect nou creat va putea memora valori diferite pentru variabilele sale de instan. Pentru variabilele de clas (statice) sistemul aloc o singur zon de memorie la care au acces toate instanele clasei respective, ceea ce nseamn c dac un obiect modific valoarea unei variabile statice ea se va modifica i pentru toate celelalte obiecte. Deoarece nu depind de o anumit instan a unei clase, variabilele statice pot fi referite i sub forma: NumeClasa.numeVariabilaStatica class Exemplu2 { int x ; // Variabila de instanta static long n; // Variabila de clasa } ... Exemplu2 o1 = new Exemplu2(); Exemplu2 o2 = new Exemplu2(); o1.n = 100; System.out.println(o2.n); // Afiseaza 100 o2.n = 200; System.out.println(o1.n); // Afiseaza 200 System.out.println(Exemplu2.n); // Afiseaza 200 // o1.n, o2.n si Exemplu2.n sunt referinte la aceeasi valoare Note Iniializarea variabilelor de clas se face o singur dat, la ncrcarea n

Programare orientat obiect memorie a clasei respective, i este realizat prin atribuiri obinuite: class Exemplu3 { static final double PI = 3.14; static long nrInstante = 0; } b) Metode de instan i de clas Similar ca la variabile, metodele declarate fr modificatorul static sunt metode de instan iar cele declarate cu static sunt metode de clas. Diferena ntre cele dou tipuri de metode este urmtoarea: metodele de instan opereaz att pe variabilele de instan ct i pe cele statice ale clasei; metodele de clas opereaz doar pe variabilele statice ale clasei. class Exemplu { int x ; // Variabila de instanta static long n; // Variabila de clasa void metodaDeInstanta() { n++; // Corect x--; // Corect } static void metodaStatica() { n++; // Corect x--; // Eroare la compilare ! } } Intocmai ca i la variabilele statice, ntruct metodele de clas nu depind de starea obiectelor clasei respective, apelul lor se poate face i sub forma: NumeClasa.numeMetodaStatica Exemplu.metodaStatica(); // Corect, echivalent cu Exemplu obj = new Exemplu(); obj.metodaStatica(); // Corect, de asemenea Metodele de instan nu pot fi apelate dect pentru un obiect al clasei respective: Exemplu.metodaDeInstanta(); // Eroare la compilare ! Exemplu obj = new Exemplu(); obj.metodaDeInstanta(); // Corect 2.1.5 Tablouri Tablourile n Java au suferit unele mbuntiri fa de modul de implementare al lor n alte limbaje cum ar fi C/C++. Astfel, tablourile sunt ntotdeauna iniializate i nu pot fi accesate nafara dimensiunilor stabilite la declararea lor. Tablourile n Java pot conine att tipuri de date primitive ct i date de tip referin (obiecte). a) Crearea unui vector Crearea unui vector presupune realizarea urmatoarelor etape: Declararea vectorului - Pentru a putea utiliza un vector trebuie, nainte de toate, s l declaram. Acest lucru se face prin expresii de forma: Tip[] numeVector; sau Tip numeVector[]; Exemple: int[] intregi; String adrese[];

33

Note

34

Programare orientat obiect Instanierea - Declararea unui vector nu implica i alocarea memoriei necesare pentru reinerea elementelor. Operaiunea de alocare a memoriei, numita i instanierea vectorului, se realizeaza ntotdeauna prin intermediul operatorului new. Instanierea unui vector se va face printr-o expresie de genul: numeVector = new Tip[nrElemente]; unde nrElemente reprezinta numarul maxim de elemente pe care le poate avea vectorul. n urma instanierii vor fi alocai: nrElemente*dimensiune(Tip) octei necesari memorarii elementelor din vector, unde prin dimensiune(Tip) am notat numarul de octei pe care se reprezinta tipul respectiv. Exemple: v = new int[10]; //aloca spatiu pentru 10 intregi: 40 octeti c = new char[10]; //aloca spatiu pentru 10 caractere: 20 octeti Declararea i instanierea unui vector pot fi facute simultan astfel: Tip[] numeVector = new Tip[nrElemente]; Iniializarea (opional): Dup declararea unui vector, acesta poate fi iniializat, adic elementele sale pot primi nite valori iniiale, evident dac este cazul pentru aa ceva. n acest caz instanierea nu mai trebuie facuta explicit, alocarea memoriei facndu-se automat n funcie de numarul de elemente cu care se iniializeaza vectorul. Exemple: String culori[] = {"Rosu", "Galben", "Verde"}; int []factorial = {1, 1, 2, 6, 24, 120}; Primul indice al unui vector este 0, deci poziiile unui vector cu n elemente vor fi cuprinse ntre 0 i n-1. Nu sunt permise construcii de genul Tip numeVector[nrElemente], alocarea memoriei facndu-se doar prin intermediul opearatorului new. int v[10]; //ilegal int v[] = new int[10]; //corect b) Dimensiunea unui vector Cu ajutorul variabilei length se poate afla numarul de elemente al unui vector. int []a = new int[5]; // a.length are valoarea 5 int m[][] = new int[5][10]; // m[0].length are valoarea 10 Pentru a nelege modalitatea de folosire a lui length trebuie menionat ca fiecare vector este de fapt o instana a unei clase iar length este o variabila publica a acelei clase, n care este reinut numarul maxim de elemente al vectorului. c) Metode pentru lucrul cu vectori Copierea vectorilor void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) unde src vector sursa ; dest vector destinatie ; length nr. de elemente de copiat Copierea elementelor unui vector a ntr-un alt vector b se poate face, fie element cu element, fie cu ajutorul metodei System.arraycopy, ca n exemplele de mai jos. Dup cum vom vedea, o atribuire de genul b = a are alta semnificaie dect copierea elementelor lui a n b i nu poate fi folosita n acest scop. int a[] = {1, 2, 3, 4}; int b[] = new int[4]; // Varianta 1 for(int i=0; i= vector.length) throw new ArrayIndexOutOfBoundsException(); ... catch(Exception e) { System.out.println("A aparut o exceptie); throw e; } Aceast instruciune este folosit mai ales la aruncarea excepiilor proprii.

Note

58

Programare orientat obiect 2.3.5 Avantajele tratrii excepiilor Prin modalitatea sa de tratare a excepiilor, Java are urmtoarele avantaje fa de mecanismul tradiional de tratare a erorilor: Separarea codului pentru tratarea unei erori de codul n care ea poate s apar. Propagarea unei erori pn la un analizor de excepii corespunztor. Gruparea erorilor dup tipul lor. 2.3.6 Excepii la execuie n general, tratarea excepiilor este obligatorie n Java. De la acest principu se sustrag ns aa numitele excepii la execuie sau, cu alte cuvinte, excepiile care provin strict din vina programatorului i nu generate de o anumit situaie extern, cum ar fi lipsa unui fiier. Aceste excepii au o superclas comun RuntimeException i n acesata categorie sunt incluse excepiile provocate de: operaii aritmetice ilegale (mprirea ntregilor la zero) - ArithmeticException accesarea membrilor unui obiect ce are valoarea null - NullPointerException a elementelor unui vector accesarea eronat ArrayIndexOutOfBoundsException Excepiile la execuie pot aprea oriunde n program i pot fi extrem de numeroase, iar ncercarea de prindere a lor ar fi extrem de anevoioas. Din acest motiv, compilatorul permite ca aceste excepii s rmn netratate, tratarea lor nefiind ns ilegal. Reamintim ns c, n cazul apariiei oricrui tip de excepie care nu are un analizor corespunztor, programul va fi terminat. 2.3.7 Excepii definite de utilizator Poate apare uneori necesitatea crerii unor excepii proprii pentru a pune n eviden cazuri speciale de erori, cazuri care un au fost prevazute n ierarhia excepiilor standard Java. O clasa de exceptii proprie trebuie s implementeze una din clasele de excepii deja existente, n cazul cel mai general, trebuie sa implementeze clasa Exception. Exemplu: class MyException extends Exception { MyException () {} MyException (String msg){ super(msg); } }

Test de autoevaluare: 1. Ce conin blocurile try, catch, finally?

Note

Programare orientat obiect

59

2. Cte blocuri try i cte blocuri catch pot exista ntr-o construcie trycatch-finally?

3. Care este cuvntul cheie folosit de o metod care nu dorete s trateze excepiile i vrea s le arunce la nivelele superioare?

4. Care este diferena dintre erori i excepii?

5. Care este particularitatea clasei RuntimeException?

Bibliografie : 1. Cristian Frsinaru Curs practic de Java 2. Bruce Eckel Thinking in Java 4th Edition, Ed. Prentice Hall, 2006, ISBN 0-13-187248-6 3. P. Niemeyer, J. Knudsen - Learning Java 3rd Edition, Ed. OReilly, 2005 4. .Tanas,.Andrei,C. Olaru Java de la 0 la expert, Ed.Polirom, 2007, ISBN 978-973-46-0317-6 5. D.Danciu, G.Mardale - Arta programrii n JAVA (Vol. I) Elemente-suport fundamentale, Ed. Albastr, 2005 Note

60

Programare orientat obiect 2.4 Intrri i ieiri. Fluxuri

Obiective: Cunoaterea noiunii de flux n Java Cunoa Cunoaterea principalelor tipuri de fluxuri i utilitatea lor Cunoa Cunoaterea fluxurilor pentru intrarea i ieirea standard Cunoa irea Cunoaterea posibilitailor de citire a datelor de la tastatur Cunoa ilor tastatur Lucrul cu fi iere folosind clasa RandomAccessFile fiiere Lucrul cu fi fiiere folosind clasa File

2.4.1 Introducere 1 a) Ce sunt fluxurile? Majoritatea aplica aplicaiilor necesit citirea unor informaii care se g gsesc pe o surs extern sau trimiterea unor informaii ctre o destina tre destinaie extern. Informaia se poate g oriunde: ntr-un fiier pe disc, n reea, n memorie sau ia gsi ier n alt program i poate fi de orice tip: date primitive, obiecte, imagini, sunete, i etc. Pentru a aduce informa dintr-un mediu extern, un progam Java trebuie informaii un s deschid un canal de comunica (flux) de la sursa informa comunicaie ) informaiilor (fiier, memorie, socket, etc) i s citeasc secvenial informaiile respective. iile Similar, un program poate trimite informa ctre o destina extern informaii tre destinaie deschiznd un canal de comunica comunicaie (flux) ctre acea destina tre destinaie i scriind secvenial informa ial informaiile respective. Indiferent de tipul informa iilor, citirea/scrierea de pe/c informaiilor, pe/ctre un mediu extern respect urm urmtorul algoritm: ieire deschide canal comunicatie while (mai sunt informatii) { Program Java Surs extern citeste/scrie informatie; } intrare inchide canal comunicatie; Pentru a generaliza, att sursa extern a unor date ct i destinaia lor extern sunt vzute ca fiind ni te procese care produc, respectiv consum informaii. zute nite consum Definiii: - Un flux este un canal de comunica unidirecional ntre dou procese. comunicaie ional dou - Un proces care descrie o surs extern de date se nume surs numete proces productor. - Un proces care descrie o destina extern pentru date se nume proces destinaie numete consumator. - Un flux care cite date se numete flux de intrare. citete - Un flux care scrie date se nume flux de ieire. numete Observaii: Fluxurile sunt canale de comunica ie seriale pe 8 sau 16 bi comunicaie bii. Fluxurile sunt unidirec unidirecionale, de la productor la consumator. tor Fiecare flux are un singur proces produc x productor i un singur proces consumator. i Intre dou procese pot exista oricte fluxuri, orice proces putnd fi att producator ct i consumator n acela i timp, dar pe fluxuri diferite. acelai Consumatorul i producatorul nu comunic direct printr-o interfa de flux ci o interfa

Note

Programare orientat obiect prin intermediul codului Java de tratare a fluxurilor. Clasele i intefeele standard pentru lucrul cu fluxuri se gsesc n pachetul java.io. Deci, orice program care necesit operaii de intrare sau ieire trebuie s conin instruciunea de import a pachetului java.io: import java.io.*; b) Clasificarea fluxurilor Exist trei tipuri de clasificare a fluxurilor: Dup direcia canalului de comunicaie deschis fluxurile se mpart n: fluxuri de intrare (pentru citirea datelor) fluxuri de ieire (pentru scrierea datelor) Dup tipul de date pe care opereaz: fluxuri de octei (comunicarea serial se realizeaz pe 8 bii) fluxuri de caractere (comunicarea serial se realizeaz pe 16 bii) Dup aciunea lor: fluxuri primare de citire/scriere a datelor (se ocup efectiv cu citirea/scrierea datelor) fluxuri pentru procesarea datelor c) Ierarhia claselor pentru lucrul cu fluxuri Clasele rdcin pentru ierarhiile ce reprezint fluxuri de caractere sunt: Reader- pentru fluxuri de intrare i Writer- pentru fluxuri de ieire. Acestea sunt superclase abstracte pentru toate clasele ce implementeaz fluxuri specializate pentru citirea/scrierea datelor pe 16 bii i vor conine metodele comune tuturor. Ca o regul general, toate clasele din aceste ierarhii vor avea terminaia Reader sau Writer n funcie de tipul lor, cum ar fi n exemplele: FileReader, BufferedReader, FileWriter, BufferedWriter, etc. De asemenea, se observ ca o alt regul general, faptul c unui flux de intrare XReader i corespunde uzual un flux de ieire XWriter, ns acest lucru nu este obligatoriu. Clasele radacin pentru ierarhia fluxurilor de octei sunt: InputStream- pentru fluxuri de intrare i OutputStream- pentru fluxuri de ieire. Acestea sunt superclase abstracte pentru clase ce implementeaz fluxuri specializate pentru citirea/scrierea datelor pe 8 bii. Ca i n cazul fluxurilor pe caractere denumirile claselor vor avea terminaia superclasei lor: FileInputStream, BufferedInputStream, FileOutputStream, BufferedOutputStream, etc., fiecrui flux de intrare XInputStream corespunzndu-i uzual un flux de ieire XOutputStream, fr ca acest lucru s fie obligatoriu. Pn la un punct, exist un paralelism ntre ierarhia claselor pentru fluxuri de caractere i cea pentru fluxurile pe octei. Pentru majoritatea programelor este recomandat ca scrierea i citirea datelor s se fac prin intermediul fluxurilor de caractere, deoarece acestea permit manipularea caracterelor Unicode n timp ce fluxurile de octei permit doar lucrul pe 8 biti - caractere ASCII. d) Metode comune fluxurilor Superclasele abstracte Reader i pentru citirea datelor. Reader int read() int read (char buf[]) InputStream definesc metode similare InputStream int read() int read (char buf[])

61

Note

62

Programare orientat obiect ... ... De asemenea, ambele clase pun la dispoziie metode pentru marcarea unei locaii ntr-un flux, saltul peste un numr de poziii, resetarea poziiei curente, etc. Acestea sunt ns mai rar folosite i nu vor fi detaliate. Superclasele abstracte Writer i OutputStream sunt de asemenea paralele, definind metode similare pentru scrierea datelor: Reader InputStream void write (int c) void write (int c) void write (char buf[]) void write (char buf[]) void write (String str) ... ... Inchiderea oricrui flux se realizeaz prin metoda close(). n cazul n care aceasta nu este apelat explicit, fluxul va fi automat nchis de ctre colectorul de gunoaie atunci cnd nu va mai exista nici o referin la el, ns acest lucru trebuie evitat deoarece, la lucrul cu fluxrui cu zon tampon de memorie, datele din memorie vor fi pierdute la nchiderea fluxului de ctre gc. Metodele referitoare la fluxuri pot genera excepii de tipul IOException sau derivate din aceast clas, tratarea lor fiind obligatorie. Aa cum am vzut, fluxurile pot fi mprite n funcie de activitatea lor n fluxuri care se ocup efectiv cu citirea/scrierea datelor i fluxuri pentru procesarea datelor (de filtrare). n continuare, vom vedea care sunt cele mai importante clase din cele dou categorii i la ce folosesc acestea, precum i modalitile de creare i utilizare a fluxurilor. 2.4.2 Fluxuri primitive Fluxurile primitive sunt responsabile cu citirea/scrierea efectiv a datelor, punnd la dispoziie implementri ale metodelor de baz read, respectiv write, definite n superclase. n funcie de tipul sursei datelor, ele pot fi mprite astfel: Fiier : FileReader, FileWriter, FileInputStream, FileOutputStream Numite i fluxuri fiier, acestea sunt folosite pentru citirea datelor dintrun fiier, respectiv scrierea datelor ntr-un fiier i vor fi analizate ntr-o seciune separat. Memorie : CharArrayReader, CharArrayWriter, ByteArrayInputStream, ByteArrayOutputStream Aceste fluxuri folosesc pentru scrierea/citirea informaiilor n/din memorie i sunt create pe un vector existent deja. Cu alte cuvinte, permit tratarea vectorilor ca surs/destinaie pentru crearea unor fluxuri de intrare/ieire. StringReader, StringWriter permit tratarea irurilor de caractere aflate n memorie ca surs/destinaie pentru crearea de fluxuri. Pipe : PipedReader, PipedWriter, PipedInputStream, PipedOutputStream Implementeaz componentele de intrare/ieire ale unei conducte de date (pipe). Pipe-urile sunt folosite pentru a canaliza ieirea unui program sau fir de execuie ctre intrarea altui program sau fir de execuie. 2.4.3 Fluxuri de procesare Fluxurile de procesare (sau de filtrare) sunt responsabile cu preluarea datelor de la un flux primitiv i procesarea acestora pentru a le oferi ntr-o alt

Note

Programare orientat obiect form, mai util dintr-un anumit punct de vedere. De exemplu, BufferedReader poate prelua date de la un flux FileReader i s ofere informaia dintr-un fiier linie cu linie. Fiind primitiv, FileReader nu putea citi dect caracter cu caracter. Un flux de procesare nu poate fi folosit dect mpreun cu un flux primitiv. Clasele ce descriu aceste fluxuri pot fi mpartite n funcie de tipul de procesare pe care l efectueaza astfel: Bufferizare : BufferedReader, BufferedWriter, BufferedInputStream, BufferedOutputStream Sunt folosite pentru a introduce un buffer n procesul de citire/scriere a informaiilor, reducnd astfel numrul de accesri la dispozitivul ce reprezint sursa/destinaia original a datelor. Sunt mult mai eficiente dect fluxurile fr buffer i din acest motiv se recomand folosirea lor ori de cte ori este posibil. Filtrare: FilterReader, FilterWriter, FilterInputStream, FilterOutputStream Sunt clase abstracte ce definesc o interfa comun pentru fluxuri care filtreaz automat datele citite sau scrise. Conversie octei-caractere: InputStreamReader, OutputStreamWriter Formeaz o punte de legatur ntre fluxurile de caractere i fluxurile de octei. Un flux InputStreamReader citete octei dintr-un flux InputStream i i convertete la caractere, folosind codificarea standard a caracterelor sau o codificare specificat de program. Similar, un flux OutputStreamWriter convertete caractere n octei i trimite rezutatul ctre un flux de tipul OutputStream. Concatenare: SequenceInputStream Concateneaz mai multe fluxuri de intrare ntr-unul singur. Serializare: ObjectInputStream, ObjectOutputStream Sunt folosite pentru serializarea obiectelor. Conversie tipuri de date: DataInputStream, DataOutputStream Folosite la scrierea/citirea datelor de tip primitiv ntr-un format binar, independent de maina pe care se lucreaz. Numrare: LineNumberReader, LineNumberInputStream Ofer i posibilitatea de numrare automat a liniilor citite de la un flux de intrare. Citire n avans: PushbackReader, PushbackInputStream Sunt fluxuri de intrare care au un buffer de 1-caracter(octet) n care este citit n avans i caracterul (octetul) care urmeaz celui curent citit. Afiare: PrintWriter, PrintStream Ofer metode convenabile pentru afisarea informaiilor. 2.4.4 Crearea unui flux Orice flux este un obiect al clasei ce implementeaz fluxul respectiv. Crearea unui flux se realizeaz aadar similar cu crearea obiectelor, prin instruciunea new i invocarea unui constructor corespunztor al clasei respective: Exemple: //crearea unui flux de intrare pe caractere FileReader in = new FileReader("fisier.txt"); //crearea unui flux de iesire pe caractere FileWriter out = new FileWriter("fisier.txt");

63

Note

64

Programare orientat obiect //crearea unui flux de intrare pe octeti FileInputStream in = new FileInputStream("fisier.dat"); //crearea unui flux de iesire pe octeti FileOutputStrem out = new FileOutputStream("fisier.dat"); Aadar, crearea unui flux primitiv de date care citete/scrie informaii de la un dispozitiv extern are formatul general: FluxPrimitiv numeFlux = new FluxPrimitiv(dispozitivExtern); Fluxurile de procesare nu pot exista de sine stttoare ci se suprapun pe un flux primitiv de citire/scriere a datelor. Din acest motiv, constructorii claselor pentru fluxurile de procesare nu primesc ca argument un dispozitiv extern de memorare a datelor ci o referina la un flux primitiv responsabil cu citirea/scrierea efectiv a datelor: Exemple: //crearea unui flux de intrare printr-un buffer BufferedReader in = new BufferedReader(new FileReader("fisier.txt")); //echivalent cu FileReader fr = new FileReader("fisier.txt"); BufferedReader in = new BufferedReader(fr); //crearea unui flux de iesire printr-un buffer BufferedWriter out = new BufferedWriter(new FileWriter("fisier.txt"))); //echivalent cu FileWriter fo = new FileWriter("fisier.txt"); BufferedWriter out = new BufferedWriter(fo); Aadar, crearea unui flux pentru procesarea datelor are formatul general: FluxProcesare numeFlux = new FluxProcesare(fluxPrimitiv); n general, fluxurile pot fi compuse n succesiuni orict de lungi: DataInputStream in = new DataInputStream(new BufferedInputStream (new FileInputStream ("fisier.dat"))); 2.4.5 Fluxuri pentru lucrul cu fiiere Fluxurile pentru lucrul cu fiiere sunt cele mai usor de nteles, ntruct operaia lor de baz este citirea, respectiv scrierea unui caracter sau octet dintrun sauntr-un fiier specificat uzual prin numele su complet sau relativ la directorul curent. Dup cum am vzut deja, clasele care implementeaz aceste fluxuri sunt urmtoarele: FileReader, FileWriter - caractere FileInputStream, FileOutputStream - octeti Constructorii acestor clase accept ca