+ All Categories
Home > Documents > Introducere în limbajul de programare Java

Introducere în limbajul de programare Java

Date post: 03-Jan-2017
Category:
Upload: dinhtuong
View: 265 times
Download: 15 times
Share this document with a friend
185
1. Introducere în limbajul de programare Java 1.1. Ce este Java? o insulă din Indonezia (126 650 km², 65 mil. locuitori) un jargon american pentru cafea o platformă şi un limbaj de programare orientat pe obiecte Utilizarea Internetului ca mediu pentru difuzarea de informaţii, dar şi de programe, conduce la ideea de numitor comun, de platformă comună pentru care să fie dezvoltate aplicaţiile. Costurile implementării de aplicaţii pot să scadă spectaculos dacă nu sunt necesare adaptări de soluţii pentru fiecare tip sau versiune hardware sau de sistem de operare existent în lume. 1
Transcript
Page 1: Introducere în limbajul de programare Java

1. Introducere în limbajul de programare Java

1.1. Ce este Java?

o insulă din Indonezia (126 650 km²,

65 mil. locuitori)

un jargon american pentru cafea

o platformă şi un limbaj de programare orientat pe obiecte

Utilizarea Internetului

ca mediu pentru difuzarea de informaţii, dar şi de programe, conduce la ideea

de numitor comun, de platformă comună pentru care să fie dezvoltate aplicaţiile.

Costurile implementării de aplicaţii pot să scadă spectaculos dacă nu sunt

necesare adaptări de soluţii pentru fiecare tip sau versiune hardware sau de sistem

de operare existent în lume.

1.2. Limbajul de programare Java

Java este un limbaj de programare de nivel înalt, dezvoltat de JavaSoft,

companie în cadrul firmei Sun Microsystems. Dintre caracteristicile principale ale

limbajului amintim:

simplitate – Java este uşor de învăţat, caracteristicile complicate

(supraîncărcarea operatorilor, moştenirea multiplă, şabloane) întâlnite în

alte limbaje de programare sunt eliminate.

1

Page 2: Introducere în limbajul de programare Java

robusteţe, elimină sursele frecvente de erori ce apar în programare prin

eliminarea pointerilor, administrarea automată a memoriei şi eliminarea

fisurilor de memorie printr-o procedură de colectare a 'gunoiului' care

rulează în fundal. Un program Java care a trecut de compilare are

proprietatea că la execuţia sa nu "crapă sistemul".

complet orientat pe obiecte - elimină complet stilul de programare

procedural; se bazează pe încapsulare, moştenire, polimorfism uşurinţă în ceea ce priveşte programarea în reţea

securitate, este cel mai sigur limbaj de programare disponibil în acest

moment, asigurând mecanisme stricte de securitate a programelor

concretizate prin: verificarea dinamică a codului pentru detectarea

secvenţelor periculoase, impunerea unor reguli stricte pentru rularea

programelor lansate pe calculatoare aflate la distanta, etc

este neutru din punct de vedere arhitectural portabilitate, cu alte cuvinte Java este un limbaj independent de

platforma de lucru, aceeaşi aplicaţie rulând, fără nici o modificare, pe

sisteme diferite cum ar fi Windows, UNIX sau Macintosh, lucru care aduce

economii substanţiale firmelor care dezvoltă aplicaţii pentru Internet.

Sloganul de bază este: „Write once, run anywhere”

compilat şi interpretat asigură o performanţă ridicată a codului de octeţi

conţine o librărie de clase şi interfeţe pentru domenii specifice cum ar fi

programarea interfeţelor utilizator (JFC, AWT, Swing), programare

distribuită (comunicare TCP/IP, CORBA, RMI etc.)

permite programarea cu fire de execuţie (multithreaded)

dinamicitate

este modelat după C şi C++, trecerea de la C / C++ la Java făcându-se

foarte uşor.

face diferenţa între literele mici şi mari (este case sensitive)

permite dezvoltarea aplicaţiilor pentru Internet – crearea unor

documente Web îmbunătăţite cu animaţie şi multimedia.

Java Development Kit (JDK) este disponibil gratis

2

Page 3: Introducere în limbajul de programare Java

1.3. Java : un limbaj compilat şi interpretat

În funcţie de modul de execuţie al programelor, limbajele de programare se

împart în două categorii :

interpretate: instrucţiunile sunt citite linie cu linie de un program numit

interpretor şi traduse în instrucţiuni maşină; avantaj: simplitate;

dezavantaj: viteza de execuţie redusă;

compilate: codul sursă al programelor este transformat de compilator într-

un cod ce poate fi executat direct de procesor; avantaj: execuţie rapidă;

dezavantaj: lipsa portabilităţii, codul compilat într-un format de nivel scăzut

nu poate fi rulat decât pe platforma pe care a fost compilat.

Programele Java sunt atât interpretate cât şi compilate

Codul de octeţi este diferit de codul maşină. Codul maşină este reprezentat de

o succesiune de 0 şi 1; codurile de octeţi sunt seturi de instrucţiuni care seamănă cu

codul scris în limbaj de asamblare. Codul maşină este executat direct de către

procesor şi poate fi folosit numai pe platforma pe care a fost creat; codul de octeţi

este interpretat de mediul Java şi de aceea poate fi rulat pe orice platformă care

foloseşte mediul de execuţie Java.

Fazele prin care trece un program Java sunt:

Cod sursa Java -> (compilare) -> Cod de octeti -> (interpretare)

1.4. Istoria limbajului Java

1991: în cadrul companiei Sun Microsystems începe dezvoltarea unui proiect

pentru aparatură electronică inteligentă conectată în reţea.

1992: începe dezvoltarea limbajului de programare Oak (James Gosling);

1993: devine disponibil primul browser WWW (World Wide Web) Mosaic;

dezvoltarea unui web-browser (Webrunner), capabil să încarce şi să execute

programe mici scrise în Oak;

1994: Oak este redenumit Java iar Webrunner, HotJava

1995: Netscape (fondat de cei care au dezvoltat Mosaic-ul) decide să integreze

Java în Netscape Navigator 2.0

3

Page 4: Introducere în limbajul de programare Java

ianuarie 1996 : apare JDK 1.0 (soft gratuit);

februarie

1997: apare JDK 1.1;

martie 1997: apar HotJava 1.0 şi JavaOS 1.0;

1998 Java Foundation Classes JVC released, incluzând Swing 1.0

după 1999 apar versiuni noi ale JDK

în prezent s-a ajuns la JDK1.4.

1.5. Mediul Java

În acest curs se utilizează distribuţia JDK 1.3 (Java Development Kit), produsă

de firma Sun.

Există două posibilităţi de a lucra în Java: în linie de comandă – paşii fiind

indicaţi mai jos, sau folosind un editor Java cum ar fi JCreator, Eclipse, etc.

Realizarea unui program Java constă în următorii paşi:

Editarea programului într-un editor de texte;

Salvarea programului sub numele NumeClasa.java unde NumeClasa este

numele clasei care conţine metoda main(). Într-un program Java trebuie să

existe o singură clasă care să conţină o metodă main(). Cu alte cuvinte, numele

clasei trebuie să coincidă cu numele fişierului. Extensia fişierului este .java

Compilarea programului se face cu ajutorul comenzii

javac NumeClasa.java

Executarea programului se face cu ajutorul comenzii

java NumeClasa

1.6. Crearea unei aplicaţii simple

1. Scrierea codului sursă:

4

Page 5: Introducere în limbajul de programare Java

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

System.out.println("Salut !!!");}

}Toate aplicaţiile Java conţin o clasă principală în care trebuie să se găsească

metoda main(). Clasele aplicaţiei se pot găsi fie într-un singur fişier, fie în mai

multe.

2. Salvarea fişierelor sursă

Se va face în fişiere cu extensia .java. Fişierul care conţine codul sursă al

clasei principale trebuie să aibă acelaşi nume cu clasa principală a aplicaţiei (clasa

care conţine metoda main). Prin urmare, fişierul nostru o să-l salvăm sub numele:

Salut.java

3. Compilarea aplicaţiei

Se foloseşte compilatorul Java, javac. Apelul compilatorului se face pentru

fişierul ce conţine clasa principală a aplicaţiei. Compilatorul creează câte un fişier

separat pentru fiecare clasă a programului; acestea au extensia .class şi sunt

plasate în acelaşi director cu fişierele sursă. Rezultatul comenzii

javac Salut.javaeste fişierul Salut.class

4. Rularea aplicaţiei

Se face cu interpretorul java, apelat pentru unitatea de compilare

corespunzătoare clasei principale, fiind însă omisă extensia .class asociată

acesteia.

java Salut

Rularea unei aplicaţii care nu foloseşte interfaţă grafică, se va face într-o fereastră

sistem.

1.7. Crearea unui applet

Crearea structurii de fişiere şi compilarea applet-urilor sunt identice ca în cazul

aplicaţiilor. Diferă în schimb structura programului şi modul de rulare al acestuia.

1. Scrierea codului sursă:

5

Page 6: Introducere în limbajul de programare Java

import javax.swing.*;import java.awt.*;

public class Salut extends JApplet {public void paint(Graphics g){

g.drawString("Salut",50,50); }}

2. Salvarea fişierelor sursă

Salvarea se va face în fişierul Salut.java

3. Compilarea applet-uluijavac Salut.java

În urma compilării rezultă fişierul Salut.class

4. Rularea applet-ului

Applet-urile nu rulează independent. Ele pot fi rulate doar prin intermediul unui

browser: Internet Explorer, Netscape sau printr-un program special cum ar fi

appletviewer-ul din setul JDK.

Crearea unui fişier HTML pentru miniaplicaţie (exemplu.html)

<html>

<head>

<title>Primul Applet Java</title>

</head>

<body>

<applet code=Salut.class width=400 height=400>

</applet>

</body>

</html>

5. Vizualizarea applet-tlui appletviewer exemplu.html

6

Page 7: Introducere în limbajul de programare Java

2. Programarea Orientată pe Obiecte şi Java

2.1. Obiecte şi clase

Programarea Orientată pe Obiecte (OOP) este una dintre cele mai mari idei de

programare apărută în anii 1990. Ideea centrală a OOP este: organizarea

programelor astfel încât ele să reprezinte un ecou al modului în care lucrurile sunt

puse împreună în lumea reală.

Exemplu:

Pentru cine nu s-a jucat niciodată cu Lego, acesta constă în diferite bucăţi de

plastic, de diferite culori şi dimensiuni. Ele sunt dotate cu crescături şi adâncituri prin

intermediul cărora piesele pot fi conectate între ele. Cu diferite componente Lego se

poate forma aproape orice: maşini, oameni, castele, case, etc. în funcţie de

imaginaţia fiecăruia. Fiecare piesă de Lego este un mic obiect care împreună cu

altele ajută la crearea altor obiecte mai mari. Exact aşa stau lucrurile şi în

programarea orientată pe obiecte: obiecte mici puse împreună formează obiecte

mari.

Programarea orientată pe obiecte este gândită după modelul lumii reale –

obiectele sunt adesea formate din mai multe tipuri de obiecte mici.

Când scriem programe într-un limbaj orientat pe obiecte, nu definim obiecte ci

clase de obiecte, unde o clasă reprezintă un şablon pentru mai multe obiecte cu caracteristici similare. Clasele întrupează toate caracteristicile unei mulţimi

particulare de obiecte. De exemplu, ne putem gândi la clasa Copac care descrie

caracteristicile tuturor copacilor (au rădăcini, trunchi şi frunze, cresc, produc clorofilă,

îşi schimbă frunzele, etc). Clasa Copac reprezintă un model abstract pentru

conceptul de copac – pentru a planta un copac, a-l atinge, a-i rupe o frunză sau a-l

tăia avem nevoie de un copac concret, altfel spus de o instanţă a copacului.

Bineînţeles că, odată ce avem clasa copac, putem crea oricâte instanţe diferite ale

7

Page 8: Introducere în limbajul de programare Java

copacului respectiv – ”copaci concreţi”. Aceştia pot avea caracteristici diferite (unii

sunt înalţi, alţii pitici, unii îşi pierd frunzele toamna, alţii nu, etc)

O altă noţiune specifică OOP este cea de obiect. Obiect sau instanţă a clasei

reprezintă acelaşi lucru. Clasa este reprezentarea generală a unui obiect iar instanţa /obiectul este reprezentarea concretă a clasei.

2.2. Atribute şi comportamente

Fiecare clasă scrisă în Java are două caracteristici de bază: atribute şi

comportament.

2.2.1. Atribute

Atributele diferenţiază obiectele între ele şi determină aparenţa, starea sau alte

calităţi ale obiectului în cauză. Dacă ne gândim să creăm o clasă Maşină, ea ar

trebui să includă următoarele atribute: culoare, stil, marcă.

Atributele sunt definite în clase ca variabile. Tipul şi numele variabilelor sunt definite în clase şi fiecare obiect are valori proprii pentru fiecare atribut.

8

Page 9: Introducere în limbajul de programare Java

Deoarece fiecare instanţă a clasei poate avea valori diferite pentru variabilele sale,

aceste variabile se mai numesc şi variabile instanţă.Exemplu: O instanţă a clasei maşină, MaşinaMea ar putea avea următoarele

valori pentru atribute:

culoare = alb stil = elegantmarcă = Mercedes

Există, de asemenea, şi un alt tip de variabile numite variabile clasă.

Diferenţa dintre cele două tipuri de variabile este aceea că valorile variabilelor

instanţă sunt păstrate în instanţe şi se schimbă pentru fiecare instanţă iar valorile

variabilelor clasă sunt păstrate în clasă şi nu se schimbă pentru fiecare instanţă.

Asupra diferenţei dintre cele două tipuri de variabile o să revin într-un capitol

următor.

2.2.2. Comportament

Comportamentul unei clase determină cum operează o instanţă a unei clase.

De exemplu, cum reacţionează un obiect atunci când un alt obiect sau o altă clasă îi

cere să facă ceva. Să revenim la clasa Maşină. Comportamentul unei maşini constă

în: porneşte, opreşte, frânează, schimbă viteza, schimbă

direcţia, etc.

Pentru a defini comportamentul unei clase se definesc metode, echivalentul

funcţiilor sau procedurilor din alte limbaje de programare. Spre diferenţă de alte

limbaje de programare, în Java nu se pot defini funcţii în afara claselor. Prin urmare,

metodele sunt funcţii definite în interiorul claselor care operează în instanţele claselor respective.

Metoda unui obiect poate fi apelată de către un alt obiect sau o altă clasă.

Ca şi în cazul atributelor, există două tipuri de metode: metode instanţă şi

metode clasă. Metodele instanţă operează doar în cadrul instanţei unei clase. În

schimb, metodele clasă operează în interiorul clasei.

9

Page 10: Introducere în limbajul de programare Java

2.3. Principiile OOP

Obiectul este o variabilă care are o structura şi o stare. Fiecare obiect dispune

de operaţii prin intermediul cărora i se poate manipula starea.

Obiectul trebuie privit ca o unitate atomică pe care utilizatorul nu ar trebui să o

disece. De exemplu, când lucrăm cu numere întregi, nu ne punem problema

reprezentării lor. Utilizatorul nu are acces direct la părţile constituente ale unui obiect

sau la implementarea sa; acestea vor putea fi accesate doar prin intermediul

metodelor care au fost furnizate împreună cu obiectul. Gruparea datelor şi a

operaţiilor care pot fi efectuate asupra acestor date, având grijă ca detaliile de

implementare să fie ascunse, poarta numele de încapsulare.

Unul din principalele scopuri ale OOP este refolosirea codului. Limbajele de

programare orientate pe obiecte furnizează mai multe mecanisme în acest scop.

1. Folosirea codului generic – dacă implementarea este identică, şi diferă

doar tipul de bază al obiectului, nu este necesară rescrierea completă a

codului – se scrie un cod generic care funcţionează pentru orice tip. De

exemplu, se poate scrie o metodă care să ordoneze un şir de numere întregi,

caractere, şiruri de caractere.

2. Moştenirea este un mecanism care permite extinderea funcţionalităţii unei

clase. Se pot crea noi tipuri de date care să extindă (sau să restricţioneze)

proprietăţile tipului de date original.

3. Polimorfismul Un tip referinţă polimorfic poate să refere obiecte de mai

multe tipuri. Atunci când se apelează o metodă a tipului polimorfic, se va

selecta automat metoda care corespunde tipului referit în acel moment.

10

Page 11: Introducere în limbajul de programare Java

3. Elementele de bază ale limbajului de programare Java

3.1. Structura lexicală a limbajului

3.1.1. Setul de caractere

Limbajului Java foloseşte setul de caractere Unicode. Este un standard

internaţional care înglobează setul de caractere ASCII (permite reprezentarea a 256

de caractere). Foloseşte pentru reprezentarea caracterelor 2 octeţi, ceea ce

înseamnă că se pot reprezenta 65536 de semne. Primele 256 caractere Unicode

corespund celor din ASCII. Referirea la un caracter se face prin \uxxxx, unde xxxx

reprezintă codul caracterului.

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

3.1.2. Cuvinte cheie

Cuvintele rezervate în Java sunt cele din C++, cu câteva excepţii.

3.1.3. Identificatori

Sunt secvenţe nelimitate de litere şi cifre Unicode, începând cu o literă.

Identificatorii nu au voie să fie identici cu cuvintele rezervate.

11

Page 12: Introducere în limbajul de programare Java

3.1.4. Constante

Constantele pot fi de următoarele tipuri

1. constante întregiSunt acceptate 3 baze de numeraţie : baza 10, baza 16 (încep cu

caracterele 0x) şi baza 8 (încep cu cifra 0) şi pot fi de două tipuri:

normale, (se reprezintă pe 4 octeţi - 32 biţi)

lungi (8 octeţi - 64 biţi): se termină cu caracterul L (sau l).

2. constante realePentru ca o constantă să fie considerată reală ea trebuie să aibă cel puţin

o zecimală după virgulă, să fie în notaţie exponenţială sau să aibă sufixul F sau f

pentru valorile normale (reprezentate pe 32 biţi), respectiv D sau d pentru valorile

lungi (reprezentate pe 64 biţi).

3. constante logicetrue : valoarea booleană de adevăr

false : valoarea booleană de fals

Observaţie: spre deosebire de C++, constantele întregi 1 şi 0 nu mai au rolul

de adevărat şi fals.

4. constante caracterO constantă 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. Secvenţele escape permit reprezentarea

caracterelor care nu au reprezentare grafică şi reprezentarea unor caractere

speciale precum backslash, apostrof, etc. Secvenţe escape predefinite în Java:

Cod Secvenţa Escape Caracter

\u0008 '\b' Backspace(BS)

\u0009 '\t' Tab orizontal (HT)

\u000a '\n' Linie nouă - linefeed (LF)

\u000c '\f' Pagină nouă - formfeed (FF)

\u000d '\r' Început de rând (CR)

\u0022 '\"' Ghilimele

\u0027 '\'' Apostrof

12

Page 13: Introducere în limbajul de programare Java

\u005c '\\' Backslash

\u0008 '\b' Backspace(BS)

5. constante şiruri de caractereUn şir de caractere este format din zero sau mai multe caractere cuprinse

între ghilimele. Caracterele care formează şirul de caractere pot fi caractere

grafice sau secvenţe escape. Dacă şirul este prea lung el poate fi scris ca o

concatenare de subşiruri de dimensiune mai mică. Concatenarea şirurilor se face

cu operatorul + ("Ana " + " are " + " mere "). Şirul vid este "". După

cum vom vedea, orice şir este de fapt, o instanţă a clasei String, definită în

pachetul java.lang.

3.1.5. Separatori

Un separator este un caracter care indică sfârşitul unei unităţi lexicale şi

începutul alteia. În Java separatorii sunt următorii: ( ) { } [ ] ; , . Instrucţiunile unui

program se separă cu ”;”.

3.1.6. Operatori

1. operator de atribuire: = (semnul egal)

Exemplu: a=9 (lui a i se atribuie valoarea 9)

Operatorii de atribuire pot fi înlănţuiţi. De exemplu: a=b=c=10

2. operatori aritmetici binari: +, -, *, /, %

Exemplu: s=a+b

În Java există forme prescurtate care cuprind operatorul de atribuire şi un

operator aritmetic binar. Operatorii prescurtaţi sunt:+=, -=, *=, /=, %=

Exemplu: n += 2 este echivalentă cu n=n+2

3. operatori aritmetici unari: +, -, ++ (operator de incrementare), -- (operator de

decrementare). Operatorii de incrementare şi decrementare pot fi prefixaţi (++x

sau --x) sau postfixaţi (x++ sau x--). Diferenţa dintre operatorii prefixaţi şi cei

postfixaţi este semnificativă doar atunci când expresia de incrementare /

13

Page 14: Introducere în limbajul de programare Java

decrementare apare în cadrul unei expresii. Exemplele următoare vor evidenţia

aceste lucruri.

Exemple:

a) -x reprezintă opusul lui x

b) int x=5,y=7;x++; // x primeste valoarea 6y--; // y primeste valoarea 6

c) int x=5,y=7;++x; // x primeste valoarea 6--y; // y primeste valoarea 6

d) int x=5,y;y=x++; // y primeste valoarea 5, x primeste

valoarea 6e) int x=5,y;

y=x--; // y primeste valoarea 5, x primeste valoarea 4f) int x=5,y;

y=++x; // x primeste valoarea 6, y primeste valoarea 6g) int x=5,y;

y=--x; // x primeste valoarea 4, y primeste valoarea 4

Observaţii: În exemplele b şi c nu se observă nici o diferenţă între

operatorii postfixaţi şi cei prefixaţi deoarece ei nu sunt folosiţi în cadrul altor

expresii. În exemplele d şi f, respectiv, e şi g se observă că x primeşte aceeaşi

valoare dar y are valori diferite. În exemplele d şi e sunt folosiţi operatorii

postfixaţi de incrementare şi decrementare care se comportă astfel: valoarea

variabilei asupra căreia acţionează operatorul postfixat (în cazul nostru x)

participă la evaluarea expresiei din care face parte (y primeşte valoarea lui x)

după care se aplică operatorul (valoarea lui x creşte / scade cu o unitate). În

exemplele f şi g sunt folosiţi operatorii prefixaţi de incrementare şi decrementare

care se comportă astfel: valoarea variabilei asupra căreia acţionează operatorul

postfixat (în cazul nostru x) îşi schimbă valoarea (valoarea lui x creşte / scade cu

o unitate), noua valoare participând la evaluarea expresiei din care face parte (y

primeşte noua valoare a lui x).

4. operatori logici: &&(and), ||(or), !(not)

Observaţie: evaluarea expresiilor logice se face prin scurtcircuitare

(evaluarea se opreşte în momentul în care valoarea de adevăr a expresiei este

sigur determinată)

14

Page 15: Introducere în limbajul de programare Java

5. operatori relaţionali: <, <=, >, >=, ==, !=

6. operatori pe biţi: & (and), |(or), ^(xor), ~(not)

7. operatori de translaţie: <<, >>, >>> (shift-are la dreapta fără semn)

8. operatorul condiţional: ”? : ” . Are forma:

expresie_logica ? expresie1 : expresie2

Valoarea expresiei este dată de expresie1 dacă expresie_logică

este true sau de expresie2 dacă expresie_logică este false.

Exemplu: Metoda de calculul minimului a două numere este:

public int min (int a, int b){return a<b?a:b;

}

9. operatorul , (virgula) este folosit pentru evaluarea secvenţială a operaţiilor

Exemplu: int x=0, y=1, z=2; (x=1,y=a=10,c=1)

10. operatorul + pentru concatenarea şirurilor:

String s="abcd"int x=100;System.out.println(s + " - " + x); //afiseaza abcd-100

11. operatorul de conversie de tip (cast) este: (tip_de_data)

int i = 200;long l = (long)i; //conversie prin extensielong l2 = (long)200;int i2 = (int)l2; // conversie prin contractie

Exemplu 1: Fie programul

public class Operator{ public static void main(String args[]){ int a=2, b=3,c; c=a+b; System.out.println(a+" "+b+" "+c); a++; --b; System.out.println(a+" "+b+" "+c); c=++a+b++; System.out.println(a+" "+b+" "+c); a/=2;b*=2; System.out.println(a+" "+b+" "+c); c=a-- + --b; System.out.println(a+" "+b+" "+c); c=b=(a+=1);

15

Page 16: Introducere în limbajul de programare Java

System.out.println(a+" "+b+" "+c); }}

Rezultatul afişat este:

2 3 53 2 54 3 62 6 61 5 72 2 2

Exemplu 2: Fie programul

public class OpLogic{ public static void main(String args[]){ byte a=0; System.out.println("Primul if"); if ((a!=0) && ((1/a)<1)) System.out.println("Ambele conditii sunt adevarate"); else System.out.println("O conditie este falsa"); System.out.println("Al doilea if"); if ((1/a<1) && (a!=0)) System.out.println("Ambele conditii sunt adevarate"); else System.out.println("O conditie este falsa"); }}

Rezultatul afişat este:

Primul ifO conditie este falsaAl doilea ifException in thread ”main” java.lang.ArithmeticException:

/ by zero at OpLogic.main(OpLogic.java:11)

Explicaţia se găseşte în modul în care sunt evaluate expresiile logice (prin

scurtcircuitare). În primul if se evaluează expresia a!=0 care are valoarea false.

Indiferent de rezultatul celei de-a doua expresii, rezultatul final va fi false. Prin

urmare, evaluarea întregii expresii se opreşte după evaluarea lui a!=0, ceea ce

urmează după nu mai contează. În al doilea if, evaluarea începe tot cu prima

expresie, şi anume 1/a<1. Dar, ea nu poate fi evaluată deoarece 1/a nu are sens

16

Page 17: Introducere în limbajul de programare Java

(a fiind 0) şi, este generată o excepţie. Din nou, nu se ajunge la evaluarea celei de a

doua expresii.

3.1.7. Comentarii

În Java există trei feluri de comentarii:

Comentarii pe o singură linie: încep cu //.

Comentarii pe mai multe linii, închise între /* şi */.

Comentarii pe mai multe linii care formează documentaţia, închise între /** şi

**/. Textul dintre cele douã secvenţe este automat mutat în documentaţia

aplicaţiei de către generatorul automat de documentaţie javadoc.

Observaţii:

1. nu pot fi scrise comentarii în interiorul altor comentarii.

2. nu pot fi introduse comentarii în interiorul constantelor caracter sau şir de

caractere.

3. secvenţele /* şi */ pot să apară pe aceeaşi linie cu secvenţa // dar îşi pierd

semnificaţia; la fel se întâmplã cu secvenţa // în comentarii care încep cu /*

sau /**.

3.2. Tipuri de date

În Java tipurile de date se împart în două categorii:

tipuri primitive de date

tipuri referinţă.

Java porneşte de la premiza că "orice este un obiect". Prin urmare, tipurile de

date ar trebui să fie de fapt definite de clase şi toate variabilele ar trebui să

memoreze de fapt instanţe (obiecte) ale acestor clase. În principiu acest lucru este

adevărat, însă, pentru uşurinţa programării, mai există şi aşa numitele tipuri primitive de date, care sunt cele uzuale:

1. tipuri întregi

17

Page 18: Introducere în limbajul de programare Java

Tip de date Dimensiune în octeţi Domeniu

Byte 1 -128 .. 127

Short 2 -32768 .. 32767

Int 4-2147483648 ..

2147483647

Long 8 -263 .. 263-1

2. tipuri reale

Tip de date Dimensiune în octeţi Domeniu

float 4 -1046 .. 1038

double 8 -10324 .. 10308

3. tipul caracter: char memorat pe 2 octeţi

4. tipul boolean: are două valori – true şi false

În alte limbaje formatul şi dimensiunea tipurilor primitive de date folosite într-un

program pot depinde de platforma pe care rulează programul. În Java acest lucru nu

mai este valabil, Java fiind independent de platformă.

Vectorii, clasele şi interfeţele sunt tipuri referinţă. Valoarea unei variabile de

acest tip este, spre diferenţă de tipurile primitive, o referinţă (adresă de memorie)

către valoarea sau mulţimea de valori reprezentată de variabila respectivă.

Există trei tipuri de date C care nu sunt suportate de limbajul Java: pointer,

struct şi union. Pointerii au fost eliminaţi din cauza că erau o sursă constantă de

erori, locul lor fiind luat de tipul referinţă, iar struct şi union nu îşi mai au rostul atât

timp cât tipurile compuse de date sunt formate în Java prin intermediul claselor.

3.3. Variabile

Variabilele pot avea ca tip fie un tip primitiv de dată, fie o referinţă la un obiect.

Declararea variabilelor se face prin:

tip_de_date nume_variabila

Iniţializarea variabilelor se face prin:

nume_variabila = valoare

18

Page 19: Introducere în limbajul de programare Java

Declararea şi iniţializarea variabilelor pot fi făcute în acelaşi moment:

tip_de_date nume_variabila = valoare

Declararea constantelor se face prin:

final tip_de_date nume_variabila

Exemple:int a; a=5;final double PI = 3.14;int valoare = 100;long numarElemente = 12345678L;String floare = "frezie";

În funcţie de locul în care sunt declarate, variabilele se împart în următoarele

categorii:

1. Variabile membru, declarate în interiorul unei clase, vizibile pentru toate

metodele clasei respective şi pentru alte clase în funcţie de modificatorul lor

de acces

2. Variabile locale, declarate într-o metodă sau într-un bloc de cod, vizibile

doar în metoda / blocul respectiv

3. Parametrii metodelor, vizibili doar în metoda respectivă

4. Parametrii de la tratarea excepţiilor Imaginea următoare ilustrează tipurile de variabile şi parametrii împreună cu

domeniul lor de vizibilitate.

19

Page 20: Introducere în limbajul de programare Java

Observaţie: Variabilele declarate într-un for, rămân locale corpului ciclului. De

exemplu:

for(int i=0; i<100; i++) { }int i; //posibil în Java, eroare în C++

3.4. Instrucţiuni

3.4.1. Instrucţiunea vidă

Este formată din ”;”.

3.4.2. Instrucţiuni de decizie

1. Instrucţiunea if–else are forma:

if (expresie_logică)

public class Nume_Clasa

…}

{ …}

declararea variabilelor locale…catch (parametrii de la tratarea

…}

{ …

{ ... declararea variabilelor membru public void Metoda (parametrii metodei)

20

Page 21: Introducere în limbajul de programare Java

instrucţiuni1 else

instrucţiuni2 instrucţiuni

Dacă expresie_logică are valoarea true atunci se execută instrucţiuni1, altfel

se execută instrucţiuni2. Expresie_logică este obligatoriu să fie cuprinsă între

paranteze. Dacă pe una din ramuri sunt mai multe instrucţiuni ele trebuie să fie

cuprinse între acolade {…}. Ramura

else instrucţiuni2

poate să lipsească.

Exemplu 3: Să se calculeze maximul a două numere.

1. public class Maxim 2. { public static void main(String args[])3. {int a=12, b=5,m;4. if (a>b)5. m=a;6. else7. m=b;8. System.out.println("Maximul dintre "+a+" si "+b+" este: "+m);

9. } 10. }

Exemplu 4: Să se rezolve ecuaţia de gradul I ax+b=0 cunoscând coeficienţii a şi b.

1. public class ecGrI2. { public static void main(String args[])3. {int a=12, b=5;4. System.out.print("Ecuatia: "+a+"x+"+b+"=0");5. if (a==0)6. if (b==0)7. System.out.println(" are o infinitate de solutii");8. else9. System.out.println(" nu are solutii");10. else { double x =-(double)b/a;11. System.out.println(" are solutia "+x);11. } 12. }13. }

În exemplu 4 au fost folosite if-uri imbricate. Pe linia 10 a fost folosit

operatorul de conversie pentru ca rezultatul împărţirii să se fie număr real. Dacă

21

Page 22: Introducere în limbajul de programare Java

acest operator nu ar fi fost folosit, împărţirea ar fi fost efectuată între doi operanzi

întregi şi, prin urmare, rezultatul ar fi fost număr întreg.

2. Instrucţiunea switch are forma:

switch (expresie_selectare){ case val_1: instrucţiune_1; break; case val_2: instrucţiune_2; break; . . . case val_i: instrucţiune_i; break; . . . case val_n: instrucţiune_n; break; default: instrucţiune; }

Instrucţiunea switch selectează dintre mai multe secvenţe de cod una care

va fi executată. Se evaluează expresie_selectare; rezultatul obţinut se compară

pe rând cu val_1, val_2, ..., val_n. Dacă se întâlneşte o valoare val_i pentru

care se obţine egalitate (expresie_selectare = val_i ) se execută

instrucţiunile instrucţiune_i. Altfel, (dacă nu are loc nici o egalitate) se execută

instrucţiunile de pe ramura default.

Instrucţiune break întâlnită pe fiecare ramură are rolul de a întrerupe execuţia

instrucţiunii switch după ce au fost executate instrucţiunile aferente ramurii alese.

Dacă instrucţiunea break lipseşte atunci se execută şi instrucţiunile de pe

următoarele ramuri până la întâlnirea primului break.

Exemplu 5: Se citeşte de la tastatură un caracter reprezentând un operator: ’+’, ’–’,

’*’ sau ’/’. În funcţie de operatorul citit să se facă suma, diferenţa, înmulţirea sau

împărţirea celor două numere a şi b.

1. public class Operatii{2. public static void main(String args[]){3. double a=12, b=5, r=0;4. char oper=' ';5. try{6. System.out.println("Introduceti operatorul");7. oper=(char)System.in.read();8. }9. catch(Exception e){}10. switch (oper) {11. case '+':12. r=a+b; break;13. case '-':14. r=a-b; break;

22

Page 23: Introducere în limbajul de programare Java

15. case '*':16. r=a*b; break;17. case '/':18. r=a/b; break;19. default:20. System.out.println("Operator invalid");21. System.exit(1);22. }23. System.out.println(a+" "+oper+" "+b+" = "+r);24. }25. }

În linia 7 se citeşte un caracter de la tastatură memorat în oper şi, în funcţie de

el se execută instrucţiunile de pe liniile 12, 14, 16, 18 sau 20-21. Instrucţiunile de pe

liniile 20-21 se execută doar în cazul în care nu a fost introdus un operator corect.

Exemplu 6: Să se spună dacă un număr dat mai mic decât 10 este par sau impar.

1. public class ParImpar{2. public static void main(String args[]){3. int x=2;4. switch (x) {5. case 0:6. case 2:7. case 4:8. case 6:9. case 8: 10. System.out.println(x+" este numar par");break;11. default: 12. System.out.println(x+" este numar impar");13. }14. }15. }

În exemplul precedent ne interesează ca aceeaşi instrucţiune, cea din linia 9

să fie executată pentru mai multe potriviri. În acest caz, sunt folosite mai multe linii

de case fără nici un rezultat, instrucţiunea switch executând prima instrucţiune

întâlnită după găsirea potrivirii. Prin urmare, instrucţiunea break nu apare pe nici

una din liniile 5, 6, 7,8.

3.4.3. Instrucţiuni repetitive

23

Page 24: Introducere în limbajul de programare Java

1. Instrucţiunea for repetă un bloc de instrucţiuni cât timp o condiţie este

adevărată. În general, se cunoaşte de la început de câte ori urmează să se

execute blocul de instrucţiuni. Are forma generală:

for (iniţializare; test; incrementare)instrucţiuni

unde:

iniţializare este o expresie care iniţializează variabila de control a

instrucţiunii for

test este o expresie booleană evaluată înaintea fiecărei reluări a buclei; cât

timp valoarea ei este true blocul de instrucţiuni se execută. Când valoarea

ei este false, se părăseşte instrucţiunea for.

incrementare este o expresie care modifică variabila de control a

instrucţiunii for.

Oricare dintre cele trei părţi constituente ale instrucţiunii for poate să

lipsească.

for ( ; ; )

În acest caz se obţine o buclă infinită. Pentru a evita acest lucru este necesar

ca în cadrul blocului de instrucţiuni să existe o condiţie de oprire.

De asemenea, blocul de instrucţiuni poate să lipsească, el fiind înlocuit de

instrucţiunea vidă. Exemplul 8 de mai jos ilustrează această situaţie.

Exemplu 7: Să se calculeze n! unde n este iniţializat în program.

2. public class Factorial{3. public static void main(String args[]){4. long f=1;5. int n=15;6. for(int i=2; i<=n; i++)7. f*=i; //f=f*i;8. System.out.println(n+"!="+f);9. }10. }

Exemplu 8: Să se calculeze n! unde n este iniţializat în program.

1. public class Factorial{2. public static void main(String args[]){3. long f=1;4. int n=15;5. for(int i=2; i<=n; f*=i, i++)

24

Page 25: Introducere în limbajul de programare Java

6. ;7. System.out.println(n+"!="+f);8. }9. }

După cum se poate remarca, pe linia 6 este folosită instrucţiunea vidă

deoarece codul f*=i a fost mutat în cadrul părţii de incrementare.

O altă observaţie ar fi că, oricare dintre părţile constituente ale instrucţiunii for

poate fi formată din mai multe instrucţiuni. Acest lucru este ilustrat în programul

următor.

Exemplu 9:1. public class Factorial{2. public static void main(String args[]){3. long f, LimSup;4. int n=10,i;5. LimSup=(long)Math.pow(2,63); 6. for(i=2,f=1; i<=n && f<=LimSup/i; f*=i,i++)7. ;8. if (i==n+1)9. System.out.println(n+"!="+f);10. else11. System.out.println(n+"!=este prea mare pentru puterile mele");12. }13. }

În linia 5 este calculat numărul maxim reprezentabil, de tip long. În for,

iniţializăm două variabile i=2,f=1. Test-ul este format din două condiţii unite prin

&&. Incrementarea este, de asemenea, formată din două instrucţiuni f*=i,i++.

11. Instrucţiunea while are forma:

while (condiţie) instrucţiuni

Instrucţiunea while este folosită pentru a repeta execuţia unui grup de

instrucţiuni atâta timp cât condiţie are valoare true.

Exemplu 10: Să se calculeze suma cifrelor unui număr.

1. public class SumCifNr{2. public static void main(String args[]){3. long x=12345,xInit=x;

25

Page 26: Introducere în limbajul de programare Java

4. int s=0;5. while(x>0){6. s+=x%10;7. x/=10;8. } 9. System.out.println("Suma cifrelor numarului "+xInit+" este: "+s);10. }11. }

Instrucţiunea while se mai numeşte şi instrucţiune cu test iniţial. Dacă la prima

evaluarea a condiţiei aceasta are valoarea false instrucţiunile din corpul

while-ului nu se execută niciodată. În exemplul precedent, dacă iniţializăm x cu 0,

condiţia x>0 este falsă şi se continuă cu instrucţiunea din linia 9.

12. Instrucţiunea do-while are forma:

do{ instrucţiuni}while (condiţie);

Ca şi while, instrucţiunea do-while este folosită pentru a repeta execuţia

unui grup de instrucţiuni atâta timp cât condiţie are valoare true. Diferenţa dintre

cele două instrucţiuni este că, dacă la while se executau instrucţiunile doar dacă

condiţie era adevărată, în cazul lui do-while blocul de instrucţiuni se execută

cel puţin o dată după care se verifică valoarea condiţiei.

Instrucţiunea do-while se mai numeşte şi instrucţiune cu test final.

Exemplu 11: Să se calculeze cel mai mare divizor comun a două numere a şi b.

1. public class Cmmdc{2. public static void main(String args[]){3. long a=54,b=68,r;4. System.out.print("Cmmdc-ul numerelor "+a+" si "+b+"

este: ");5. do{6. r=a%b;7. a=b;8. b=r;9. }while(r>0);10. System.out.println(a);11. }12. }

26

Page 27: Introducere în limbajul de programare Java

13. Instrucţiunea break break

Este folosită pentru părăsirea forţată a corpurilor instrucţiunilor repetitive (for,

while, do-while).

Exemplu 12: Să se caute un număr cuprins în intervalul [a,b].1. public class ExBreak{2. public static void main(String args[]){3. int a=10, b=20, x;4. while(true){5. x=(int)(Math.random()*b); 6. if ( (a<=x) && (x<=b) )7. break;8. } 9. System.out.println(x);10. }11. }

În linia 5 se generează aleator un număr întreg mai mic decât b. Dacă numărul

este cuprins în intervalul [a,b] se părăseşte instrucţiunea while.

Dacă instrucţiunea break este plasată în cadrul mai multor instrucţiuni

repetitive imbricate, ea are ca efect părăsirea doar a instrucţiuni care o conţine.

Exemplu:1. for(...){2. ...3. for(...){4. ...5. break;6. ...7. }8. ... 9. }

Efectul instrucţiunii break este părăsirea for-ului din linia 3, execuţia

continuându-se cu instrucţiunile de pe linia 8.

14. Instrucţiunea continue

Are ca efect întreruperea execuţiei iteraţiei curente şi trecerea la iteraţia

următoare.

27

Page 28: Introducere în limbajul de programare Java

Exemplu 13: Următorul cod afişează toate caracterele citite cu excepţia cifrelor de la

0 la 9.

1. public class ExContinue{2. public static void main(String args[]){3. for(int i=0; i<=10; i++){4. char c=' ';5. try{6. c=(char)System.in.read();7. }8. catch(Exception e){} 9. if ( ('0'<=c) && (c<='9') )10. continue;11. System.out.print(c+" "); 12. } 13. }14. }

În cazul în care se citeşte o cifră, se execută instrucţiunea continue de pe

linia 10, nu se mai execută linia 11 şi se sare direct la linia 3.

Observaţie: Instrucţiunile break şi continue pot să apară doar în cadrul unor

instrucţiuni repetitive. Excepţie face instrucţiunea break care poate să apară şi în

cadrul instrucţiunii switch.

3.5. Tablouri (vectori)

3.5.1. Tablouri (vectori) unidimensionale

Declararea unui vector se face prin

TipElement[] numeVector; sau TipElement numeVector[];

unde TipElement reprezintă tipul elementelor vectorului, iar parantezele []

aşezate fie înaintea fie după numele vectorului arată că este vorba despre un vector.

Exemple: int[] v;String adrese[];

28

Page 29: Introducere în limbajul de programare Java

Instanţierea unui vector se realizează cu operatorul new şi are ca efect

alocarea memoriei necesare pentru memorarea elementelor vectorului, mai precis

specificarea numărului maxim de elemente pe care îl va avea vectorul. Instanţierea

unui vector se face astfel:

numeVector = new TipElement[dimensiune];

Exemple:

v = new int[10]; //se alocă spaţiu pentru 10 întregi

adrese = new String[100]; //se alocă spaţiu pentru 100 de String-uri

Declararea şi instanţierea unui vector pot fi făcute simultan astfel:

TipElement[] numeVector = new TipElement[dimensiune];

Exemple:

int [] v = new int[10];

După declararea unui vector, acesta poate fi iniţializat, adică elementele sale

pot primi valori. În acest caz instanţierea lipseşte, alocarea memoriei făcându-se

automat în funcţie de numărul de elemente cu care se iniţializează vectorul.

Exemple:String culori[] = {"Rosu", "Galben", "Verde"};int []v = {2, 4, 6, 8, 10, 12};

Observaţii:

Primul indice al unui vector este 0, deci poziţiile unui vector cu n elemente vor

fi cuprinse între 0 şi n-1.

Nu sunt permise construcţii de genul:TipElement numeVector[dimensiune]

alocarea memoriei făcându-se doar prin intermediul operatorului new sau prin

iniţializare.

Exemple:

int v[10]; //incorect

int v[] = new int[10]; //corect

29

Page 30: Introducere în limbajul de programare Java

Accesul la elementul unui vector se face prin:

numeVector[indice]

Exemplu 1:int v[]=new int[10];for(i=0; i<10; i++)

v[i]=i;

Exemplu 2:int v[]={1,2,3,4,5};for(i=0; i<5; i++)

System.out.println(v[i]+” “);

3.5.2. Tablouri (vectori) cu mai multe dimensiuni

În Java tablourile cu mai multe dimensiuni sunt de fapt vectori de vectori. Prin

urmare, declararea, instanţierea şi iniţializarea se fac la fel ca în cazul vectorilor

unidimensionali.TipElement numeVector[][]… = new TipElement[dim1][dim2]…

sau TipElement[][]… numeVector = new[dim1][dim2]… TipElement

sau parantezele pot fi de o parte şi de alta a lui numeVector.

Exemplu: int m[][]; //declararea unei matricem = new int[5][10]; //cu 5 linii, 10 coloane

Observaţie:

m[0], m[1], ..., m[4] sunt vectori de întregi cu 10 elemente

3.5.3. Dimensiunea unui vector

Cu ajutorul cuvântului cheie length se poate afla dimensiunea unui vector.

Exemple:

Fie vectorul

int []a = new int[5];atunci a.length are valoarea 5.

Fie matricea

int m = new int[5][10];

30

Page 31: Introducere în limbajul de programare Java

atunci:

m.length are valoarea 5 şi reprezintă numărul de linii al matricei

m[0].length are valoarea 10 şi reprezintă numărul de elemente al

primei linii a matricei,

m[1].length are valoarea 10 şi reprezintă numărul de elemente al

celei de-a doua linii a matricei, etc.

Exemplu 14: Să se calculeze minimul elementelor unui vector.

1. public class MinVect{2. public static void main(String args[]){3. int a[]={2,1,4,7,3};4. int min=a[0];5. for(int i=0; i<a.length; i++)6. if (min>a[i])7. min=a[i];8. System.out.println("Minimul este "+min); 9. }10. }

Exemplu 15: Să se ordoneze elementele de pe diagonala principală a unei matrice.

1. public class OrdDiagPrinc{2. public static void main(String args[]){3. int a[][]={{2,1,4,7},{3,5,1,8},{2,5,1,9},{3,2,5,8}};4. boolean ordonat;5. for(int i=0; i<a.length; i++){6. for(int j=0; j<a[i].length; j++)7. System.out.print(a[i][j]+" ");8. System.out.println("");9. } 10. do{11. ordonat=true;12. for(int i=0; i<a.length-1; i++)13. if (a[i][i]>a[i+1][i+1]){14. int aux=a[i][i];15. a[i][i]=a[i+1][i+1];16. a[i+1][i+1]=aux;17. ordonat=false;18. }19. }while(!ordonat);20. System.out.println("Matricea cu diagonala

ordonata:"); 21. for(int i=0; i<a.length; i++){22. for(int j=0; j<a[i].length; j++)23. System.out.print(a[i][j]+" ");24. System.out.println("");25. }

31

Page 32: Introducere în limbajul de programare Java

26. }27. }

3.5.4. Tablouri cu dimensiuni variabile

Java permite folosirea tablourilor cu dimensiuni variabile adică, a vectorilor de

vectori cu dimensiuni variabile.

Exemplu 16: Să se genereze şi să se afişeze triunghiul lui Pascal.

1. public class TrPascal{2. public static void main(String args[]){3. int []a[]=new int[10][];4. a[0]=new int[1];5. a[1]=new int[2];6. a[0][0]=a[1][0]=a[1][1]=1;7. for(int i=2; i<a.length; i++){8. a[i]=new int[i+1];9. a[i][0]=a[i][i]=1;10. for(int j=1; j<a[i].length-1; j++)11. a[i][j]=a[i-1][j-1]+a[i-1][j];12. }13. for(int i=0; i<a.length; i++){14. for(int j=0; j<a[i].length; j++)15. System.out.print(a[i][j]+" ");16. System.out.println("");17. } 18. }19. }

În linia 8 se observă că, pentru fiecare linie a matricei se alocă memorie pentru

un număr variabil de elemente: pe linia 0 va fi memorat un element, pe linia 1 vor fi

memorate două elemente, etc.

3.6. Şiruri de caractere

În Java, un şir de caractere poate fi reprezentat printr-un vector format din

elemente de tip char, un obiect de tip String sau un obiect de tip StringBuffer.

Exemple echivalente de declarare a unui şir:

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

32

Page 33: Introducere în limbajul de programare Java

Concatenarea şirurilor de caractere se face prin intermediul operatorului +.

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

În Java, operatorul de concatenare + este extrem de flexibil în sensul că

permite concatenarea şirurilor cu obiecte de orice tip care au o reprezentare de tip

şir de caractere.

Exemplu:System.out.print("Vectorul v are" + v.length + "

elemente");

33

Page 34: Introducere în limbajul de programare Java

4. Clase şi obiecte în Java

4.1. Referinţe

După cum am arătat în capitolul 2, o clasă este un şablon pentru mai multe

obiecte cu caracteristici asemănătoare. Un obiect este o colecţie de variabile

(atribute) şi metode asociate descrise în clasă.

Clasa poate fi asemănată cu un tip de date iar obiectul cu o variabilă. Dacă se

declară o variabilă folosind numele unei clase ca şi tip, această variabilă conţine o

referinţă către un obiect al clasei respective. Cu alte cuvinte, variabila nu va conţine

obiectul actual ci o referinţă către un obiect / o instanţă a clasei. Deoarece folosind

numele unei clase ca şi tip se declară o referinţă către un obiect, aceste tipuri poartă

numele de tipuri referinţă.

Se disting două caracteristici principale ale obiectelor în Java:

obiectele sunt întotdeauna alocate dinamic. Durata de viaţă a unui

obiect este determinată de logica programului. Ea începe atunci când

obiectul este creat şi se termină în momentul în care obiectul nu mai

este folosit, el fiind distrus de un mecanism de curăţenie oferit de

limbajul Java – garbage collector (colectorul de gunoaie).

obiectele nu sunt conţinute de către variabile. O variabilă păstrează o

referinţă către un obiect. o referinţă este similară cu ceea ce se

numeşte pointer în alte limbaje de programare cum ar fi C++. Dacă

există două variabile de acelaşi tip referinţă şi o variabilă este atribuită

celeilalte, ambele vor referi acelaşi obiect. Dacă informaţia din obiect se

modifică, schimbarea este vizibilă în ambele variabile.

O variabilă referinţă poate conţine şi o referinţă către nimic. Valoarea unei

asemenea variabile referinţă este null.În Java nu se permite tipurilor referinţă să fie convertite către tipuri primitive

sau invers.

În capitolul 2 am văzut cum se poate lucra cu tablouri (şiruri) fără să ne punem

problema cu ce tip de date lucrăm – primitiv sau referinţă. În Java, şirurile nu sunt

tipuri primitive ci referinţă. Ele se comportă ca nişte obiecte.

34

Page 35: Introducere în limbajul de programare Java

4.2. Obiecte

4.2.1. Noţiuni generale

În Java obiectele sunt create prin instanţierea unei clase, cu alte cuvinte prin

crearea unei instanţe a unei clase.

Declararea obiectului se face prin:

NumeClasa numeObiect;Exemplu:

String s;Complex c;

În urma declarării, variabila este iniţializată cu null.

Crearea obiectului echivalentă cu instanţierea clasei se realizează prin

intermediul operatorului new şi presupune alocarea spaţiului de memorie necesar

păstrării obiectului. Adresa (referinţa) către obiectul respectiv o să fie memorată în

variabila numeObiect.

numeObiect = new NumeClasa();Exemplu:

s=new String() ;Complex c=new Complex(2,3);

Declararea şi crearea obiectului pot fi făcute pe aceeaşi linie.

Exemplu:

String s=new String() ;Complex c=new Complex(2,3);

În momentul în care se realizează crearea obiectului are loc şi iniţializarea lui.

Atenţie

Spaţiul de memorie nu este alocat în momentul declarării obiectului.

Exemplu:Complex c;c.re = 10; //EROARE!

Alocarea memoriei se face doar la apelul instrucţiunii new !

Referirea valorii unei variabile se face prin obiect.variabila

35

Page 36: Introducere în limbajul de programare Java

Exemplu:Complex c = new Complex();c.re = 2; c.im = 3;System.out.println("Re=" +c.re+ " Im="+c.im);

Observaţie: 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:Complex c = new Complex();c.setRe(2); c.setIm(3);

În Java programatorul nu mai are responsabilitatea distrugerii obiectelor sale

întrucât, în momentul rulării unui program, simultan cu interpretorul Java rulează şi

un proces care se ocupă de distrugerea obiectelor care nu mai sunt folosite. Acest

proces pus la dispoziţie de platforma Java de lucru se numeşte garbage collector (colector de gunoaie). Un obiect este eliminat din memorie de procesul de colectare

atunci când nu mai exista nici o referinţă la acesta. Referinţele (care sun de fapt

variabile) sunt distruse:

natural, atunci când variabila respectivă nu mai este folosită (de exemplu,

la terminarea unei metode)

explicit, dacă atribuim variabilei respective valoare null.

4.2.2. Operatorul de atribuire =

În cazul în care operatorul = este folosit împreună cu date de tip primitiv, are

loc o atribuire de valori.

Exemplu:int x = 12, y = 10;x = y;

Valoarea lui x se schimbă, primind valoarea lui y.

În cazul în care operatorul = este folosit împreună cu date de tip referinţă, are

loc tot o atribuire de valori. Atâta doar că valorile sunt în acest caz adrese.

36

Page 37: Introducere în limbajul de programare Java

Exemplu:1. class Nimic{2. int x;3. }

4. class Test{5. public static void main(String args[]){6. Nimic a1=new Nimic(),a2;7. a1.x=10;8. a2=a1; 9. System.out.println(a1.x+" "+a2.x);10. a1.x=5;11. System.out.println(a1.x+" "+a2.x); 12. }13. }

În linia 7 se modifică valoarea atributului x a obiectului a1. În linia 8 conţinutul

variabilei a1 se copiază în a2. Se afişează 10 10. Se schimbă valoarea atributului lui

a1 şi, ne-am aştepta să se afişeze 5 10 dar se afişează 5 5. Nu este greşit! În linia 8

se copiază valoarea lui a1 adică referinţa către obiect în a2. Din acest moment

există un singur obiect către care referă atât a1 cât şi a2. Orice modificare are loc

asupra obiectului, ea este văzută şi de a1 şi de a2.

Exemplu:public class Test{ public static void main(String args[]){ int[] a1={1,2,3,4,5}; int[] a2; a2=a1; for(int i=0; i<a1.length; i++) a2[i]++; for(int i=0; i<a1.length; i++) System.out.print(a1[i]+" "); System.out.println(""); for(int i=0; i<a2.length; i++) System.out.print(a2[i]+" "); }}

Rezultatul este:

2 3 4 5 6

2 3 4 5 6

37

Page 38: Introducere în limbajul de programare Java

4.2.3. Operatorul de egalitate ==

În cazul în care operatorul == este folosit împreună cu date de tip primitiv, are

loc o testare a egalităţii valorilor celor două variabile.

Exemplu:int x = 12, y = 10, z = 12;x == y are valoarea false; x şi y au valori diferite x == z are valoarea true; x şi z au valori egale

În cazul în care operatorul = este folosit împreună cu date de tip referinţă, se

verifică dacă cele două variabile referă acelaşi obiect.

Exemplu:1. class Nimic{2. int x;3. Nimic(int x){4. this.x=x;5. }6. }

7. class Test{8. public static void main(String args[]){9. Nimic a1=new Nimic(1),a2=new Nimic(1);10. if(a1==a2)11. System.out.println("Sunt egale");12. else13. System.out.println("Nu sunt egale");14. a2=a1; 15. if(a1==a2)16. System.out.println("Sunt egale");17. else18. System.out.println("Nu sunt egale");19. }20. }

În linia 9 se creează două obiecte cu aceeaşi valoare. Totuşi testul din linia 10

are ca rezultat valoarea false. După linia 14 cele două variabile referă acelaşi

obiect şi, prin urmare, testul din linia 15 are ca rezultat valoarea true.

38

Page 39: Introducere în limbajul de programare Java

4.3. Clase

4.3.1. Definirea claselor

[public][abstract][final] class NumeClasa [extends NumeSuperclasa]

[implements Interfata1 [, Interfata2 ... ]]{

//corpul clasei}

Antetul clasei: [public][abstract][final] class NumeClasa

este format din modificatorii clasei, cuvântul rezervat class şi numele clasei

NumeClasa.

Prezenţa parantezelor [] indică faptul că ceea ce este cuprins între ele este

opţional.

Modificatorii clasei sunt:

public: dacă o clasă este declarată public, ea este accesibilă oricărei

alte clase. Dacă modificatorul public nu apare, clasa poate fi accesată

doar de către clasele din pachetul căruia aparţine clasa (dacă nu se

specifică un anume pachet, toate clasele din directorul curent sunt

considerate a fi în acelaşi pachet). Spaţiul de căutare este definit de

variabila sistem CLASSPATH.

abstract: o clasă declarată abstractă este o clasă şablon adică ea este

folosită doar pentru a crea un model comun pentru o serie de subclase. O

clasă trebuie declarată abstractă daca ea este incomplet implementată

adică nu toate metodele ei sunt definite. O astfel de clasă nu poate fi instanţiată, dar poate fi extinsă de alte clase care să implementeze

metodele nedefinite. Doar clasele abstracte pot să conţină metode

abstracte (metode declarate dar nu implementate).

final o clasă poate fi declarată finală dacă a fost complet definită şi nu se

doreşte să fie extinsă (să aibă subclase); cu alte cuvinte ea nu poate apare

în clauza extends a altei clase.

Observaţie: O clasă declarată atât abstractă cât şi finală generează eroare.

Dacă clasa este abstractă înseamnă că ea conţine metode neimplementate şi, prin

39

Page 40: Introducere în limbajul de programare Java

urmare trebuie extinsă de o altă clasă care să le implementeze. Dar, dacă ar fi şi

finală, nu ar putea fi extinsă.

După numele clasei se pot specifica, dacă este cazul, clasele moştenite şi

interfeţele implementate. O clasă poate moşteni o singură clasă, prin urmare dacă

apare clauza extends ea este urmată doar de numele unei clase. Însă, o clasă

poate implementa mai multe interfeţe, ale căror nume apar după clauza

implements şi trebuie separate prin virgulă. Asupra moştenirii şi interfeţelor se

găsesc mai multe detalii în subcapitolele „Moştenire” respectiv „Interfeţe”.

Corpul unei clase urmează după antetul clasei şi este cuprins între acolade.

Conţine:

declararea variabilelor instanţă şi clasă care împreună formează

variabilele membru;

definirea metodelor instanţă şi clasă care împreună formează metodele membru.

Observaţie: variabilele unei clase pot avea acelaşi nume cu metodele clasei.

4.3.2. Variabile membru

Variabilele se declară de obicei înaintea metodelor, deşi acest lucru nu este

impus de compilator.

class NumeClasa {//declararea variabilelor//declararea metodelor

}Variabilele unei clase sunt doar cele care sunt declarate în corpul clasei şi nu

în corpul unei metode. Variabilele declarate în cadrul unei metode sunt locale

metodei respective.

Declararea unei variabile presupune specificarea următoarelor lucruri:

numele variabilei;

tipul de date;

nivelul de acces la acea variabilă de către alte clase;

dacă este constantă sau nu;

tipul variabilei: instanţă sau clasă

Tiparul declarării unei variabile este:

40

Page 41: Introducere în limbajul de programare Java

[modificatori] TipDeDate numeVariabila [ = valoareInitiala ] ;unde un modificator poate fi :

un specificator de acces: public, protected, private;

unul din cuvintele rezervate: static, final, transient, volatile.

Exemple:double x;protected static int n;public String s = "abcd";private Point p = new Point(10, 10);final long MAX = 100000L;

Detalii despre modificatorii de acces se găsesc în subcapitolul „Modificatori de

acces pentru membrii unei clase”.

Cuvintele rezervate: static, final, transient, volatile au următoarele

roluri:

static este folosit pentru declararea variabilelor clasă.

Exemplu:

int x ; //variabilă instanţă

static int nrDeObiecteCreate; //variabilă clasă

final este folosit pentru declararea constantelor. O constantă este o

variabilă a cărei valoare nu mai poate fi schimbată. Valoarea unei variabile

finale nu trebuie specificată neapărat la declararea ei, ci poate fi specificată

şi ulterior, după care ea nu va mai putea fi modificată.

Exemplu: se declară şi se iniţializează o variabilă finală (linia 1). Valoarea ei nu mai

poate fi modificată (linia 3).

1. final double PI = 3.14 ;2. ...3. PI = 3.141 // eroare la compilare

Exemplu: se declară o variabilă finală (linia 2). În linia 4 se iniţializează iar în linia 5

se doreşte modificarea valorii ei.

1. class Test {2. final int MAX;3. Test() {4. MAX = 100; // legal5. MAX = 200; // ilegal -> eroare la compilare6. }7. }

41

Page 42: Introducere în limbajul de programare Java

transient este folosit la serializarea obiectelor, pentru a specifica ce

variabile membru ale unui obiect nu participa la serializare.

volatile este folosit pentru a semnala compilatorului să nu execute

anumite optimizări asupra membrilor unei clase. Este o facilitate avansată

a limbajului Java.

4.3.3. Metode

4.3.3.1 Definirea metodelor

Metodele sunt folosite pentru descrierea comportamentului unui obiect. O

metodă se declară astfel:

[modificatori] TipReturnat numeMetoda ([argumente]) [throws TipExceptie]

{//corpul metodei

}

4.3.3.2 Modificatorii metodelor

Un modificator poate fi :

un specificator de acces: public, protected, private;

unul din cuvintele rezervate: static, abstract, final, native, synchronized.

Detalii despre modificatorii de acces se găsesc în subcapitolul „Modificatori de

acces”.

Cuvintele rezervate: static, abstract, final, native, synchronized

au următoarele roluri:

static este folosit pentru declararea metodelor clasă.

Exemplu:void metoda1() ; //metoda de instantastatic void metoda2(); //metoda de clasa

abstract este folosit pentru declararea metodelor abstracte. O metodă

abstractă este o metodă care nu are implementare şi trebuie să aparţină

unei clase abstracte.

42

Page 43: Introducere în limbajul de programare Java

final este folosit pentru a specifica faptul că acea metodă 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ă în subclasele ei.

native este folosit pentru refolosirea unor funcţii scrise în alt limbaj de

programare decât Java (C de exemplu).

synchronized este folosit în cazul în care se lucrează cu mai multe fire de

execuţie iar metoda respectivă se ocupă cu partajarea unei resurse

comune. Are ca efect construirea unui semafor care nu permite executarea

metodei la un moment dat decât unui singur fir de execuţie.

4.3.3.3 Tipul returnat de o metodă

Metodele pot să returneze sau nu o valoare (un obiect) la terminarea lor. Tipul

valorii returnate poate fi atât un tip primitiv de date (int, double, etc.) cât şi o referinţă

la un obiect al unei clase. În cazul în care o metoda nu returnează nimic atunci

TipReturnat este void.

Exemplu: void afisareRezultat()

Returnarea valorii de către o metodă se realizează prin intermediul instrucţiunii

return.

Dacă o metodă returnează o valoare de un tip de bază atunci tipul ei trebuie să

coincidă cu TipReturnat, în caz contrar se primeşte eroare la compilare.

Exemplu: Metodă care calculează maximul a două numere

public int max(int a, int b){return a>b?a:b;

}

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.

43

Page 44: Introducere în limbajul de programare Java

4.3.3.4 Parametrii unei metode

După cum am văzut, numele clasei este urmat de lista parametrilor

(argumentelor), listă care este opţională (o metodă poate să nu aibă parametrii).

Parametrii sunt specificaţi prin numele şi tipul lor, fiind despărţiţi unul de altul prin

virgulă.

NumeMetoda([tip1 argument1], [tip2 argument2] ... )

Tipul de date al unui argument poate fi orice tip valid al limbajului, atât tip

primitiv de date cât şi referinţă la un obiect.

Exemplu:

void adaugarePersoana(String nume, int varsta, float salariu){

...}

unde String este tip referinţă, int şi float sunt tipuri primitive.În Java o metodă nu poate primi un număr variabil de argumente, ceea ce

înseamnă că apelul unei metode trebuie să se facă cu specificarea exactă a

numărului şi tipurilor argumentelor.

Nu este permisă gruparea parametrilor după tipul lor.

Exemplu:public int max(int a,b){...} //este greşitpublic int max(int a, int b){ ...} //este corect

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 diferenţierea se va face prin

intermediul variabile this. Vezi subcapitolul „Obiectul this”

Exemplu:class Complex{

int re,im; public schimba(int re, int im){

this.re = re;this.im = im;

} }

Atenţie: În Java argumentele sunt trimise doar prin valoare !!!

44

Page 45: Introducere în limbajul de programare Java

Asta însemnă că metoda recepţionează doar valorile variabilelor primite ca

parametri. Când argumentul are tip primitiv de date metoda nu-i poate schimba

valoarea decât local (în cadrul metodei); la revenirea din metodă variabila are

aceeaşi valoare ca la apelul iniţial al metodei (modificările făcute în cadrul metodei

sunt pierdute). Când argumentul este de tip referinţă metoda nu poate schimba

referinţa obiectului însă poate schimba variabilele membru ale respectivului obiect.

Prin urmare, dacă dorim ca o metodă să schimbe starea (valoarea) unui argument

primit, atunci el trebuie să fie neapărat de tip referinţă (trebuie să fie un obiect!).

4.3.4. Constructorii unei clase

Constructorii unei clase sunt metode speciale care au acelaşi nume cu cel al

clasei, nu returnează nici o valoare şi sunt folosiţi pentru iniţializarea obiectelor

acelei clase în momentul instanţierii lor. Constructorii controlează modul în care un

obiect este creat şi iniţializat.

Class COMPLEX {COMPLEX() {

//constructor}

}

O clasă poate avea unul sau mai mulţi constructori care trebuie însă să difere

prin lista de parametri primiţi. Astfel sunt permise diferite tipuri de iniţializări ale

obiectului la crearea sa, în funcţie de numărul parametrilor cu care este apelat

constructorul.

Exemplu: Clasa COMPLEX are trei constructori: unul fără parametrii definit în liniile

3-5, altul cu doi parametrii definit în liniile 6-8, altul cu un parametru definit în liniile 9-

11.

1. class COMPLEX {2. double re, im;

3. COMPLEX () { 4. re=im=0; 5. }6. COMPLEX (double r, double i ) {7. re=r; im=i; 8. }9. COMPLEX (double r) { 10. re=r; im=0;

45

Page 46: Introducere în limbajul de programare Java

11. }12. }

Constructorii sunt apelaţi automat la instanţierea unui obiect. În cazul în care

dorim să apelăm explicit constructorul unei clase folosim metoda this(argumente),

care apelează constructorul corespunzător (ca argumente) al clasei respective.

Această metodă este folosită atunci când sunt implementaţi mai mulţi constructori

pentru o clasă pentru a nu repeta secvenţele de cod scrise la constructorii cu mai

puţine argumente.

Exemplu: În clasa COMPLEX a fost definit constructorul cu doi parametrii. Ceilalţi doi

constructori fac apel la constructorul cu doi parametrii în liniile 4 şi 10.

1. class COMPLEX {2. double re, im;

3. COMPLEX () { 4. this(0,0);5. }6. COMPLEX (double r, double i ) {7. re=r; im=i; 8. }9. COMPLEX (double r) { 10. this(r,0);11. }12. }

Dacă într-o clasă nu este defineşte nici un constructor, sistemul îi creează

automat un constructor implicit care nu primeşte nici un argument. El iniţializează

variabilele membru de tipuri primitive cu 0 şi pe cele de tipuri referinţă cu null. Deci

prezenţa constructorilor în corpul unei clase nu este obligatorie. Dacă într-o clasă a

fost definit cel puţin un constructor cu parametrii, atunci constructorul implicit (fără

parametrii) nu va mai fi creat automat.

Exemplu: În clasa COMPLEX nu a fost definit nici un constructor. În linia 5 se

apelează constructorul implicit creat automat pentru clasa Complex.

1. class COMPLEX {2. double re, im;3. }4. ...5. COMPLEX c= new COMPLEX ();

46

Page 47: Introducere în limbajul de programare Java

Exemplu: În clasa COMPLEX au fost definiţi doi constructori: cu un parametru şi cu

doi parametrii. În linia 11 se apelează constructorul fără parametrii. Această linie

generează o eroare deoarece nu există constructor fără parametrii – el nu a fost

creat implicit.

1. class COMPLEX {2. double re, im;3. COMPLEX (double r, double i ) {4. re=r; im=i; 5. }6. COMPLEX (double r) { 7. this(r,0);8. }9. }10. ...11. COMPLEX c= new Complex(); //eroare

Constructorii unei clase pot avea următorii specificatori de acces:

private: nici o altă clasă nu poate instanţia obiecte ale acestei clase. O astfel

de clasă poate conţine metode publice care să-şi creeze propriile obiecte şi să le

returneze altor clase;

public: orice clasă poate crea instanţe ale clasei respective;

protected: doar subclasele pot crea obiecte de tipul clasei respective.

Dacă specificatorul lipseşte, doar clasele din acelaşi pachet pot crea instanţe

ale clasei respective.

4.3.5. Obiectul this

Obiectul this este o referinţă către obiectul curent.

Este folosit în trei situaţii:

în cadrul unei metode care are parametrii cu nume identic cu numele

atributelor clasei. În această situaţie, trebuie făcută o diferenţă între cele

două. Cu this se califică atributele clasei.

Exemplu: Metoda schimba primeşte doi parametrii cu acelaşi nume cu atributele

clasei: re şi im.

1. class Complex{ 2. int re,im; 3. public schimba(int re, int im){

47

Page 48: Introducere în limbajul de programare Java

4. this.re = re;5. this.im = im;6. } 7. }

în cadrul constructorilor pentru a apela ceilalţi constructori ai clasei.

Exemplu: În liniile 4 şi 11 se apelează constructorul cu doi parametrii definit în liniile

6-9.

1. public class Rational{2. private long m,n;3. public Rational(){ 4. this(0,1);5. }6. public Rational(long m,long n){7. this.m=m;8. this.n=n;9. }10. public Rational(long m){11. this(m,1);12. }13. }

pentru a testa că obiectul primit ca parametru nu este chiar obiectul curent.

Exemplu: Clasa ContBancar conţine metoda transfer în care se transferă suma

de bani din contul primit în contul curent – liniile 10, 11. În linia 15 se creează un

obiect ContBancar. În linia 16 se apelează metoda transfer a obiectului c cu

parametru c. Asta înseamnă că, suma din contul c va fi transferată tot în contul c.

Citind cu atenţie codul din liniile 10, 11 observăm că se adună suma primită

(c.suma) la suma actuală (this.suma) – în cazul nostru, contul îşi dublează suma,

după care suma contului primit (c.suma) se face zero.

1. public class ContBancar{2. private long suma;3. public ContBancar(){4. this(0);5. }6. public ContBancar(long suma){7. this.suma=suma;8. }9. public void transfer(ContBancar c){ 10. this.suma+=c.suma;11. c.suma=0;12. }13. }

48

Page 49: Introducere în limbajul de programare Java

14. ... 15. ContBancar c=new ContBancar(100);16. c.transfer(c);

Din punct de vedere logic, nu este corect. Ar trebui ca înaintea începerii

transferului de bani să se verifice dacă nu cumva este vorba despre acelaşi cont,

caz în care nu ar trebui să se întâmple nimic. Metoda transfer ar arăta astfel:

1. public void transfer(ContBancar c){ 2. if (this == c)3. return; 4. this.suma+=c.suma;5. c.suma=0;6. }7. }

În linia 2, this reprezintă obiectul curent iar c obiectul primit ca parametru.

4.3.6. Supraîncărcarea şi supradefinirea metodelor

supraîncărcarea (overloading): în cadrul unei clase pot exista metode cu

acelaşi nume cu condiţia ca ele să difere prin lista parametrilor – diferenţa

constă în numărul parametrilor sau în tipul lor. Astfel la apelul metodei cu

acel nume se poate face distincţia între ele şi se stabileşte în mod unic

care dintre ele se execută.

Exemplu: În clasa Maxim sunt definite două metode max cu doi respectiv cu trei

parametrii.

1. public class Maxim {2. public static int max(int a, int b){3. return a>b?a:b;4. }

5. public static int max(int a, int b, int c){6. int m=a>b?a:b;7. m=m>c?m:c;8. return m;9. }

10. public static void main(String args[]){11. int a=12, b=5,c=90,m;12. m=max(a,b);13. System.out.println("Max. dintre "+a+" si "+b+"

este: "+m);

49

Page 50: Introducere în limbajul de programare Java

14. m=max(a,b,c);15. System.out.println("Max. dintre "+a+", "+b+" si

"+c+" este: "+m);16. }17. }

.

supradefinirea (overriding): o subclasă a unei clase poate rescrie o metodă

a clasei părinte, prin implementarea unei metode cu acelaşi antet ca al

superclasei.

4.3.7. Modificatori de acces pentru membrii unei clase

Sunt cuvinte rezervate ce controlează accesul celorlalte clase la membrii unei

clase. Modificatoriii de acces pentru variabilele şi metodele unei clase sunt: public,

protected, private şi cel implicit. Nivelul lor de acces este dat în tabelul de mai

jos:

Modificat

or

Clasă Subclasă Pachet Altundev

a

private x

protected x x x

public x x x x

implicit x x

După cum se vede în tabelul de mai sus, modificatorii au următoarele

semnificaţii.

private – un membru declarat private este accesibil doar în clasa în care

este declarat;

protected – un membru declarat protected este accesibil oricărei clase

care aparţine aceluiaşi pachet ca şi clasa în care este declarat membrul; de

asemenea, este accesibil şi oricărei subclase a clasei respective;

public – un membru declarat public este accesibil oricărei clase indiferent

de locul unde se află ea.

Dacă modificatorul unui membru lipseşte, se consideră implicit un modificator

„friendly” care dă acces oricărei clase din pachetul respectiv.

50

Page 51: Introducere în limbajul de programare Java

Exemple: private int re,im;protected String secret;public float[] elemente;long x;private void metodaInterna();public void setRe(int re);

Observaţie: În cazul în care declarăm un membru "protected" atunci accesul la

acel membru din subclasele clasei în care a fost declarată variabila depinde şi de

pachetul în care se găseşte subclasa: dacă sunt în acelaşi pachet accesul este

permis, dacă nu sunt în acelaşi pachet accesul nu este permis decât pentru obiecte

de tipul subclasei.

4.3.8. Membrii instanţă şi membrii clasă

O clasă Java poate conţine două tipuri de variabile şi metode :

instanţă: declarate fără modificatorul static, specifice fiecărei

instanţe

clasă: declarate cu modificatorul static, specifice clasei

Dacă o variabilă este declarată statică atunci există doar o copie a variabilei

asociată cu clasa respectivă şi nu mai multe copii ale ei asociate cu fiecare instanţă

a clasei.

O variabilă clasă există şi poate fi folosită chiar dacă clasa nu a fost instanţiată

spre diferenţă de variabilele instanţă care există doar după ce a fost creată o

instanţă a clasei.

Pentru variabilele statice sistemul alocă o singură zonă de memorie la care au

acces toate instanţele clasei respective, ceea ce înseamnă că dacă un obiect

modifică valoarea unei variabile statice, modificarea va fi văzută de către toate

celelalte obiecte. Variabilelor statice nu li se alocă dinamic memorie; memoria pentru

ele este rezervată înainte ca oricare obiect al clasei să fie creat. În cazul variabilelor

instanţă, la fiecare creare a unei instanţe a clasei sistemul alocă o zonă de memorie

separată pentru memorarea valorii ei.

Exemplu: Clasa Punct conţine două variabile instanţă declarate pe linia 2 şi o

variabilă clasă declarată şi iniţializată pe linia 3. Constructorul clasei Punct

51

Page 52: Introducere în limbajul de programare Java

iniţializează variabilele instanţă şi incrementează variabila clasă. Cu alte cuvinte,

variabila nr_puncte va contoriza câte ”puncte” (instanţe ale clasei Punct) se

creează. În clasa TestPunct se creează trei obiecte de tipul Punct şi se afişează

valoarea variabilei clasă nr_puncte. Trebuie remarcat că variabila nr_puncte

este accesată prin intermediul numelui clasei.

1. class Punct{2. int x, y;3. static int nr_puncte=0;

4. Punct(int xx, int yy){5. x=xx; y=yy;6. nrpuncte++;7. }8. }

9. class TestPunct{10. public static void main(String args[]){11. Punct p1=newPunct(10, 10);12. Punct p2=newPunct(20, 20);13. Punct p3=newPunct(30, 30);14. System.out.println(Punct.nr_puncte);15. }16. }

Întrucât metodele clasă nu depind de starea obiectelor clasei respective, apelul

lor se poate face prin:

NumeClasa.metodaStatica();sau

NumeClasa obiect = new NumeClasa();obiect.metodaStatica();

În cazul metodelor instanţă apelul nu se poate face decât prin intermediul unui

obiect:

NumeClass.metodaInstanta(), //ilegalNumeClasa obiect = new NumeClasa();obiect. metodaDeInstanta(); //legal

Exemplu: În clasa Cerc sunt definite: o metodă instanţă în liniile 6-11 care

returnează cercul cu raza cea mai mare şi o metodă clasă în liniile 12-18 care

returnează cercul cu raza cea mai mare dintre cele două cercuri primite ca

parametru. În liniile 21, 22 sunt create două cercuri a şi b cu raze diferite. În linia 23

este apelată metoda maimare a obiectului a. În linia 24 este apelată metoda

maimare a clasei Cerc.

52

Page 53: Introducere în limbajul de programare Java

1. class Cerc{2. double x,y,r;

3. Cerc(double x, double y, double r) {4. this.x=x; this.y=y; this.r=r;5. } 6. Cerc maimare(Cerc c) {7. if(c.r>r)8. return c;9. else10. return this;11. }

12. static Cerc maimare(Cerc a, Cerc b) {13. if (a.r>b.r)14. return a;15. else16. return b;17. }18. }19.20. ...21. Cerc a=new Cerc(10, 10, 50);22. Cerc b=new Cerc(20, 20, 100);23. Cerc c = a.maimare(b);24. Cerc d = Cerc.maimare(a,b);

Metodele clasă nu pot accesa câmpuri sau metode instanţă.

Metodele instanţă pot accesa atât membrii clasă cât şi instanţă.

Membrii clasă (statici) sunt folosiţi pentru a pune la dispoziţie valori şi metode

independente de starea obiectelor dintr-o anumită clasă.

Spre deosebire de C++, în Java nu putem avea funcţii globale definite ca

atare, întrucât "orice este un obiect". Din acest motiv şi metodele care au o

funcţionalitate globală trebuie implementate în cadrul unei clase. Acest lucru se va

face prin intermediul metodelor clasă (globale), deoarece acestea nu depind de

starea particulară a obiectelor din clasa respectivă. De exemplu, să considerăm

funcţia globală sqrt care extrage radicalul dintr-un număr şi care se găseşte în clasa

Math. Dacă nu ar fi fost funcţie clasă, apelul ei ar fi trebuit făcut astfel:

Math m = new Math();double rad121 = m.sqrt(121);

ceea ce ar fi fost extrem de neplăcut pentru programatori. Fiind însă funcţie

statică ea poate fi apelată prin: Math.sqrt(121).

53

Page 54: Introducere în limbajul de programare Java

4.3.9. Argumente în linia de comandă

În sfârşit suntem în măsură să descifrăm antetul metodei main.

public static void main(String args[])Metoda main primeşte un şir de String-uri ca parametru. Prin intermediul lui

o aplicaţie Java poate primi oricâte argumente din linia de comandă în momentul

lansării ei. Aceste argumente sunt utile pentru a permite utilizatorului să specifice

diverse opţiuni legate de funcţionarea aplicaţiei sau să furnizeze anumite date iniţiale

programului.

Argumentele din linia de comandă sunt introduse la lansarea unei aplicaţii,

fiind specificate după numele aplicaţiei şi sunt separate prin spaţiu.

Formatul general pentru lansarea unei aplicaţii care primeşte argumente din

linia de comandă este:

java NumeAplicatie [arg1 arg2 . . . argn] Evident, o aplicaţie poate să nu primească nici un argument sau poate să

ignore argumentele primite din linia de comandă.

În momentul lansării unei aplicaţii interpretorul parcurge linia de comandă cu

care a fost lansată aplicaţia şi, în cazul în care există argumente, îi transmite

aplicaţiei sub forma şirului de String-uri.

Numărul argumentelor primite de un program este dat de dimensiunea

vectorului args –args.length:

numarArgumente = args.length ;

Exemplu: Afişarea argumentelor primite din linia de comandă

public class ArgLinCom {public static void main (String[] args) {for (int i = 0; i < args.length; i++)

System.out.println(args[i]);}

}

Un apel de genul: java ArgLinCom Nu mai vine primavara odata

va produce următorul rezultat: Nu

54

Page 55: Introducere în limbajul de programare Java

maivine primavara odata

Dacă o anumită parte din şirul de intrare este cuprinsă între ghilimelele se

interpretează ca un singur argument, spaţiile fiind ignorate.

Una apel de genul:java ArgLinCom "Nu mai vine" primavara odata

va produce următorul rezultat: Nu mai vine

primavara

odata

Dacă se doreşte ca din linia de comandă să fie transmise argumente

numerice, acestea sunt primite de metoda main sub forma unui vector de String-

uri. Ulterior ele trebuie convertite din String-uri în numere. Acest lucru se

realizează cu metode de tipul parseXXX aflate în clasa XXX corespunzătoare tipului

în care vrem să facem conversia: Integer, Float, Double, etc.

Exemplu:1. public class Maxim {2. public static int max(int a, int b){3. return a>b?a:b;4. }

5. public static int max(int a, int b, int c){

6. int m=a>b?a:b;7. m=m>c?m:c;8. return m;9. }

10. public static void main(String args[]){11. if (args.length!=3){12. System.out.println("Nu ati introdus trei

numere");13. return;14. }15. int a=Integer.parseInt(args[0]), 16. b=Integer.parseInt(args[1]),17. c=Integer.parseInt(args[2]),18. m;19. m=max(a,b);20. System.out.println("Maximul dintre "+a+" si "+b+"

este: "+m);21. m=max(a,b,c);

55

Page 56: Introducere în limbajul de programare Java

22. System.out.println("Maximul dintre "+a+", "+b+" si "+c+" este: "+m);

23. }24. }

În linia 11 se verifică dacă au fost transmişi atâţia parametrii câţi sunt necesari.

În liniile 15-17 se convertesc argumentele în întregi.

4.4. Moştenirea

4.4.1. Principiul moştenirii

După încapsularea datelor, este al doilea principiu de bază al programării

orientate pe obiecte. Moştenirea este folositoare deoarece reduce rescrierea codului.

Adică, o clasă poate fi moştenită de către o altă clasă (toate caracteristicile primei

clase se regăsesc şi în a doua clasă). Noua clasă îşi poate modifica o parte din

comportament, poate adăuga ceva nou sau poate ignora ceea ce este neinteresant.

Această idee provine din lumea înconjurătoare. De exemplu, primul model de

maşină a fost mult timp gândit şi dificil de construit. Evident că nu a atins

perfecţiunea şi, omul a dorit repede ceva mai performant şi mai frumos. Prin urmare,

s-a trecut la crearea celui de-al doilea model. Ar fi o naivitate să credem că lucrul la

acest al doilea model a fost luat de la zero. De fapt, s-a pornit de la primul model şi

s-a încercat o îmbunătăţire a lui în diferite direcţii – s-a redus ceea ce nu era bun, s-

au adăugat elemente noi şi au fost făcute modificări. Astfel s-a născut şi al doilea

model. Pornind de la el, în acelaşi stil, s-au creat noi modele. Şi maşinile elegante pe

care le vedem azi rulând cu viteză pe şosele se trag tot din acea primă maşină. Baza

este aceeaşi, „puţin” îmbunătăţită.

În Java pentru a crea o clasă nouă trebuie specificate: clasa moştenită şi

diferenţele faţă de clasa moştenită. Clasa moştenită se specifică în clauza extends.

modificator NumeClasa extends ClasaDeBaza

Clasa moşteneşte toate metodele accesibile şi variabilele superclasei sale.

56

Page 57: Introducere în limbajul de programare Java

Exemplu: Următoare ierarhie de clase:

se exprimă în Java astfel:

class A{...

}

class B extends A{...

}class C extends B{

...}class D extends B{

...}

Dacă clauza extends lipseşte, implicit clasa moşteneşte clasa Object.

Observaţie: În Java moştenirea multiplă nu este permisă. Adică o clasă poate

să moştenească o singură clasă nu mai multe.

Prin urmare, orice clasă are o superclasă şi poate avea una sau mai multe

subclase.

În exemplul nostru avem:

clasa A este subclasă a clasei Object şi are o subclasă: clasa B.

clasa B este subclasă a clasei A şi are o subclasă: clasa C.

clasele C şi D sunt subclase ale clasei B şi nu au subclase.

Nu este permisă o asemenea moştenire (moştenire multiplă):

Avantajele creării unei ierarhii de clase

DC

B

A

C

BA

57

Page 58: Introducere în limbajul de programare Java

- funcţionalitatea comună a mai multor clase se pune în superclase. Acest

aranjament permite ca funcţionalitatea să fie refolosită în mod repetat

deoarece fiecare subclasă primeşte informaţia comună din superclasă.

- schimbarea sau inserarea unei clase în partea de sus a ierarhiei

determină automat schimbări în comportamentul claselor de jos

Ce se întâmplă când o clasă conţine o metodă care are acelaşi antet cu

metoda unei superclase? Este executată prima metodă întâlnită – căutarea făcându-

se pornind de la baza ierarhiei în sus. Datorită acestui fapt, se pot scrie metode care

să ascundă metodele din superclase.

Dacă o metodă din superclasă nu este rescrisă ea va fi luată ca atare de

subclasă. Nu acelaşi lucru se întâmplă şi cu constructorii. Fiecare clasă derivată

trebuie să îşi definească proprii constructori. Dacă nu se scrie nici un constructor în

subclasă, atunci se generează constructorul implicit.

Exemplu: Se definesc două clase Rational şi RationalIred care moşteneşte

clasa Rational. În linia 15 se construieşte un obiect al clasei Rational prin

apelarea constructorului cu doi parametrii. Acest constructor există deci, totul este în

regulă. În linia 16 se doreşte construirea unui obiect al clasei RationalIred tot

prin apelarea constructorului cu doi parametrii. Dar, în acest caz este generată o

eroare deoarece clasa RationalIred nu are definit constructorul cu doi parametrii.

1.public class Rational{2. private long m,n;3. public Rational(){ 4. m=0; n=1;5. }6. public Rational(long m,long n){7. this.m=m;8. this.n=n;9. }10. }

11. public class RationalIred extends Rational {12. ...13. }

14. ...

15. Rational r = new Rational(2,5); 16. RationalIred r1 = new RationalIred(2,5);

58

Page 59: Introducere în limbajul de programare Java

Pentru ca linia 16 să nu mai genereze eroare, clasa RationalIred trenbuie

să arate astfel:

1. public class RationalIred extends Rational {2. public RationalIred(){3. m=0; n=1;4. }

5. public RationalIred(long m,long n){6. this.m=m;7. this.n=n;8. }9. }

În cadrul unei metode a subclasei care supradefineşte o metodă din

superclasă se poate apela metoda supradefinită (a superclasei), folosind super.

Exemplu: Reluăm exemplul precedent. Subclasa RationalIred conţine ca şi

superclasa Rational doi constructori: unul fără parametrii şi unul cu doi parametrii.

Constructorii subclasei au aceeaşi funcţionalitate cu cei ai superclasei. În linia 16 se

apelează constructorul fără parametrii ai superclasei Rational. În linia 19 se

apelează constructorul cu doi parametrii ai superclasei Rational. Pe lângă cei doi

constructori care au aceeaşi funcţionalitate în ambele clase, a mai fost definită o

metodă produs care este suprascrisă în subclasă. Metoda produs din subclasă

trebuie să facă ceva în plus faţă de metoda superclasei. Prin urmare, „se copiază ”

comportamentul metodei din liniile 10-12 şi se adaugă ceva în plus. „Copierea” se

realizează în linia 22, iar adăugarea în linia 23. Această „copiere” constă în apelarea

metodei din superclasă.

1. public class Rational{2. public long m,n;3. public Rational(){ 4. m=0; n=1;5. }6. public Rational(long m,long n){7. this.m=m;8. this.n=n;9. }10. public void produs(){11. System.out.println("Inmultesc doua numere

rationale");12. }13. }

59

Page 60: Introducere în limbajul de programare Java

14. public class RationalIred extends Rational {15. public RationalIred(){16. super();17. }18. public RationalIred(long m,long n){19. super(m,n);20. }21. public RationalIred produs(RationalIred r){22. super.produs(r);23. System.out.println("si ireductibile");24. }25. }

Observaţii:

Când se doreşte apelarea constructorului superclasei se foloseşte doar

super(...).

Când se doreşte apelarea unei metode a superclasei se foloseşte

super.NumeMetoda(...).

4.4.2. Interfeţe

Interfeţele duc conceptul de clasă abstractă cu un pas înainte prin eliminarea

oricărei implementări a metodelor, punând în practică unul din conceptele OOP de

separare a modelului unui obiect (interfaţa) de implementarea sa.

O interfaţă Java defineşte un set de metode dar nu specifică nici o

implementare pentru ele. O clasă care implementează o interfaţă trebuie obligatoriu

să definească toate metodele interfeţei. Prin urmare, o interfaţă este o colecţie de metode fără implementare şi declaraţii de constante.

Definirea unei interfeţe se face prin intermediul cuvântului cheie interface:

[public] interface NumeInterfata extends SuperInterfata1 [,extends

SuperInterfata2...]]{

//corpul interfetei:constane si metode abstracte}

O interfaţă poate fi declarată doar public. O clasă poate extinde oricâte

interfeţe. Acestea se numesc superinterfeţe şi sunt separate prin virgulă.

Corpul unei interfeţe conţine:

60

Page 61: Introducere în limbajul de programare Java

constante: acestea pot fi sau nu declarate cu modificatorii public,

static şi final care sunt impliciţi; nici un alt modificator nu poate apărea

în declaraţia unei variabile a unei interfeţe. Constantele dintr-o interfaţă

trebuie obligatoriu iniţializate.

Exemplu:1. interface NumeInterfata {2. int x = 100; //corect3. public static final int y = 100; //corect4. private z=100; //incorect5. int a; //incorect6. }

metode fără implementare: acestea pot fi sau nu declarate cu

modificatorul public care este implicit; nici un alt modificator nu poate

apărea în declaraţia unei metode a unei interfeţe.

Exemplu:7. interface NumeInterfata {8. void metoda1(); //corect9. public void metoda2(); //corect10. private void metoda3(); //incorect11. }

Atenţie: Variabilele şi metodele unei interfeţe sunt implicit publice chiar dacă nu sunt

declarate cu modificatorul public.

Variabilele unei interfeţe sunt implicit constante chiar dacă nu sunt declarate

cu modificatorii static şi final.

Implementarea unei interfeţe se face prin intermediul cuvântului cheie

implements:

class NumeClasa implements NumeInterfata sau

class NumeClasa implements Interfata1, Interfata2...O clasă poate implementa oricâte interfeţe. O clasă care implementează o

interfaţă trebuie obligatoriu să definească toate metodele interfeţei.

Exemplu: Se defineşte o interfaţă FigGeom care este implementată de clasa

Cerc şi clasa Dreptunghi. Clasa Patrat moşteneşte clasa Dreptunghi, iar

clasa Pataratel moşteneşte clasa Patrat.

61

Page 62: Introducere în limbajul de programare Java

1. interface FigGeom{2. void desen();3. void arie();4. }

5. class Cerc implements FigGeom{6. int r;7. Cerc(int r){8. this.r=r;9. System.out.println("Constructor cerc "+r);10. }11. public void desen(){12. System.out.println("Deseneaza cercul "+r);13. }14. public void arie(){15. double s=Math.PI*r*r;16. System.out.println("Cercul "+r+" are aria "+s);17. }18. }

19. class Dreptunghi implements FigGeom{20. int L,l;21. Dreptunghi(){}22. Dreptunghi(int L,int l){23. this.L=L;24. this.l=l;25. System.out.println("Constructor dreptunghi "+L+"

"+l);26. }27. public void desen(){28. System.out.println("Deseneaza dreptunghiul "+L+"

"+l);29. }30. public void arie(){31. double s=L*l;32. System.out.println("Dreptunghiul "+L+" "+l+" are

aria "+s);33. }34. }

35. public class TestFigGeom{36. public static void main(String args[]){37. FigGeom c=new Cerc(10),38. d=new Dreptunghi(20,25),39. c.desen();40. c.arie();41. d.desen();42. d.arie();43. }44. }

62

Page 63: Introducere în limbajul de programare Java

Rezultatul execuţiei este:

Constructor cerc 10Constructor dreptunghi 20 25Deseneaza cercul 10Cercul 10 are aria 314.1592653589793Deseneaza dreptunghiul 20 25Dreptunghiul 20 25 are aria 500.0

Diferenţa dintre o interfaţă şi o clasă abstractăLa prima vedere o interfaţă nu este altceva decât o clasă abstractă în care

toate metodele sunt abstracte (nu au nici o implementare). Deosebirea dintre ele

constă în faptul că unele clase sunt forţate să extindă o anumită clasă (de exemplu

orice applet trebuie să fie subclasă a clasei Applet) şi nu ar mai putea să extindă o

clasă abstractă deoarece în Java nu există decât moştenire simplă. Fără folosirea

interfeţelor nu am putea forţa clasa respectiva să respecte un anumit protocol.

La nivel conceptual diferenţa constă în:

extinderea unei clase abstracte forţează o relaţie între clase;

implementarea unei interfeţe specifică doar necesitatea implementării

unor anumite metode.

4.5. Probleme

Exemplu 1: Exemplificarea moştenirii.

class Masina { private String s = new String("Masina");

public void append(String a){ s += a; } public void porneste(){ append(" porneste()"); } public void merge(){ append(" merge()"); } public void opreste(){ append(" opreste()"); } public void print(){ System.out.println(s);

63

Page 64: Introducere în limbajul de programare Java

}}

class BMW extends Masina { //schimbarea unei metode public void opreste() { append(" BMW opreste sigur()"); super.opreste(); // apelul metodei clasei de baza }

// adaugarea unei metode noi public void franeazaBine(){ append(" franeazaBine()"); }} // testarea noii clasepublic class TestMasina{ public static void main(String[] args) { BMW bmw = new BMW();/* System.out.println(bmw.s); //Eroare s nu apartine lui bmw */ bmw.porneste(); bmw.merge(); bmw.franeazaBine(); bmw.opreste(); bmw.print(); }}

Rezultatul execuţiei este:

Masina porneste() merge() franeazaBine() BMW opreste sigur()

opreste()

Exemplu 2: Exemplificarea moştenirii şi a polimorfismului.

abstract class FigGeom{abstract void desen();abstract void arie();

}

class Cerc extends FigGeom{int r;Cerc(int r){

this.r=r;System.out.println("Constructor cerc "+r);

}void desen(){

System.out.println("Deseneaza cercul "+r);}void arie(){

64

Page 65: Introducere în limbajul de programare Java

double s=Math.PI*r*r;System.out.println("Cercul "+r+" are aria "+s);

}}

class Dreptunghi extends FigGeom{int L,l;Dreptunghi(){}Dreptunghi(int L,int l){

this.L=L;this.l=l;System.out.println("Constructor dreptunghi "+L+"

"+l);}void desen(){

System.out.println("Deseneaza dreptunghiul "+L+" "+l);

}void arie(){

double s=L*l;System.out.println("Dreptunghiul "+L+" "+l+" are

aria "+s);}

}

class Patrat extends Dreptunghi{int l;Patrat(int l){// super(l,l);

this.l=l;System.out.println("Constructor patrat "+l);

}void desen(int k){

System.out.println("Deseneaza patratul "+l+" indice "+k);

}void arie(){

double s=l*l;System.out.println("Patrat "+l+" are aria "+s);

}}

class Patratel extends Patrat{int l;Patratel(int l){

super(l);this.l=l;System.out.println("Constructor patratel "+l);

}void desen(int k){

System.out.println("Deseneaza patratelul "+l+" indice "+k);

65

Page 66: Introducere în limbajul de programare Java

}void arie(){

double s=l*l;System.out.println("Patratelul "+l+" are aria "+s);

}}

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

FigGeom c=new Cerc(10),d=new Dreptunghi(20,25),p=new Patrat(30),pm=new Patratel(40);

c.desen();c.arie();d.desen();d.arie();

// p.desen(100); da eroare p fiind o figura geometrica

p.desen(); //se apeleaza desen din dreptunghip.arie();pm.desen(); //se apeleaza desen din dreptunghipm.arie();Patrat p1=new Patrat(300);p1.desen(100); //este okp1.arie();

}}

Rezultatul afişat este:

Constructor cerc 10

Constructor dreptunghi 20 25

Constructor patrat 30

Constructor patrat 40

Constructor patratel 40

Deseneaza cercul 10

Cercul 10 are aria 314.1592653589793

Deseneaza dreptunghiul 20 25

Dreptunghiul 20 25 are aria 500.0

Deseneaza dreptunghiul 0 0

Patrat 30 are aria 900.0

Deseneaza dreptunghiul 0 0

Patratelul 40 are aria 1600.0

66

Page 67: Introducere în limbajul de programare Java

Constructor patrat 300

Deseneaza patratul 300 indice 100

Patrat 300 are aria 90000.0

Exemplu 3: Ilustrează ordinea iniţializărilor

class Floare { Floare(int nr) { System.out.println("Floare(" + nr + ")"); } void actiune(String fel) { System.out.println("actiune(" + fel + ")"); }}

class Vaza { static Floare f1 = new Floare(1); //var STATICA Vaza() { System.out.println("Vaza()"); f2.actiune("Floare in vaza"); } void pozitie(String loc) { System.out.println("pozitie(" + loc + ")"); } static Floare f2 = new Floare(2); //var STATICA}

class Gradina { Floare f3 = new Floare(3); static Floare f4 = new Floare(4); //var STATICA Gradina() { System.out.println("Gradina()"); f4.actiune("Floare doarme"); } void aspect(String tip) { System.out.println("aspect(" + tip + ")"); } static Floare f5 = new Floare(5); //var STATICA}

public class StaticInit { public static void main(String[] args) { System.out.println( "Creaza o Gradina() noua in main"); new Gradina(); System.out.println( "Creaza o Gradina() noua in main"); new Gradina(); v2.pozitie("pe masa");

67

Page 68: Introducere în limbajul de programare Java

g3.aspect("frumos"); } static Vaza v2 = new Vaza(); //var STATICA static Gradina g3 = new Gradina(); //var STATICA}

Rezultatul execuţiei este:

Floare(1)

Floare(2)

Vaza()

actiune(Floare in vaza)

Floare(4)

Floare(5)

Floare(3)

Gradina()

actiune(Floare doarme)

Creaza o Gradina() noua in main

Floare(3)

Gradina()

actiune(Floare doarme)

Creaza o Gradina() noua in main

Floare(3)

Gradina()

actiune(Floare doarme)

pozitie(pe masa)

aspect(frumos)

Exemplu 4: Exemplificarea moştenirii. Clasa Rational implementează lucrul cu

numere raţionale. Clasa RationalIred moşteneşte clasa Rational şi

implementează lucrul cu numere raţionale ireductibile.

public class Rational{private long m,n;

public Rational(){this(1,0);

}

public Rational(long m,long n){setm(m);setn(n);

68

Page 69: Introducere în limbajul de programare Java

}

public Rational(long m){this(m,1);

}

public void setm(long m){this.m=m;

}

public long getm(){return m;

}

public void setn(long n){this.n=n;

}

public long getn(){return n;

}

public Rational produs(Rational r){return new Rational(m*r.m,n*r.n);

}

public String toString(){return m+"/"+n;

}

} public class RationalIred extends Rational {

public RationalIred(){super();

}

public RationalIred(long m,long n){super(m,n);

}

public RationalIred(long m){super(m);

}

private void simplifica(){long x=getm(), y=getn();while(x!=y){

if(x>y) x-=y;else y-=x;

}

69

Page 70: Introducere în limbajul de programare Java

setm(getm()/x);setn(getn()/x);

}

public RationalIred produs(RationalIred r){RationalIred p=new RationalIred();p.setm(getm()*r.getm());p.setn(getn()*r.getn());p.simplifica();return p;

}

} public class TestRational{

public static void main(String[] args) { RationalIred r1,r2,p; r1=new RationalIred(Integer.parseInt(args[0]), Integer.parseInt(args[1])); r2=new RationalIred(Integer.parseInt(args[2]), Integer.parseInt(args[3]));

System.out.println(r1);System.out.println(r2);p=r1.produs(r2);System.out.println(p);

}}

70

Page 71: Introducere în limbajul de programare Java

5. Pachete

Un pachet este o colecţie de clase şi interfeţe înrudite. Sunt folosite pentru

găsirea şi utilizarea mai uşoarã a claselor, pentru a evita conflictele de nume şi

pentru a controla accesul la anumite clase.

În Java toate clasele şi interfeţele sunt grupate în diferite pachete după

funcţionalitatea lor. Cu ajutorul lor se pot construi aplicaţiile. Cele mai importante

pachete pe care le pune Java la dispoziţie sunt:

pachetul java.lang cuprinde clasele de bazã ale limbajului;

pachetul java.io cuprinde clasele pentru intrãri/ieşiri, lucru cu fişiere;

pachetul java.math cuprinde clasele în care sunt definite operaţiile

matematice;

pachetul java.util cuprinde clasele utile : Vector, Stack, Random,

Date etc;

pachetul java.text oferă suport pentru formatarea textelor;

pachetul java.sql oferă suport pentru interogări SQL;

pachetul java.beans cuprinde clasele necesare scrierii de

componente reutilizabile;

pachetul java.net cuprinde clasele care asigură accesul la reţea;

pachetul java.awt cuprinde clasele pentru graficã (Abstract

Windowing Toolkit);

pachetul javax.swing cuprinde clasele pentru graficã; extinde

funcţionalitatea claselor din pachetul java.awt.

pachetul java.rmi cuprinde clasele care asigură execuţie la distanţă

(Remote Message Interface);

pachetul java.securitz cuprinde clasele care asigură mecanisme de

securitate: criptare, autentificare;

71

Page 72: Introducere în limbajul de programare Java

Pentru a folosi o componentă a unui pachet trebuie făcut cunoscut clasei

curente fie pachetul în care se găseşte componenta, fie doar componenta. Acest

lucru se realizează prin importarea pachetului sau, doar a clasei.

5.1. Importul unui pachet, al unei clase sau a unei interfeţe

Importul se realizează prin instrucţiunea import.

Importul pachetelor se face prin specificarea numelui pachetului urmat de

simbolul '*'. '*' are semnificaţia că toate clasele şi interfeţele pachetului sunt

importate.

import NumePachet.*;Exemple:

import java.io.*;

import javax.swing.*;

O dată realizat într-un fişier importul pachetului, orice clasă din pachet poate fi

accesată prin numele ei.

Exemplu: Clasa Date aparţine pachetului java.util.

import java.util.*;public class ExData{ public static void main(String[] args) { Date d=new Date(2003,4,13); System.out.println(d); }}

Atenţie: În cazul în care sunt importate două pachete care conţin o clasă cu

acelaşi nume atunci referirea la ea trebuie făcută folosind numele complet al clasei

respective (nume pachet urmat de nume clasă).

Implicit, mediul Java importă trei pachete:

pachetul java.lang

pachetul curent

pachetul implicit (fără nume)

Importul claselor (interfeţelor) se realizează prin specificarea numelui clasei

(interfeţei) pe care dorim să o folosim dintr-un pachet:

72

Page 73: Introducere în limbajul de programare Java

import NumePachet.NumeClasa;Exemple:

import java.util.Date;

O dată realizat într-un fişier importul clasei (interfeţei), aceasta poate fi

accesată prin numele ei.

Exemplu: import java.util.Date;public class ExData{ public static void main(String[] args) { Date d=new Date(2003,4,13); System.out.println(d); }

}

În cazul în care nu avem nevoie decât de câteva clase dintr-un pachet este

mai eficient să importăm clasele decât întregul pachet.

5.2. Crearea unui pachet

Se creează un director cu numele NumePachet în care vor fi salvate toate

fişierele sursă ce conţin clasele şi interfeţele pe care dorim să le grupăm într-un

pachet. Numele directorului dă numele pachetului.

În prima linie a fiecărui fişier din directorul NumePachet se specifică faptul că

toate clasele din fişierul respectiv vor aparţine clasei. Aceasta se realizează prin:

package NumePachet; Prin urmare codul unei clase care se adaugă la un pachet arată astfel:

package NumePachet;public class NumeClasa{ . . .}

Instrucţiunea package acţionează asupra întregului fişier sursă la începutul

căruia apare. Cu alte cuvinte nu putem specifica faptul că anumite clase dintr-un

fişier sursă aparţin unui pachet iar altele altui pachet.

Dacă nu este specificat un anumit pachet, clasele unui fişier sursă vor face

parte din pachetul implicit (care nu are nici un nume). În general, pachetul implicit

este format din toate clasele şi interfeţele directorului curent.

Pentru compilare trebuie să ne plasăm în directorul părinte al directorului

NumePachet.

73

Page 74: Introducere în limbajul de programare Java

Se execută comanda:

javac NumePachet\*.java

În cazul în care nu sunt erori în pachet, în directorul NumePachet trebuie să

se creeze fişierele .class.

Clasele care folosesc pachetul creat se aşează în afara directorului. Pentru ca

ele să aibă acces la pachet trebuie setată variabila sistem CLASSPATH:

SET CLASSPATH = CaleDirectorNumePachet

Exemplu 1: În directorul c:\lucru se formează un director Pachete în care se

salvează următoarele fişiere:

Fişierul A1.java conţine clasa:

package Pachete;public class A1{ int a=0; public int b=0; private int c=0; protected int d=0;

void a(){ System.out.println(a); } public void b(){ System.out.println("public "+ b); } protected void d(){ System.out.println("protected "+d); }}

Fişierul A2.java conţine clasa:

package Pachete;public class A2 implements A3{ public void a3(){ A1 a1=new A1(); a1.a=1; a1.b=1; a1.d=1; System.out.println(a1.a+" "+a1.b+" "+a1.d); a1.a(); a1.b(); a1.d(); }}

74

Page 75: Introducere în limbajul de programare Java

Fişierul A3.java conţine clasa:

package Pachete;public interface A3{ public void a3();}

Setăm variabila CLASSPATH:

SET CLASSPATH = c:\lucru

Pentru compilare ne poziţionăm în directorul c:\lucru şi executăm

comanda:

javac Pachete\*.java

Construim o clasă de test A4.java pe care o salvăm în c:\lucru:

import Pachete.*;public class A4{ public static void main(String args[]){ A2 a=new A2(); a.a3(); A1 a1=new A1(); //a1.a(); eroare – metoda a() este ca şi protected a1.b(); //a1.d(); eroare – metoda d() este protected }}

Se compilează şi se execută ca orice clasă Java .

Exemplu 2: Construim un pachet Tablou care conţine o clasă Matrice şi una

Vector.

package Tablou;public class Vector{ private double a[]; public Vector(){ a=new double[1]; }

public Vector(int n, double a[]){ this.a=new double[n]; for(int i=0; i<n; i++) this.a[i]=a[i]; } public int getLungime(){ return a.length;

75

Page 76: Introducere în limbajul de programare Java

} public double getElem(int poz){ return a[poz]; } public double[] getVector(){ return a; }

public void setElem(int poz, double val){ a[poz]=val; } public void setVector(double a[]){ this.a=new double[a.length]; for(int i=0; i<a.length; i++) this.a[i]=a[i]; } public String toString(){ String s=""; for(int i=0; i<a.length; i++) s=s+a[i]+" "; return s; }}

package Tablou;public class Matrice{ private double a[][]; public Matrice(){ a=new double[1][]; }

public Matrice(int n, int m, double a[][]){ this.a=new double[n][m]; for(int i=0; i<n; i++) for(int j=0; j<m; j++) this.a[i][j]=a[i][j]; } public int getNrLin(){ return a.length; }

public int getNrCol(int l){ return a[l].length; }

76

Page 77: Introducere în limbajul de programare Java

public double getElem(int l, int c){ return a[l][c]; } public double[][] getMatrice(){ return a; } public String toString(){ String s=""; for(int i=0; i<a.length; i++){ for(int j=0; j<a[i].length; j++) s+=a[i][j]+" "; s+="\n"; } return s; }}

O clasă care foloseşte pachetul Tablou ar fi:

1. import Tablou.*;2. public class TestTablou{3. public static void main(String args[]){4. double x[][]={{2,4},{5,6},{1,3}};5. Matrice m=new Matrice(3,2,x);6. System.out.println(m);7. double y[]={2,4,5,6};8. Vector v=new Vector(4,y);9. System.out.println(v);10. java.util.Vector vv=new java.util.Vector(5);11. for (int i=0;i<5;i++)12. vv.add(new Integer(i));13. System.out.println(vv);14. }15. }

Se observă că în linia 10 se creează un obiect folosind de data aceasta clasa

Vector din pachetul java.util. Pentru a face diferenţă între clasa pachetului

nostru şi clasa pachetului java.util trebuie să specificăm şi numele pachetului.

77

Page 78: Introducere în limbajul de programare Java

6. Excepţii

6.1. Aspecte generale

O excepţie este un eveniment ce se produce în timpul execuţiei unui program

şi care provoacă întreruperea cursului normal al execuţiei.

De exemplu, o împărţire la 0 sau utilizarea unui indice care depăşeşte o

dimensiune declarată a unui tablou reprezintă un eveniment care perturbă execuţia

normală a programului – este vorba despre o excepţie. Când apare o astfel de

eroare în timpul execuţiei programului sistemul generează automat un obiect de tip

excepţie ce conţine:

informaţii despre excepţia respectivă;

starea programului în momentul producerii excepţiei

Exemplu:public class Exceptii {

public static void main(String args[]) { int v[] = new int[10];

v[10] = 0; //exceptie, vectorul are elementele v[0]...v[9] System.out.println("Aici nu se mai ajunge...");}

}

La rularea programului va fi generată o excepţie şi se va afişa mesajul :

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException :3

at Exceptii.main (Exceptii.java:4)

Java dispune de un mecanism care permite programatorului să preia controlul

programului în momentul în care apare o excepţie şi să o trateze.

78

Page 79: Introducere în limbajul de programare Java

Crearea unui obiect de tip excepţie se numeşte aruncarea unei excepţii

("throwing an exception"). În momentul în care o metodă generează o excepţie

(aruncă o excepţie) sistemul de execuţie este responsabil cu găsirea unei secvenţe

de cod dintr-o metodă care să trateze acea excepţie. Excepţiile sunt propagate

înapoi prin secvenţa de metode apelate până când o anumită metodă prinde

excepţia. Secvenţa de cod dintr-o metodă care tratează o anumită excepţie se

numeşte analizor de exceptie ("exception handler") iar interceptarea şi tratarea

excepţiei se numeşte prinderea excepţiei ("catch the exception").

Cu alte cuvinte la apariţia unei erori este "aruncată" o excepţie iar cineva trebuie să

o "prindă" pentru a o trata. Dacă sistemul nu găseşte nici un analizor pentru o

anumita excepţie atunci programul Java se opreşte cu un mesaj de eroare.

Ierarhia claselor ce conţin excepţii este:

Toate excepţiile Java sunt subclase ale clasei Exception.

6.2. Instrucţiunea try

try{ instrucţiuni ce pot declanşa excepţii

} [catch(ClasaExceptie obiectExceptie){

instrucţiuni de tratare a excepţiei de clasă ClasaExceptie}]*[finally{

instrucţiuni care se execută necondiţionat în final

}]

79

Page 80: Introducere în limbajul de programare Java

Instrucţiunea try conţine un bloc de instrucţiuni ce trebuie executate. Punerea

unor instrucţiuni în cadrul lui try înseamnă că există posibilitatea apariţiei unor

excepţii sau terminării anormale a unei instrucţiuni. O instrucţiune try poate avea

oricâte clauze catch (opţionale) în care sunt tratate excepţiile. De asemenea,

instrucţiunea try poate avea o clauză finally a cărui bloc se execută întotdeauna

înaintea părăsirii instrucţiunii try. Instrucţiunea try trebuie să aibă fie o clauză

catch, fie una finnaly.

Formele generale ale instrucţiunii try.

1.

try{ ... } catch(ClasaExceptie obiectExceptie){...}

2.try{ ... } catch(ClasaExceptie obiectExceptie){... }...catch(ClasaExceptie obiectExceptie){... }

3.try{ ... } finnaly{... }

4.try{ ... } catch(ClasaExceptie obiectExceptie){... }...

catch(ClasaExceptie obiectExceptie){... }finnaly{... }

80

Page 81: Introducere în limbajul de programare Java

În cazul în care este declanşată o excepţie şi există mai multe clauze catch,

este căutată, în ordine, acea clauză care poate trata excepţia. Adică este găsită o

clauză a cărui parametru are un tip care se potriveşte cu tipul excepţiei. Ordinea în

care clauzele catch apar este importantă: clauzele catch mai specifice trebuie să

apară înaintea celor mai generale. Dacă nu există o clauză care să trateze excepţia,

aceasta este propagată în sus, la instrucţiunile imediat următoare.

Excepţii uzuale:

ArithmeticException Depăşire limită tip sau împărţire la 0

NumberFormatException Conversia nepermisă a unui

String la un tip numeric

IndexOutOfBoundsException Indice ilegal într-un şir

NegativeArraySizeException Crearea unui şir cu număr negativ

de elemente

NullPointerException Tentativă de a folosi o referinţă care

are valoarea null

SecurityException Încălcarea normelor de securitate în

timpul execuţiei

6.3. Crearea unei excepţii

Adeseori poate apărea necesitatea creării unor excepţii proprii pentru a pune

în evidenţă cazuri speciale de erori provocate de clasele unei librării, cazuri care nu

au fost prevăzute în ierarhia excepţiilor standard Java.

O excepţie proprie trebuie să se încadreze în ierarhia excepţiilor Java, cu alte

cuvinte clasa care o implementează trebuie să fie subclasă a clasei Exception.

public class ExceptieNoua extends Exception{ ... }

Exemplu:1. public class Exc extends Exception{2. public Exc(){3. super(); //apeleaza constructorul clasei Exception4. ...5. }6. }

81

Page 82: Introducere în limbajul de programare Java

Într-o clasă în care se doreşte folosirea unei excepţii există o metodă care creează

excepţia (obiect al clasei de excepţii), mai multe metode care aruncă excepţia

primită şi, eventual o metodă care o prinde, adică o tratează. Dacă într-o metodă

apare o excepţie – creată în metoda respectivă sau ca urmare a apelării unei

metode care a aruncat o excepţie, atunci ea trebuie fie să fie tratată, fie să fie

aruncată mai departe. În ambele cazuri codul care ar putea genera excepţia trebuie

pus în cadrul unei instrucţiuni try care să aibă o clauză catch cu parametru care

să coincidă cu clasa excepţiei. Dacă excepţia se doreşte să fie tratată, atunci în

clauza catch se pune un cod corespunzător. Dacă se doreşte ca excepţia să nu fie

tratată atunci ea trebuie aruncată mai departe (metodei care a făcut apelul) şi acest

lucru se realizează prin adăugarea clauzei throws ClasaExceptie în antetul

metodei.

Exemplu 1: În clasa RationalIred se verifică dacă numitorul fracţiei este 0. Dacă da

atunci se creează o excepţie – linia 53.

1. public class Exc extends Exception{2. public Exc(){3. super();4. System.out.println("Numitor 0");5. }6. }

7. public class Rational{8. private long m,n;

9. public Rational(){10. this(1,0);11. }12. public Rational(long m,long n){13. setm(m);14. setn(n);15. }16. public Rational(long m){17. this(m,1);18. }19. public void setm(long m){20. this.m=m;21. }22. public long getm(){23. return m;24. }25. public void setn(long n){26. this.n=n;27. }

82

Page 83: Introducere în limbajul de programare Java

28. public long getn(){29. return n;30. }31. public Rational produs(Rational r){32. return new Rational(m*r.m,n*r.n);33. }34. public String toString(){35. return m+"/"+n;36. }37. }

38. public class RationalIred extends Rational {39. public RationalIred(){40. super();41. }42. public RationalIred(long m,long n) throws Exc{43. setm(m);44. try{45. setIn(n);46. }47. catch(Exc e){throw e;}48. }49. public void setIn(long n) throws Exc{50. if (n!=0)51. super.setn(n);52. else53. throw new Exc();54. }55. private void simplifica(){56. long x=getm(), y=getn();57. while(x!=y){58. if(x>y) x-=y;59. else y-=x;60. }61. setm(getm()/x);62. setn(getn()/x);63. }64. public RationalIred produs(RationalIred r){65. RationalIred p=new RationalIred();66. p.setm(getm()*r.getm());67. p.setn(getn()*r.getn()); 68. p.simplifica();69. return p;70. }71. }

72. public class TestRational{73. public static void main(String[] args) {74. RationalIred r1,r2,p;75. try{76. r1=new RationalIred(77. Integer.parseInt(args[0]),

83

Page 84: Introducere în limbajul de programare Java

78. Integer.parseInt(args[1]));79. r2=new RationalIred(80. Integer.parseInt(args[2]),81. Integer.parseInt(args[3]));82. }83. catch(Exc e){84. System.exit(1);85. } 86. System.out.println(r1);87. System.out.println(r2);88. p=r1.produs(r2);89. System.out.println(p);90. }91. }

84

Page 85: Introducere în limbajul de programare Java

7. Intrări şi ieşiri

Informaţia poate fi preluată de oriunde (fişier, disk, reţea, memorie, alt

program) şi poate fi de orice tip (obiecte, caractere, imagini, sunete).

Pentru a aduce informaţii, un program Java deschide un flux (canal de

comunicaţii) la o sursă de informaţii şi citeşte informaţia. Un flux care citeşte date se

numeşte flux de intrare.

Similar, un program poate trimite informaţii către o destinaţie externă

deschizând un flux (canal de comunicaţii) către acea destinaţie şi scriind serial

informaţiile respective. Un flux care scrie date se numeşte flux de ieşire.

Algoritmul de citire este:

85

Page 86: Introducere în limbajul de programare Java

deschide flux cât timp există informaţie citeşte informaţia închide flux

Algoritmul de afişare este:

deschide flux cât timp există informaţie scrie informaţia închide flux

Pachetul java.io conţine o colecţie de clase folosite pentru citiri şi afişări.

Prin urmare, orice program care necesită operaţii de intrare / ieşire trebuie să

importe pachetul java.io:

import java.io.*.

7.1. Clasificarea fluxurilor

Există trei tipuri de clasificare a fluxurilor:

După "direcţia" canalului de comunicaţie deschis, fluxurile se împart în:

o fluxuri de intrare (pentru citirea datelor)

o fluxuri de ieşire (pentru scrierea datelor)

După tipul de date pe care operează:

o fluxuri de octeţi (comunicarea serială se realizează pe 8 biţi)

o fluxuri de caractere (comunicarea serială se realizează pe 16

biţi)

După acţiunea lor:

o fluxuri pentru citirea / scrierea datelor

o fluxuri pentru procesarea datelor

7.2. Ierarhia claselor pentru lucrul cu fluxuri

7.2.1. Fluxuri de caractere

86

Page 87: Introducere în limbajul de programare Java

Clasele rădăcină pentru ierarhia claselor ce se ocupă cu fluxurile de caractere

sunt Reader (pentru fluxuri de intrare) şi Writer (pentru fluxuri de ieşire).

Ierarhia claselor pentru fluxuri de intrare pe caractere este:

Ierarhia claselor pentru fluxuri de ieşire pe caractere este:

7.2.2. Fluxuri de octeţi

Clasele rădăcină pentru ierarhia claselor ce se ocupă cu fluxurile de octeţi sunt

InputStream (pentru fluxuri de intrare) şi OutputStream (pentru fluxuri de ieşire).

Subclasele lor sunt folosite pentru citiri şi scrieri de date binare cum ar fi imagini şi

sunete.

Ierarhia claselor pentru fluxuri de intrare pe octeţi:

87

Page 88: Introducere în limbajul de programare Java

Ierarhia claselor pentru fluxuri de ieşire pe octeţi:

7.3. Superclasele de intrare / ieşire

Clasele Reader şi InputStream definesc metode similare pentru citirea

datelor, tipul parametrilor variind.

Clasa Reader

int read()

int read(char cbuf[ ])

int read(char cbuf[ ], int index, int lungime)

Clasa InputStream

int read()

int read(byte cbuf[ ])

int read(byte cbuf[ ], int index, int lungime)

88

Page 89: Introducere în limbajul de programare Java

Analog, clasele Writer şi OutputStream definesc metode similare pentru

afişarea datelor, tipul parametrilor variind.

Clasa Writer

int write()

int write(char cbuf[ ])

int write(char cbuf[ ], int index, int lungime)

Clasa OutputStream

int write()

int write(byte cbuf[ ])

int write(byte cbuf[ ], int index, int lungime)

7.4. Crearea unui flux

Orice flux este un obiect al clasei ce implementează fluxul respectiv. Crearea

unui flux se realizează similar cu crearea obiectelor, prin instrucţiunea new().

Exemple://crearea unui flux de intrare pe caractereFileReader in = new FileReader("fisier_intrare.txt");

//crearea unui flux de iesire pe caractereFileWriter out = new FileWriter("fisier_iesire.txt");

//crearea unui flux de intrare pe octetiFileInputStream in = new

FileInputStream("fisier_intrare.txt");

//crearea unui flux de iesire pe octetiFileOutputStrem out = new

FileOutputStream("fisier_iesire.txt");

Prin urmare, crearea unui flux de date care scrie / citeşte informaţii de la un

dispozitiv extern are formatul general:

FluxPrimitiv numeFlux = new FluxPrimitiv (dispozitiv extern)

89

Page 90: Introducere în limbajul de programare Java

7.5. Citirea datelor de la tastatură

7.5.1. Obiectul System.in

În general, tastatura reprezintă perifericul standard pentru introducerea datelor.

Clasa System conţine o variabilă membru care reprezintă tastatura sau fluxul de

intrare standard. Această variabilă membru se numeşte in şi este o instanţă a clasei

InputStream.

Exemplu 1: Se citesc de la tastatură caractere. Fiecare caracter citit se adaugă la un

şir de caractere. Citirea se încheie când se apasă tasta Enter.

1. class Citire1 {2. public static void main(String args[]) {3. StringBuffer s=new StringBuffer();4. char c;5. try {6. while((c=(char)System.in.read()) != ’\n’)7. s.append(c);8. }9. catch(Exception e) {10. System.out.println(”Error:”+e.getMessage());11. }12. System.out.println("Sirul este:"+s);13. }14. }

Exemplu 2: Se citesc de la tastatură caractere. Ele sunt memorate într-un vector de

bytes (linia 5). Citirea se încheie când se apasă tasta Enter. Pe baza vectorului se

formează un String (linia 10) care este afişat.

1. class Citire2 {2. public static void main(String args[]) { 3. byte buf[]=new byte[30]; 4. try {5. System.in.read(buf);6. }7. catch(Exception e) {8. System.out.println(”Error:”+e.getMessage());9. }10. String s=new String(buf);11. System.out.println(s); 12. }13. }

90

Page 91: Introducere în limbajul de programare Java

7.5.2. Clasa InputStreamReader

Reprezintă legătura dintre fluxurile de octeţi şi fluxurile de caractere: citeşte

octeţi şi îi transformă în caractere. Transformarea octeţilor în caractere este

efectuată conform unei reguli de codificare. Dacă nu se specifică o astfel de regulă,

atunci se utilizează codificarea implicită (dată de proprietatea de sistem ”file

encoding”).

Clasa InputStreamReader are următorii constructori:

InputStreamReader(InputStream in)InputStreamReader(InputStream in, String enc)

Metoda principală pentru citirea unui caracter este:

int read()

Exemplu 3: Se citesc de la tastatură caractere. Fiecare caracter citit se adaugă la un

şir de caractere. Citirea se încheie când se apasă tasta Enter.

1. import java.io.*;2. class Citire3 {3. public static void main(String args[]) {4. InputStreamReader in=5. new InputStreamReader(System.in);6. char c;7. StringBuffer s=new StringBuffer();8. try {9. while((c=(char)in.read()) != ’\n’)10. s.append(c);11. }12. catch(Exception e) {13. System.out.println(”Error:”+e.getMessage());14. }15. System.out.println(s); 16. }17. }

7.5.3. Clasa BufferedReader

91

Page 92: Introducere în limbajul de programare Java

În cazul folosirii clasei InputStreamReader, citirea se face caracter cu

caracter (adică, discul este accesat de fiecare dată). Pentru a creşte eficienţa se

foloseşte un flux care utilizează o zonă tampon pentru citire (BufferedReader).

Clasa BufferedReader are definită metoda read() cu aceeaşi signatură ca şi cea

definită în InputStreamReader dar, în plus, defineşte şi metoda readLine().

Această metodă poate fi folosită pentru a citi un şir de caractere terminat cu ’\n’,’\r’

sau ’\r\n’.

Exemplu 4: Se introduce un şir de caractere de la tastatură. La apăsarea tastei Enter

şirul este citit în întregime şi este depus într-un String.

1. import java.io.*;2. class Citire4 {3. public static void main(String args[]) {4. InputStreamReader in1= new InputStreamReader(System.in);5. String s=new String();6. try {7. BufferedReader in= new BufferedReader(in1);8. s=in.readLine(); 9. }10. catch(Exception e) {11. System.out.println(”Error:”+e.getMessage());12. }13. System.out.println(s); 14. }15. }

7.6. Citirea şi scrierea datelor din fişier

7.6.1. Clasele FileReader şi FileWriter

Clasa FileReader este folosită la citirea datelor dintr-un fişier text. Cei mai

importanţi constructori ai săi sunt:

creează un flux care citeşte caractere din fişierul nume

public FileReader(String nume) throws FileNotFoundException

92

Page 93: Introducere în limbajul de programare Java

creează un flux care citeşte caractere din fişierul varFis.

public FileReader(File varFis) throws FileNotFoundException

Clasa FileWriter este folosită la scrierea datelor într-un fişier text. Cei mai

importanţi constructori ai săi sunt:

creează un flux care scrie caractere in fişierul nume

public FileWriter (String nume) throws IOException

creează un flux care citeşte caractere din fişierul varFis

public FileWriter (File varFis) throws IOException

Exemplu 5: Citeşte caracter cu caracter un fişier în linia 8. Când valoarea

caracterului citit este –1 înseamnă că s-a ajuns la sfârşitul fişierului. Caracterele sunt

adăugate la un şir de caractere în linia 9, care la sfârşit este afişat.

1. import java.io.*;2. public class CitireFis {3. public static void main(String args[]) {4. int c; 5. StringBuffer s=new StringBuffer();6. try {7. FileReader in= new FileReader(”cit4.txt”);8. while((c=in.read())!=-1)9. s.append((char)c); 10. }11. catch(Exception e) {12. System.out.println(”Error:”+e.getMessage());13. }14. System.out.println(s); 15. }16. }

Exemplu 6: Copiază conţinutul unui fişier în alt fişier.

1. import java.io.*;2. public class CitireFis {3. public static void main(String[] args){4. try{5. FileReader in = new FileReader("cit4.txt");6. FileWriter out = new FileWriter("out.txt");7. int c;8. while ((c = in.read()) != -1)9. out.write(c);10. in.close();11. out.close();12. }

93

Page 94: Introducere în limbajul de programare Java

13. catch (IOException e) {14. System.out.println("Error: " + e.toString());15. }16. }17. }

8. Applet-uri

8.1. Ce este un applet?

Unul dintre scopurile limbajului Java a fost crearea unor programe mici

(applet) care să ruleze în interiorul unui browser Web.

Un applet reprezintă o suprafaţă de afişare (container) ce poate fi inclusă într-o

pagina Web şi gestionată printr-un program Java. Un astfel de program se mai

numeşte miniaplicaţie.

Codul unui applet poate fi format din una sau mai multe clase. Una dintre

acestea este principală şi extinde clasa JApplet, fiind clasa ce trebuie specificată în

documentul HTML ce descrie pagina de Web în care dorim să includem applet-ul.

Diferenţa fundamentală dintre un applet şi o aplicaţie constă în faptul că, un applet

nu poate fi executat independent, ci va fi executat de browser-ul în care este

încărcată pagina Web ce conţine applet-ul respectiv. O aplicaţie independentă este

executată prin apelul interpretorului java, având ca parametru numele clasei

principale a aplicaţiei, clasa principală fiind cea care conţine metoda main.

Un applet nu se poate atinge de hardisk-ul local prin citiri sau scrieri. Scrierea

este împiedicată din cauza viruşilor care s-ar putea instala, iar citirea deoarece nu se

doreşte preluarea de informaţii de pe staţia locală.

Un neajuns al applet-urilor ar putea fi timpul destul de lung necesar încărcării

lor. O metodă de înlăturare a acestui neajuns ar fi arhivarea applet-urilor într-un fişier

JAR (Java ARchive) care să cuprindă toate componentele. Astfel, fişierul compresat

este download-at la o singură tranzacţie cu server-ul.

Un avantaj al folosirii applet-urilor este lipsa necesităţii instalării lor. De fapt,

instalarea este automată de câte ori utilizatorul încarcă pagina Web care conţine

applet-ul.

Pachetul care oferă suport pentru crearea de applet-uri este javax.swing.

Clasa JApplet furnizează tot ce este necesar pentru construirea şi întreţinerea unui

94

Page 95: Introducere în limbajul de programare Java

applet. Crearea unui applet implică implementarea metodelor puse la dispoziţie de

clasa JApplet care ne ajută să descriem comportamentul dorit al applet-ului.

Ierarhia de clase este:

java.lang.Object | +--java.awt.Component | +--java.awt.Container | +--java.awt.Panel | +--java.applet.Applet | +--javax.swing.JApplet

8.2. Funcţiile unui applet

Execuţia unui applet începe în momentul în care un browser afişează o pagină

Web în care este inclus applet-ul respectiv şi poate trece prin mai multe etape.

Fiecare etapă este strâns legată de un eveniment generat de către browser şi

determină apelarea unei metode specifice din clasa ce implementează appletul.

Încărcarea în memorie – se creează o instanţă a clasei principale a

applet-ului şi se încarcă în memorie.

Iniţializarea – se apelează metoda init ce permite iniţializarea

diverselor variabile, citirea unor parametri de intrare, etc. Metoda init

este responsabilă şi pentru aşezarea tuturor componentelor pe formă.

Pornirea – se apelează metoda start

Execuţia propriu-zisă – constă în interacţiunea dintre utilizator şi

componentele afişate pe suprafaţa applet-ului.

Oprirea temporară – În cazul în care utilizatorul părăseşte pagina Web

în care rulează applet-ul se apelează metoda stop a acestuia, dându-i

astfel posibilitatea să se oprească temporar cât timp nu este vizibil,

pentru a nu consuma inutil din timpul procesorului. Acelaşi lucru se

întâmplă dacă fereastra browser-ului este minimizată. În momentul când

pagina Web ce conţine applet-ul devine din nou activă, va fi reapelată

metoda start.

95

Page 96: Introducere în limbajul de programare Java

Oprirea definitivă – La închiderea tuturor instanţelor browser-ului folosit

pentru vizualizare, applet-ul va fi eliminat din memorie şi va fi apelată

metoda destroy a acestuia, pentru a-i permite să elibereze resursele

deţinute. Apelul metodei destroy este întotdeauna precedat de apelul lui

stop.

8.3. Structura generală a unui applet

import javax.swing.JApplet;import java.awt.*;import java.awt.event.*;

public class StructuraApplet extends JApplet {

public void init() {/* codul descrie acţiunile care dorim să fie efectuate la instanţierea clasei

applet-ului. */

}

public void start() {/* codul descrie acţiunile care dorim să fie executate la lansarea applet-

ului în execuţie sau la reîntoarcerea în pagina applet-ului */

}

public void paint(Graphics g) {/* codul descrie acţiunile care dorim să fie executate la fiecare redesenare

a ferestrei applet-ului */

}

public void stop() {/* codul descrie acţiunile care dorim să fie executate la oprirea temporară

a applet-ului (pagina Web nu mai este vizibilă, fereastra browser-ului este

minimizată, etc) */

}

public void destroy() {/* codul descrie acţiunile care dorim să fie executate la distrugerea applet-

ului (browser-ul părăseşte documentul .html din care a fost apelat applet-ul) */

}

96

Page 97: Introducere în limbajul de programare Java

}

Observaţie: Aceste metode sunt apelate automat de browser şi nu trebuie

apelate explicit din program !

8.4. HTML

Un browser Web interpretează conţinutul (textul) unui fişier .html (Hyper Text

Markup Language). Limbajul HTML constă într-o colecţie de marcaje (tag-uri).

Marcajele au rolul de a descrie modul în care va apărea afişat textul, de a comanda

browser-ului să utilizeze şi alte resurse Internet, aflate în fişiere diferite.

Sintaxa unui marcaj este:

<NumeTag [parametri ]> text </NumeTag>

Parametrii se scriu sub forma:

NumeParametru = valoareStructura unui document .html este:

<HTML><HEAD>

<TITLE>titlul documentului

</TITLE></HEAD>

<BODY>. . .<APPLET parametrii>

<PARAM parametrii><PARAM parametrii>. . .<PARAM parametrii>

</APPLET>. . .

</BODY></HTML>

Considerăm cunoscute noţiunile de bază ale HTML. Ceea ce ne interesează

pentru construirea applet-urilor este marcajul <APPLET>. Acesta are parametrii

obligatorii şi opţionali.

Parametrii obligatorii:

97

Page 98: Introducere în limbajul de programare Java

CODE – valoarea lui este numele fişierului care conţine clasa applet-

ului: NumeClasa.class;

WIDTH – valoarea lui este lăţimea ferestrei atribuită de browser applet-

ului la afişarea documentului .html;

HEIGHT – valoarea lui este înălţimea ferestrei atribuită de browser

applet-ului la afişarea documentului .html;

Parametrii opţionali:

CODEBASE – valoarea lui este adresa URL (Universal Resource

Locator) sau calea la fişierul cu clasa applet-ului. Dacă parametru

lipseşte, căutarea clasei se face în directorul curent (cel din care a fost

încărcat fişierul .html);

VSPACE – valoarea lui este înălţimea zonei (exprimată în pixeli) care

se lasă liberă deasupra şi dedesubtul ferestrei applet-ului;

HSPACE – valoarea lui este lăţimea zonei (exprimată în pixeli) care se

lasă liberă în stânga şi în dreapta ferestrei applet-ului;

ALT – Specifică textul ce trebuie afişat dacă browser-ul înţelege

marcajul <APPLET> dar nu poate rula applet-uri Java.

NAME – Oferă posibilitatea de a da un nume respectivei instanţe a

applet-ului, astfel încât mai multe applet-uri aflate pe aceeaşi pagină să

comunice între ele folosindu-se de numele lor.

ALIGN – Semnifică modalitatea de aliniere a applet-ului în pagina Web.

Acest atribut poate primi una din următoarele valori: left, right, top, texttop, middle, absmiddle, baseline, bottom,

absbottom, semnificaţiile lor fiind aceleaşi ca şi la marcajul IMG.

Marcajul <PARAM> nu este obligatoriu şi poate să apară atunci când se

doreşte ca applet-ul să preia parametrii. Un parametru este definit prin:

NAME – reprezintă numele variabilei recunoscut de applet;

VALUE – reprezintă valoarea recepţionată de applet; este de tip String.

8.5. Exemple

Exemplu 1: Exemplifică ordinea apelării metodelor.

import javax.swing.*;

98

Page 99: Introducere în limbajul de programare Java

import java.awt.*;

public class app1 extends JApplet{ public void init(){

System.out.println("Sunt in init"); }

public void start(){System.out.println("Sunt in start");

} public void paint(Graphics g){ g.drawString("Sunt in paint", 20, 120);

System.out.println("Sunt in paint"); }

public void stop(){System.out.println("Sunt in stop");

} public void destroy(){

System.out.println("Sunt in destroy"); } }

Documentul .html este:

<HTML> <HEAD> <TITLE> Primul Applet </TITLE> </HEAD> <BODY> <APPLET CODE="app1.class" WIDTH=300 HEIGHT=200> </APPLET> </BODY>

</HTML>

Exemplu 2: Afişează nişte figuri geometrice.

import javax.swing.*;import java.awt.*;

public class app2 extends JApplet{ public void paint(Graphics g){ g.setColor(Color.red); g.drawRect(10,10,100,200); g.setColor(new Color(200,100,255)); g.fillRect(20,20,50,50); g.setColor(Color.blue); g.drawOval(60,60,50,50); }}

99

Page 100: Introducere în limbajul de programare Java

Documentul .html este:

<HTML> <HEAD> <TITLE> Figuri geometrice </TITLE> </HEAD> <BODY> <APPLET CODE="app2.class" WIDTH=300 HEIGHT=200> </APPLET> </BODY></HTML>

Exemplu 3: Afişează lista tuturor font-urilor cunoscute de sistem.

import java.awt.*;import javax.swing.*;

public class app3 extends JApplet{

public void init(){Container c=getContentPane();c.setLayout(new FlowLayout());JTextArea ta=new JTextArea();JScrollPane sp=new JScrollPane(ta);sp.setPreferredSize(new Dimension(100, 100));c.add(sp, BorderLayout.CENTER);GraphicsEnvironment gr=GraphicsEnvironment.

getLocalGraphicsEnvironment(); Font []f=gr.getAllFonts();for (int i=0;i<f.length;i++)

ta.append(f[i].getFontName()+"\n");}

}

Documentul .html este:

<HTML> <HEAD> <TITLE> Ce de mai font-uri !!! </TITLE> </HEAD> <BODY> <APPLET CODE="app3.class" WIDTH=300 HEIGHT=200> </APPLET> </BODY></HTML>

Exemplu 4: Setează un font şi îi tipăreşte caracteristicile.

import javax.swing.JApplet;import java.awt.Graphics;

100

Page 101: Introducere în limbajul de programare Java

import java.awt.Font;

public class app6 extends JApplet {private Font fon;

public void init(){ fon=new Font("Courier", Font.ITALIC + Font.BOLD, 24);}public void paint (Graphics g){

int stil, dim;String str, nume;

g.setFont (fon);stil = fon.getStyle();

if ( stil == Font.PLAIN)str = "Plin";

else if (stil == Font.BOLD)str = "Bold";

else if (stil == Font.ITALIC)str = "Italic";

elsestr = "Bold italic";

dim = fon.getSize();str += dim + " puncte ";nume = fon.getName();str += nume;

g.drawString (str, 20, 40);g.drawString ("Familia de font-uri este " +

fon.getFamily(), 20, 60);

}}

Documentul .html este:

<HTML> <HEAD> <TITLE> Ce font frumos !!! </TITLE> </HEAD> <BODY> <APPLET CODE="app6.class" WIDTH=700 HEIGHT=200> </APPLET> </BODY></HTML>

101

Page 102: Introducere în limbajul de programare Java

Exemplu 5: Desenează un poligon şi îl copiază într-o altă zonă a ferestrei.

import javax.swing.JApplet;import java.awt.*;

public class app7 extends JApplet {int xValues[] = {20, 40, 50, 30, 20, 15, 20};int yValues[] = {20, 20, 30, 50, 50, 30, 20};

private Polygon p2;

public void init (){

p2 = new Polygon();p2.addPoint (70, 70);p2.addPoint (90, 70);p2.addPoint (100, 80);p2.addPoint (80, 100);p2.addPoint (70, 100);p2.addPoint (65, 80);p2.addPoint (60, 60);

}public void paint (Graphics g){

//deseneaza conturul unui poligong.drawPolygon (xValues, yValues, 7); //deseneaza un poligong.fillPolygon (p2);//copiaza cele doua poligoane la noile coordonateg.copyArea (0, 0, 100, 100, 10,10 );

}}

Documentul .html este:

<HTML> <HEAD> <TITLE> Ce poligoane... </TITLE> </HEAD> <BODY> <APPLET CODE="app7.class" WIDTH=300 HEIGHT=200> </APPLET> </BODY></HTML>

Exemplu 6: Desenează un poligon şi îl copiază într-o altă zonă a ferestrei.

import javax.swing.JApplet;import java.awt.*;

public class app7 extends JApplet {

102

Page 103: Introducere în limbajul de programare Java

int xValues[] = {20, 40, 50, 30, 20, 15, 20};int yValues[] = {20, 20, 30, 50, 50, 30, 20};

private Polygon p2;

public void init (){

p2 = new Polygon();p2.addPoint (70, 70);p2.addPoint (90, 70);p2.addPoint (100, 80);p2.addPoint (80, 100);p2.addPoint (70, 100);p2.addPoint (65, 80);p2.addPoint (60, 60);

}public void paint (Graphics g){

//deseneaza conturul unui poligong.drawPolygon (xValues, yValues, 7); //deseneaza un poligong.fillPolygon (p2);//copiaza cele doua poligoane la noile coordonateg.copyArea (0, 0, 100, 100, 10,10 );

}}

Documentul .html este:

<HTML> <HEAD> <TITLE> Ce poligoane... </TITLE> </HEAD> <BODY> <APPLET CODE="app7.class" WIDTH=300 HEIGHT=200> </APPLET> </BODY></HTML>

Exemplu 7: Suma a două numere folosind preluarea parametrilor.

import javax.swing.*;import java.awt.*;

public class suma extends JApplet{ int m,n; String s; public void init(){ String sm=getParameter("m"),

103

Page 104: Introducere în limbajul de programare Java

sn=getParameter("n"); m=Integer.parseInt(sm); n=Integer.parseInt(sn); s=new Integer(m+n).toString(); }

public void paint(Graphics g){ g.drawString("Cmmdc = "+s, 50, 60 ); }}

Documentul .html este:

<HTML> <HEAD> <TITLE> Suma... </TITLE> </HEAD> <BODY> <APPLET CODE="suma.class" WIDTH=300 HEIGHT=200> <PARAM name="m" value="2"> <PARAM name="n" value="3"> </APPLET> </BODY></HTML>

104

Page 105: Introducere în limbajul de programare Java

9. Interfeţe grafice

9.1. Ce este o interfaţă grafică?

Interfaţa grafică se referă la toate tipurile de comunicare vizuală între un

program şi utilizatorii săi. Interfaţa grafică se referă nu numai la ceea ce utilizatorul

vede pe ecran ci şi la toate mecanismele de comunicare între acesta şi program.

Limbajul Java pune la dispoziţie numeroase clase pentru implementarea

diferitelor functionalităţi ale interfaţei grafice, însă ne vom ocupa în continuare de

acelea care permit realizarea unei intefeţe grafice cu utilizatorul (GUI – Graphical

User Interface).

În principiu, crearea unei aplicaţii grafice presupune următorii paşi:

1. crearea unei suprafeţe de afişare (cum ar fi o fereastră) pe care vor fi

aşezate obiectele grafice care servesc la comunicarea cu utilizatorul

(butoane, controale de editare, texte, etc);

2. crearea şi aşezarea obiectelor grafice pe suprafaţa de afişare în

poziţiile corespunzătoare;

3. definirea unor acţiuni care trebuie să se execute în momentul când

utilizatorul interacţionează cu obiectele grafice ale aplicaţiei;

4. "ascultarea" evenimentelor generate de obiecte în momentul

interacţiunii cu utilizatorul şi executarea acţiunilor corespunzătoare aşa

cum au fost ele definite.

În Java există două pachete de clase care oferă servicii grafice: java.awt şi

javax.swing. În acest curs ne vom ocupa de pachetul Swing care este o extensie a

pachetului awt. "Swing" a fost numele de cod dat proiectului care dezvolta

componente noi. Începând cu javax.swing este numele pachetelor pentru Swing

API.

105

Page 106: Introducere în limbajul de programare Java

Majoritatea obiectelor grafice sunt subclase ale clasei JComponent, clasă

care defineşte generic o componentă grafică care poate interacţiona cu utilizatorul.

Aşadar, printr-o componentă grafică vom înţelege orice obiect care are o

reprezentare grafică ce poate fi afişată pe ecran şi care poate interacţiona cu

utilizatorul. Exemple de componente sunt ferestrele, butoanele, bare de defilare, etc.

În general, toate componentele sunt definte de clase proprii ce se găsesc în pachetul

javax.swing, clasa JComponent fiind superclasa abstractă a tuturor acestor clase.

Crearea obiectelor grafice nu realizează automat şi afişarea lor pe ecran. Mai

întâi ele trebuie aşezate pe o suprafaţă de afişare, care poate fi o fereastră sau

suprafaţa unui applet, şi vor deveni vizibile în momentul în care suprafaţa pe care

sunt afişate va fi vizibilă. O astfel de suprafaţă pe care se aşează obiectele grafice

reprezintă o instanţă a unei clase obţinută prin extensia clasei Container; din acest

motiv suprafeţele de afişare vor mai fi numite şi containere. Clasa Container este o

subclasă aparte a clasei Component, fiind la rândul ei superclasa tuturor suprafeţelor

de afişare Java (ferestre, applet-uri, etc).

Pachetul Swing oferă programelor care folosesc componentele lui posibilitatea

să-şi aleagă natura interfeţei („look and feel”) sau, pur şi simplu, să o conserve pe

cea caracteristică platformei respective.

9.2. Primele aplicaţii Swing

9.2.1. Exemple

Exemplu 1: O aplicaţie de sine stătătoare, care nu utilizează applet-ul.

1. import javax.swing.*; 2. import java.awt.*;3. import java.awt.event.*;

4. public class SwingTest {5. private static String Prefix = "Numarul de click-

uri: ";6. private int nrClick = 0;7. JLabel eticheta = new JLabel(Prefix + "0 ");8. JButton buton = new JButton("Buton Swing!");9.10. public Component creazaComponente() {11. buton.addActionListener(new ActionListener() {

106

Page 107: Introducere în limbajul de programare Java

12. public void actionPerformed(ActionEvent e) {13. nrClick++;14. eticheta.setText(Prefix + nrClick);15. }16. });17. JPanel panou = new JPanel();18. panou.setBorder(BorderFactory.createEmptyBorder( 3

0,30,10,30));19. panou.setLayout(new FlowLayout());20. panou.add(buton);21. panou.add(eticheta);22. return panou;23. }//creazaComponente24.25. public static void main(String[] args) {26. try {27. UIManager.setLookAndFeel(

UIManager.getLookAndFeel());28. }catch (Exception e) { }29. JFrame frame = new JFrame("Prima aplicatie

Swing");30. SwingTest app = new SwingTest();31. Component comp = app.creazaComponente();32. frame.getContentPane().add(comp);33. frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } });34. frame.pack();35. frame.setVisible(true);36. }//main37. }//class

În linia 17 se crează un panel (panou) pe care vor fi aşezate componentele.

În linia 18 se setează marginea panel-ului cu dimensiunile pentru (sus,

stânga, jos, dreapta).

În linia 29 se crează container-ul principal (din vârful ierarhiei) şi în linia 32 se

adaugă componentele pe el.

În liniile 33–35 se încheie setările pentru frame şi se afişează.

Exemplu 2: O aplicaţie care utilizează applet-ul.

1. import javax.swing.*; 2. import java.awt.*;

3. public class SwingAppletTest extends JApplet {

107

Page 108: Introducere în limbajul de programare Java

4. public void init() {5. JLabel eticheta=new JLabel("O eticheta

frumoasa!");6. eticheta.setHorizontalAlignment(JLabel.CENTER);7.

label.setBorder(BorderFactory.createMatteBorder( 1,1,2,2,Color.black));

8. getContentPane().add(eticheta, BorderLayout.CENTER);

9. }10. }

9.2.2. Comentarea exemplelor

9.2.2.1 Alegerea naturii interfeţei

În codul următor se specifică natura interfeţei:

try { UIManager.setLookAndFeel( UIManager. getLookAndFeel()); } catch (Exception e) { }

9.2.2.2 Setarea container-ului principal (din vârful ierarhiei)

Orice program care prezintă o GUI Swing conţine cel puţin un container Swing.

În general, container-ele principale sunt instanţe ale lui JFrame, JDialog sau (pentru

appleturi) JApplet. Fiecare obiect JFrame implementează o singură fereastră

principală, fiecare obiect JDialog câte o fereastră secundară şi fiecare obiect

JApplet implementează un applet în cadrul unui browser. Container-ul principal

Swing furnizează suportul necesar componentelor Swing pentru a fi afişate şi pentru

a manipula evenimentele. În exemplu 1 container-ul folosit este JFrame şi este creat

în linia 29. În exemplu 2 container-ul folosit este JApplet (vezi linia 3).

Aplicaţiile Swing grupează etichetele şi butoanele într-un container (un

JPanel) înainte să le adauge pe frame. Adăugarea componentelor pe panel

înseamnă că ele vor fi controlate de manager-ul de layout al panel-ului. Manager-ul

de layout al unui container determină dimensiunea şi poziţia fiecărei componente

care este adăugată pe container.

108

Page 109: Introducere în limbajul de programare Java

9.2.2.3 Manipularea evenimentelor

Aplicaţia din exemplu 1 conţine două evenimente tratate. Una tratează click-ul

pe buton (action events); cealaltă tratează închiderea ferestrei (window events):

button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { numClicks++; label.setText(labelPrefix + numClicks); }});

...

frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {

System.exit(0); }});

9.3. Containere principale

După cum am văzut, suprafeţele de afişare ale componentelor grafice

(containerele) sunt extensii ale clasei Container.

Spre deosebire de un applet care îşi poate plasa componentele direct pe

suprafaţa de afişare a browser-ului în care rulează, o aplicaţie independentă are

nevoie de propriile ferestre pe care să facă afişarea componentelor sale grafice. O

astfel de suprafaţă pe care se aşează obiectele grafice se numeşte suprafaţă de

afişare sau container şi reprezintă o instanţă a unei clase obţinută prin extensia

superclasei Container.

Cele mai importante containere principale sunt: JFrame, JDialog,

JWindow şi JApplet. Ierarhia de clase este:

java.awt.Container|__ java.awt.Panel

|__ java.applet.Applet|__ javax.swing.JApplet

|__ java.awt.Window|__ java.awt.Frame| |__ javax.swing.JFrame|__ java.awt.Dialog| |__ javax.swing.JDialog|__ javax.swing.JWindow

109

Page 110: Introducere în limbajul de programare Java

9.3.1. Clasa JFrame

Clasa JFrame este folosită pentru implementarea ferestrelor principale.

Această componentă are caracteristic cadrul, bara de titlu şi controalele ferestrei

furnizate de sistemul de operare. Acestea nu pot fi modificate. Comportamentul

ferestrelor (redimensionare, minimizare, poziţionare) este controlat de sistemul de

operare.

Constructorii clasei JFrame sunt:

JFrame() – construieşte o fereastră, fără titlu, iniţial invizibilă.

JFrame(String title) – construieşte o fereastră, cu titlu specificat,

iniţial invizibilă.

Aşadar, o fereastră nou creată este invizibilă. Pentru a fi făcută vizibilă se va

apela metoda show().

Exemplu 3: Se construieşte şi se afişează o fereastră cu titlul "Prima

fereastra".

import javax.swing.*;public class AplJFrame {

public static void main(String args[]) {JFrame f = new JFrame("Prima fereastra");f.show();

}}

Câteva dintre metodele cele mai folosite ale clasei JFrame sunt prezentate în

continuare.

Metoda pack() este folosită pentru a da o dimensiune frame-ului. O

alternativă pentru pack() este setarea explicită a dimensiunii frame-ului prin

apelarea metodei setSize(). În general, folosirea lui pack() este preferabilă

folosirii lui setSize(), deoarece pack() lasă în seama layout manager-ului calculul

dimensiunii frame-ului care ţine seama şi de alţi factori care pot afecta dimensiunea

componentelor.

Metoda setVisible() este folosită pentru a afişarea frame-ului.

Metoda getContentPane() returnează obiectul contentPane al frame-ului.

Orice componentă se adaugă pe contentPane-ul frame-ului curent.

Exemplu 4:

110

Page 111: Introducere în limbajul de programare Java

import javax.swing.*; import java.awt.*;import java.awt.event.*;

public class AplicFrame{ public static void main(String[] args) { try { UIManager.setLookAndFeel( UIManager.getLookAndFeel()); } catch (Exception e) { }

/*Se creaza container-ul principal (din varful ierarhiei) si se adauga componentele pe el*/ JFrame frame = new JFrame();

JLabel comp = new JLabel("eticheta1"); JLabel comp1 = new JLabel("eticheta2");

//eticheta2 va fi pusa peste eticheta1 frame.getContentPane().add(comp); frame.getContentPane().add(comp1);

frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.pack(); frame.setVisible(true); }}

9.3.2. Ferestre secundare şi clasa JDialog

Pentru a crea ferestre secundare se foloseşte, de obicei, JDialog. Alte

ferestre secundare pot fi create cu:

JOptionPane – creează o fereastră standard de dialogProgressMonitor – creează o fereastră care arată progresul unei operaţii JColorChooser – creează o fereastră pentru alegerea culoriiJFileChooser – creează o fereastră pentru selectarea unui fişier

Exemplu 5:import javax.swing.*; import java.awt.*;import java.awt.event.*;

public class AplicJOptionPane{

111

Page 112: Introducere în limbajul de programare Java

public static void main(String[] args) { try { UIManager.setLookAndFeel( UIManager.getLookAndFeel()); } catch (Exception e) { }

JFrame frame = new JFrame(); JButton b=new JButton("Apasa-ma"); frame.getContentPane().add(b); b.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) {

JOptionPane.showMessageDialog(new Frame(),"Fereastra de informare"); } }); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.pack(); frame.setVisible(true); }}

Fiecare fereastră secundară este dependentă de una principală (de un frame).

O fereastră de dialog poate fi modală. Dacă este modală, ea blochează

accesul la oricare altă fereastră din program.

Cele mai simple ferestre modale pot fi create folosind una din metodele:

JOptionPane.showMessageDialog – fereastră modală înzestrată

cu un buton. Se poate specifica mesajul, icoana şi titlul ferestrei .

JOptionPane.showOptionDialog – fereastră modală înzestrată

cu butoane, mesaj, icoana şi titlul ferestrei. Pot fi modificate de

utilizator.

Exemplu 6:Object[] options = {"Da!!!","Niciodata!!!","Cine stie!!!"};int n=JOptionPane.showOptionDialog( new Frame(), "Ma parasesti?",

"Fereastra de Optiuni", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[2]);

112

Page 113: Introducere în limbajul de programare Java

JOptionPane.showConfirmDialog – fereastră modală înzestrată

cu două butoane.

Exemplu 7:JOptionPane.showConfirmDialog( null, "Alege un buton", "Fereastra de confirmare", JOptionPane.YES_NO_OPTION);

Parametrii folosiţi de aceste metode:

parentComponent: poate fi frame-ul care conţine fereastra de dialog

(ea este afişată pornind de la coordonatele ferestrei părinte) sau null

(se foloseşte un frame implicit şi fereastra de dialog este centrată pe

ecran);

message: mesajul care apare în fereastra de dialog;

messageType: defineşte stilul mesajului. Valori posibile sunt:

– ERROR_MESSAGE

– INFORMATION_MESSAGE

– WARNING_MESSAGE

– QUESTION_MESSAGE

– PLAIN_MESSAGE

optionType: defineşte mulţimea de butoane care apar pe fereastră:

– DEFAULT_OPTION

– YES_NO_OPTION

– YES_NO_CANCEL_OPTION

– OK_CANCEL_OPTION

Pot fi folosite şi alte tipuri de butoane;

options: descriere detaliată a mulţimii butoanelor afişate pe fereastră;

în general, este un vector de String-uri;

icon: icoana afişată pe fereastră;

title: titlul ferestrei;

initialValue: butonul selectat implicit.

113

Page 114: Introducere în limbajul de programare Java

Metodele showMessageDialog, showConfirmDialog şi showOptionDialog

returnează un întreg semnificând opţiunea utilizatorului. Valorile acestui întreg pot fi

YES_OPTION, NO_OPTION, CANCEL_OPTION, OK_OPTION şi CLOSED_OPTION.

Ferestre de dialog nemodale se pot crea cu JDialog.

JDialog este folosită pentru implementarea ferestrelor secundare (cum ar fi

dialog boxes şi alert boxes) şi a celor utilitare. Această componentă are

caracteristic cadrul şi bara de titlu furnizate de sistemul de operare. Aduce nou faţă

de clasa Dialog suportul pentru operaţia de închidere implicită.

Exemplu 8:import javax.swing.*;import java.awt.event.*;import java.awt.*;

public class Dialog{public static void main(String a[]){

final JFrame frame=new JFrame("Frame-ul meu"); Container contentPane = frame.getContentPane(); contentPane.setLayout(new GridLayout(1,1)); JButton Buton = new JButton("Apasa-ma!"); contentPane.add(Buton); Buton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("Apasa-ma!")) { final JDialog dialog=new JDialog(frame, "O fereastra copil",true);

Container c=dialog.getContentPane(); JLabel label=new JLabel("Eticheta frumoasa");

c.add(label); dialog.pack(); dialog.setVisible(true); } }

}); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } });

frame.pack(); frame.setVisible(true); }}

114

Page 115: Introducere în limbajul de programare Java

9.3.3. Clasa JWindow

Clasa JWindow este folosită pentru implementarea ferestrelor pline

(dreptunghiuri albe pline). Aceste ferestre nu conţin bară de titlu sau controale de

fereastră.

Exemplu 9:import javax.swing.*; import java.awt.*;import java.awt.event.*;

public class AplicJWindow { public static void main(String[] args) { try { UIManager.setLookAndFeel( UIManager.getLookAndFeel()); } catch (Exception e) { }

final JFrame frame=new JFrame("Frame-ul meu"); Container contentPane = frame.getContentPane(); contentPane.setLayout(new GridLayout(1,1)); JButton Buton = new JButton("Apasa-ma!"); contentPane.add(Buton); Buton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("Apasa-ma!")) {

JWindow win = new JWindow(); JRootPane pane=new JRootPane(); JLabel label=new JLabel("hasd"); pane.setLayout(new FlowLayout()); pane.add(label); win.getContentPane().add(pane); win.setSize(200,200); win.setVisible(true); } } }); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.pack(); frame.setVisible(true);

}}

115

Page 116: Introducere în limbajul de programare Java

9.3.4. Clasa JApplet

Clasa JApplet este folosită pentru implementarea applet-urilor. A se vedea

exemplul 2.

Forma containere-lor principale este ilustrată în figura următoare:

9.4. Containere intermediare

Sunt componente JFC folosite pentru organizarea ferestrelor. Container-ele

intermediare folosesc la împărţirea ferestrei în mai multe zone sau la gruparea

componentelor. Swing furnizează următoarele containere intermediare:

Panel – Este cel mai flexibil şi frecvent utilizat container

intermediar. Se implementează folosind clasa JPanel. Un

panel grupează componentele dintr-o fereastră sau dintr-un

alt panel. Un panel poate folosi orice layout manager şi poate

avea o margine (border).

116

Page 117: Introducere în limbajul de programare Java

Scroll Pane

– Furnizează scroll bar (orizontal şi vertical) pentru

componentele prea mari.

Split Pane

– Afişează două componente într-un spaţiu fix, oferind

utilizatorului posibilitatea să redimensioneze fiecare

componentă.

Tabbed Pane

– Conţine mai multe componente dar afişează numai

una la un moment dat. Utilizatorul poate alege între

componente.

Tool Bar

– Grupează componentele (în general butoane) într-o

linie sau o coloană, permiţând utilizatorului să o mute

oriunde.

Forma containere-lor intermediare este ilustrată în figura următoare:

Exemplu 10: Pentru JScrollPane

JFrame frame = new JFrame("Doar un exemplu");

117

Page 118: Introducere în limbajul de programare Java

JTextArea t = new JTextArea(20, 40); JScrollPane scrpane=new JScrollPane(t); scrpane.setPreferredSize(new Dimension(100, 100)); frame.getContentPane().add(scrpane); for(int i=0;i<100;i++) t.append(i+"\n");//(new Integer(i)).toString());

Exemplu 11: Pentru JSplitPane

JFrame frame = new JFrame("Doar un exemplu"); JTextArea t=new JTextArea(); for(int i=0;i<100;i++) t.append(i+"\n"); JLabel label=new JLabel("hjsdkljasldjasljdlafj"); JSplitPane splitpane=new JSplitPane(); splitpane.setOneTouchExpandable(true); splitpane.setLeftComponent(t); splitpane.setRightComponent(label); splitpane.setPreferredSize(new Dimension(100, 100)); frame.getContentPane().add(splitpane);

Exemplu 11: Pentru JTabbedPane

import javax.swing.JTabbedPane;import javax.swing.ImageIcon;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JFrame;

import java.awt.*;import java.awt.event.*;

public class AplicTabbed extends JPanel { public AplicTabbed() { JTabbedPane tabbedPane = new JTabbedPane();

Component panel1 = crearePanel("Salut"); tabbedPane.addTab("Unu", panel1); tabbedPane.setSelectedIndex(0);

Component panel2 = crearePanel("Salut Salut"); tabbedPane.addTab("Doi", panel2);

Component panel3 = crearePanel("Salut Salut Salut"); tabbedPane.addTab("Trei", panel3);

Component panel4 = crearePanel("Salut Salut Salut Salut"); tabbedPane.addTab("Patru", panel4);

//Se adauga tabbed pane-ul pe panel.

118

Page 119: Introducere în limbajul de programare Java

setLayout(new GridLayout(1, 1)); add(tabbedPane); }

protected Component crearePanel(String text) { JPanel panel = new JPanel(false); JLabel label = new JLabel(text); label.setHorizontalAlignment(JLabel.CENTER); panel.setLayout(new GridLayout(1, 1)); panel.add(label); return panel; }

public static void main(String[] args) { JFrame frame = new JFrame("Exemplu de TabbedPane"); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } });

frame.getContentPane().add( new AplicTabbed(), BorderLayout.CENTER); frame.setSize(400, 125); frame.setVisible(true); }}

Figura următoare ilustrează execuţia exemplului.

9.5. Folosirea gestionarilor de poziţionare (Layout Manager)

Un program poate avea interfeţe diferite, chiar dacă sunt folosite aceleaşi

componente. Acest lucru se datorează folosirii a diferiţi gestionari de poziţionare

care controlează dimensiunea şi poziţiile componentelor.

Gestionarea poziţionării este procesul prin care se determină dimensiunea şi

poziţia componentelor. Implicit, fiecare container are un gestionar de poziţionare –

un obiect care gestionează poziţionarea fiecărei componente de pe container. Acest

119

Page 120: Introducere în limbajul de programare Java

obiect implementează interfaţa LayoutManager. Acesta poate fi înlocuit cu altul care

să fie pe măsura cerinţelor. În general, se setează gestionarul de poziţionare pentru

două tipuri de containere: contentpane (foloseşte implicit BorderLayout) şi

JPanel (foloseşte implicit FlowLayout).

De câte ori se adaugă o componentă pe container trebuie ţinut cont de

gestionarul de poziţionare al containerului respectiv.

9.5.1. Setarea poziţionării (Layout Manager–ului)

Pentru schimbarea layout manager-ului folosit de un container se apelează

metoda setLayout. Metoda poate primi ca parametru orice instanţă a unei clase

care implementează interfaţa LayoutManager. Secvenţa de ataşare a unui gestionar

pentru un container este:

FlowLayout gestionar = new FlowLayout();container.setLayout(gestionar);

sau:

container.setLayout(new FlowLayout());

De exemplu:

JPanel jp = new JPanel();jp.setLayout(new BorderLayout());

Dacă argumentul este null, container-ul nu foloseşte un layout manager. În

acest caz trebuie specificate dimensiunile şi poziţiile fiecărei componente de pe

container.

Cei mai folosiţi gestionari în Java sunt: BorderLayout, BoxLayout,

FlowLayout, GridBagLayout şi GridLayout.

9.5.1.1 BorderLayout

BorderLayout este layout manager-ul implicit pentru fiecare container

principal. Un BorderLayout are cinci zone în care pot fi aşezate componentele:

nord, sud, est, vest şi centru.

Exemplu 12:1. import javax.swing.*;

120

Page 121: Introducere în limbajul de programare Java

2. import java.awt.*;3. import java.awt.event.*;

4. public class AplicBorderLayout extends JFrame{5. public static void main(String[] args) {6. AplicBorderLayout f=new AplicBorderLayout();7. Container contentPane = f.getContentPane();8. contentPane.setLayout(new BorderLayout());9. contentPane.add(new JButton("Buton 1 NORD"), BorderLayout.NORTH);10. contentPane.add(new JButton("2 CENTRU"), BorderLayout.CENTER);11. contentPane.add(new JButton("Buton 3 VEST"), BorderLayout.WEST);12. contentPane.add(new JButton("Buton 4 SUD"), BorderLayout.SOUTH);13. contentPane.add(new JButton("Buton 5 EST"),

BorderLayout.EAST);14. f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } });15. f.setSize(400, 125);16. f.setVisible(true);17. }18. }

Ţinând cont că pentru frame-uri gestionarul implicit este BorderLayout, linia 8

nu mai este necesară. Rezultatul execuţiei acestui program este:

9.5.1.2 BoxLayout

Gestionarul BoxLayout aşează componentele pe o singură linie sau coloană.

Respectă dimensiunile minime ale componentelor şi permite alinierea lor.

Exemplu 13:

121

Page 122: Introducere în limbajul de programare Java

import javax.swing.*;import java.awt.*;import java.awt.event.*;

public class AplicBoxLayout extends JFrame{ private static void adaugBut(String text, Container container, float unde) { JButton button = new JButton(text); button.setAlignmentX(unde); container.add(button); } public static void main(String[] args) { AplicBoxLayout f=new AplicBoxLayout(); Container contentPane = f.getContentPane(); contentPane.setLayout(new BoxLayout( contentPane, BoxLayout.Y_AXIS)); adaugBut("Buton 1", contentPane, Component.CENTER_ALIGNMENT); adaugBut("2", contentPane,Component.RIGHT_ALIGNMENT); adaugBut("Buton 3", contentPane, Component.LEFT_ALIGNMENT); adaugBut("Buton 4 foarte lung", contentPane, Component.CENTER_ALIGNMENT); adaugBut("Buton 5", contentPane, Component.LEFT_ALIGNMENT); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0);} }); f.pack(); f.setVisible(true); }}

Rezultatul execuţiei acestui program este:

122

Page 123: Introducere în limbajul de programare Java

9.5.1.3 CardLayout

Clasa CardLayout permite implementarea unei arii care conţine diferite

componente la momente diferite. Tabbed pane-urile sunt containere intermediare

care furnizează o funcţionalitate similară. Un CardLayout este în general controlat

de un Combo Box, starea lui determinând panel-ul de afişat.

Exemplu 14:import java.awt.*;import java.awt.event.*;import javax.swing.*;

public class AplicCardWindow extends JFrame implements ItemListener { JPanel cards; String BUTONPANEL = "Panel cu Butoane"; String TEXTPANEL = "Panel cu TextField-uri";

public AplicCardWindow() { Container contentPane = getContentPane(); String comboBoxItems[] = { BUTONPANEL, TEXTPANEL }; JPanel cbp = new JPanel(); JComboBox c = new JComboBox(comboBoxItems); c.setEditable(false); c.addItemListener(this); cbp.add(c);

contentPane.add(cbp, BorderLayout.NORTH);

cards = new JPanel(); cards.setLayout(new CardLayout()); JPanel p1 = new JPanel(); p1.add(new JButton("Buton 1")); p1.add(new JButton("Buton 2")); p1.add(new JButton("Buton 3"));

JPanel p2 = new JPanel(); p2.add(new JTextField("TextField", 20));

cards.add(p1, BUTONPANEL); cards.add(p2, TEXTPANEL); contentPane.add(cards, BorderLayout.CENTER); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } });

123

Page 124: Introducere în limbajul de programare Java

}

public void itemStateChanged(ItemEvent evt) { CardLayout cl = (CardLayout)(cards.getLayout()); cl.show(cards, (String)evt.getItem()); }

public static void main(String args[]) { AplicCardWindow window = new AplicCardWindow(); window.setTitle("CardLayout"); window.pack(); window.setVisible(true); }}

În imaginea următoare se văd cele două stări ale ferestrei în funcţie de starea

Combo Box-ului:

9.5.1.4 FlowLayout

FlowLayout este layout manager-ul implicit pentru orice JPanel. Aşează

componentele de la stânga spre dreapta, de sus în jos.

Exemplu 15:import javax.swing.*;import java.awt.*;import java.awt.event.*;

public class AplicFlowLayout extends JFrame{ private static void adaugBut(String text, Container container){ JButton button = new JButton(text); container.add(button); } public static void main(String[] args) { AplicFlowLayout f=new AplicFlowLayout(); Container contentPane = f.getContentPane(); contentPane.setLayout(new FlowLayout()); adaugBut("Buton 1", contentPane); adaugBut("2", contentPane);

124

Page 125: Introducere în limbajul de programare Java

adaugBut("Buton 3", contentPane); adaugBut("Buton 4 foarte lung", contentPane); adaugBut("Buton 5", contentPane);

f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0);} }); f.pack(); f.setVisible(true); }

}

Rezultatul execuţiei acestui program este:

9.5.1.5 GridLayout

GridLayout-ul aşează componentele în celulele unui tabel. Fiecare

componentă ocupă tot locul disponibil din celulă. Toate celulele au aceeaşi

dimensiune. La redimesionarea ferestrei GridLayout-ului, celulele îşi vor schimba

dimensiunile astfel încât să fie ocupat tot spaţiul ferestrei.

Clasa GridLayout are doi constructori:

public GridLayout(int rows, int columns)public GridLayout(int rows, int columns,

int horizontalGap, int verticalGap)

Cel puţin unul din cele două argumente rows şi columns trebuie să fie nenul.

Argumentele horizontalGap şi verticalGap din cel de-al doilea constructor permit

specificarea numărului de pixeli dintre celule. Implicit ele au valoarea 0.

Exemplu 16:import javax.swing.*;import java.awt.*;import java.awt.event.*;

public class AplicGridLayout extends JFrame{ public static void main(String[] args) {

125

Page 126: Introducere în limbajul de programare Java

AplicGridLayout f=new AplicGridLayout(); Container contentPane = f.getContentPane(); contentPane.setLayout(new GridLayout(0,2)); contentPane.add(new JButton("Buton 1")); contentPane.add(new JButton("2")); contentPane.add(new JButton("Buton 3")); contentPane.add(new JButton("Buton 4 foarte lung")); contentPane.add(new JButton("Buton 5")); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0);} }); f.pack(); f.setVisible(true); }}

Rezultatul execuţiei acestui program este:

Constructorul apelat creează o instanţă a lui GridLayout care are două

coloane şi oricâte linii sunt necesare – new GridLayout(0,2).

9.5.1.6 GridBagLayout

GridBagLayout este cel mai sofisticat şi flexibil layout manager pe care

platforma Java îl furnizează. Aşează componentele în celulele unui tabel, fiecare

componentă putând să ocupe mai multe celule. Liniile / coloanele tabelului nu este

obligatoriu să aibă aceeaşi înălţime / lăţime. Pentru fiecare componentă care se

adaugă pe fereastră se setează o serie de constrângeri prin crearea unui obiect al

clasei GridBagConstraints. Aceeaşi instanţă a lui GridBagConstraints

poate fi folosită pentru mai multe componente, chiar dacă ele au constrângeri

diferite. GridBagLayout extrage valorile constrângerilor şi nu refoloseşte

GridBagConstraints. Clasa conţine următoarele atribute care pot fi setate:

126

Page 127: Introducere în limbajul de programare Java

gridx, gridy – Specifică linia şi coloana colţului din stânga sus a

componentei. Coloana cea mai din stânga are gridx=0 iar linia cea mai de sus are

gridy=0.

gridwidth, gridheight – Reprezintă numărul de coloane (pentru

gridwidth) sau de linii (pentru gridheight) pe care va fi afişată componenta. Valoarea

implicită este 1.

fill – Este folosită atunci când aria de afişare a componentei este mai mare

decât dimensiunea cerută, pentru a determina cum poate fi redimensionată

componenta. Valorile valide sunt:

NONE (implicit),

HORIZONTAL (măreşte componenta pe orizontală astfel încât să

acopere întreaga suprafaţă disponibilă dar nu schimbă înălţimea),

VERTICAL (măreşte componenta pe verticală astfel încât să

acopere întreaga suprafaţă disponibilă dar nu schimbă lăţimea),

BOTH (măreşte componenta astfel încât să acopere întreaga

suprafaţă disponibilă.

ipadx, ipady – Folosite pentru redimensionarea celulelor. Specifică cât

trebuie adunat la dimensiunea minimă a componentei. Valoarea implicită este 0.

Lăţimea / înălţimea va avea valoarea minimă plus ipadx*2 / ipady*2 pixeli (se aplică

în ambele capete ale componentei).

insets – Specifică distanţa dintre componentă şi colţurile suprafeţei pe care

se afişează. Valoarea atribuită este un obiect Insets.

anchor – Este folosită atunci când componenta este mai mică decât suprafaţa

pe care urmează să fie afişată, pentru a determina unde se plasează componenta.

Valori valide sunt CENTER (implicit), NORTH, NORTHEAST, EAST, SOUTHEAST,

SOUTH, SOUTHWEST, WEST şi NORTHWEST.

weightx, weighty – Folosite pentru a determina modul în care să fie

repartizat spaţiul dintre coloane / linii. Dacă nu se specifică nici o valoare (implicit

este 0) atunci toate componentele vor fi grupate în centru container-ului deoarece

GridBagLayout pune orice spaţiu în plus între tabel şi colţurile container-ului.

Exemplu 17:import java.awt.*;import java.awt.event.*;

127

Page 128: Introducere în limbajul de programare Java

import javax.swing.*;

public class AplicGridBagLayout extends JFrame { final boolean shouldFill = true; final boolean shouldWeightX = true; public AplicGridBagLayout() { JButton buton; Container contentPane = getContentPane(); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); contentPane.setLayout(gridbag); if (shouldFill) { //inaltime implicita, latime maxima c.fill = GridBagConstraints.HORIZONTAL; } buton = new JButton("Buton 1"); if (shouldWeightX) { c.weightx = 0.5; } c.gridx = 0; c.gridy = 0; gridbag.setConstraints(buton, c); //constrangerile impuse sunt atasate componentei contentPane.add(buton);

buton = new JButton("2"); c.gridx = 1; c.gridy = 0; gridbag.setConstraints(buton, c); contentPane.add(buton);

buton = new JButton("Buton 3"); c.gridx = 2; c.gridy = 0; gridbag.setConstraints(buton, c); contentPane.add(buton);

buton = new JButton("Buton 4 foarte lung"); c.ipady = 40; //seteaza cu cat va creste inaltimea componentei c.weightx = 0.0; c.gridwidth = 3; c.gridx = 0; c.gridy = 1; gridbag.setConstraints(buton, c); contentPane.add(buton);

buton = new JButton("Button 5"); c.ipady = 0; //se revine la inaltimea implicita

128

Page 129: Introducere în limbajul de programare Java

c.weighty = 1.0; //spatiu vertical intre celule suplimentar c.anchor = GridBagConstraints.SOUTH; //componenta va fi plasata in partea de jos a ferestrei c.insets = new Insets(10,0,0,0); c.gridx = 1; //componenta se alinieaza cu butonul 2 c.gridwidth = 2; //ocupa latimea a doua butoane c.gridy = 2; //se afla pe a treia linie gridbag.setConstraints(buton, c); contentPane.add(buton);

addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); }

public static void main(String args[]) { AplicGridBagLayout window = new AplicGridBagLayout(); window.setTitle("Exemplu GridBagLayout"); window.pack(); window.setVisible(true); }}

Rezultatul execuţiei acestui program este:

9.6. Tratarea evenimentelor

Apăsarea unei taste sau a unui buton al mouse-ului declanşează un

eveniment. Pentru a trata evenimentul este necesar un obiect care să implementeze

interfaţa corespunzătoare şi să fie înregistrat ca un consumator de evenimente

129

Page 130: Introducere în limbajul de programare Java

(event listener). Componentele Swing pot genera mai multe tipuri de evenimente.

Câteva dintre interfeţele corespunzătoare ar fi:

ActionListener acţiuni asupra unui control (click pe un

buton, Enter după introducerea unui text într-

un câmp, selectarea într-un meniu)

ComponentListener redimensionări, deplasări, ascunderi ale

unei componente

FocusListener preluare / pierdere focus

ItemListener selecţie / deselecţie obiect în listă,

meniu, etc.

TextListener modificarea textului din control

AdjustmentListener modificarea unei valori variind între

două limite (ex: ScrollBar)

KeyListener acţionarea unei taste

MouseListener apăsarea butonului mouse-ului în timp

ce cursorul se află pe componenta respectivă

MouseMotionListener drag; mişcarea mouse-ului pe o

componentă

WindowListener închidere, minimizare, maximizare etc.

ContainerListener adăugare, ştergere componentă

ListSelectionListener schimbarea selecţiei într-o tabelă sau

într-o listă

Fiecare eveniment este reprezentat de un obiect care dă informaţii despre

eveniment şi identifică sursa evenimentului. Fiecare generator de eveniment poate

avea mai mulţi consumatori.

generator obiect eveniment /----> consummator de evenimentde eveniment------------------------------------------> consummator de eveniment

\----> consummator de eveniment

130

Page 131: Introducere în limbajul de programare Java

Un eveniment, o dată apărut, este distribuit tuturor ascultătorilor înregistraţi (nu

este consumat numai de primul).

Aşa cum am spus mai devreme, pentru ca evenimentele unei componente să

fie interceptate de către o instanţă a unei clase ascultător, această clasă trebuie

înregistrată în lista ascultătorilor componentei respective. Am spus listă, deoarece

evenimentele unei componente pot fi ascultate de oricâte clase - cu condiţia ca

acestea să fie înregistrate la componenta respectivă. Înregistrarea unei clase în lista

ascultătorilor unei componente se face cu metode din clasa Component de tipul

addXXXListener, iar eliminarea ei din aceasta lista cu removeXXXListener unde

XXX reprezintă tipul evenimentului.

9.6.1. Exemplu de tratare a unui eveniment

Sunt necesari următorii paşi:

1. Clasa trebuie să implementeze interfaţa corespunzătoare sau să

extindă o clasă care implementează interfaţa.

public class NumeClasa implements ActionListener {...}

2. Scrierea codului care înregistrează o instanţă a clasei (care va

consuma evenimentul) ca şi consumator pentru una sau mai multe componente.

Componenta.addActionListener(instantaNumeClasa);

3. Scrierea codul care implementează metodele din interfaţa

consumator.

public void actionPerformed(ActionEvent e) { //cod care reacţioneaza la acţiune}

Exemplu 18:

import javax.swing.*;import java.awt.*;

131

Page 132: Introducere în limbajul de programare Java

import java.awt.event.*;

public class AplicEv extends JFrame{

JButton uB,lB,rB;JPanel pbut;JTextField txt;Listener lsn;TextWorker txtWorker;

public AplicEv() {uB=new JButton("Majuscule"); lB=new JButton("Minuscule"); rB=new JButton("Sterge");uB.setActionCommand("ActMajuscule");lB.setActionCommand("ActMinuscule"); pbut=new JPanel();pbut.add(uB);pbut.add(lB);pbut.add(rB);txt= new JTextField("Introduceti text!");lsn=new Listener();getContentPane().setLayout(new BorderLayout());getContentPane().add("North",txt);getContentPane().add("Center",lsn);getContentPane().add("South",pbut);txtWorker=new TextWorker(txt);rB.addActionListener(lsn);uB.addActionListener(lsn);lB.addActionListener(lsn);

rB.addActionListener(txtWorker);uB.addActionListener(txtWorker);lB.addActionListener(txtWorker);

} public static void main(String[] args) { AplicEv f=new AplicEv(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.addWindowListener(f.lsn);

f.setSize(400, 125); //f.pack(); f.setVisible(true); }}

class TextWorker implements ActionListener { private JTextField txt;

132

Page 133: Introducere în limbajul de programare Java

public TextWorker(JTextField txt){ this.txt=txt; } public void actionPerformed(ActionEvent e){ String c=e.getActionCommand(); if(c.equals("Sterge")) txt.setText(""); if(c.equals("ActMajuscule")){ String oldText=txt.getText(); String uText=oldText.toUpperCase(); txt.setText(uText); } if(c.equals("ActMinuscule")){ String oldText=txt.getText(); String lText=oldText.toLowerCase(); txt.setText(lText); } }}

class Listener extends JTextArea implements ActionListener, WindowListener{

public Listener(){super();this.setEditable(false);

}public void actionPerformed(ActionEvent e){

append(e.paramString()+" [ "+e.toString()+" ]\n");}public void windowClosed(WindowEvent e){

append(e.paramString()+" [ "+e.toString()+" ]\n");}public void windowOpened(WindowEvent e){

append(e.paramString()+" [ "+e.toString()+" ]\n");}public void windowClosing(WindowEvent e){

append(e.paramString()+" [ "+e.toString()+" ]\n");}public void windowIconified(WindowEvent e){

append(e.paramString()+" [ "+e.toString()+" ]\n");}public void windowDeiconified(WindowEvent e){

append(e.paramString()+" [ "+e.toString()+" ]\n");}public void windowActivated(WindowEvent e){

append(e.paramString()+" [ "+e.toString()+" ]\n");}public void windowDeactivated(WindowEvent e){

append(e.paramString()+" [ "+e.toString()+" ]\n");}

}

133

Page 134: Introducere în limbajul de programare Java

Rezultatul execuţiei programului este:

9.7. Folosirea componentelor

9.7.1. Clasa JLabel

Un obiect de tip JLabel (etichetă) reprezintă o componentă pentru plasarea

unui text pe o suprafaţă de afişare. O etichetă este formată dintr-o singură linie de

text static ce nu poate fi modificat de către utilizator, dar poate fi modificat din

program.

9.7.2. Clasa JButton

Un obiect de tip JButton (buton) reprezintă o componentă pentru plasarea

unui buton etichetat pe o suprafaţă de afişare.

9.7.3. Clasa JTextField

Un obiect de tip JTextField defineşte un control de editare a textului pe o

singură linie. Este util pentru interogarea utilizatorului asupra unor valori.

9.7.4. Clasa JTextArea

Un obiect de tip JTextArea defineşte un control de editare a textului pe mai

multe linii. Este util pentru editarea de texte, introducerea unor comentarii, etc .

9.7.5. Clasa JCheckBox

134

Page 135: Introducere în limbajul de programare Java

Un obiect de tip JCheckbox (comutator) reprezintă o componentă care se

poate afla în două stări : "selectată" sau "neselectată" (on/off). Acţiunea utilizatorului

asupra unui comutator îl trece pe acesta în starea complementară celei în care se

găsea. Este folosit pentru a prelua o anumită opţiune de la utilizator.

9.7.6. Clasa JRadioButton

Un obiect de tip JRadioButton defineşte un grup de comutatoare din care

doar unul poate fi selectat. Uzual, aceste componente se mai numesc radio butoane.

9.7.7. Clasa JComboBox

Un obiect de tip JComboBox defineşte o listă de opţiuni din care utilizatorul

poate selecta una singură. La un moment dat, din întreaga lista doar o singură

opţiune este vizibilă, cea selectată. O componentă JComboBox este însoţită de un

buton etichetat cu o săgeată verticală la apăsarea căruia este afişată întreaga sa

listă, pentru ca utilizatorul să poată selecta o anumită opţiune.

9.7.8. Clasa JList

Un obiect de tip JList defineşte o listă de opţiuni care poate fi setată astfel

încât utilizatorul să poată selecta o singură opţiune sau mai multe. Toate opţiunile

listei sunt vizibile în limita dimensiunilor grafice ale componentei.

9.7.9. Clasa JScrollBar

Un obiect de tip JScrollbar defineşte o bară de defilare verticală sau

orizontală. Este utilă pentru punerea la dispoziţie a utilizatorului a unei modalităţi

sugestive de a alege o anumită valoare dintr-un interval.

1. Introducere în limbajul de programare Java..............................................1

135

Page 136: Introducere în limbajul de programare Java

1.1. Ce este Java?.....................................................................................1

1.2. Limbajul de programare Java.............................................................1

1.3. Java : un limbaj compilat şi interpretat...............................................3

1.4. Istoria limbajului Java.........................................................................3

1.5. Mediul Java........................................................................................4

1.6. Crearea unei aplicaţii simple..............................................................4

1.7. Crearea unui applet............................................................................5

2. Programarea Orientată pe Obiecte şi Java...............................................7

2.1. Obiecte şi clase..................................................................................7

2.2. Atribute şi comportamente..................................................................8

2.2.1. Atribute...........................................................................................8

2.2.2. Comportament................................................................................9

2.3. Principiile OOP...................................................................................9

3. Elementele de bază ale limbajului de programare Java..........................11

3.1. Structura lexicală a limbajului...........................................................11

3.1.1. Setul de caractere........................................................................11

3.1.2. Cuvinte cheie................................................................................11

3.1.3. Identificatori..................................................................................11

3.1.4. Constante.....................................................................................11

3.1.5. Separatori.....................................................................................13

3.1.6. Operatori......................................................................................13

3.1.7. Comentarii....................................................................................17

3.2. Tipuri de date....................................................................................17

3.3. Variabile............................................................................................18

3.4. Instrucţiuni........................................................................................20

3.4.1. Instrucţiunea vidă.........................................................................20

3.4.2. Instrucţiuni de decizie...................................................................20

3.4.3. Instrucţiuni repetitive....................................................................24

3.5. Tablouri (vectori)...............................................................................28

3.5.1. Tablouri (vectori) unidimensionale...............................................28

3.5.2. Tablouri (vectori) cu mai multe dimensiuni...................................30

3.5.3. Dimensiunea unui vector..............................................................30

3.5.4. Tablouri cu dimensiuni variabile...................................................32

136

Page 137: Introducere în limbajul de programare Java

3.6. Şiruri de caractere............................................................................32

4. Clase şi obiecte în Java...........................................................................34

4.1. Referinţe...........................................................................................34

4.2. Obiecte.............................................................................................35

4.2.1. Noţiuni generale...........................................................................35

4.2.2. Operatorul de atribuire =..............................................................36

4.2.3. Operatorul de egalitate ==............................................................37

4.3. Clase................................................................................................38

4.3.1. Definirea claselor..........................................................................38

4.3.2. Variabile membru.........................................................................40

4.3.3. Metode.........................................................................................42

4.3.3.1 Definirea metodelor................................................................42

4.3.3.2 Modificatorii metodelor............................................................42

4.3.3.3 Tipul returnat de o metodă......................................................43

4.3.3.4 Parametrii unei metode...........................................................44

4.3.4. Constructorii unei clase................................................................45

4.3.5. Obiectul this...............................................................................47

4.3.6. Supraîncărcarea şi supradefinirea metodelor..............................49

4.3.7. Modificatori de acces pentru membrii unei clase.........................50

4.3.8. Membrii instanţă şi membrii clasă................................................51

4.3.9. Argumente în linia de comandă....................................................53

4.4. Moştenirea........................................................................................56

4.4.1. Principiul moştenirii......................................................................56

4.4.2. Interfeţe........................................................................................60

4.5. Probleme..........................................................................................63

5. Pachete....................................................................................................70

5.1. Importul unui pachet, al unei clase sau a unei interfeţe...................71

5.2. Crearea unui pachet.........................................................................72

6. Excepţii...............................................................................................77

6.1. Aspecte generale..............................................................................77

6.2. Instrucţiunea try................................................................................78

6.3. Crearea unei excepţii........................................................................80

7. INTRĂRI ŞI IEŞIRI...................................................................................83

137

Page 138: Introducere în limbajul de programare Java

7.1. Clasificarea fluxurilor........................................................................84

7.2. Ierarhia claselor pentru lucru cu fluxuri.............................................85

7.2.1. Fluxuri de caractere......................................................................85

7.2.2. Fluxuri de octeţi............................................................................86

7.3. Superclasele de intrare / ieşire.........................................................87

7.4. Crearea unui flux..............................................................................87

7.5. Citirea datelor de la tastatură...........................................................88

7.5.1. Obiectul System.in......................................................................88

7.5.2. Clasa InputStreamReader......................................................89

7.5.3. Clasa BufferedReader.............................................................90

7.6. Citirea şi scrierea datelor din fişier...................................................91

7.6.1. Clasele FileReader şi FileWriter......................................91

8. APPLET-URI..................................................................................92

8.1. Ce este un applet?...........................................................................92

8.2. Funcţiile unui applet..........................................................................94

8.3. Structura generală a unui applet......................................................94

8.4. HTML................................................................................................95

8.5. Exemple............................................................................................97

9. Interfeţe grafice......................................................................................103

9.1. Ce este o interfaţă grafică?............................................................103

9.2. Primele aplicaţii Swing....................................................................105

9.2.1. Exemple.....................................................................................105

9.2.2. Comentarea exemplelor.............................................................106

9.2.2.1 Alegerea naturii interfeţei......................................................106

9.2.2.2 Setarea container-ului principal (din vârful ierarhiei)............107

9.2.2.3 Manipularea evenimentelor..................................................107

9.3. Containere principale......................................................................107

9.3.1. Clasa JFrame............................................................................108

9.3.2. Ferestre secundare şi clasa JDialog.......................................110

9.3.3. Clasa JWindow..........................................................................113

9.3.4. Clasa JApplet..........................................................................114

9.4. Containere intermediare.................................................................115

138

Page 139: Introducere în limbajul de programare Java

9.5. Folosirea gestionarilor de poziţionare (Layout Manager)...............118

9.5.1. Setarea poziţionării (Layout Manager–ului)...............................119

9.5.1.1 BorderLayout........................................................................119

9.5.1.2 BoxLayout.............................................................................120

9.5.1.3 CardLayout...........................................................................121

9.5.1.4 FlowLayout...........................................................................123

9.5.1.5 GridLayout............................................................................124

9.5.1.6 GridBagLayout......................................................................125

9.6. Tratarea evenimentelor..................................................................128

9.6.1. Exemplu de tratare a unui eveniment.........................................130

9.7. Folosirea componentelor................................................................132

9.7.1. Clasa JLabel...............................................................................132

9.7.2. Clasa JButton.............................................................................133

9.7.3. Clasa JTextField.........................................................................133

9.7.4. Clasa JTextArea.........................................................................133

9.7.5. Clasa JCheckBox.......................................................................133

9.7.6. Clasa JRadioButton....................................................................133

9.7.7. Clasa JComboBox......................................................................134

9.7.8. Clasa JList..................................................................................134

9.7.9. Clasa JScrollBar.........................................................................134

139


Recommended