Sunteți pe pagina 1din 146

10/12/2015

Obiective

• Aprofundarea programarii orientata obiect


(limbajele Java si C#).

Metode Avansate de Programare • Programare dirijata de evenimente - Interfete grafice.

• Sabloane de proiectare.

Suport de curs • Programare paralela bazata pe threaduri.

• Introducere in analiza si proiectarea sistemelor soft folosind paradigma


Virginia Niculescu orientata obiect.

V. Niculescu - MAP 1 V. Niculescu - MAP 2

Evaluarea
Activitati asociate cursului

• Curs
– Prezenta obligatorie • Examen final in sesiune:
• Laborator: – Scris – nota ES
– Prezenta obligatorie – Practic- nota EP
– Teme de laborator – nota pentru fiecare L1, L2, …
• Media (ponderata) lor va fi notata cu LL – Nota Finala
– Proiect – nota LP
• Seminar: N = (LL*30 + LP*15 + ES*25+ EP*30)/100 +S
– Prezenta obligatorie
– Activitatea – poate conduce la cresterea finala a notei finale cu pana la 1 punct-
S

V. Niculescu - MAP 3 V. Niculescu - MAP 4

1
10/12/2015

Analiza si Proiectare
Cateva referinte…
• “Cine va folosi sistemul?" (pentru a descoperi actorii)
• Bruce Eckel, Thinking in Java, Ed. Prentice Hall, 4thedition, 2006. • “Ce pot face acesti actori cu sistemul?"
• Larry O’Brien and Bruce Eckel, Thinking in C#, Ed. Prentice Hall, 2002. • “Cum poate sistemul reactiona daca altcineva face acestea?"
• E. Gamma, R. Helm, R. Johnson, J. Vlissides, DesignPatter ns – Elements of (pentru a descoperi variatiile)
Reusable Object Oriented Software, Ed. Addison Wesley, 1994. • “Ce probleme pot apare in sistem?"
• Kent Beck, Test Driven Development: By Example, Ed. Addison-Wesley Professional, (pentru a descoperi exceptiile)
2002.
• Craig Larman, Applying UML and Patterns: An Introduction to Object-Oriented
Analysis and Design and Iterative Development, Ed. Addison Wesley,2004. 1. Descoperirea obiectelor
• Tutoriale Java si C# 2. Asamblarea obiectelor
http://download.oracle.com/javase/tutorial/ 3. Constructia sistemului
http://msdn.microsoft.com/en-us/library/aa288436%28v=vs.71%29.aspx 4. Extensia sistemului
5. Reutilizarea obiectelor

V. Niculescu - MAP 5 V. Niculescu - MAP 6

Limbajul JAVA
LOO Pur

• C++  limbaj de programare orientat-obiect hibrid Caracteristici:


Programare OO pura (Alan Kay): − simplu,
ex. - Smalltalk − object-oriented,
• Orice este un obiect!!! − distribuit si dinamic,
• Un program este o colectie de obiecte care isi trimit mesaje unul altuia. − interpretat,
• Fiecare obiect are propria memorie care contine alte obiecte. − robust,
• Orice obiect are un tip. − sigur,
• Toate obiectele de un tip particular pot primi acelasi set de mesaje. (Substitutie) − independent de arhitectura,
− portabil,
Java  ‘aproape’ un LOO pur
C# -> ~ LOO pur − high-performance,
− multithreaded

V. Niculescu - MAP 7 V. Niculescu - MAP 8

2
10/12/2015

Java este un limbaj interpretat Cum se executa un program Java?

• Compilatorul Java genereaza byte-code pentru Java Virtual Machine (JVM - interpretorul si
sistemul run-time), si nu cod masina.
bytecode
• A executa un program Java = interpretorul Java executa byte-codul compilat compilare
MyClass.java MyClass.class
• Byte-codul Java este independent de platforma  Programele Java se pot executa pe orice
platforma pe care exista JVM. executat pe
• Intr-un mediu interpretat, faza standard de "link-edit" nu mai exista.
Java Virtual Machine
• Daca e sa consideram ca Java are faza link, atunci aceasta inseamna doar procesul de > javac MyClass.java executat pe
incarcare a noilor clase in mediu, proces care este unul incremental, si apare la run-time
> java MyClass
(executie).
Host Machine

V. Niculescu - MAP 9 V. Niculescu - MAP 10

Portabilitate si independenta de arhitectura

• O aplicatie Java se poate executa pe orice sistem, cu conditia ca pe acel sistem sa fie
implementata Java Virtual Machine.

• Acest lucru este important pentru aplicatiile distribuite pe Internet sau pe retele
heterogene.

• Formatul Byte-code este important pentru portabilitate.

• Nu exista aspecte “dependente de implementare" ale limbajului.


(De exemplu, Java specifica explicit dimensiunea pentru fiecare tip primitiv de date, si
deasemenea si aritmetica corespunzatoare.
In C tipul int poate fi reprezentat pe 16, 32, or 64 biti in functie de platforma.)

• "Write Once, Run Anywhere."

V. Niculescu - MAP 11 V. Niculescu - MAP 12

3
10/12/2015

Dinamic si Distribuit Simplitate

• Java este un limbaj dinamic. • Java este un limbaj simplu


– Orice clasa Java poate fi incarcata de catre interpretorul Java la orice moment. – poate fi invatat usor
– Toate aceste clase incarcate dinamic pot fi instantiate dinamic. – numarul constructiilor limbajului a fost pastrat relativ mic
– Bibliotecile de cod nativ pot fi incarcate dinamic de asemenea. – sunt multe similaritati cu C++
– Clasa Class: se pot obtine informatii in mod dinamic despre orice clasa.
• Un numar de elemente din C si C++ au fost eliminate:
• Java este un limbaj pentru programare distribuita =
– Nu exista goto; exista insa instructiuni etichetate break si continue mecanisme de
furnizeaza suport de nivel inalt pentru programare distribuita. tratare a exceptiilor ,
– clasele URL si cele conexe sunt in pachetul java.net, – Java nu foloseste fisiere header si elimina preprocesarea din C,
– Remote Method Invocation (RMI) – Nu exista struct si union ,
– suport pentru operatii in retele traditionale de nivel jos – Nu exista supraincarcarea operatorilor si mostenire multipla.
(datagrams si stream-based connections prin sockets)
• Java nu foloseste pointeri
• Aceste caracteristici permit interpretorului Java sa incarce si sa execute cod de pe Internet (ex.
Java applets) – Java face automat referentierea si dereferentierea obiectelor
– Automatic garbage collection

V. Niculescu - MAP 13 V. Niculescu - MAP 14

Capacitatea unui sistem/program de a se executa/reactiona


corect/’”bine” nu Robustete
doar in conditii optime dar si in conditiile unui Securitate
input care nu respecta toate conditiile impuse.
Securitatea este foarte importantă pentru aplicaţiile distribuite!
• Java este un limbaj puternic tipizat  • Java furnizeaza câteva niveluri de control:
verificare la compilarea compatibilitatii tipurilor.
– Java este mai tipizat decat C++. 1. La nivelul cel mai de jos, securitatea are legatura cu robustetea.
– Java cere declararea explicita a metodelor; nu permite stilul C implicit pentru declararatii
C-style  compilatorul poate verifica erorile de apel.
1. Interpretorul Java incarca un proces de verificare a byte-codului pentru orice cod
• Nu sunt pointeri  cresterea robustetii programelor Java prin eliminarea unei intregi clase susceptibil .
de erori datorate pointerilor.
• Toate accesarile la tablouri si string-uri sunt verificate pentru a se asigura ca sunt in (Acest pas de verificare asigura ca este un cod bine format— de exemplu, codul nu va
interiorul limitelor si astfel se elimina posibilitatea de suprascriere a memoriei si a distrugerii supraincarca stiva si nici nu o va goli si nu contine byte-code ilegal)
datelor.
3. Modelul "sandbox": codul suspect este plasat in "sandbox," unde se poate executa in
mod sigur, fara a periclita “lumea reala”, sau mediul Java (este executat cu anumite
• Operatiile Cast ale obiectelor de la un tip la altul sunt de asemenea verificate pentru a se restrictii.)
asigura ca sunt legale.

• Mecanismul automatic garbage collection previne ‘umplerea’ memoriei si alte erori 3. Prin atasarea de semnaturi digitale codului Java, originea codului respectiv poate fi
stabilita intr-un mod sigur criptografic.
datorate alocarii si dealocarii memoriei.

• Mecanism de tratare a exceptiilor puternic!

V. Niculescu - MAP 15 V. Niculescu - MAP 16

4
10/12/2015

High-Performance and Multithreaded Internationalizare - Unicode

• Internationalizare este procesul de proiectare a unei aplicatii astfel incat sa poata fi adaptata
 Java este un limbaj interpretat, deci este dificil a se obtine o performatnta ca timp diferitelor limbi si conventii de notare, fara reprogramare.
de executie similara programelor C sau C++ (nu este insa exclusa).
UNICODE (www.unicode.org)
 Codul C compilat se executa in general mai repede decat bytecodul Java
interpretat. • Caracterele Java sunt caractere 16-bit Unicode.
◦ Viteza este insa mai mult decat adecvata pentru aplicatiile interactive( GUI) si • Deoarece majoritatea mediilor nu suporta codificarea Unicode, Java foloseste o faza de pre-
pentru aplicatiile retea, pentru care aplicatia asteapta deseori imput de la procesare pentru a asigura faptul ca toate caracterele unui program sunt in Unicode.
utilizator sau date din retea. • Java defineste secvente escape care permite folosirea tuturor caracterelor (\uxxxx, unde xxxx
◦ Sectiunile critice d.p.d.v. ale vitezei sunt implementate prin cod nativ eficient este o secventa de patru cifre hexazecimale )
• Unicode defineste codurile de la 0 la 127 in mod consistent cu ASCII.
 Multe interpretoare Java includ acum "just in time compilers” care pot transforma
Java byte-codes in cod-masina pentru un CPU particular. char newline = '\n', apostrophe = '\", delete = '\377‘;
char aleph='\u05D0‘, a = ‘A’ , aa=\u0103;
 Java este un limbaj multithreaded .

V. Niculescu - MAP 17 V. Niculescu - MAP 18

Un exemplu simplu

Hello World!
Limbajul C#
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}

• Compilare
> javac HelloWorld.java
• Executie
> java HelloWorld

V. Niculescu - MAP 19 V. Niculescu - MAP 20

5
10/12/2015

Limbajul C# Platforma Microsoft .NET

• .NET Framework constituie un nivel de abstractizare intre aplicatie si nucleulul


using System; sistemului de operare (sau alte programe), pentru a asigura portabilitatea codului;
class HelloWorld – integreaza tehnologii care au fost lansate de catre Microsoft incepand cu
{ mijlocul anilor 90 (COM, DCOM, ActiveX, etc) sau tehnologii actuale (servicii
public static void Main()
Web, XML).
{
Console.WriteLine(‘‘Hello world!’’); • Motivatie (pe scurt)
} 1. Aplicatiile distribuite - sunt din ce ın ce mai numeroase aplicatiile de tip client /
server sau cele pe mai multe nivele (n−tier).
}
2. Dezvoltarea orientata pe componente –
C# limbaj folosit in cadrul platformei .NET
3. Modificari ale paradigmei Web –
In cmd
4. Alti factori de maturizare a industriei software - constientizarea cererilor de
• Compilare
interoperabilitate, scalabilitate, disponibilitate;
>c:\windows\Microsoft.NET\Framework\v3.5\bin\csc.exe /t:exe /out:MyApplication.exe MyApplication.cs
• Executie
> MyApplication

V. Niculescu - MAP 21 V. Niculescu - MAP 22

Arhitectura platformei .NET Common Intermediate Language

Abstractizare…

• Microsoft a realizat propria sa abstractizare de limbaj – CIL

• (C#, Managed C++, Visual Basic .NET, etc), la compilare toate vor produce cod ın
acelasi limbaj intermediar: CIL

• Asemanator cu bytecod-ul (java), CIL are trasaturi OO

• Aceasta abstractizare de limbaj permite rularea aplicatiilor independent de


platforma (cu aceeasi conditie ca la Java: sa existe o masina virtuala pentru acea
platforma).

V. Niculescu - MAP 23 V. Niculescu - MAP 24

6
10/12/2015

Common Language Specification Common Language Runtime


• CLR este cea mai importanta componenta .NET Framework.
• Unul din scopurile .NET :
– integrarea limbajelor astfel incat • Este responsabila cu managementul si executia codului scris in limbaje .NET, aflat
– programele, desi scrise ın diferite limbaje, pot interopera! in format CIL;
• Este foarte similar cu Java Virtual Machine.
• Common Language Specification (CLS), un subset al lui • CLR instantiaza obiectele, face verificari de securitate, depune obiectele in
CTS (Common Type System) memorie, disponibilizeaza memoria prin garbage collection.
• In urma compilarii unei aplicatii poate rezulta un fisier cu extensia .exe, dar care nu
este un executabil portabil Windows, ci un executabil portabil .NET (.NET PE).
• Contine specificatii de reguli necesare pentru integrarea limbajelor.
Acest cod nu este deci un executabil nativ, ci se va rula de catre CLR, intocmai cum
un fisier .class este rulat in cadrul JVM.
• CLR folosete tehnologia compilarii JIT

V. Niculescu - MAP 25 V. Niculescu - MAP 26

JIT = Just-in-Time compilation Common Type System

• JIT • Facilitati comune tuturor limbajelor .NET


– o implementare de masina virtuala, in care o metoda sau o functie, in momentul
in care este apelata pentru prima oara, este tradusa in cod masina. 1. Tipuri valoare –
– Codul translatat este depus intr-un cache, evitand-se astfel recompilarea 2. Tipuri referinta –
ulterioara. 3. Boxing si unboxing –
4. Clase, proprietati, indexatori
1. Normal JIT - a se vedea descrierea de mai sus. 5. Interfete
2. Pre-JIT - compileaza ıntregul cod in cod nativ o singura data; folosit la instalari. 6. Delegati - inspirati de pointerii la functii din C
3. Econo-JIT – folosit pt. dispozitive cu resurse limitate. Compileaza
codul CIL bit cu bit, eliberand resursele folosite de codul nativ ce este
stocat in cache.

V. Niculescu - MAP 27 V. Niculescu - MAP 28

7
10/12/2015

Assemblies Caracteristici ale platformei .NET

• Un assembly reprezinta un bloc functional al unei aplicatii .NET. • Dezvoltarea multilimbaj


• El formeaza unitatea fundamentala de distribuire, versionare, reutilizare si • Independenta de procesor si de platforma
permisiuni de securitate. • Managementul automat al memoriei
• Suportul pentru versionare
• Exista o oarecare similitudine cu fisiere .jar din Java…?! • Sprijinirea standardelor deschise: (XML,SOAP,HTTP)
• Distribuirea usoara:
– Ambele pot contine resurse si metadate • Arhitectura distribuita
• diferente: • Interoperabilitate cu codul “unmanaged”: Codul “unmanaged” se refera la cod care nu
se afla ın totalitate sub controlul CLR.
– un assembly este compilat
• Securitate
– Putem avea o aplicatie Java fara fisiere JAR; dar nu putem avea o
aplicatie .NET fara un assembly..
• Exista fisiere JAR executabile => acestea sunt similare cu Assemblies

V. Niculescu - MAP 29 V. Niculescu - MAP 30

Recap. ->Tipuri de locatii de stocare

• Registrii: (cel mai rapid) in procesor


– numarul de registrii este limitat
– fara control direct • Elemente de baza de limbaj
• Stiva: RAM
– Java
– Procesorul foloseste pointerul de stiva
– Pointerul stivei este mutat in ‘jos’ pt. a se aloca memorie si in ‘sus’ pentru a se – C#
elibera.
– Rapida si eficienta pentru alocare
– Referintele la obiecte si valorile primitive
• Heap: RAM – Tipuri simple
– flexibilitate – Variable
– alocarea necesita mai mult timp decat alicarea pe stiva
– obiectele Java sunt stocate in heap
• Stocare statica: “in locatie fixa” (RAM).
– datele statice au durata de viata egala cu cea a programului
• Stocarea constantelor: constantele sunt stocate in general in codul programului
(nu intotdeauna)
• Stocare Non-RAM:
– streamed objects, persistent objects

V. Niculescu - MAP 31 V. Niculescu - MAP 32

8
10/12/2015

Tipuri primitive
Java

Declarare
Variabile:

V. Niculescu - MAP 33 V. Niculescu - MAP 34

Precc. Operator Operand Type(s) Assoc. Operation Performed

Java 1 ++
--
arithmetic
arithmetic
R
R
pre-or-post increment (unary)
pre-or-post decrement (unary) Scope = {…} (Domeniu de vizibilitate)
operators +, -
~
arithmetic
integral
R
R
unary plus, unary minus
bitwise complement (unary)
! boolean R logical complement (unary)
• Nu este permisa “ascunderea unei variabile intr-un sub-scope
(type) any R cast
2 *, /, % arithmetic L multiplication, division, remainder
3 +, - arithmetic L addition, subtraction {int x = 12;
+ string L string concatenation
4 << integral L left shift { int x = 96; /* illegal */
>> integral L right shift with sign extension
>>> integral L right shift with zero extension }
5 <, <= arithmetic L less than, less than or equal
>, >=
instanceof
arithmetic
object, type
L
L
greater than, greater than or equal
type comparison
}
6 ==
!=
primitive
primitive
L
L
equal (have identical values)
not equal (have different values)
Object scope
== object L equal (refer to same object) {
!= object L not equal (refer to different objects)
7 & integral L bitwise AND String s = new String("a string");
& boolean L boolean AND
} /* end of scope */
8 ^ integral L bitwise XOR
^ boolean L boolean XOR
9 | integral L bitwise OR
| boolean L boolean OR
10 && boolean L conditional AND
11 || boolean L conditional OR
12 ?: boolean, any, any R conditional (ternary) operator
13 = variable, any R assignment
*=, /=, %=, +=, -=, <<=,
variable, any R assignment with operation
V. Niculescu
>>=, >>>=, &=, ^=, |= - MAP 35 V. Niculescu - MAP 36

9
10/12/2015

Tipuri simple – tipuri valoare


C# • In C# exista tipuri valoare si tipuri referinta.
– Tipurile valoare includ :
• tipurile simple (ex. char, int, float),
• tipul enumerare si
• tipul structura
– au ca principale caracteristici faptul ca ele contin direct datele referite si sunt
alocate pe stiva sau inline ıntr–o structura.

• Tipurile referinta includ tipurile:


– clasa,
– interfata,
– delegat
– tablou,
– Au proprietatea ca variabilele de acest tip stocheaza referinte catre obiectele care
sunt alocate in heap.

V. Niculescu - MAP 37 V. Niculescu - MAP 38

Ierarhie unica de clase Tipuri predefinite

• Toate tipurile de date sunt derivate (direct sau nu) din tipul System.Object, • Set de tipuri predefinite, pentru care nu este necesara referirea vreunui spatiu de
nume via directiva using sau calificare completa.
• Mod unitar de tratare ! • Exemple:
– string,
– object,
– tipurile ıntregi cu semn ¸si fara semn,
– tipuri numerice ın virgula mobila,
– tipurile bool si decimal.
• Tipul string este folosit pentru manipularea ¸sirurilor de caractere codificate
Unicode; continutul obiectelor de tip string nu se poate modifica

V. Niculescu - MAP 39 V. Niculescu - MAP 40

10
10/12/2015

Tipuri primitive in C# Tipuri valoare

• Toate tipurile valoare sunt derivate din clasa System.ValueType, care la randul ei
este derivata din clasa object (alias pentru System.Object).
• Nu este posibil ca dintr–un tip valoare sa se deriveze.
• Atribuirea pentru un astfel de tip ınseamna copierea valorii!!!

• Tipurile simple sunt identificate prin cuvinte rezervate, dar acestea reprezinta doar
alias–uri pentru tipurile struct corespunzatoare din spatiul de nume System.

V. Niculescu - MAP 41 V. Niculescu - MAP 42

Tipuri simple si corespondentele lor cu tipurile din


Exemple
spatiul de nume System
int i = int.MaxValue; //constanta System.Int32.MaxValue
string s = i.ToString(); //metoda System.Int32.ToString()
string t = 3.ToString(); //idem
double d = Double.Parse("3.14");

V. Niculescu - MAP 43 V. Niculescu - MAP 44

11
10/12/2015

Tipul decimal
• Este un tip de date reprezentat pe 128 de biti, Instructiuni de control
• gandit a fi folosit ın calcule financiare sau care necesita precizie mai mare.
• Poate reprezenta valori aflate ın intervalul 1.0 × 10−28 ¸7.9 × 1028, cu 28 de cifre
semnificative. • Java
• nu poate reprezenta zero cu semn, infinit sau NaN. • C#
• nu se fac conversii implicite ıntre nici un tip ın virgul˘a mobila si decimal
• nu este posibila mixarea variabilelor de acest tip ıntr-o expresie, fara conversii
explicite.
• Literalii se exprima folosind ca sufix caracterele m sau M.
Tipul bool
• Este folosit pentru reprezentarea valorilor de adevar true si false.
• Nu exista conversii standard ıntre bool si nici un alt tip.

V. Niculescu - MAP 45 V. Niculescu - MAP 46

Java Instructiunea switch:


• Instructiunea compusa:
{ switch(integral-selector) {
instructiune1; case integral-value1 : statement; [break;]
instructiune2; … case integral-value2 : statement; [break;]
} case integral-value3 : statement; [break;]
• Daca: case integral-value4 : statement; [break;]
if (expresie_logica) case integral-value5 : statement; [break;]
instructiune; // ...
if (expresie_logica) default: statement;
instructiune1; }
else
instructiune2;
Obs: expresie_logica trebuie sa se evalueze la true sau false. Nu se accepta valori
numerice.

V. Niculescu - MAP 47 V. Niculescu - MAP 48

12
10/12/2015

Instructiuni de ciclare

 Instructiunea while:  Instructiunea return:


while(expresie_booleana) return;
instructiune return valoare;
 Instructiunea do-while:
do  Instructiunea break: opreste executia unei iteratii.
instructiune int[] x= { 2, 8, 3, 5, 12, 8, 62};
while(expresie_booleana); int elem = 8;
 Obs: Instructiunea este executata pana cand expresia_booleana boolean gasit = false;
devine false. for (int i = 0; i < x.length; i++) {
 Instructiunea for: if (x[i] == elem) {
for(initializari; expresie_booleana; pas) gasit = true;
instructiune break;
 Obs: Oricare din expresiile initializari, expresie_booleana, pas }
poate sa lipseasca. }

V. Niculescu - MAP 49 V. Niculescu - MAP 50

• Instructiunea continue:
– sare peste iteratia curenta din interiorul unui ciclu (for, while, dowhile) • if (expresie logica) instructiune;
– opreste executia instructiunilor din interiorul unui ciclu si determina • if (expresie logica) instructiune; else instructiune;
reevaluarea expresiei booleene.
int[] x= { 2, 8, 3, 5, 12, 8, 62}; • switch (expresie)
int elem = 8; {
int nrApar=0; case eticheta: instructiune;
for (int i = 0; i < x.length; i++) { case eticheta: instructiune;
if (x[i] != elem) ...
continue; default: instructiune;
nrApar++; }
}

V. Niculescu - MAP 51 V. Niculescu - MAP 52

13
10/12/2015

Exemplu
switch (i)
Exemple instructiuni de ciclare
{
case 0:
Console.WriteLine("0"); while (r != 0)
break; {
case 1: r = a%b; a = b; b = r;
Console.Write("Valoarea "); }
goto case 2;
case 2: do
case 3:
{
Console.WriteLine(i);
break; S += i++;
case 4: }while(i<=n)
goto default;
default: for (int i=0; i<n; i++)
Console.WriteLine("Numar in afara domeniului admis"); {
break;//neaparat, altfel eroare de compilare Console.WriteLine("i={0}", i);
}
}

V. Niculescu - MAP 53 V. Niculescu - MAP 54

Instructiuni de salt (NERECOMANDATE)


Edsger W. Dijkstra, "Go To Statement Considered Harmful": Instructiunile checked si unchecked
http://www.acm.org/classics/oct95/

• Controleaza contextul de verificare de depasire a domeniului pentru aritmetica pe


 Permit schimbarea ordinii de executie a instructiunilor ıntregi si conversii. Au forma:
◦ Break,continue, goto, return, throw. checked
 Instructiunea break {
Produce iesirea fortata dintr–un ciclu de tip while, do, for, foreach. //instructiuni
 Instructiunea continue }
Porneste o noua iteratie ın interiorul celui mai apropiat ciclu continator unchecked
de tip while, do, for, foreach. {
 Instructiunea goto //instructiuni
Goto permite saltul al o anumita instructiune. Are 3 forme: }
◦ goto eticheta; • Verificare se va face la run–time.
◦ goto case expresieconstanta;
◦ goto default;
Cerinta este ca eticheta la care se face saltul sa fie definita ın cadrul functiei curente si
saltul sa nu se faca ın interiorul unor blocuri de instructiuni.
V. Niculescu - MAP 55 V. Niculescu - MAP 56

14
10/12/2015

Comentarii

• Java suporta trei tipuri de comentarii:


– stilul standard C:
/* and continua pana la */
(nu pot fi incuibate)
− stilul C++

Curs 2 - Java // continua pana la sfarsitul liniei.

– stilul "doc comment"


•Comentarii /** and continua pana la */ (nu pot fi incuibate)
•Constante
•Tipuri : valoare &referinte Comentariile Doc sunt procesate de catre programul
•Transmitere parametrii
•Boxing /Unboxing javadoc

pentru a produce documentatie simpla(html file)din codul sursa Java.


•Testare identitate.vs. egalitate
>javadoc Myclass.java

V. Niculescu - MAP 57 V. Niculescu - MAP 58

Definirea Constantelor
Clase
• Orice variabila declarata final in Java reprezinta o constanta
– initializarea trebuie facuta la declarare
[ abstract][ final][public] class <name>
Ex. private final int x = 2;
[extends <superclass_name>]
//c, c++
#define PI 3.14159
[implements <interface_name> [, <interface_name>] * ]
const double PI = 3.14159;  a static final declarata in interiorul unei clase
{

[ [public|private|protected] [static][final][abstract] <method> ]*


//java
public final class Math { ...
[ [public|private|protected] [static][final] <attribute> ]*
public static final double PI = 3.14159.....;
...
} }
• Conventia C de folosire a literelor MARI valabila.

• Constantele Java au o ierarhie unica globala a numelor.

• Constantele Java sunt tipizate!

V. Niculescu - MAP 59 V. Niculescu - MAP 60

15
10/12/2015

Definirea obiectelor Object class


• Ierarhie unica de clase
// Complex.java • Clasa radacina = clasa Object
public class Complex{
private double re = 2.5;
private double im; Object
public Complex ( double re, double im){
this.re = re;
+ Object()
this.im = im;
}
# Object clone()
public Complex() {} + boolean equals(Object obj)
public double getReal() { return re; } # protected void finalize()
public double getImag() { return im; } + Class getClass()
+ int hashCode()
public static void main(String [] args){ + void notify()
Complex c1 = new Complex(); + void notifyAll()
Complex c2 = new Complex(5.0, 10.5);
+ String toString()
System.out.println(“c1=“+c1.getReal()+”+i”+c1.getImag()+”\n”);
// c1=2.5+i0.0
+ void wait()
System.out.println(“c2=“+c2.getReal()+”i+”+c2.getImag()+”\n”); + void wait(long timeout)
// c2=5.0+i10.5 + void wait(long timeout, int nanos)
}
}
V. Niculescu - MAP 61 V. Niculescu - MAP 62

Tipuri de date primitive Tipuri de date referinta

Primitive Size Minimum Maximum Wrapper


type type
• Tipurile Java neprimitive sunt obiectele si tablourile
boolean 1-bit — — Boolean
( tablourile sunt de fapt obiecte).
16
char 16-bit Unicode 0 Unicode 2 - 1 Character
byte 8-bit -128 +127 Byte • Tipurile Java neprimitive sunt numite in general “tipuri referinta" pentru ca se
short 16-bit -215 +215—1 Short utilizeaza prin “ referinta”
int 32-bit -231 +231—1 Integer (adresa obiectului sau tabloului este stocata intr-o variabila, transmisa metodelor,
64-bit -263 +263—1
etc.).
long Long
float 32-bit IEEE754 IEEE754 Float
• Tipurile primitive sunt “utilizate prin valoare“
double 64-bit IEEE754 IEEE754 Double
void — — — Void

V. Niculescu - MAP 63 V. Niculescu - MAP 64

16
10/12/2015

Nu sunt pointeri in Java! null

• Referentierea si dereferentierea obiectelor se face automat. • Valoarea implicita pentru variabilele de tip referinta este null.
– null este un cuvant rezervat si corespunde unei valori care indica faptul ca
• Java nu permite manipularea pointerilor sau a adreselor de memorie: variabila nu refera nici un obiect.
– NU este permisa transformarea prin cast a unei referinte la obiect sau la tablou (in C NULL este doar o constanta egala cu 0)
la intregi si vice-versa.
– NU este permisa aritmetica cu adrese. • null nu poate fi transformat prin cast la nici un tip primitiv. Nu trebuie sa fie
– NU este permisa calcularea marimii reprezentarii in octeti pentru nici un tip considerat a fi egal cu zero desi ar putea fi implementat in acest fel.
primitiv sau obiect.

V. Niculescu - MAP 65 V. Niculescu - MAP 66

Exemplu
Exemplu –swap - eronat!

Complex p, q;
p = new Complex();
// p refers to a Complex object. public void swap( Object a, Object b)
q = p;
{
// q refers to the same object of type Complex.
p.setReal(10.2); Object temp = a;
// A change to the object through p... a = b;
double r = q.getReal(); b = temp;
// ...is also visible through q. }
// r now contains 10.2

int i = 3; • Parametrii se transmit prin valoare!


// i contains the value 3.
int j = i;
// j contains a copy of the value in i.
i = 2;
// Changing i doesn't change j.
// Now, i == 2 and j == 3.

V. Niculescu - MAP 67 V. Niculescu - MAP 68

17
10/12/2015

Copierea Obiectelor Verificarea egalitatii

Complex a = new Complex(1,1); • Operatorul == testeaza daca doua variabile refera acelasi obiect, si nu daca doua obiecte au
Complex b = new Complex(); aceeasi stare.
a = b;

• variabila a contine o referinta la obiectul pe care b il refera. Obiectul pe care a il referea


este pierdut. • Metoda equals() se poate folosi pentru a testa egalitatea.
• Pentru a copia un obiect se foloseste metoda clone():
• Daca o clasa are atribute de tip referinta, metoda equals() ar trebui suprascrisa!
Vector b = new Vector();
Vector c = b.clone();

• Pentru a se putea folosi metoda clone() clasa respectiva trebuie sa implementeze interfata
Cloneable.

V. Niculescu - MAP 69 V. Niculescu - MAP 70

Tablouri Tablouri(2)

• Tablourile se utilizeaza folosind referinte. • creare si initializare tablou

• Sunt create dinamic (new); ca si obiectele: -> clasa Array int lookup_table[] = {1, 2, 4, 8, 16, 32, 64, 128};

• Garbage collecter-ul elibereaza memoria corespunzatoare lor atunci cand nu mai


sunt referite.
• creare anonima -> parametrii
byte octet_buffer[] = new byte[1024];
Complex tc[] = new Complex[10];
Menu m = createMenu("File",
new String[] {"Open...", "Save", "Quit" });
• Elementele unui tablou se initializeaza cu valoarea implicita a tipului lui.
(deci pentru obiecte = null)
• =>Creare unui tablou cu elemente de tip obiect nu implica si crearea obiectelor
constitutive.

for (int i=0; i<10; i++)


tc[i] = new Complex(i, i);

V. Niculescu - MAP 71 V. Niculescu - MAP 72

18
10/12/2015

Tablouri multidimensionale Tablouri multidimensionale nerectangulare

• se implementeaza ca tablouri de tablouri ca si in C short triangle[][] = new short[10][];


// Tablou uni- dimensional
byte TwoDimArray[][] = new byte[256][16];
for(int i = 0; i < triangle.length; i++) {
int threeD[][][] = new int[10][][]; // pentru fiecare element al tabloului
triangle[i] = new short[i+1];
double temperature_data[][][] =
new double[100][][10]; // illegal // se aloca un nou tablou

String param_info[][] = { for(int j=0; j < i+1; j++)


{"foreground", "Color", "foreground color"}, {"background", // fiecare element al noului tablou
"Color", "background color"}, {"message", "String", "the
banner to display"}}; triangle[i][j] = (short) i + j;
// se initializeaza cu o valoare

static int[][] twodim =


{{1, 2}, {3, 4, 5}, {5, 6, 7, 8}};

V. Niculescu - MAP 73 V. Niculescu - MAP 74

Variabile si parametrii de tip tablou Enhanced for..

int i; String s;
• C vs. Java
// for clasic
void reverse(char strbuf[], int buffer_size) { for(i=0, s = "testing"; // Initializare
char buffer[500]; (i < 10) && (s.length() >= 1); // Testare pentru continuare.
...} i++, s = s.substring(1)) // avans
{ System.out.println(s); // corpul ciclului
}
void reverse(char[] strbuf, int buffer_size) {
char[] buffer = new char[500];
String my_array[] = {“Ana”,”Maria”,”Lia”,”Ioana”};
...}
// for clasic
for(int i = 0; i < my_array.length; i++)
• lungimea unui tablou nu face parte din tip ca in C System.out.println("a[" + i + "] = " + my_array[i]);

String[] strings;
// this variable can refer to any String array //new for (for each)
strings = new String[10]; for (String s: my_array)
System.out.println(s);
// one that contains 10 Strings
strings = new String[20];
// or one that contains 20.

V. Niculescu - MAP 75 V. Niculescu - MAP 76

19
10/12/2015

Functii cu numar variabil de parametrii String-uri

• functionalitate adaugata incepand J2SE 5.0 • String-urile in Java nu sunt terminate printr-un caracter nul cum sunt in C
void someMethod(Object ... args) {
• sunt instante ale clasei java.lang.String sau ale clasei StringBuffer
// do something
} • obiectele de tip String sunt nemodificabile
someMethod("arg1", "arg2", "arg3");
• Exemplu1: • obiectele de tip StringBuffer sunt modificabile
System.out.printf("%s %3d", name, age);
• Cateva metode ale clase String::
• Doar o data si la sfarsit…
• Exemplu2: – length
public static void variabil(int x, int...a){ – charAt
for (int i: a) – equals
System.out.println(i*x); – compareTo
} – indexOf
public static void main(String args[]){ – lastIndexOf
int t_int[] = {1,2,3 ,4}; – substring
variabil(2, t_int);
variabil(2, 1, 2, 3 ,4);
}

V. Niculescu - MAP 77 V. Niculescu - MAP 78

Comentarii C#

// Acesta este un comentariu pe o singură linie;


i=0;
/* Acesta este un comentariu
pe mai multe linii */
Curs 2 – C#
• Documentatii .XML generate automat
– Comentarii care incep cu ///
•Comentarii – Contin diverse tag-uri: ex <summary>…<\summary>
•Constante – Optiunea /doc a compilatorului
•Tipuri : valoare &referinte
•Transmitere parametrii
•Boxing /Unboxing > csc myprogram.s /doc:mycomments.xml

•Testare identitate.vs. egalitate

V. Niculescu - MAP 79 V. Niculescu - MAP 80

20
10/12/2015

Declaratii variabile si constante locale


Campuri Constante
initializari
void F() = camp al carei valoare poate fi calculata la compilare
{
int x = 3, y;//ok • Constante = membrii statici
const double d = 1.1;//ok
{
class A
string x = "Mesaj: ";//eroare, x mai este declarat in blocul continator
int z = x + y;//eroare, y nu are o valoare definita asignata {
} public const int n=2;
} }

V. Niculescu - MAP 81 V. Niculescu - MAP 82

Camp readonly Tablouri


• Exemplu:
• Declararea unui camp de tip readonly (static sau nu) se face folosind cuvantului cheie • Tablouri unidimensionale using System;
class Unidimensional
readonly : – Declararea (spre deosebire de {
class A Java, nu se poate modifica locul public static int Main()
parantezelor, nu se poate scrie: {
{ int sir[]. int[] sir;
public readonly string salut = ‘‘Salut’’; int[] sir; int n;
public readonly string nume; – Instantierea / initializare Console.Write(‘‘Dimensiunea
vectorului: ’’);
public class A(string nume) sir = new int[10]; n = Int32.Parse( Console.ReadLine() );
{ int[] a = new int[] {1,2,3}; sir = new int[n];
this.nume = nume; sau ın forma mai scurta: for( int i=0; i<sir.Length; i++)
{
} int[] a = {1,2,3}; sir[i] = i * i;
} }
• Atribuirea asupra unui camp de tip readonly se poate face: • Length = proprietate in clasa for( int i=0; i<sir.Length; i++)
System.Array {
– la declararea sa, sau Console.WriteLine(‘‘sir[{0}]={1}’’, i,
– prin intermediul unui constructor. sir[i]);
• orice tablou este un obiect, derivat }
• Nu este obligatoriu cunoasterea valorii unui astfel de camp la compilare. din clasa System.Array. return 0;
}

V. Niculescu - MAP 83 V. Niculescu - MAP 84

21
10/12/2015

Tablouri multidimensionale
-rectangulare Nr. Dimensiuni -> Rank
-neregulate (jagged arrays) …> Java (Rank = proprietate in clasa System.Array)
using System;
class Test
{ using System;
• Declarare public static void Main() class Dimensiuni
int[,] tab; {
tab = new int[2,3]; int[,] tabInm = new int[10,10];
{
tab[i, j]. for( int i=0; i<tabInm.GetLength(0); i++ ) public static void Main()
• initializare: { {
int[,] tab = new int[,] for( int j=0; j< tabInm.GetLength(1); j++) int[] t1 = new int[2];
{{1,2},{3,4}}; {
tabInm[i,j] = i * j;
int[,] t2 = new int[3,4];
int[,] tab = {{1, 2}, {3, 4}}; int[,,] t3 = new int[5,6,7];
}
• Referire element: } Console.WriteLine(‘‘t1.Rank={0}\n t2.Rank={1}\n t3.Rank={2}’’,
tab[i,j] for( int i=0; i<tabInm.GetLength(0); i++) t1.Rank, t2.Rank, t3.Rank);
{
Exemplu:tabla inmultirii for( int j=0; j<tabInm.GetLength(1); j++) }
{ }
Console.WriteLine(‘‘{0}*{1}={2}’’, i, j, Pe ecran va aparea:
tabInm[i,j]);
}
t1.Rank=1
} t2.Rank=2
Console.WriteLine(‘‘tabInm.Length={0}’’, t3.Rank=3
tabInm.Length);
//tabInm.Length=100

V. Niculescu - MAP 85 V. Niculescu - MAP 86

Tablouri neregulate
using System; foreach
class JaggedArray
• Reprezinta un tablou de tablouri. {
public static void Main()
• Declararea : {
int[][] tab; int[][] a = new int[2][]; int[] numbers = { 4, 5, 6, 1, 2, 3, -2, -1, 0 };
a[0] = new int[2];
• Referirea : a[1] = new int[3]; foreach (int i in numbers)
tab[i][j] for( int i=0; i<a[0].Length; i++)
{ {
• Initializarea a[0][i] = i;
int[][] myJaggedArray = new int [][] } System.Console.Write("{0} ", i);
for( int i=0; i<a[1].Length; i++) }
{ {
new int[] {1,3,5,7,9}, a[1][i] = i * i; // Output: 4 5 6 1 2 3 -2 -1 0
}
new int[] {0,2,4,6}, for(int i=0; i<a.Length; i++)
new int[] {11,22} {
}; for( int j=0; j<a[i].Length; j++ )
{
Console.Write(‘‘{0} ’’, a[i][j]);
Sau }
Console.WriteLine();
int[][] myJaggedArray = { }
new int[] {1,3,5,7,9}, Console.WriteLine(‘‘a.Rank={0}’’,
a.Rank);
new int[] {0,2,4,6}, }
}
new int[] {11,22} va scrie pe ecran:
}; 0 1
0 1 4
Sau (vezi exemplu) a.Rank=1

V. Niculescu - MAP 87 V. Niculescu - MAP 88

22
10/12/2015

Siruri de caractere: String Operatii -String


• Clasa System.String (pentru care se poate folosi aliasul "string“)
• Obiectele de acest tip sunt imutabile • Operatorii "==" ¸si "!="
• Sirurile pot contine secvente escape si pot fi de doua tipuri:
• Clasa String pune la dispozitie metode pentru:
– regulate
• comparare : Compare, CompareOrdinal, CompareTo,
– tip "verbatim".
• Cautare : EndsWith, StartsWith, IndexOf, LastIndexOf,
• Exemplu:
String a = "string literal"; • modificare (=obtinerea altor obiecte pe baza celui curent )
String versuri = "vers1\nvers2"; Concat, CopyTo, Insert, Join, PadLeft, PadRight, Remove, Replace, Split,
Substring, ToLower, ToUpper,Trim, TrimEnd, TrimStart
String caleCompleta = "\\\\minimax\\protect\\csharp";
• Accesarea unui caracter aflat pe o pozitie ia unui sir s se face prin folosirea
• Exemplu verbatim – incepe cu @
parantezelor drepte, cu aceleasi restrictii asupra indicelui ca si pentru tablouri: s[i].
String caleCompleta=@"\\minimax\protect\csharp";
//ghilimelele se dubleaza intr-un verbatim string • Functia Split()
String s=@"notiunea ""aleator"" se refera...";
//string multilinie reprezentat ca verbatim
String dialog=@"-Alo? Cu ce va ajutam?
-As avea nevoie de o informatie.";

V. Niculescu - MAP 89 V. Niculescu - MAP 90

Exemplu Varianta:
Fixed Size Buffers
using System;
class Class1 String[] tokens = s.Split( new char[]{’ ’, ’,’},
{ StringSplitOptions.RemoveEmptyEntries );
static void Main(string[] args) private fixed char name[30];
{
String s = "Oh, I hadn’t thought of that!";
char[] x = {’ ’, ’,’ };
String[] tokens = s.Split( x );
for(int i=0; i<tokens.Length; i++) This is useful when you are working with existing code, such as code written in
{ other languages…
Console.WriteLine("Token: {0}", tokens[i]);
}
}
}
Output:

Token: Oh
Token:
Token: I
Token: hadn’t
Token: though
Token: of
Token: that!

V. Niculescu - MAP 91 V. Niculescu - MAP 92

23
10/12/2015

Transmiterea parametrilor: ref si out Exemplu:


class Program
• ref static void squareVal(int valParameter)
{
{
Argument transmis prin referinta static void Main(string[] args)
{ valParameter *= valParameter;
- Trebuie precizat si la definitia functiei si la apel int arg; }
- Argumentul poate fi de tip valoare sau de tip referinta
// Passing by value. // Passing by reference
- Parametrul trebuie sa fie initializat // The value of arg in Main is not changed.
static void squareRef(ref int refParameter)
arg = 4;
squareVal(arg); {
• out Console.WriteLine(arg); refParameter *= refParameter;
– Cauzeaza transmiterea prin referinta // Output: 4 }
}
– Nu impune intializarea paramentrului actual // Passing by reference.
• in // The value of arg in Main is changed.
arg = 4;
squareRef(ref arg);
Console.WriteLine(arg);
// Output: 16
}

V. Niculescu - MAP 93 V. Niculescu - MAP 94

params Boxing/unboxing
public class MyClass
{
• Permite numar variabil de parametrii public static void UseParams(params int[] list) • Conversia de tip boxing permite oricarui tip valoare sa fie implicit convertit catre
{ tipul object sau catre un tip interfata implementat de tipul valoare.
• Parametrii actuali pot fi for (int i = 0; i < list.Length; i++)
{
– o lista de parametrii separati prin Console.Write(list[i] + " ");
virgula sau • Boxing–ul unei valori consta ın alocarea unei variabile de tip obiect si copierea
}
– un tablou. Console.WriteLine(); valorii initiale ın acea instanta.
}

static void Main() int i = 10;//linia 1


{
UseParams(1, 2, 3, 4); object o = i;//linia 2
UseParams(); int j = (int)o;//linia 3
int[] myIntArray = { 5, 6, 7, 8, 9 };
UseParams(myIntArray);

}
}

V. Niculescu - MAP 95 V. Niculescu - MAP 96

24
10/12/2015

Pointers in C#
Clase C#
• Clasele reprezinta tipuri referinta. O clasa poate sa mosteneasca o
• Can be used in an unsafe context - only singura clasa ¸si poate implementa mai multe interfete.
• Membrii:
– constante,
– campuri,
– metode,
– proprietati,
– evenimente,
– indexatori,
– operatori,
– constructori de instanta,
– destructori,
– constructori de clasa,
– tipuri imbricate.

V. Niculescu - MAP 97 V. Niculescu - MAP 98

Clasa Object Clasa ValueType

• Constructor: • Derivata din clasa Object


– Object() Initializes a new instance of the Object class.
• Metode • Metode:
+ Equals(Object)Determines whether the specified object is equal to the current +EqualsIndicates whether this instance and a specified object are equal.
object. (Overrides Object.Equals(Object).)
$+ Equals(Object, Object)Determines whether the specified object instances are #FinalizeAllows an object to try to free resources and perform other cleanup
considered equal. operations before it is reclaimed by garbage collection. (Inherited from Object.)
# FinalizeAllows an object to try to free resources and perform other cleanup +GetHashCodeReturns the hash code for this instance. (Overrides
operations before it is reclaimed by garbage collection. Object.GetHashCode().)
+GetHashCodeServes as the default hash function. +GetTypeGets the Type of the current instance. (Inherited from Object.)
+ GetTypeGets the Type of the current instance. #MemberwiseCloneCreates a shallow copy of the current Object. (Inherited from
#MemberwiseCloneCreates a shallow copy of the current Object. Object.)
$+ ReferenceEqualsDetermines whether the specified Object instances are the +ToStringReturns the fully qualified type name of this instance. (Overrides
same instance. Object.ToString().)
+ToStringReturns a string that represents the current object.

V. Niculescu - MAP 99 V. Niculescu - MAP 100

25
10/12/2015

Structuri Exemplu
public class Tester
• tipuri de date asemanatoare claselor, using System; {
– diferenta -> sunt tipuri valoare public struct Point public static void MyFunc(Point loc)
{
Sunt considerate versiuni “usoare” ale claselor, sunt folosite predilect pentru tipuri {
public Point(int xCoordinate, int yCoordinate)
{ loc.X = 50;
pentru care aspectul comportamental este mai putin pronuntat. loc.Y = 100;
xVal = xCoordinate;
• Modificatori: new, public, protected, internal, private. yVal = yCoordinate; Console.WriteLine(‘‘In MyFunc loc: {0}’’, loc);
} }
• O structura este automat derivata din System.ValueType, care la randul ei este derivata din public int X
System.Object ; de asemenea, este automat considerata sealed { static void Main( )
get {
• Poate sa implementeze una sau mai multe interfete. {return xVal;} Point loc1 = new Point(200,300);
set
Console.WriteLine(‘‘Loc1 location: {0}’’, loc1);
• poate sa contina: { xVal = value; }
} MyFunc(loc1);
– constante, campuri, public int Y Console.WriteLine(‘‘Loc1 location: {0}’’, loc1);
{ }
– metode, proprietati, get }
– evenimente, indexatori, operatori, { return yVal; }
set
– constructori, constructori statici, { yVal = value; } Output:
} Loc1 location: 200, 300
– tipuri imbricate. public override string ToString( )
In MyFunc loc: 50, 100
{
• Nu poate defini destructor! return (String.Format(‘‘{0}, {1}’’, xVal,yVal)); Loc1 location: 200, 300
• La atribuire, se face o copiere a valorilor continute de catre sursa ın destinatie (indiferent de }
public int xVal;
tipul campurilor: valoare sau referinta). public int yVal;
}

V. Niculescu - MAP 101 V. Niculescu - MAP 102

• Daca programatorul defineste un constructor, atunci acesta trebuie sa dea valori initiale pentru
Particularitati pentru structuri campurile continute, altfel apare eroare la compilare.

• Campurile nu pot fi initializate la declarare; • Daca nu se apeleaza new, atunci respectiva instanta nu va avea asociata nici o valoare
(constructorul implicit nu este apelat automat!).
• Nu se poate defini un constructor implicit.
– Cu toate acestea, compilatorul va crea un astfel de constructor, care va initializa
• Nu se poate folosi respectiva variabila de tip structura decat dupa ce i se initializeaza toate
campurile la valorile lor implicite
campurile:
• Pentru tipul Point de mai sus, urmatoarea secvena de cod este corecta: {
Point a = new Point(0, 0); Point p;
Point b = new Point(); //p.xVal=p.yVal=0;
• Un constructor implicit este apelat atunci cand se creeaza un tablou de structuri: Console.WriteLine(p);
Point[] points = new Points[10]; }
for( int i=0; i<points.Length; i++ ) eroare de compilare: Use of unassigned local variable ‘p’
{
Console.WriteLine(points[i]); • Nu se poate declara destructor. Acestia se declara numai pentru clase.
}
• Boxing: Daca o instanta de tip struct este folosita acolo unde un object este necesar, atunci se
• se creeaza un obiect de tip tablou ın heap, dupa care ın interiorul lui (si nu pe stiva!) se va face automat o conversie implicita catre System.Object
creeaza cele 10 puncte (alocare inline).

V. Niculescu - MAP 103 V. Niculescu - MAP 104

26
10/12/2015

Structuri sau clase? Object Identity vs. Value Equality


• Structurile pot fi mult mai eficiente ın alocarea memoriei atunci cand sunt stocate
ıntr–un tablou. Exemplu:
– crearea unui tablou de 100 de elemente de tip Point va duce la crearea unui singur obiect • Metoda
(tabloul), iar cele 100 de instante de tip structura ar fi alocate inline ın vectorul creat (si System.Object.Equals
nu referinte ale acestora).
public virtual Boolean Equals(Object obj) {
– Daca Point ar fi declarat ca si clasa, ar fi fost necesara crearea a 101 instante de obiecte
ın heap (un obiect pentru tablou, alte 100 pentru puncte), ceea ce ar duce la mai mult // If both references point to the same
lucru pentru garbage collector si ar putea duce la fragmentarea heap-ului. // object, they must be equal.
if (this == obj) return true;
• Dar ın cazul ın care structurile sunt folosite ın colectii de tip Object (ex. ArrayList ), // Assume that the objects are not equal.
se va face automat un boxing, ceea ce duce la overhead (consum suplimentar de return false;
memorie si cicli procesor). }

• De asemenea, la transmiterea prin valoare a unei structuri, se va face copierea Object.ReferenceEquals(Object obj1, Object, obj2)
tuturor campurilor continute pe stiva, ceea ce poate duce la un overhead
semnificativ • Metoda
System.ValueType.Equals

V. Niculescu - MAP 105 V. Niculescu - MAP 106

Examplu: Equals pt struct Exemplu: Equals pt class


public struct Person Person p1 = new Person(“ION", 75); public class Customer : Object { public override bool Equals(object obj)
{
{ Person p2; if (obj == null) return false;
private readonly string _id;
public string Name; if (Object.ReferenceEquals(this,obj)) return true;
p2.Name = “ION"; if (this.GetType() != obj.GetType()) return false;
public int Age; public string ID
p2.Age = 75; {
public Person(string name, int age) get { return _id; } Customer objCustomer = (Customer)obj;
{ } if (_id.Equals(objCustomer.ID)) return true;
Name = name; if (p2.Equals(p1)) return false;
public Customer(string id)
Age = age; Console.WriteLine("p2 and p1 have the same { }
} values."); if (id == null || id.Length == 0)
throw new public override int GetHashCode()
} ArgumentNullException(“id“); {
return _id.GetHashCode();
// Output: p2 and p1 have the same values. _id = id; }
}
}
public override string ToString()
{
return _id;
}

V. Niculescu - MAP 107 V. Niculescu - MAP 108

27
10/12/2015

Structures for floating-point values Operator is

public struct Single : IComparable, IFormattable, public static bool IsNumeric(ValueType value)
IConvertible, IComparable<float>, IEquatable<float> {
if ( ! (value is Byte ||
alias float value is Int16 ||
value is Int32 ||
value is Int64 ||
public struct Double : IComparable, IFormattable, IConvertible, value is SByte ||
IComparable<double>, IEquatable<double>
value is UInt16 ||
value is UInt32 ||
alias double value is UInt64 ||
• Metode … value is BigInteger ||
IsInfinityReturns a value indicating whether the specified number evaluates to negative or value is Decimal ||
positive infinity value is Double ||
IsNaNReturns a value that indicates whether the specified value is not a number (NaN). value is Single))
IsNegativeInfinityReturns a value indicating whether the specified number evaluates to negative return false;
infinity. else
IsPositiveInfinityReturns a value indicating whether the specified number evaluates to positive return true;
infinity. }

V. Niculescu - MAP 109 V. Niculescu - MAP 110

Exemplu : clasa
class MyClass public int MyProperty class Test
{ { {
public MyClass() get static void Main()
{ { {
Console.WriteLine return myField; MyClass a = new MyClass(); • Constructorii instanta sunt membri care implementeaza actiuni cerute pentru initializarea
("Constructor instanta"); } MyClass b = new MyClass(1); fiecarui obiect.
} set Console.WriteLine("MyConst={0}",
public MyClass( int value ) { MyClass.MyConst);
• Destructorul
{ myField = value; //a.myField++; – nu are parametri,
myField = value; } a.MyMethod();
Console.WriteLine("Constructor } a.MyProperty++;
– nu poate avea modificatori de acces,
instanta"); public int this[int index] Console.WriteLine – nu poate fi apelat explicit ci este apelat automat de catre garbage collector.
} { ("a.MyProperty={0}", a.MyProperty);
public const int MyConst = 12; get • Constructorul static este un membru care implementeaza actiuni necesare pentru a initializa
a[3] = a[1] = a[2];
{ Console.WriteLine("a[3]={0}", a[3]); o clasa, mai exact membrii statici ai clasei.
private int myField = 42; return 0; MyClass c = a + b; – Nu poate avea parametri,
}
public void MyMethod() set internal class MyNestedType
– nu poate avea modificatori de acces,
{ { {} – nu este apelat explicit, ci automat de catre sistem.
Console.WriteLine Console.WriteLine("t }
("this.MyMethod"); his[{0}]={1}", • Indexatorul este un membru care permite unui obiect sa fie indexat ın acelasi mod ca un
} index, value); tablou (C++: supraıncarcarea operatorului []).
} }
public static MyClass }
operator+(MyClass a, MyClass b) • Operatorul este un membru care defineste semnificatia (supraıncarcarea) unui operator care
{ se aplica instantelor unei clase.
return
new MyClass(a.myField + b.myField); – Se pot supraıncarca operatorii binari, unari si de conversie.
}
}
V. Niculescu - MAP 111 V. Niculescu - MAP 112

28
10/12/2015

Proprietati Exemplu

• O proprietate este un membru care permite acces la partea de stare a using System; }
unei clase.
class Circle }
• Proprietatile sunt extensii naturale ale campurilor, dar!!! ele nu presupun
alocarea de memorie. {
• Sintaxa: private double radius; class Test
modificator-de-proprietate{opt} public double Radius {
tip numeproprietate
definitie-get{opt} { static void Main()
definitie-set{opt}
get{return radius;} {
• Modificatorii de acces sunt: protected, internal, private, protected internal,
public. set Circle c = new Circle();
{radius = value;} c.Radius = 10;
V. Niculescu - MAP 113
} Console.WriteLine(‘‘Are
V. Niculescu - MAP 114

public double Area a: {0}’’, c.Area);


{ c.Area = 15;
get{return Math.PI * Console.WriteLine(‘‘Ra
radius * radius;} dius: {0}’’. c.Radius)
Java
Curs 3 set{radius = }
Math.Sqrt(value/Mat }
• Clase:
– definire membrii
–Membrii h.PI);}
–Mostenire – instantiere
–Clase abstracte
–Interfete
–Legare dinamica

– Singleton Pattern

Diferente: Java vs. C#

V. Niculescu - MAP 115 V. Niculescu - MAP 116

29
10/12/2015

Clasa cu constructor implicit Constructor

public class Circle {


class Circle{
public double x, y; // . . .
// The coordinates of the center public Circle(double x, double y, double r) {
public double r;
this.x = x;
// The radius
this.y = y;
// Methods that return the this.r = r;
// circumference and area of the circle }
public double circumference() {
return 2 * 3.14159 * r;
} public static void main(String args[]){
public double area() { Circle c = new Circle(10.0,10.0,20);
return 3.14159 * r*r; // Circle c=new Circle(); incorect
} }
public static void main(String args[]){
Circle c = new Circle(); }
}
}

Curs 3 - MEP 117 Curs 3 - MEP 118


V. Niculescu - MAP 117 V. Niculescu - MAP 118

Mai multi constructori Apelul unui constructor in alt constructor

public class Circle { public class Circle {


public double x, y, r; public double x, y, r;

public Circle(double x, double y, double r) { public Circle(double x, double y, double r) {


this.x = x; this.y = y; this.r = r; } this.x = x; this.y = y; this.r = r;
}
public Circle(double r) {
public Circle(double r) {
x = 0.0; y = 0.0; this.r = r; } this(0.0,0.0,r);
public Circle(Circle c) { }
x = c.x; y = c.y; r = c.r; } public Circle(Circle c) {
public Circle() { this(c.x, c.y, c.r);
// x = 0.0; y = 0.0; r = 1.0; } }
public Circle() {
public double circumference() { // x = 0.0; y = 0.0; r = 1.0;
return 2 * 3.14159 * r; } }
public double area() { public double circumference() {
return 2 * 3.14159 * r; }
return 3.14159 * r*r; }
public double area() { return 3.14159 * r*r; }
} }
• Regula: apelul altui constructor = prima instructiune

Curs 3 - MEP 119 Curs 3 - MEP 120


V. Niculescu - MAP 119 V. Niculescu - MAP 120

30
10/12/2015

Variabile de tip clasa (statice) Observatii:

public class Circle {


public double x, y, r; . Datele membru statice nu se memoreaza ca stare a obiectului.
1

public static int num_obj; 2. Unei date membru statice i se aloca memorie o singura data
public Circle(double x, double y, double r) {
indiferent de numarul obiectelor de tipul clasei respective existente
this.x = x; this.y = y; this.r = r; in memorie.
num_obj++; 3. Referirea datelor membre statice se face astfel:
}
// ...
NumeClasa.numeDataMembru sau
public static void main(String args[]){ numeObiect.numeDataMembru.
System.out.println(Circle.num_obj);
Circle c = new Circle(10.0,10.0,20);
System.out.println(Circle.num_obj); 4. Daca o data membru statica nu este initializata explicit, atunci ea va
} fi initializata cu valoarea implicita corespunzatoare tipului sau.

Curs 3 - MEP 121 Curs 3 - MEP 122


V. Niculescu - MAP 121 V. Niculescu - MAP 122

Initializator static Metode de tip clasa (statice)

public class Circle { public class Circle {


public double x, y, r;
static private double sines[] = new double[1000];
static private double cosines[] = new double[1000]; // An instance method.
// A static initializer "method" that fills them in. public Circle bigger(Circle c) {
// Notice the lack of any method declaration! if (c.r > r) return c;
else return this;
static { }
// A class method.
double x, delta_x; int i; public static Circle bigger(Circle a, Circle b) {
if (a.r > b.r) return a;
delta_x = (Math.PI/2)/(1000-1); else return b;
for(i = 0, x = 0.0; i < 1000; }
// . . .
i++, x += delta_x) { public static void main(String args[]){
sines[i] = Math.sin(x); Circle c1 = new Circle(10.0,10.0,20);
Circle c2=new Circle();
cosines[i] = Math.cos(x); if ( c1.bigger(c2)==c1 )
System.out.println(“c1 is bigger than c2”);
} if ( Circle.bigger(c1, c2)==c1 )
} // . . . }
System.out.println(“c1 is bigger than c2”);
}
}
Curs 3 - MEP 123 Curs 3 - MEP 124
V. Niculescu - MAP 123 V. Niculescu - MAP 124

31
10/12/2015

Observatii: C#

1. Metodele de tip clasa (statice) se declara folosind atributul static in fata. • Clase:
– Definire membrii
2. O metoda statica nu poate folosi direct membrii nestatici ai clasei (atribute sau metode)!
– Instantiere
3. Metodele statice pot apela doar alte metode statice si pot referi doar atributele statice.

4. In implementarea unei metode statice nu se poate folosi cuvantul this.


(... Ce inseamna this?)

Curs 3 - MEP 125


V. Niculescu - MAP 125 V. Niculescu - MAP 126

Exemplu : clasa
class MyClass public int MyProperty class Test
{ { {
public MyClass() get static void Main()
{ { {
Console.WriteLine return myField; MyClass a = new MyClass(); • Constructorii instanta sunt membri care implementeaza actiuni cerute pentru initializarea
("Constructor instanta"); } MyClass b = new MyClass(1); fiecarui obiect.
} set Console.WriteLine("MyConst={0}",
public MyClass( int value ) { MyClass.MyConst);
• Destructorul
{ myField = value; //a.myField++; – nu are parametri,
myField = value; } a.MyMethod();
Console.WriteLine("Constructor } a.MyProperty++;
– nu poate avea modificatori de acces,
instanta"); public int this[int index] Console.WriteLine – nu poate fi apelat explicit ci este apelat automat de catre garbage collector.
} { ("a.MyProperty={0}", a.MyProperty);
public const int MyConst = 12; get • Constructorul static este un membru care implementeaza actiuni necesare pentru a initializa
a[3] = a[1] = a[2];
{ Console.WriteLine("a[3]={0}", a[3]); o clasa, mai exact membrii statici ai clasei.
private int myField = 42; return 0; MyClass c = a + b; – Nu poate avea parametri,
}
public void MyMethod() set internal class MyNestedType
– nu poate avea modificatori de acces,
{ { {} – nu este apelat explicit, ci automat de catre sistem.
Console.WriteLine Console.WriteLine("t }
("this.MyMethod"); his[{0}]={1}", • Indexatorul este un membru care permite unui obiect sa fie indexat ın acelasi mod ca un
} index, value); tablou (C++: supraıncarcarea operatorului []).
} }
public static MyClass }
operator+(MyClass a, MyClass b) • Operatorul este un membru care defineste semnificatia (supraıncarcarea) unui operator care
{ se aplica instantelor unei clase.
return
new MyClass(a.myField + b.myField); – Se pot supraıncarca operatorii binari, unari si de conversie.
}
}
V. Niculescu - MAP 127 V. Niculescu - MAP 128

32
10/12/2015

Proprietati Exemplu
using System; class Test
class Circle {
• O proprietate este un membru care permite acces la partea de stare { static void Main()
a unei clase.
private double radius; {
public double Radius Circle c = new Circle();
• Proprietatile sunt extensii naturale ale campurilor. { c.Radius = 10;
get{return radius;} Console.WriteLine(‘‘Area: {0}’’, c.Area);
• Sintaxa: set c.Area = 15;
{radius = value;} Console.WriteLine(‘‘Radius: {0}’’. c.Radius)
} }
modificator-de-proprietate{opt}
public double Area }
tip numeproprietate {
definitie-get{opt} get{return Math.PI * radius * radius;}
definitie-set{opt} set{radius = Math.Sqrt(value/Math.PI);}
}// nerecomandata!!!
• Modificatorii de acces sunt: protected, internal, private, protected Preferabil Read Only
internal, public. }

V. Niculescu - MAP 129 V. Niculescu - MAP 130

Sintaxa Clase
Comparatie Java versus C# • Java • C#
[public] [final ] class A{ [public][sealed] class A{
} }

• Mostenire
class A extends B{ class A: B {
} }
• implementare interfete
class implements I1, I2{ class A : I1, I2 {
} }

• clase statice
static class MyStaticClass
{
//membri statici
}

V. Niculescu - MAP 131 V. Niculescu - MAP 132

33
10/12/2015

Modificatori acces – membrii clase Constructori


• tip instanta • tip instanta

class A{ class A{
public A(){... public A(){...
} }
} }

• initializator static • constructor static


Accessible to: public protected package private
static{ public static A(){...}
Same class yes yes yes yes
Class in same package yes yes yes no }
Subclass in different package yes yes no no
Non-subclass, different package yes no no no

V. Niculescu - MAP 133 V. Niculescu - MAP 134

Apel explicit constructor clasa de baza


Constructori
- exemplu
• modificator acces: • modificator acces: super base
– public, protected, private – public, protected, internal, private, • apel super() • initializator de constructor

extern. public class Employee


public class Employee
{
• declarator de constructor: {
protected string name;
protected string name;
nume-clasa ([lista-parametrilor-formali]) • declarator de constructor: protected string ssn; protected string ssn;
public Employee( string name, string ssn) public Employee( string name, string ssn)
nume-clasa ([lista-parametrilor-formali]) {
{
• apel alt constructor [initializator-de-constructor] this.name = name; this.name = name;
this.ssn = ssn; this.ssn = ssn;
} }
this([ lista-argumente]) • initializatorul-de-constructor : } }
public class Salaried extends Employee public class Salaried : Employee
{ {
: base( [lista-argumente]) protected double salary; protected double salary;
public Salaried(string name, string ssn, double salary) public Salaried(string name, string ssn, double salary):
sau {
base(name, ssn)
{
: this([ lista-argumente]). super(name, ssn);
this.salary = salary;
this.salary = salary;
}
}
}
}

V. Niculescu - MAP 135 V. Niculescu - MAP 136

34
10/12/2015

Shadowed Variables Proprietati


class A{ int x; // . . .}
class B extends A { int x; // . . .}
• base class Cerc{ • Modificatorii de acces: protected, internal,
... private, protected internal, public.
class C extends B {int x; // . . . } in loc de double raza;
class Cerc{
inside the definition of a method from C: • super public double get(){
...
return raza;
double raza;
x // Variable x in class C. }
this.x // Variable x in class C. public double Raza{
public void set(double value){
get{
super.x // Variable x in class B. raza = value;
return raza;
}
}
((B)this).x // Variable x in class B. }
set{
...
((A)this).x // Variable x in class A. raza = value;
public static void Main(){
}
super.super.x // Illegal; does not refer Cerc c = new Cerc();
}
to x in c.set( 10 );...
...
// class A. }
public static void Main(){
Cerc c = new Cerc();
c.Raza = 10;...
}

137
V. Niculescu - MAP 137 V. Niculescu - MAP 138

Legare statica – legare dinamica Indexatori


Un indexator este o generalizare a supraıncarcarii operatorului [] din C++.
• metode virtuale implicit • similar C++
nu exista [modificatori] declarator-de-indexator
• metode virtuale sau nevirtuale {declaratii-de-accesori}

• cuvant rezervat: virtual • Modificatori: new, public, protected, internal, private, protected internal,
virtual, sealed, override, abstract, extern.

• Declaratorul deindexator are forma:


tip-de-retur this[lista-parametrilor-formali]

• Lista parametrilor formali trebuie sa contina cel putin un parametru si


nu poate sa aibe vreun parametru de tip ref sau out.
– ex: un arg. de tip int (vector), doua arg. de tip int (matrice), alte
tipuri (~search)

• Declaratiile de accesor vor contine accesor get sau accesor set.

V. Niculescu - MAP 139 V. Niculescu - MAP 140

35
10/12/2015

Exemplu: indexator Suprascriere operatori(1)


• nu exista • similar C++
using System; class Test Reguli:
class MyVector { 1. Orice operator trebuie sa fie declarat public si static!!!
{ static void Main() 2. Parametrii unui operator trebuie sa fie transmisi prin valoare;
private double[] v; {
public MyVector( int length ) Exemple:operatori unari (true, false)
MyVector v = new MyVector( 10 );
{ Operatorii true si false trebuie sa fie ori ambii definiti, ori nici unul (altfel apare o eroare
v = new double[ length ]; v[0] = 0;
v[1] = 1; de compilare).
} if( a==true )
public int Length for( int i=2; i<v.Length; i++)
{ if( a==false )
{
get v[i] = v[i-1] + v[i-2];
{ return v.Length;} public struct DBBool
} {
} for( int i=0; i<v.Length; i++) private int x;
public double this[int index] { public static bool operator true(DBBool x)
{ {
Console.WriteLine(‘‘v[‘‘ + i.ToString() + ‘‘]=’’ + v[i]);
get return x.value > 0;
{ return v[ index]; } }
}
set }
public static bool operator false(DBBool x)
{v[index] = value;} } {
} return x.value <= 0;
} }
...
}

V. Niculescu - MAP 141 V. Niculescu - MAP 142

Suprascriere operatori(2) Suprascriere operatori(3)


• nu exista • operatori binari: • nu exista • operatori de conversie
def. in pereche: – implicit operator tip (tip parametru) corp
1. operatorii == ¸si != – explicit operator tip (tip parametru) corp
2. operatorii > ¸si <
Reguli: S= sursa, T=destinatie
3. operatorii >= ¸si <= 1. S si T sunt tipuri diferite
2. Unul din cele doua tipuri este clasa ın care se face definirea.
• Daca se redef. operatorul ==, trebuie definita si metoda Equals() si 3. T si S nu sunt objecte sau tip interfata.
viceversa. 4. T si S nu sunt baze una pentru cealalta.
• Nu se pot supraıncarca operatorii + =,− =, / =, =; public class Digit
– pentru ca acestia sa functioneze diferit, este suficient sa se { byte value;
public Digit(byte value)
supraıncarce operatorii corespunzatori: +,−, /, . { if (value < 0 || value > 9) throw new ArgumentException();
this.value = value; }

public static implicit operator byte(Digit d)


{ return d.value;}
public static explicit operator Digit(byte b)
{ return new Digit(b);}
}

V. Niculescu - MAP 143 V. Niculescu - MAP 144

36
10/12/2015

Clase abstracte Implementare interfata - UML notation

abstract class Shape abstract class Shape


{ {
public abstract void draw(); public abstract void Draw(); Comparable
} } <<interface>> Comparable

• orice metoda abstracta este automat si


virtuala!

Rational
Rational

146
V. Niculescu - MAP 145 V. Niculescu - MAP 146

Interfete Conversii: downcast, upcast


O interfata poate sa mosteneasca de la zero sau mai multe interfete. <ref_instanta_clasa_baza> = <ref_instanta_clasa_derivata>; (implicit)
• implementare
– implicita (similar Java)
• metoda implementatoare poate fi virtuala sau nu!!!
interface IMyInterface • Properties and indexers of a class can define extra
<ref_instanta_clasa_derivata> = (<clasa_derivata>) <ref_instanta_clasa_baza> (explicit)
{ accessors for a property or indexer that's defined in an
void F(); interface.
} – explicita
class MyClass implements IMyInterface permite ascunderea metodelor mostenite dintr-o interfata, acestea
{ devenind private (calificarea lor ca fiind publice este semnalata ca o
eroare).
public void F()
• acces doar prin cast la interfata
{
//...
interface IMyInterface
}
{
}
void F();
}
class MyClass : IMyInterface
{
void IMyInterface.F()
{
//...
}
}

V. Niculescu - MAP 147 V. Niculescu - MAP 148

37
10/12/2015

Override Exemplu: new versus override


class BaseClass
{
• Adnotari • Cuvant cheie: override public virtual void Method1()
{
Console.WriteLine("Base - Method1");
@Override public override bool Equals(Object o){ }
public boolean equals(Object o){ }
public virtual void Method2()
} {
Console.WriteLine("Base - Method2");
}
• cuvant cheie: new }
class DerivedClass : BaseClass
{
public new bool Equals(Object o){ public override void Method1()
} {
Console.WriteLine("Derived - Method1");
}

public new void Method2()


{
Console.WriteLine("Derived - Method2");
}
}

V. Niculescu - MAP 149 V. Niculescu - MAP 150

using System;
using System.Text;
namespace OverrideAndNew
{ class Program
{ static void Main(string[] args)
{
“Hiding”
BaseClass bc = new BaseClass();
DerivedClass dc = new DerivedClass();
BaseClass bcdc = new DerivedClass();
class Base
// The following two calls do what you would expect. They call
// the methods that are defined in BaseClass. {
bc.Method1();
bc.Method2(); public static void F() {}
// Output:
// Base - Method1 }
// Base - Method2
class Derived: Base
// The following two calls do what you would expect. They call {
// the methods that are defined in DerivedClass.
dc.Method1(); new private static void F() {} // Hides Base.F in Derived only
dc.Method2();
// Output: }
// Derived - Method1
// Derived - Method2 class MoreDerived: Derived
// The following two calls produce different results, depending
{
// on whether override (Method1) or new (Method2) is used. static void G() { F(); } // Invokes Base.F
bcdc.Method1();
bcdc.Method2(); }
// Output:
// Derived - Method1
// Base - Method2
}
}
V. Niculescu - MAP 151 V. Niculescu - MAP 152
}

38
10/12/2015

Singleton pattern

• se permite instantierea unui singur obiect pentru o clasa

• implementarea se bazeaza pe folosirea


– membrilor statici si
– constructor privat
Curs 4
–Delegati
–Nullable (C#)
–Garbage Collection
–Clase incuibate
–Pachete/ Spatii de nume
– Adapter design pattern

V. Niculescu - MAP 153 V. Niculescu - MAP 154

Operatorul “as” Delegati

• Acest operator este folosit pentru conversii explicite, returnand un obiect de tipul la • Problema: trebuie sa se execute o anumita actiune, dar nu se stie dinainte care
care se face conversia sau null daca conversia nu se poate face (nu se arunca anume, sau chiar ce obiect va trebui efectiv utilizat.
exceptii).
• Determinarea validitatii conversiei se face testand valoarea rezultata fata de null: • Un delegat este un tip referinta folosit pentru a ıncapsula o metoda cu un anumit
daca rezultatul e null atunci conversia nu s–a putut face. antet
• Orice metoda care are acest antet poate fi legata la un anumit delegat.
Exemplu:
Employee e =new Salaried(“Pop”, 12345);
Salaried s = e as Salaried;
if (s != null)
{
//se lucreaza cu instanta valida de tip Salaried
}

V. Niculescu - MAP 155 V. Niculescu - MAP 156

39
10/12/2015

Delegati Exemplu:
Problema: trebuie sa se execute o anumita actiune, dar nu se stie dinainte care
anume, sau chiar ce obiect va trebui efectiv utilizat.
using System;
•Un delegat este un tip referinta folosit pentru a ıncapsula o metoda cu un anumit antet
namespace AplicatieDeTest
•Orice metoda care are acest antet poate fi legata la un anumit delegat. {
class Program
• Simulare: public {
delegate int WhichIsFirst(object obj1, object obj2); private delegate int Delegat1(string sir_f);
public interface Delegate{ static int lungime_sir(string sir)
int WhichIsFirst(object obj1, object obj2); class Pair{
{
} private object[] thePair = new object[2];
public void Sort( WhichIsFirst theDelegatedFunc ) return sir.Length;
class Pair{ { }
private object[] thePair = new object[2]; if (theDelegatedFunc(thePair[0],thePair[1]) ==2){
object temp = thePair[0];
static void Main()
public void Sort( Delegate del ) {
{ thePair[0] = thePair[1]; Delegat1 instanta_Delegat=new Delegat1(lungime_sir);
if (del.WhichIsFirst(thePair[0],thePair[1]) ==2){ thePair[1] = temp;}
object temp = thePair[0]; }
Console.Write(instanta_Delegat(“tra la la"));
thePair[0] = thePair[1]; } }
thePair[1] = temp;} }
}} }

V. Niculescu - MAP 157 V. Niculescu - MAP 159

Simulare Java
Metode anonime
interface Delegate1{
int functie(string sir); class SomeClass class SomeClass
} { {
class Lungime implements Delegate1{ delegate void SomeDelegate(); delegate void SomeDelegate();
public int functie(string sir){ public void InvokeMethod() public void InvokeMethod()
return sir.length();
{ {
}
SomeDelegate del = new SomeDelegate del = delegate()
}
SomeDelegate(SomeMethod); {
del(); MessageBox.Show("Hello");
class Program
{ } };
public static void main(String []a) void SomeMethod() del();
{ {
Delegat1 instanta_Delegat=new Lungime(); }
MessageBox.Show("Hello"); }
System.out.println(instanta_Delegat.functie(“tra la la"));
} }
} }

V. Niculescu - MAP 160 V. Niculescu - MAP 161

40
10/12/2015

Exemplu cu parametrii Nullable

class SomeClass • Nullable types = instante ale structurii System.Nullable<T>


{
delegate void SomeDelegate(string str); • Un astfel de tip permite instantelor sale sa ia valori din intervalul corespunzator
public void InvokeMethod() tipului de baza PLUS valoarea aditionala null .
{
SomeDelegate del = delegate(string str)
• Exemple:
{
MessageBox.Show(str);
Nullable<Int32> : [-2147483648, 2147483647] U {null}
};
del("Hello");
}
ANullable<bool> : { true, false, null}
}

V. Niculescu - MAP 162 V. Niculescu - MAP 164

Exemplu Garbage Collection


class NullableExample
{
• Garbage collection determina ce obiecte nu mai sunt referite de catre nici o referinta si
static void Main()
pentru acestea elibereaza memoria.
{
int? num = null;
– obiectele pot retine diferite tipuri de resurse: descriptori de fisiere, socheturi, etc.
if (num.HasValue) System.Console.WriteLine("num = " + num.Value);  metode folosite pentru asigurarea operatiilor de tipul: inchidere fisiere, inchiderea
else System.Console.WriteLine("num = Null"); conexiunilor de retea…

int y = num.GetValueOrDefault(); //zero


try
{ • Garbage collection consista in urmatorii pasi of the following steps:
y = num.Value; // throws an InvalidOperationException if num.HasValue is false – colectorul ‘cauta’ obiectele care nu mai sunt referite.
} – colectorul ‘incearca’ sa finalizeze aceste obiecte.
catch (System.InvalidOperationException e) – colectorul elibereaza memoria pentru obiectele nereferite.
{
System.Console.WriteLine(e.Message);
}
}
}

Curs 3 - MEP 166


V. Niculescu - MAP 165 V. Niculescu - MAP 166

41
10/12/2015

Destructori
• nu exista • sintaxa:
• System.GC
• metoda finalize ~<NumeClasa>()
protected void finalize() { public static class GC
}

• doar unul pentru o clasa • Collect()


• nu poate avea modificatori de acces – forteaza eliberarea memoriei
• nu se pot mosteni
• KeepAlive
• un destructor se translateaza intr-o suprascriere
a
• metodei Finalize() din clasa Object
– unde se face apel al metodei Finalize() din
clasa de baza corespunzatoare

•apelare automata
•fara parametrii

V. Niculescu - MAP 167 V. Niculescu - MAP 168

Reguli pentru finalize Example: static, garbage collector and finalization


class NrObj{
public int val;
• Daca un obiect are un finalizator atunci acea metoda este apelata inainte eliberarea zonei de public static int nrobj;
memorie corespunzatoare lui. public static NrObj x[]=new NrObj[100];
public NrObj(){
• Interpretorul Java isi poate incheia executia inainte ca GC sa elibereze toate obiectele nrobj++;
nereferite => deci este posibil ca finalizatorii sa nu fie apelati. val = nrobj;
(In general resursele sunt eliberate in acest caz de catre sistem.) System.out.println(":"+nrobj+":");
}
• Nu se poate cunoaste exact momentul in care un obiect este distrus si prin urmare nici cand protected void finalize(){
un finalizator este apelat. Ordinea in care obiectele sunt eliberate nu este in mod necesar nrobj--;
aceeasi cu cea in care ele au ramas nereferite. System.out.println(">"+nrobj+">");
x[nrobj]=this; //resurrection
}
– Un finalizator poate sa “readuca la viata” un obiect prin crearea unei referinte la el. public static void main(String args[]){
– Un finalizator nu este apelat decat o singura data. for(int i=0;i<10;i++) new NrObj();
System.gc();
// System.runFinalization();
for(int i=0;i<10;i++)
System.out.println(NrObj.x[i].val);

}
}///:~

Curs 3 - MEP 169


V. Niculescu - MAP 169 V. Niculescu - MAP 170

42
10/12/2015

public class Garbage {


Example: garbage collector and finalization public static void main(String[] args) {
// As long as the flag hasn't been set,
class Chair { // make Chairs and Strings:
static boolean gcrun = false; while(!Chair.f) {
static boolean f = false; new Chair();
static int created = 0; new String("To take up space");
static int finalized = 0; int i; }
Chair() { System.out.println( "After all Chairs have been created:\n" +
i = ++created; "total created = " + Chair.created + ", total finalized = " +
if(created == 47) System.out.println("Created 47"); Chair.finalized);
} // Optional arguments force garbage
public void finalize() { // collection & finalization:
if(!gcrun) { // The first time finalize() is called: if(args.length > 0) {
gcrun = true; if(args[0].equals("gc") || args[0].equals("all")) {
System.out.println( "Beginning to finalize after " + System.out.println("gc():");
created + System.gc();
" Chairs have been created");
}
}
if(i == 47) { if(args[0].equals("finalize") || args[0].equals("all")) {
System.out.println( "Finalizing Chair #47, " + System.out.println("runFinalization():");
"Setting flag to stop Chair creation"); System.runFinalization();
f = true; }
} }
finalized++; System.out.println("bye!");
if(finalized >= created) }
System.out.println( "All " + finalized + " finalized"); } ///:~
}
}
V. Niculescu - MAP 171 V. Niculescu - MAP 172

Nested classes
class OuterClass {
...
static class StaticNestedClass {
...
Clase incuibate }
class InnerClass {
...
}
}
• Note: A static nested class interacts with the instance members of its outer class (and other classes) just
like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been
nested in another top-level class for packaging convenience.

• Static nested classes are accessed using the enclosing class name:
OuterClass.StaticNestedClass

OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();

174
V. Niculescu - MAP 173 V. Niculescu - MAP 174

43
10/12/2015

Inner Classes Local and Anonymous Inner Classes

• Objects that are instances of an inner class exist


within an instance of the outer class. • There are two additional types of inner classes:
– You can declare an inner class within the body of a method. Such a class is known as a local inner
class OuterClass { class.
...
class InnerClass {
... – You can also declare an inner class within the body of a method without naming it. These classes
} are known as anonymous inner classes.
}

Types of Nested Classes


Type Scope Inner
• An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the
methods and fields of its enclosing instance. static nested class member no
inner [non-static] class member yes
• An InnerClass Exists Within an Instance of OuterClass
local class local yes
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
anonymous class only the point where it is defined yes

175 176
V. Niculescu - MAP 175 V. Niculescu - MAP 176

Static Nested Classes – Inner Classes – non-static class members


public class LinkedList {
public static class Node{
private Object e; • O instanta a clasei inner este intotdeauna asociata cu un obiect a clasei outer (are o referinta
private Node link;
public Object getObject(){return e;}
catre ecesta).
public Node getNext(){return link;}
public void setNext(Node node){ link = node;} • Inversa nu este adevarata!
}
private Node head;
public Node getHead() { return head; } • clasele inner classes cnu pot avea membrii statici (exceptie: final static).
public void insert(Node node) { ... }
public remove(Node node) { ... }
// . . . • In clasa inner se pot folosi membrii clasei outer prin simpla numire.
public static void main(String args[]){
// . . .
• Clasa outer are acces la toti membrii (inclusiv cei privati) ai clasei inner –
LinkedList l = new LinkedList();
LinkedList.Node n = l.getHead(); prin intermediul unei referinte la o instanta a clasei inner.
}

• Nested Interfaces

177 178
V. Niculescu - MAP 177 V. Niculescu - MAP 178

44
10/12/2015

Inner class - Exemplu Local and Anonymous Inner Classes

public class LinkedList {


private Node head; • Local inner classes = classes defined in a code block
// . . . (method, constructor or initialization body)
class ListIterator implements Iterator{ • Anonymous inner classes = local inner classes without a name
private Node p;
ListIterator(){ p = head;}
boolean hasNext(){ return (p!=null);}
button.addActionListener( new ActionListener() {
Object next() { Object e = p->getObject();
p = p ->getNext(); public void actionPerformed(ActionEvent e) {
return e; } numClicks++;
} s=new String(text.getSelectedText());
Iterator iterator(){ label.setText(labelPrefix + numClicks+ s );
return new ListIterator();
} }
public static void main(String args[]){ });
LinkedList l = new LinkedList();
Iterator i = l.iterator();
// . . .
}
}

179 180
V. Niculescu - MAP 179 V. Niculescu - MAP 180

Nested classes – similar nested classes in Java

using System;
Nested Classes in C# class A
{
class B
{
public static void F()
{
Console.WriteLine(‘‘A.B.F’’);
}
}
static void Main()
{
A.B.F();
}
}
• o clasa C# imbricata se comporta ca un membru static al tipului continator.

V. Niculescu - MAP 181 V. Niculescu - MAP 182

45
10/12/2015

UML – nested classes

• Exemplu: Lista inlatuita cu iterator

V. Niculescu - MAP 183 V. Niculescu - MAP 184

Pachete Java Pachet: unitate de biblioteca

• Definirea unei clase a.i. sa apartina unui pachet


• Pachet = colectie de clase (prima instructiune)
package mypackage;
public class Vector {
• Se folosesc pentru partitionarea spatiilor de // . . .
nume }
• folosirea unei clase definita intr-un pachet
• Introduc un nou tip de acces la membrii claselor //. . .
mypackage.Vector m = new mypackage.Vector();
ori
• Un pachet poate contine alte pachete
 ierarhie de pachete import mypackage.*;
// . . .
Vector m = new Vector();
• Pachete  Structura de directoare

Curs 3 - MEP 185 Curs 3 - MEP 186


V. Niculescu - MAP 185 V. Niculescu - MAP 186

46
10/12/2015

Java ClassPath Nume complete in Java

• Implicit interpretorul Java cauta clasele definite de


programator in si relativ la directorul curent.
• Se poate seta variabila de mediu CLASSPATH a.i. sa se dea si
alte cai de cautare.
• Interpretorul adauga intodeauna calea spre clasele sistem
la sfarsitul cailor precizate de aceasta variabila.
Exemple:
-UNIX:
CLASSPATH = .:/home
- Windows:
CLASSPATH = .;C:\home;
Curs 3 - MEP 187 Curs 3 - MEP 188
V. Niculescu - MAP 187 V. Niculescu - MAP 188

Coliziuni
Pachete din Java API

Package name Contents


java.applet Applet classes
java.awt Graphics, window, and GUI classes
java.awt.datatransfer Data transfer (e.g., cut-and-paste) classes
import mypackage.util.*; java.awt.event Event processing classes and interfaces
java.awt.image Image processing classes
import java.util.*; java.awt.peer GUI interfaces for platform independence
java.beans JavaBeans component model API
java.io Various types of input and output classes
java.lang Core language classes
//coliziune: java.lang.reflect Reflection API classes
java.math Arbitrary precision arithmetic
java.net Networking classes

Vector v = new Vector(); java.rmi


java.rmi.dgc
Remote Method Invocation classes
RMI-related classes
java.rmi.registry RMI-related classes
java.rmi.server RMI-related classes

java.util.Vector v = new java.security


java.security.acl
Security classes
Security-related classes
java.util.Vector(); java.security.interfaces Security-related classes
java.sql JDBC SQL API for database access
java.text Internationalization classes
java.util Various useful data types
java.util.zip Compression and decompression classes
Curs 3 - MEP 189 Curs 3 - MEP 190
V. Niculescu - MAP 189 V. Niculescu - MAP 190

47
10/12/2015

Spatii de nume C#

using System;
Spatii de nume C#
namespace Curs3
{
public class Buffer
{
public Buffer()
{
Console.WriteLine("Bufferul meu!");
}
}
}

V. Niculescu - MAP 191 V. Niculescu - MAP 192

Se pot de asemenea crea spatii de nume imbricate.


Directiva using Def: un spatiu de nume este o colectie de tipuri sau de alte spatii de nume.

using System; class A namespace N1 namespace N1.N2


class A { { {
{ static void Main() namespace N2 class A{}
static void Main() { { }
{ System.Console.WriteLine("Mesaj"); class A{} namespace N1.N2
Console.WriteLine("Mesaj"); } class B{} {
} } } class B{}
} } }
__________________________________
namespace N1.N2
{
class A{}
class B{}
}

V. Niculescu - MAP 193 V. Niculescu - MAP 194

48
10/12/2015

Ambiguitati - coliziuni Directiva using ca alias


namespace N1 • solutie: calificare completa namespace N1.N2 namespace N3
{
{ {
class A{}
} class A{} using N = N1.N2;
namespace N2 } class B
{ namespace N3 {
class A{}
{ N.A obj = null;
}
namespace N3 using a = N1.N2.A; }
{ class B }
using N1; {
using N2;
a obj = null;
class B
{ }
A a = null; }
//ambiguitate: N1.A sau N2.A?
}
}

O directiva alias afecteaza doar blocul ın care este definita!


V. Niculescu - MAP 195 V. Niculescu - MAP 196

Sablonul Adapter (Wrapper) Adapter pattern – object adapter

Aplicabilitate :

• Vrem sa folosim o clasa existenta si interfata pe care o folosim nu se potriveste cu


cea de care avem nevoie.

• Vrem sa folosim o clasa reutilizabila pentru a coopera cu alte clase.

• Vrem sa folosim mai multe sub-clase existente dar este imposibil de adaptat interfata
lor. (doar in cazul obiectului adaptor).

V. Niculescu - MAP 197 V. Niculescu - MAP 198

49
10/12/2015

Adapter pattern – class adapter Adapter pattern – class adapter - generalization

V. Niculescu - MAP 199 V. Niculescu - MAP 200

Disscusion…

How much adapting should be done?

– Simple interface conversion that just changes operation names and order of
arguments
CURS 5
– Totally different set of operations

• Use Adapter when you want to use something that you already have.
Bridge , Template Method, Strategy –
design patterns
Tratarea exceptiilor

V. Niculescu - MAP 201 V. Niculescu - MAP 202

50
10/12/2015

Sursa: http://www.codeproject.com/Articles/12183/Design-Your-Soccer-Engine-and-
Clasificarea sabloanelor (GoF) Learn-How-To-Apply-D

• Scop- “Pentru ce se foloseste?”


– Creational Patterns
– Structural Patterns
– Behavioral Patterns
• Mod de realizare
– Class Patterns
• Focus pe relatii intre clase
• Presupune reutilizare prin mostenire
– Object Patterns
• Focus pe relatii intre obiecte
• Presupune reutilizare prin compozitie

V. Niculescu - MAP 203 V. Niculescu - MAP 204

Clasificare sabloane –
Riehle and Zullighoven: “Understanding and Using References
Patterns in Software Development”
• Conceptual Pattern • Design Patterns: Elements of Reusable Object-Oriented Software,
– Descriere bazata pe termeni si concepte din domeniul aplicatiei Gamma, Helm, Johnson and Vlissides, Addison-Wesley, 1995
• Design Pattern • Design Patterns for Object-Oriented Software Development,Wolfgang Pree,
Addison-Wesley/ACM Press, 1995
– descriere bazata pe constructii specifice proiectarii software: obiecte,
• Patterns of Software: Tales From The Software Community,Richard P. Gabriel,
clase, mostenire, agregare… Oxford University Press, 1996
• Programming Pattern (Programming Idiom) • Pattern Oriented Software Architecture : A System of Patterns,Frank Buschmann
– descriere bazata pe constructii ale unui limbaj de programare. (Editor), Wiley, 1996
• Analysis Patterns: Reusable Object Models, Martin Fowler,Addison-Wesley, 1997
• AntiPatterns, Brown, Malveau, McCormick and Mowbray,Wiley, 1998
• Design Patterns Explained, Alan Shalloway and James R. Trott, Addison-Wesley,
2001

V. Niculescu - MAP 205 V. Niculescu - MAP 206

51
10/12/2015

• Core J2EE Patterns: Best Practices and Design Strategies, Alur,Crupi and • C# Design Patterns - A Tutorial, James W. Cooper, Addison-Wesley, 2002
Malks, 2001 • Design Patterns In C#, Steven John Metsker, Addison-Wesley,2004
• Design Patterns Java Workbook, Steven John Metsker, Addison-Wesley, • Head First Design Patterns, Freeman and Freeman, O'Reilly,2004
2002 • Core Security Patterns - Best Practices and Strategies for J2EE(TM), Web
• Applied Java Patterns, Stephen Stelting and Olav Maassen,Prentice Hall, Services, and Identity Management, Christopher Steel, Ramesh Nagappan
2002 and Ray Lai, Prentice Hall, 2005
• EJB Design Patterns: Advanced Patterns, Processes, and Idioms, Floyd • Refactoring To Patterns, Joshua Kerievsky, Addison-Wesley,2005
Marinescu, Wiley, 2002
• Patterns Of Enterprise Application Archictecture, Martin Fowler, Addison-
Wesley, 2002

V. Niculescu - MAP 207 V. Niculescu - MAP 208

Bridge Structura

Decupleaza o abstractie de posibilele ei implementari astfel incat sa poata varia


independent.

Context
• Cand o anumita abstractiune poate avea mai multe variante de
implementare, de obicei se utilizeaza mostenirea: o clasa abstracta defineste
interfata abstractiunii, iar subclasele concrete o implementeaza in diverse
moduri. Abstraction:
• Aceasta abordare nu este intotdeauna suficient de flexibila. defineste interfata abstractiunii;
• Prin mostenire o implementare este legata permanent de abstractiune si detine o referinta spre un obiect de tip Implementor.
RefinedAbstraction: extinde interfata Abstraction
acest lucru face foarte dificila modificarea independenta a abstractiunii si a
Implementor: defineste interfata pentru clasele ce contin implementari.
implementarii.
Aceasta interfata nu trebuie neaparat sa corespunda exact cu interfata
Abstraction. De fapt, cele 2 pot fi total diferite. De obicei Implementor ofera
doar operatii primitive, iar Abstraction defineste operatii de nivel mai inalt,
V. Niculescu - MAP 209
bazandu-se pe acele primitive; V. Niculescu - MAP 210
ConcreteImplem: implementeaza interfata Implementor.

52
10/12/2015

Aplicabilitate: Exemplu

• se doreste evitarea legarii unei abstractiuni de implementarea sa.


– Acest lucru se intampla de exemplu cand implementarea trebuie aleasa sau
modificata pe durata executiei;
• atat abstractiunea cat si implementarea trebuie sa poata fi extinse prin adaugarea de
subclase.
– In aces caz sablonul bridge permite combinarea dupa dorinta a diferitelor
abstractiuni si implementari.
• schimbarile aduse implementarii nu trebuie sa afecteze clientii, adica nu trebuie sa
necesite recompilarea codului acestora;
• se doreste ascunderea completa a implementarii fata de clienti;
• se constata ca extensiile care trebuie aduse unei abstractiuni duc la o crestere prea mare a
numarului de subclase.
– In acest caz se indica "spargerea" obiectelor in 2 parti, creindu-se 2 ierarhii separate.
Asemenea ierarhii se mai numesc "generalizari incuibate";
• se doreste partajarea unei implementari intre mai multe obiecte si acest fapt trebuie
ascuns fata de client.

V. Niculescu - MAP 211 V. Niculescu - MAP 212

Template Method Aplicabilitate


• Defineste schema unui algoritm lasand anumiti pasi a fi rezolkvati in subclase.
Template Method leasa subclasele sa redifineasca anumiti pasi al unui algoritm
• Pentru a implementa partile invariante ale unui algoritm doar odata si a alasa
fara sa schimbe structura algoritmului.
subclasele sa implementeze comportamenul care difera.
• Structura:

• Atunci cand comportamenul comun mai multor clase trebuie sa fie evidentiat si
localizat intr-o clasa comuna pentru a evita duplicarea de cod.

• Pentru a controla extinderea subclasarii.

V. Niculescu - MAP 213 V. Niculescu - MAP 214

53
10/12/2015

Template Method (exemplu) Template Method – Exemplu (1)


abstract class AppFramework { import java.util.*;
// Create a new "application":
public ApplicationFramework() { class MyApp extends AppFramework {
abstract class OperAllCollEl {
templateMethod(); void customize1() {
public void applyOper(Collection c) {
} System.out.print("Hello "); } Iterator i = c.iterator();
abstract void customize1(); void customize2() { while ( i.hasNext()){
abstract void customize2(); System.out.println("World!"); } Object e = i.next();
} operation(e);
// "private" means automatically "final": }
private void templateMethod() { }
for(int i = 0; i < 5; i++) { abstract public void operation(Object e);
customize1(); class TemplateMethodApp {
MyApp app = new MyApp(); }
customize2(); class Real{
} public void test() {
// The MyApp constr. does all the work. private double r;
} Real(double r){ this.r =r;}
} // This just makes sure it will complete
// without throwing an exception. void pow(int n){
} for(int i=0;i<n-1; i++) r*=r;
public static void main(String args[]) { new }
TemplateMethodApp().test(); public String toString(){return Double.toString(r); }
} }
}

V. Niculescu - MAP 215 V. Niculescu - MAP 216

Template Method – Example (2) Template Method – Example (3)

class Print extends OperAllCollEl{ public class Application{


public void operation(Object e){ public static void main(String args[]){
System.out.print(e+";"); Collection c1 = new HashSet();
} c1.add(new StringBuffer("unu"));
} c1.add(new StringBuffer("doi"));
class OperOnStrings extends OperAllCollEl{ OperAllCollEl op = new OperOnStrings();
public void operation(Object e){ op.applyOper(c1);
StringBuffer s = (StringBuffer) e; System.out.println();
s.toUpperCase();
} OperAllCollEl p = new Print();
} p.applyOper(c1);
class OperOnReals extends OperAllCollEl{
public void operation(Object e){ Collection c2 = new HashSet();
Real r = (Real) e ; c2.add(new Real(1.0));
r.pow(2); c2.add(new Real(2.0));
} op = new OperOnReals();
} op.applyOper(c2);
p.applyOper(c2);
}
}//:~

V. Niculescu - MAP 217 V. Niculescu - MAP 218

54
10/12/2015

Aplicatii ale Template Method in JFC: Strategy

• AbstractCollection : A Collection that is neither a Set nor a List, such as a bag. At a minimum, you must
provide the iterator and the size method. • Strategy este un obiect care reprezinta un algoritm.
• AbstractSet : A Set. Use is identical to AbstractCollection.
• Este folositor atunci cand :
• AbstractList : A List backed by a random-access data store (such as an array). At a minimum, you must
provide the positional access methods (get(int) and, optionally, set(int), remove(int), and add(int)) and the – se doreste inlocuirea unui algoritm static sau chiar dinamic;
size method. The abstract class takes care of listIterator (and iterator).
(public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> ) – exista mai multe variante ale algoritmului,
– sau atunci cand un algoritm are structuri de date complicate pe care doreste sa
• AbstractSequentialList : A List backed by a sequential-access data store (such as a linked list). At a le incorporeze.
minimum, you must provide the listIterator and size methods. The abstract class takes care of the positional
access methods. (This is the opposite of AbstractList.)

• AbstractMap : A Map. At a minimum you must provide the entrySet view. This is typically implemented
with the AbstractSet class. If the Map is modifiable, you must also provide the put method.

V. Niculescu - MAP 220 V. Niculescu - MAP 221

Strategy – Structura Strategy - Aplicabilitate

• Cand mai multe clase difera doar in comportament. “Strategy” furnizeaza


un mod de a configura o clasa cu una sau mai multe functionalitati.

• Cand este nevoie de mai multe variante ale unui algoritm. “Strategy” este
folosit atunci cand aceste variante sunt implementate ca o ierarhie de clase
de algoritmi.

• Cand un algoritm foloseste date pe care clientii nu ar trebui sa le cunoasca.


“Strategy” se foloseste pentru a evita expunerea structurilor de date
complexe specifice unui algoritm.

• Cand o clasa defineste mai multe comportamente si acestea apar in multiple


instructiuni conditionale. In loc de a folosi instructiuni conditionale
complexe, ramurile conditionale corespunzatoare se muta in clase Strategy.

V. Niculescu - MAP 222 V. Niculescu - MAP 223

55
10/12/2015

Exemplu: sursa-
http://a3ab771892fd198a96736e50.javacodegeeks.netdna-cdn.com/wp-
content/uploads/2013/08/Strategy-Pattern.png

Tratarea exceptiilor

V. Niculescu - MAP 224 V. Niculescu - MAP 225

Exception Handling – Tratarea exceptiilor (Java)


Exceptii
• Exceptie = un obiect care ıncapsuleaza informatie despre o situatie anormala. • Daca JVM sau mediul de executie detecteaza o cond. speciala, se arunca o exceptie
– implicit !
• Scop: pentru a semnala contextul ın care apare situatia deosebita
• Un program poate arunca o exceptie explicit prin instructiunea throw.

• exceptie != bug

• Exceptiile nu sunt gandite pentru a preveni bug–urile ci situatiile de executie • Clauza catch = exception handler
anormale
• exemple:
– incercarea de a deschide un fisier pentru care s-a introdus un nume eronat.
– impartire cu 0 pt numere intregi
• conditii speciale:
– “language semantic violation”
– “program-defined errors”

V. Niculescu - MAP 226 V. Niculescu - MAP 227

56
10/12/2015

try statement Exception Hierarchy

 class java.lang.Throwable
• class java.lang.Error
try {
out.write(b); ...
– class java.lang.VirtualMachineError
}
• class java.lang.InternalError
catch (IOException e) {
• class java.lang.OutOfMemoryError
System.out.println("Output Error"); • class java.lang.StackOverflowError
} • class java.lang.UnknownError
finally { • class java.lang.Exception
out.close();
}

228 229
V. Niculescu - MAP 228 V. Niculescu - MAP 229

Throwable class Clasa Exception

Method Summary
• Throwable fillInStackTrace() Constructor Summary
Fills in the execution stack trace. • Exception()
• Throwable getCause()
Returns the cause of this throwable or null if the cause is nonexistent or unknown. Constructs a new exception with null as its detail message.
• String getLocalizedMessage()
Creates a localized description of this throwable. • Exception(String message)
• String getMessage() Constructs a new exception with the specified detail message.
Returns the detail message string of this throwable.
• StackTraceElement[] getStackTrace() • Exception(String message, Throwable cause)
Provides programmatic access to the stack trace information printed by printStackTrace(). Constructs a new exception with the specified detail message and cause.
• Throwable initCause(Throwable cause)
Initializes the cause of this throwable to the specified value. • Exception(Throwable cause)
• void printStackTrace() Constructs a new exception with the specified cause and a detail message of
Prints this throwable and its backtrace to the standard error stream.
• void printStackTrace(PrintStream s) (cause==null ? null : cause.toString()) (which typically contains the class and detail
Prints this throwable and its backtrace to the specified print stream. message of cause).
• void printStackTrace(PrintWriter s)
Prints this throwable and its backtrace to the specified print writer.
• void setStackTrace(StackTraceElement[] stackTrace)
Sets the stack trace elements that will be returned by getStackTrace() and printed by
printStackTrace() and related methods.
• String toString()
Returns a short description of this throwable.

V. Niculescu - MAP 230 V. Niculescu - MAP 231

57
10/12/2015

 class java.lang.Exception
...
Cauza unei exceptii • class java.lang.RuntimeException
– class java.lang.ArithmeticException
– class java.lang.ArrayStoreException
– class java.lang.ClassCastException
• chained exception facility – class java.lang.IllegalArgumentException
• class java.lang.IllegalThreadStateException
• class java.lang.NumberFormatException
• Cauza unei exceptii: – class java.lang.IllegalMonitorStateException
– O alta excepotie – class java.lang.IllegalStateException
– class java.lang.IndexOutOfBoundsException
– O situatie speciala in program.
• class java.lang.ArrayIndexOutOfBoundsException
• class java.lang.StringIndexOutOfBoundsException
• "chain" of exceptions … – class java.lang.NegativeArraySizeException
– class java.lang.NullPointerException
– class java.lang.SecurityException
– class java.lang.UnsupportedOperationException

233
V. Niculescu - MAP 232 V. Niculescu - MAP 233

class java.lang.Exception Declararea exceptiilor


• class java.io.IOException
– class java.io.CharConversionException
– class java.io.EOFException
– class java.io.FileNotFoundException
• If a method is expected to throw any exceptions, the method declaration must
declare that fact in a throws clause.
– class java.io.InterruptedIOException
– class java.io.ObjectStreamException
– class java.io.SyncFailedException • There are certain types of exceptions that do not have to be listed in a throws
– class java.io.UnsupportedEncodingException clause
– class java.io.UTFDataFormatException (Error, RunTimeException, or a subclass of one of those classes).

– checked,
– unchecked (RuntimeExceptions)

234
V. Niculescu - MAP 234 V. Niculescu - MAP 235

58
10/12/2015

import java.io.IOException; //catches an exception internally


throws and overiding class throwsExample { int getLength() {
String s;
“The overriding method must NOT throw checked exceptions that are new or broader char[] a; int position;
try {
...
than those declared by the overridden method.” s = readUpTo(':');
//explicitly throws an exception
}
int read() throws IOException { catch (IOException e) {
class A { if (position >= a.length) return 0;
throw new IOException();
public void foo() throws IOException {..} }
return a[position++]; return s.length();
} } }
//can throw a RunTimeException
//implicitly throws an exception int getAvgLength() {
class B extends A { String readUpTo(char terminator) int count = 0;
@Override throws IOException { int total = 0;
StringBuffer s = int len;
public void foo() throws SocketException {..} // allowed new StringBuffer(); while (true){
while (true) { len = getLength();
int c = read(); if (len == 0) break;
@Override // Can throw IOException count++; total += len;
public void foo() throws SQLException {..} // NOT allowed if (c == -1 || c == terminator) { }
return s.toString(); } return total/count;
} s.append((char)c); // Can throw ArithmeticException
}
}
} //:~
return s.toString();
//SocketException extends IOException, but SQLException does not.
}

237
V. Niculescu - MAP 236 V. Niculescu - MAP 237

Generare Exceptii
public class ThrowExample {
void doIt() throws WrongDayException{
• Instructiunea throw este folosita pentru a creea si a arunca o int dayOfWeek =(new
exceptie. – obiectul “aruncat” trebuie sa fie o instanta a unei subclase java.util.Date()).getDay();
a clasei Throwable. if (dayOfWeek != 2 && dayOfWeek != 4)
throw new WrongDayException("Tue. or
• Uzual : crearea unei clase specifice problemei de semnalat, derivate Thur.");
din clasa Exception. // The rest of doIt's logic goes here
System.out.println("Did it");
}
Example: public static void main (String [] argv) {
try {
class WrongDayException extends Exception { (new ThrowExample()).doIt();
public WrongDayException () {} } catch (WrongDayException e) {
public WrongDayException(String msg) { System.out.println("Sorry, can do it
super(msg); only on "
+ e.getMessage());
} }
} }
}

238 239
V. Niculescu - MAP 238 V. Niculescu - MAP 239

59
10/12/2015

Printing Stack Traces Rethrowing Exceptions – Rearuncarea exceptiilor



java.lang.ArithmeticException: / by zero
• Dupa ce o exceptie este prinsa aceasta poate fi rearuncata (dupa
at t.cap(t.java:16) eventuala ei modificare/ adaugare de informatii).
at t.doit(t.java:8)
at t.main(t.java:3) • Ex1: simpla rearuncare pastreaza sursa originala::
try {
cap(0);
• Afisarea urmei de apel stack trace prin apelul } catch(ArithmeticException e) {
printStackTrace() throw e;
int cap (int x) {return 100/x;} }
try { • Ex2: se poate rearanja stack trace:
cap(0);
} catch(ArithmeticException e) { try {
e.printStackTrace(); cap(0);
} } catch(ArithmeticException e) {
throw
(ArithmeticException)e.fillInStackTrace();
• sau direct fara aruncarea unei exceptii: }
new Throwable().printStackTrace();
240 241
V. Niculescu - MAP 240 V. Niculescu - MAP 241

In C# se pot arunca ca exceptii obiecte de tip System.Exception


sau derivate ale acestuia.

Metode si proprietati relevante ale clasei Exception:


• Tratarea exceptiilor C# – public Exception(), public Exception(string), public Exception(string, Exception) -
constructori;
– public virtual string HelpLink {get; set;} obtine sau seteaza o legatura catre un fisier
help asociat acestei exceptii; poate fi de asemenea o adresa Web (URL)
– public Exception InnerException {get;} returneza exceptia care este ıncorporata ın
exceptia curenta
– public virtual string Message {get;} obtine un mesaj care descrie exceptia curenta
– public virtual string Source {get; set;} obtine sau seteaza numele aplicatiei sau al
obiectului care a cauzat eroarea
– public virtual string StackTrace {get;} o¸tine o reprezetare string a apelurilor de
metode care au dus la aparitia acestei exceptii
– public MethodBase TargetSite {get;} obtine metoda care a aruncat exceptia curenta

V. Niculescu - MAP 242 V. Niculescu - MAP 243

60
10/12/2015

Exemplu
Crearea propriilor exceptii using System;
public class MyCustomException :
catch (MyCustomException e)
{
System.ApplicationException Console.WriteLine(‘‘\nMyCustomException! Msg:
{ {0}’’,
public MyCustomException(string message): e.Message);
base(message) Console.WriteLine(‘‘\nHelpLink: {0}\n’’,
{} e.HelpLink);
• Se recomanda ca acestea sa fie derivate din System.ApplicationException, care este } }
derivata direct din System.Exception. public class Test catch
{ {
public static void Main( ) Console.WriteLine(‘‘Unknown exception caught’’);
• Se indica aceasta derivare deoarece astfel se face distinctie ıntre exceptiile aplicatie { }}
si cele sistem (cele aruncate de catre CLR). Test t = new Test( ); public double DoDivide(double a, double b)
t.TestFunc( ); { if (b == 0)
} { DivideByZeroException e = new
public void TestFunc( ) DivideByZeroException( );
{ try { e.HelpLink= ‘‘http://www.greselifatale.com’’;
double a = 0; throw e;
double b = 5; }
Console.WriteLine (‘‘{0} / {1} = {2}’’, a, b, DoDivide(a,b)); if (a == 0)
Console.WriteLine (‘‘This line may or may not print’’); { MyCustomException e = new MyCustomException(
} ‘‘Can’t have zero divisor’’);
catch (System.DivideByZeroException e) e.HelpLink =
{ ‘‘http://www.greselifatale.com/NoZeroDiviso
r.htm’’;
Console.WriteLine(‘‘DivideByZeroException! Msg: {0}’’, throw e;
e.Message); }
Console.WriteLine(‘‘HelpLink: {0}’’, return a/b;
V. Niculescu - MAP 244 e.HelpLink); V. Niculescu
} - MAP 245
}

Rearuncarea exceptiilor - exemplu


public class MyCustomException :
System.ApplicationException
catch(System.Exception e) Checked exceptions
{
{ MyCustomException ex = new
public MyCustomException(string message,Exception MyCustomException(‘‘E3 -Custom • In Java, o metoda trebuie sa declare toate exceptiile pe care le poate arunca.
inner): base(message,inner) Exception Situation!’’,e);
{}} throw ex; – Efect: compilatorul poate sa verifice daca o anumita exceptie este tratata sau nu
public class Test }}
{ public void DangerousFunc2( )
in interiorul metodei.
public static void Main( )
{
{ – In Java exceptiile sunt parte din signatura metodei.
try
Test t = new Test( ); { DangerousFunc3( ); }
t.TestFunc( ); catch (System.DivideByZeroException e)
} { • In C# nu exista aceasta cerinta.
public void TestFunc( ) Exception ex =
{ new Exception(
try{ DangerousFunc1( ); } “E2 - Func2 caught divide by zero’’,e);
catch (MyCustomException e) throw ex;
{ }
Console.WriteLine(‘‘\n{0}’’, e.Message); }
Console.WriteLine(‘‘Retrieving exception history...’’); public void DangerousFunc3( )
Exception inner = e.InnerException; {
while (inner != null) try { DangerousFunc4( ); }
{ catch (System.ArithmeticException)
Console.WriteLine(‘‘{0}’’,inner.Message); { throw; }
inner = inner.InnerException; catch (System.Exception)
}} {
} Console.WriteLine(‘‘Exception handled here.’’);
public void DangerousFunc1( ) }}
{ public void DangerousFunc4( )
try { DangerousFunc2( );} {
throw new DivideByZeroException("E1 - DivideByZero
Exception");
}} - MAP
V. Niculescu 246 V. Niculescu - MAP 247

61
10/12/2015

Comparatie Analiza – checked exceptions

• In Java, programatorii trebuie sa declare ca o metoda poate arunca o exceptie si sa • O problema importanta legata de exceptiile verificate este faptul ca se restringe
o declare explicit astfel incat un apelant sa stie ca se poate se poate astepta la dezvoltarea claselor derivate la suprascrierea metodei folosind doar lista de
primirea ei. exceptii specificata pentru metoda clasei de baza.

In Java:
• Aceasta cunoastere in avans permite conceperea unui plan de lucru cu fiecare
dintre ele, preferabil decat sa se prinda oricare dintre ele cu un catch generic. interface Movie{
void Enjoy() throws PeopleTalkingException;
}
• In cazul .NET se sugereaza sa se mentina o documentatie cu exceptiile care pot fi
Implementarile metodei Movie.Enjoy( ) pot sa nu arunce nici o exceptie dar daca
aruncate de fiecare metoda. arunca atunci singurul tip de exceptii verificate este PeopleTalkingException.

• Avantaj : orice cod care foloseste interfata Movie si care trateaza exceptii de tip
PeopleTalkingExceptionse este garantata sa continue sa functioneze indiferent de
cum este aceasta interfata implementata.
• Dezavantaj: uneori presupunerea initiala despre ce constituie o exceptie valida
este eronata.

V. Niculescu - MAP 248 V. Niculescu - MAP 249

Problema... Constructors, inheritance and exceptions

• Sa presupunem ca dorim sa implementam o interfata HomeMovie public class A{ • The derived class constructor
specializata, unde oamenii pot vorbi tot ceea ce doresc , dar atunci suna public A() throws Exceptie1{ have to specifies all the
} exceptions thrown by the base
telefon sa se creeaze o circumstanta de exceptie.
public A(int i){ } class constructor.
//...
• In Java este necesar: }
public class B extends A{ • The derived class constructor may
– Sa se rescrie specificatia exceptiilor interfetei de baza
public B() throws Exceptie1{ } throw new other exceptions.
– sa se deriveze PhoneRingingException din PeopleTalkingException, public B(int i){
super(i);
}
public B(char c) throws Exceptie1,
ExceptieNoua{
}
//...
}

V. Niculescu - MAP 250 V. Niculescu - MAP 251

62
10/12/2015

Exceptions in overridden methods


public class AA {
public void f() throws Exceptie1, Exceptie2{ }
public void g(){ }
public void h() throws Exceptie1{ }
}
public class BB extends AA{
public void f() throws Exceptie1{ } //doesn’t specify Exceptie2
Curs 6
public void g() throws Exceptie2{ }
public void h() throws Exceptie3{ }
}
public class Exceptie3 extends Exceptie1{...} Clase generice
• An overridden method doesn’t have to specify all the exceptions thrown Collection frameworks
by the same method in the super-class definition.
• An overridden may specify a new exception or a specialized form of an
exception thrown by the same method in the super-class definition.

V. Niculescu - MAP 252 V. Niculescu - MAP 253

C++ Templates Java Generics - implementare

• “macro processor” • Java generics furnizeaza la momentul compilarii type safety si elimina necesitatea
• oridecate ori se instantiaza cu un tip concret, intregul cod este reprodus si compilat. operatiilor cast.

• daca a mai fost instantiat, doar linkeditorul poate sesiza si indeparta (uneori) • Avantaj: erorile sunt evidentiate atunci la dezvoltare (compile time).
problema(duplicarea)
• Generics folosesc o tehnica numita type erasure.

• compilatorul gestioneaza genericele intern.

• toate instantele partajeaza aceeasi clasa la run time.

• La compilare, compilatorul “sterge” (erases) informatiile despre tipul generic,


inlocuieste fiecare variabila de tip generic cu limita superioara a tipului (de obicei
Object), si unde este nevoie insereaza un cast explicit catre tipul generic.

V. Niculescu - MAP 254 V. Niculescu - MAP 256

63
10/12/2015

Sintaxa O clasa generica este partajata de toate invocarile ei


[modificator_acces] class NumeClasa <TipGeneric1[, TipGeneric2[, ...]] >{
private TipGeneric1 atribut1;
[declaratii atribute]
[declaratii si definitii metode]
} List <String> l1 = new ArrayList<String>();
• Exemplu: List<Integer> l2 = new ArrayList<Integer>();
System.out.println(l1.getClass() == l2.getClass());
public class Stiva<E>{
private class Nod<T>{ //output: true
T info;
Nod<T> urm;
Nod(){info=null; urm=null;} => the static variables and methods of a class are shared among all the instances.
Nod(T info, Nod urm){
this.info=info;
this.urm=urm;
}
}//clasa Nod

Nod<E> varf;
//...
}

V. Niculescu - MAP 257 V. Niculescu - MAP 258

Tablouri de tipuri generice Constrangeri


• Nu pot fi create folosind operatorul new:
T[] elem=new T[dim]; //eroare la compilare • Se pot specifica constrangeri (limite) pentru tipul generic, folosind cuvantul
doar: extends.
T[] elem=(T[])new Object[dim]; //warning la compilare T extends E //T este de tipul E sau un subtip al lui E.
• Alternative: • Pot fi precizate mai multe constrangeri. Forma generala este:
A1)Se foloseste metoda Array.newInstance
import java.lang.reflect.Array; T extends [C &] I1 [& I2 &...& In]
public class Stiva <E>{ (T mosteneste clasa C si implementeaza interfetele I1, ... In)
private E[] elems; • Cand se specifica constrangeri, la compilare T este inlocuit cu primul element
private int varf; din expresia de constrangeri.
@SuppressWarnings("unchecked") T extends C //T este inlocuit cu C
public Stiva(Class<E> tip) {
elems= (E[])Array.newInstance(tip, 10); T extends C & I1 & I2 //T este inlocuit cu C
varf=0; T extends I1 & I2 //T este inlocuit cu I1
} T extends I1 //T este inlocuit cu I1
//... T //T este inlocuit cu Object
} • Daca se specifica constrangeri pentru tipul T, atunci folosind o variabila de tipul
Stiva<Integer> si=new Stiva<Integer>(Integer.class);
A2)Se foloseste clasa ArrayList in loc de tablou. T se poate apela orice metoda din clasa sau interfetele precizate ca limita.

V. Niculescu - MAP 259 V. Niculescu - MAP 260

64
10/12/2015

Generics and Subtyping


Wildcards=> “Collection of unknown”

List<String> ls = new ArrayList<String>(); • Collection<?> is the supertype of all kinds of collections.


List<Object> lo = ls; //ERROR
• It is a collection whose element type matches anything.
lo.add(new Object); • It’s called a wildcard type
String s = lo.get(0);
void printCollection(Collection<?> c) {
for (Object e : c) {
Regula: System.out.println(e);}
• If }
Foo is a subtype (subclass or subinterface) of Bar, …
and Collection<?> c = new ArrayList<String>();
c.add(new Object()); // compile time error
G is some generic type declaration,
c.add(new Stringt()); // compile time error
then
G<Foo> is NOT a subtype of G<Bar>. => tocmai pentru ca s-ar permite adaugare si de String si de Object … etc

V. Niculescu - MAP 261 V. Niculescu - MAP 262

Bounded Wildcards

public abstract class Shape { import java.util.ArrayList;


import java.util.List;
public abstract void draw(Canvas c); public static void main(String a[]){
}
public class Canvas { Canvas c = new Canvas();
private List<Shape> shapes; List<Shape> l = new ArrayList<Shape>();
public class Circle extends Shape { public Canvas (){
List<Circle> lc = new ArrayList<Circle>();
private int x, y, radius; shapes = new ArrayList<Shape>();
public void draw(Canvas c.add(new Circle(2,2,10));
}
c) { ... } lc.add(new Circle(2,2,10));
} public void add(Shape s) { shapes.add(s);}
public void addRectangle(Rectangle r){
shapes.add(r); lc.add(new Circle(21,21,100));
}
public class Rectangle extends Shape { public void addList(List<? extends Shape> ls) {
private int x, y, width, height; l.add(new Rectangle(2,2,10,11));
public void draw(Canvas c) { ... } for (Shape s: ls)
l.add(new Circle(21,21,100));
shapes.add(s);
} }
public void drawAll () { c.addList(lc); // se adauga o lista de cercuri
for (Shape s: shapes) { c.addList(l);
s.draw(this); c.drawAll();
} }
}
V. Niculescu - MAP 263 V. Niculescu - MAP 264

65
10/12/2015

Probleme posibile… Metode generice

• Nu ar fi permis: static <T extends Comparable<T>> T min(T []a){


T x = a[0];
public void addRectangle(List<? extends Shape> shapes) {
shapes.add(0, new Rectangle()); // compile-time error! for(int i=0; i<a.length;i++){
} if (a[i].compareTo(x)<0) {x=a[i];}
}
return x;
shapes.add()
is }
? extends Shape - an unknown subtype of Shape. • Apel: Compilatorul determina automat tipul generic cand se apeleaza o metoda generica.

Integer ti[] = new Integer[]{2, 3 ,4 };


• Deoarece nu stim ce tip va fi concret nu putem sa il particularizam la Rectangle
Integer a = min(ti);

• sau explicit:
– NumeClasa.<Tip>numeMetoda([parametrii]);
– obiect.<Tip>numeMetoda([parametrii]);

V. Niculescu - MAP 265 V. Niculescu - MAP 266

Metode generice (2)


when should we use generic methods, and when should we use wildcard types?
static <T> void fromArrayToCollection(
T[]a, Collection<T> c){
for(T o: a){c.add(o); }
}
interface Collection<E> {
public boolean containsAll(Collection<?> c);
//////////////////////////////////////////////////////////// public boolean addAll(Collection<? extends E> c);
}
class Collection{
public static <T, S extends T> • Se pot folosi si metode generice (efect similar)
void copy(List<T> dest, List<S> src){…} interface Collection<E> {
} public <T> boolean containsAll(Collection<T> c);
• Ori public <T extends E> boolean addAll(Collection<T> c);
class Collection{ // type variables can have bounds too!
public static <T> }
void copy(List<T> dest, List<? extends T> src){…}
}

V. Niculescu - MAP 267 V. Niculescu - MAP 268

66
10/12/2015

Analiza Type Dependency

• In ambele metode containsAll si addAll, parametrul de tip T este folosit doar o data.
class Collections {
• Tipul returnat nu depinde de parametrul de tip si nici alt argument al metodei nu depinde de public static <T> void copy(List<T> dest, List<? extends T> src){...}
acesta. }

• Aceasta sugereaza ca parametrul de tip este folosit pt polymorfism;


singurul efect dorit este de a permite o varietate de argumente sa fie folosite la apel. In acest caz exista o dependenta intre parametrii de tip ale argumentelor.
• In acest caz este de dorit a fi folosite wildcards.

V. Niculescu - MAP 269 V. Niculescu - MAP 270

Iterator – design pattern (GoF) Interfata generala pt Iterator

• Sablon comportamental • metodele standard:


• Se foloseste pt a furniza o interfata pt traversarea unei colectii de elemente fara a fi
nevoie sa se cunoasca structura de reprezentare a acesteia. void First(); // Restart iteration
void Next(); // Advance to next item
• Structura (image from http://www.dofactory.com/net/iterator-design-pattern) bool IsDone(); // Are we done yet?
T CurrentItem(); // Get current item

• Exista variante care


– cupleaza metodele next si CurrentItem
– Foloseste inversa metodei IsDone -> hasNext

V. Niculescu - MAP 271 V. Niculescu - MAP 272

67
10/12/2015

Collections Framework
Exemplu: http://www.vincehuston.org/dp/iterator.html Interface Hierarchy
problema? Ce returneaza next() pentru MapTraverser (values…)
• java.util.Comparator<T>
• java.util.Enumeration<E>
• java.util.EventListener
• java.util.Formattable
• java.lang.Iterable<T>
– java.util.Collection<E>
• java.util.List<E>
• java.util.Queue<E>
• java.util.Set<E>
– java.util.SortedSet<E>
• java.util.Iterator<E>
– java.util.ListIterator<E>
• java.util.Map<K,V>
– java.util.SortedMap<K,V>
• java.util.Map.Entry<K,V>
• java.util.Observer
• java.util.RandomAccess

V. Niculescu - MAP 273 V. Niculescu - MAP 274

java.util java.lang
Interface Iterator<E> Interface Iterable<E>

• All Known Subinterfaces: • Some Subinterfaces:


– ListIterator<E> – Collection<E>, List<E>, Queue<E>, Set<E>, SortedSet<E>

• Implementing this interface allows an object to be the target of the "foreach" statement.
• Methods
– boolean hasNext()
Returneaza true daca nu mai sunt elemente de iterat. • Iterator<E> iterator()
– E next() Returns an iterator over a set of elements of type E.
Returneaza elementul curent si cursorul se muta o pozitie.
– void remove()
Sterge din colectia iterata, ultimul element care a fost iterat .
(optional operation).

V. Niculescu - MAP 275 V. Niculescu - MAP 276

68
10/12/2015

Java generic collections


java.util
• java.util.AbstractCollection<E> (implements java.util.Collection<E>)
– java.util.AbstractList<E> (implements java.util.List<E>)
Interface Comparator<T>
• java.util.AbstractSequentialList<E>
– java.util.LinkedList<E> (implements java.lang.Cloneable, java.util.List<E>,
java.util.Queue<E>, java.io.Serializable)
int compare(T o1, T o2)
• java.util.ArrayList<E> (implements java.lang.Cloneable, java.util.List<E>,
java.util.RandomAccess, java.io.Serializable) Compares its two arguments for order.
• java.util.Vector<E> (implements java.lang.Cloneable, java.util.List<E>, boolean equals(Object obj)
java.util.RandomAccess, java.io.Serializable)
Indicates whether some other object is "equal to" this Comparator.
– java.util.Stack<E>
– java.util.AbstractQueue<E> (implements java.util.Queue<E>)
• java.util.PriorityQueue<E> (implements java.io.Serializable) • A comparison function, which imposes a total ordering on some collection of objects.
– java.util.AbstractSet<E> (implements java.util.Set<E>)
• java.util.EnumSet<E> (implements java.lang.Cloneable, java.io.Serializable)
• java.util.HashSet<E> (implements java.lang.Cloneable, java.io.Serializable, java.util.Set<E>) • The ordering imposed by a Comparator c on a set of elements S is said to be consistent with
– java.util.LinkedHashSet<E> (implements java.lang.Cloneable, java.io.Serializable, equals if and only if
java.util.Set<E>)
(compare((Object)e1, (Object)e2)==0)
• java.util.TreeSet<E> (implements java.lang.Cloneable, java.io.Serializable,
java.util.SortedSet<E>) has the same boolean value as
• java.util.AbstractMap<K,V> (implements java.util.Map<K,V>) e1.equals((Object)e2) for every e1 and e2 in S.
– java.util.EnumMap<K,V> (implements java.lang.Cloneable, java.io.Serializable)
– java.util.HashMap<K,V> (implements java.lang.Cloneable, java.util.Map<K,V>,
java.io.Serializable)
• java.util.LinkedHashMap<K,V> (implements java.util.Map<K,V>)
– java.util.IdentityHashMap<K,V> (implements java.lang.Cloneable, java.util.Map<K,V>,
java.io.Serializable)
– java.util.TreeMap<K,V> (implements java.lang.Cloneable, java.io.Serializable,
java.util.SortedMap<K,V>)
– java.util.WeakHashMap<K,V> (implements java.util.Map<K,V>)
V. Niculescu - MAP 277 V. Niculescu - MAP 278

Interface RandomAccess

• Some Implementing Classes:


– ArrayList, CopyOnWriteArrayList, Stack, Vector

public interface RandomAccess

• Marker interface used by List implementations to indicate that they support fast (generally
constant time) random access

V. Niculescu - MAP 279 V. Niculescu - MAP 280

69
10/12/2015

Exception Conventions
O analiza a performantei operatiilor in liste

• Methods that are optional in an implementation of an interface throw


UnsuportedOperationException when not implemented.

• Methods or constructors that accept elements to be added to the current collection throw
ClassCastException if the element is not of an appropriate type for the collection.

• Methods or constructors that accept elements to be added to the current collection throw
IllegalArgumentException if the element’s value is not appropriate for the collection
– for example, some collections, such as subsets, define restricted ranges on the values of the
elements allowed in the collection.

• Methods that return individual elements of a collection will give you a


NoSuchElementException if the Collection is empty.

• Methods or constructors that take parameters of reference type usually throw


NullPointerException if passed a null reference.

V. Niculescu - MAP 281 V. Niculescu - MAP 282

Loops
Exemplu

for (FormalParameter : Expression)


Statement
• Expression must be an array or an instance of a the interface called // Assume we have an instance of StringBuffer “sb”
java.lang.Iterable, which is meant to ease the task of enabling a type for use with the
enhanced for statement. public void oldFor(Collection c) {
for(Iterator i = c.iterator(); i.hasNext(); ) {
• java.util.Collection extends the Iterable interface that has the following String str = (String) i.next();
signature: sb.append(str); }
}
package java.lang;
public interface Iterable<E> {
/** * Returns an iterator over the elements in this collection.
* There are no guarantees concerning the order in which the elements public void newFor(Collection<String> c) {
* are returned (unless this collection is an instance of some class for(String str : c)
* that provides such a guarantee). { sb.append(str); }
* @return an iterator over the elements in this collection */ }
Iterator<E> iterator(); }

V. Niculescu - MAP 283 V. Niculescu - MAP 284

70
10/12/2015

Example:
writing a routine that prints out all the elements in a collection
With Arrays

• Conventional

• In an older version of the language: public int sumArray(int array[]) {


void printCollection(Collection c) { int sum = 0;
Iterator i = c.iterator(); for(int i=0;i<array.length;i++)
for (k = 0; k < c.size(); k++) { { sum += array[i]; }
System.out.println(i.next());} return sum;
} }

• A naive attempt at writing it using generics • Using the enhanced for statement:
(and the new for loop syntax):
public int sumArray(int array[]) {
void printCollection(Collection<Object> c) { int sum = 0;
for (Object e : c) { for(int i : array) { sum += i; }
System.out.println(e);} return sum;
} }

V. Niculescu - MAP 285 V. Niculescu - MAP 286

Variable arg. list and generics


Autoboxing/Unboxing and Generics
import java.util.*;
• Manual conversion between primitive types (such as an int) and wrapper classes (such as Integer) is public class CollectionsUtil {
necessary when adding a primitive data type to a collection. /**
* Private constructor.
list.add(0, new Integer(59)); */
int n = ((Integer)(list.get(0))).intValue(); private CollectionsUtil() {
}
• The new autoboxing/unboxing feature eliminates this manual conversion. The above segment of code can
be written as: private static <T> void addToCollection(
list.add(0, 59); int total = list.get(0);
Collection<T> theCollection, T... objects) {

• However, note that the wrapper class, Integer for example, must be used as a generic type: for(T object : objects) {
theCollection.add(object);
List<Integer> list = new ArrayList<Integer>(); }
}

V. Niculescu - MAP 287 V. Niculescu - MAP 288

71
10/12/2015

/**
* Create an Object {@link List} from the supplied objects. CURS 7
* @param objects The objects to be added to the list.
* @return The {@link List}.
*/
public static <T> List<T> toList(T... objects) {
List<T> theSet = new ArrayList<T>();
addToCollection(theSet, objects);
return theSet;
}
/** • Generics in C#
* Create an Object {@link Set} from the supplied objects.
* @param objects The objects to be added to the set.
* @return The {@link Set}.
*/

public static <T> Set<T> toSet(T... objects) {


Set<T> theSet = new HashSet<T>();
addToCollection(theSet, objects);
return theSet;

}
}

V. Niculescu - MAP 289 V. Niculescu - MAP 290

What Are C# Generics? Generics Implementation

• Permit crearea de clase type-safe fara a se afecta • In .NET generics au suport nativ in IL (intermediate language) si in CLR.
– performanta, ori
– productivitatea.
• Atunci cand se compileaza cod-server generic, compilatorul il traduce in IL, ca pe
• Se implementeaza server code once as a generic server. orice alt tip.
– Totusi, codul IL contine doar parametrii(place holders) pentru tipurile specifice
public class Stack<T>
{ actuale.
T[] m_Items;
public void Push(T item) • metadata codului server generic contine informatie generica.
{...}
public T Pop()
{...} • client-side compiler foloseste metadatele pentru a asigura type safety.
} – atunci cand clientul furnizeaza un tip specific, client's compiler substituie
Stack<int> stack = new Stack<int>();
parametrul generic din metadate cu tipul argument actual.
stack.Push(1);
stack.Push(2); – astfel client compiler poate forta parametrii corecti, verificari de tip...
int number = stack.Pop();

V. Niculescu - MAP 291 V. Niculescu - MAP 292

72
10/12/2015

How does .NET compile the generic IL of the server


to machine code?
default() operator

• Depinde de tip: • returneaza valoarea implicita a tipului argument


– valoare ori
– referinta public T Pop()
• value type => JIT compiler inlocuieste parametrii de tip in IL cu tipul specific si {
compileaza producand cod nativ. m_StackPointer--;
if(m_StackPointer >= 0)
{
• JIT compiler tine evidenta codului server care a fost deja generat. Daca se cere
return m_Items[m_StackPointer];
compilarea unui server generic cu un tip valoare care a fost deja compilat in cod
masina, atunci returneaza doar un pointer la acel cod (=> no code bloating) }
else
{
• Daca clientul specifica un tip referinta, atunci JIT compiler inlocuieste parametrii m_StackPointer = 0;
generici din server cu Object.
return default(T);
}
• Astfel JIT compiler doar reutilizeaza codul actual. Instantele sunt alocate in }
concordanta cu marimea lor in heap si nu se face casting.
Observatie: exemplul are doar scop didactic- nu se recomanda aceasta
V. Niculescu - MAP 293
rezolvare pentru implementare “pop” din stive –> exceptie!!
V. Niculescu - MAP 294

Exemplu: indexator cu argument tip generic Constrangeri

public class Map<K,T>


{...
private K key;
private T value;

T Find(K key)
{...}
public T this[K key]
{
get{return Find(key);}
}
}

V. Niculescu - MAP 295 V. Niculescu - MAP 297

73
10/12/2015

System.Collections IEnumerable si IEnumerator

• System.Collections • IEnumerable este interfata de baza pentru toate colectiile non-generice care pot fi
enumerate.

• System.Collections.Generic
• Versiunea generica a acestei clase este
System.Collections.Generic.IEnumerable<T>.

• IEnumerable contin e o singura metoda,


– GetEnumerator, care returneaza un IEnumerator.

• IEnumerator furnizeaza abilitatea de a itera elementele colectiei expunand spre


exterior
– Current property - ret. elem. curent
– MoveNext method – mutare la elementul urmator
– Reset - revenire la inceput

V. Niculescu - MAP 298 V. Niculescu - MAP 299

foreach yield -> (corutine)


Pentru o stiva reprezentata pe tablou
• Pentru a se putea folosi instructiunea foreach este suficient sa se public IEnumerator GetEnumerator()
{
implementeze metoda return new MyIterator(v, a);
//itereaza elem. din vectorul a in ordine inversa -
}
GetEnumerator()
SAU
public IEnumerator GetEnumerator()
{
for (int i = v - 1; i >= 0; i--)
• Nu este obligatoriu sa se implementeze interfata IEnumerable! {

yield return a[i];


}
}

V. Niculescu - MAP 300 V. Niculescu - MAP 301

74
10/12/2015

yield …. Covariance and Contravariance in C# .NET 4

class Test{ Covariance : <out T>


static void Main (){ Ex. IEnumerable, IEnumerator
foreach(string x in Foo){ public interface IEnumerable<out T> : IEnumerable
Console.Writeln (x); { IEnumerator <T> GetEnumerator(); }
}
} public interface IEnumerator<out T> : IDisposable, IEnumerator
static IEnumerable Foo(){
yield return “hello”;
DisposePerforms application-defined tasks associated with freeing, releasing, or resetting
yield return “there”; unmanaged resources. (Inherited from IDisposable.)
} MoveNextAdvances the enumerator to the next element of the collection. (Inherited
} from IEnumerator.)

ResetSets the enumerator to its initial position, which is before the first element in the
collection. (Inherited from IEnumerator.)

Contravariance: <in T>

Ex. IComparer, IComparable

V. Niculescu - MAP 302 V. Niculescu - MAP 303

implementare explicita Comparatie: C# Generics <-> C++ templates

• permite ascunderea metodelor ‘mostenite’ dintr-o interfata, acestea devenind •


private
• La nivel de sintaxa C# generics - parametrizare mai simpla decat in C++ templates.
– calificarea lor ca fiind publice este semnalata ca o eroare.

• Implementarea explicita se obtine prin calificarea numelui de metoda cu • C# nu furnizeaza toata functionalitatea pe care C++ templates le furnizeaza.
numele interfetei: • Nu se pot folosi parametrii de tip constanta (int i).
• Nu se poate face implementare specializata (in functie de tip – particularizare)
System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator()
{ • La nivel de implementare, principala diferenta este ca in C# informatiile despre
return new MyIterator(v, a); tipul generic este pastrata in obiectele instantiate.
}
public System.Collections.Generic.IEnumerator<T> GetEnumerator()
{
return new MyIterator(v, a);
}

V. Niculescu - MAP 304 V. Niculescu - MAP 305

75
10/12/2015

Streams pentru I/O


Curs 8
• Stream = un object capabil sa produca sau sa stocheze date.

• Stream-urile ascund detaliile referitoare la dispozitivele concrete de I/O.

• InputStream, Reader
– Operatii I/O
– Serializare • OutputStream, Writer

• Orice clasa derivata din InputStream ori Reader are metoda


read( ) pentru citirea unui singur octect sau a unui sir de octeti.

• Orice clasa derivata din OutputStream ori Writer are metoda


write( ) pentru scrierea unui singur octect sau a unui sir de octeti.

V. Niculescu - MAP 307 V. Niculescu - MAP 308

Tipuri de InputStream Tipuri de InputStream


• Sursele pot fi: Class Function Constructor Arguments
– Un tablou de octeti, ByteArrayInputStream Allows a buffer in memory to be The buffer from which to extract
used as an InputStream the bytes.
– Un obiect de tip String,
StringBufferInputStream Converts a String into an A String. The underlying
– Un fisier. InputStream implementation actually uses a
StringBuffer.
– un “pipe” (conducta),
FileInputStream For reading information from a A String representing the file
– O secventa de alte stream-uri, colectate intr-unul singur, file name, or a File or
FileDescriptor object.
– Alte surse, de ex. o conexiune.
PipedInputStream Produces the data that’s being PipedOutputStream
written to the associated
• FilterInputStream este tot o clasa derivata din InputStream, PipedOutput-Stream.
Implements the “piping”
pentru a fi clasa de baza a unui decorator care ataseaza atribute sau concept.
functionalitate stream-urilor de intrare. SequenceInputStream Converts two or more Two InputStream objects or an
InputStream objects into a Enumeration for a container of
single InputStream. InputStream objects.
FilterInputStream Abstract class which is an
interface for decorators that
provide useful functionality to
the other InputStream classes
V. Niculescu - MAP 309 V. Niculescu - MAP 310

76
10/12/2015

Tipuri de OutputStream

• Iesire poate fi: un sir de octeti (nu String), un fisire, ori un “pipe.”

Class Function Constructor Arguments


ByteArrayOutputStream Creates a buffer in memory. All the data that Optional initial size of the
you send to the stream is placed in this buffer. buffer.
FileOutputStream For sending information to a file. A String representing the file
name, or a File or
FileDescriptor object.
PipedOutputStream Any information you write to this PipedInputStream
automatically ends up as input for the
associated PipedInputStream. Implements
the “piping” concept.
FilterOutputStream Abstract class which is an interface for
decorators that provide useful functionality to
the other OutputStream classes.

V. Niculescu - MAP 311 V. Niculescu - MAP 312

Decorator
• Intentie
Atasare de noi responsabilitati unui obiect in mod dinamic.
Decorator furnizeaza o alternativa a extinderii functionalitatii prin derivare
directa.
• Decorator sau Wrapper

• Aplicabilitate

– Pentru a adauga noi responsabilitati in mod dinamic si transparent, fara


afecta alte obiecte.

– pentru responsibilitati care pot fi retrase.

– cand extinderea prin derivare este impracticabila.

V. Niculescu - MAP 313 V. Niculescu - MAP 314

77
10/12/2015

Decorator Adaugare de atribute si functionalitati

• Structura • Clase de Decorator = FilterInputStream si FilterOutputStream.

• Clase abstracte derivate din InputStream respectiv OutputStream,

V. Niculescu - MAP 315 V. Niculescu - MAP 316

Citirea dintr-un InputStream Scrierea intr-un OutputStream


cu FilterInputStream cu FilterOutputStream

Class Function Constructor Class Function Constructor Arguments


Arguments
DataOutputStream Used in concert with DataInputStream so OutputStream
DataInputStream Used in concert with DataOutputStream, so you can InputStream you can write primitives (int, char, long, etc.)
read primitives (int, char, long, etc.) from a stream in to a stream in a portable fashion.
a portable fashion. PrintStream For producing formatted output. While OutputStream, with optional
BufferedInputStream Use this to prevent a physical read every time you want InputStream, with DataOutputStream handles the storage of boolean indicating that the
more data. You’re saying “Use a buffer.” optional buffer size. data, PrintStream handles display. buffer is flushed with every
newline.
LineNumberInputStream Keeps track of line numbers in the input stream; you InputStream
BufferedOutputStream Use this to prevent a physical write every time OutputStream, with optional
can call getLineNumber( ) and setLineNumber(
you send a piece of data. You’re saying “Use a buffer size.
int). buffer.” You can call flush( ) to flush the
PushbackInputStream Has a one byte push-back buffer so that you can push InputStream buffer.
back the last character read.

V. Niculescu - MAP 317 V. Niculescu - MAP 318

78
10/12/2015

DataInput <<interface>> DataOutput <<interface>>

readBoolean():boolean
write(byte[] )
readChar(): char
write(b:byte[] , off: int off, len: int)
readByte() : byte
write(int)
readDouble(): double
DataInputStream writeBoolean(boolean) DataOutputStream
readFloat(): float
writeByte(int )
readFully(b; byte[])
writeBytes(String )
readFully(b; byte[],off: int, len: int)
writeChar(int )
readInt(): int
writeChars(String )
readLine(): String
writeDouble(double)
readLong(): long
writeFloat(float )
readShort(): short
writeInt(int )
readUnsignedByte(): int
writeLong(long )
readUnsignedShort(): int
writeShort(int )
readUTF() :String
writeUTF(String )
skipBytes(int) :int

V. Niculescu - MAP 319 V. Niculescu - MAP 320

RandomAccessFile UTF-8 (UCS Transformation Format — 8-bit)


RandomAccessFile
(name: String, mode: String)
getFD() : FileDescriptor • UTF-8 is a multibyte character encoding for Unicode.
getFilePointer(): long
length(): long • Unlike them, it is backward-compatible with ASCII
seek(long)

• UTF-8 has become the dominant character encoding for the World-Wide
Web, accounting for more than half of all Web pages.

• UTF-8 is also increasingly being used as the default character encoding in


operating systems, programming languages, APIs, and software
DataInput DataOutput applications.

• UTF-8 encodes each of the 1,112,0647 code points in the Unicode


character set using one to four 8-bit bytes.

V. Niculescu - MAP 321 V. Niculescu - MAP 322

79
10/12/2015

• The null character '\u0000' and characters in the range '\u0080' to '\u07FF' are
Modified UTF-8 represented by a pair of bytes:
Bit Values

Byte 1 1 1 0 bits 10-6

Byte 2 1 0 bits 5-0

• Implementarile interfetelor DataInput si DataOutput folosesc • char values in the range '\u0800' to '\uFFFF' are represented by three bytes
reprezentari Unicode pentru strings intr-un format putin modificat
fata de UTF-8. Bit Values

Byte 1 1 1 1 0 bits 15-12

• Toate caracterele din intervalul '\u0001' to '\u007F' sunt Byte 2 1 0 bits 11-6
representate pe un singur byte.
Byte 3 1 0 bits 5-0

• The differences between this format and the standard UTF-8 format are the
following:
– The null byte '\u0000' is encoded in 2-byte format rather than 1-byte, so
that the encoded strings never have embedded nulls.
Bit Values
– Only the 1-byte, 2-byte, and 3-byte formats are used.
Byte 1 0 bits 6-0 – Supplementary characters are represented in the form of surrogate pairs.

V. Niculescu - MAP 323 V. Niculescu - MAP 324

Example
Ierarhiile Reader & Writer
FileInputStream in = null; FileOutputStream out = null;
try {
in = new FileInputStream(“fisier.txt");
• Sunt orientate pe caractere
out = new FileOutputStream(“fisier2.txt");
int c;
while ((c = in.read()) != -1) { • Cel mai impotant motivul pentru crearea ierarhiilor Reader si Writer
out.write(c);
internationalizarea.
} catch(IOException e){
System.err.println(“Error ”+e); • Clasele din ierahiile InputStream si OutputStream suporta doar
}finally { steam-uri orientate pe 8-biti si nu pot sa lucreze cu caractere Unicode (16
if (in != null) biti).
try {
in.close(); • Aproape toate clasele de tip stream orientate pe octeti au corespondente
} catch (IOException e){ System.err.println(" Error "+e);} clase orientate pe caractere derivate din Reader respectiv Writer.
if (out != null)
try {
out.close();
} catch (IOException e) { System.err.println(" Error "+e);}
} V. Niculescu - MAP 325 V. Niculescu - MAP 326

80
10/12/2015

Clasele orientate pe caractere Clasele “Filter” orientate pe caractere


Filters: byte oriented class Corresponding character oriented class
Byte oriented class Corresponding character oriented class
FilterInputStream FilterReader
InputStream Reader
FilterOutputStream FilterWriter (abstract class with no subclasses)
converter: InputStreamReader
BufferedInputStream BufferedReader
OutputStream Writer
(also has readLine( ))
converter: OutputStreamWriter
FileInputStream FileReader BufferedOutputStream BufferedWriter
DataInputStream Use DataInputStream
FileOutputStream FileWriter
(Except when you need to use readLine( ), when you should use a
StringBufferInputStream StringReader BufferedReader)
(no corresponding class) StringWriter PrintStream PrintWriter
ByteArrayInputStream CharArrayReader LineNumberInputStream LineNumberReader
ByteArrayOutputStream CharArrayWriter StreamTokenizer StreamTokenizer
PipedInputStream PipedReader (use constructor that takes a Reader instead)
PipedOutputStream PipedWriter PushBackInputStream PushBackReader

V. Niculescu - MAP 327 V. Niculescu - MAP 328

// 1b. Reading standard input:


Exemple BufferedReader stdin =
new BufferedReader(
new InputStreamReader(System.in));
import java.io.*; System.out.print("Enter a line:");
System.out.println(stdin.readLine());
public class IOStreamDemo {
// Throw exceptions to console: // 2. Input from memory
public static void main(String[] args) throws IOException { StringReader in2 = new StringReader(s2);
int c;
while((c = in2.read()) != -1)
// 1. Reading input by lines: System.out.print((char)c);
BufferedReader in =
new BufferedReader( // 3. Formatted memory input
try {
new FileReader("IOStreamDemo.java")); DataInputStream in3 =
String s, s2 = new String(); new DataInputStream(
while((s = in.readLine())!= null) new ByteArrayInputStream(s2.getBytes()));
s2 += s + "\n"; while(true)
System.out.print((char)in3.readByte()); }
in.close();
catch(EOFException e) {
System.err.println("End of stream"); }

V. Niculescu - MAP 329 V. Niculescu - MAP 330

81
10/12/2015

// 4. File output
try { // 5. Storing & recovering data
try {
BufferedReader in4 = DataOutputStream out2 = new DataOutputStream(
new BufferedReader( new BufferedOutputStream(
new FileOutputStream("Data.txt")));
new StringReader(s2));
PrintWriter out1 = out2.writeDouble(3.14159);
new PrintWriter( out2.writeUTF("That was pi\n");
new BufferedWriter( out2.writeBytes("That was pi\n");
//For every character in the string, taken in order, one byte is written.
new FileWriter("IODemo.out"))); //The high-order eight bits of each character in the string are ignored
out2.writeDouble(1.41413);
out2.writeUTF("Square root of 2");
int lineCount = 1; out2.close();
while((s = in4.readLine()) != null ) DataInputStream in5 = new DataInputStream(
out1.println(lineCount++ + ": " + s); new BufferedInputStream(
out1.close(); new FileInputStream("Data.txt")));
// Must use DataInputStream for data:
} System.out.println(in5.readDouble());
catch(IOException e) { // Only readUTF() will recover the Java-UTF String properly:
System.err.println(e.getMessage()); System.out.println(in5.readUTF());
} System.out.println(in5.readUTF());//?!!
System.out.println(in5.readDouble());
System.out.println(in5.readUTF());
} catch(EOFException e) {
System.err.println("End of stream");
}

V. Niculescu - MAP 331 V. Niculescu - MAP 332

// 6. Reading/writing random access files Testarea sfarsitului de fisier(1)


RandomAccessFile rf =
new RandomAccessFile("rtest.dat", "rw");
import java.io.*;
for(int i = 0; i < 10; i++)
rf.writeDouble(i*1.414);
public class TestEOF {
rf.close();
// Throw exceptions to console:
public static void main(String[] args)
rf = new RandomAccessFile("rtest.dat", "rw"); throws IOException {
rf.seek(5*8); DataInputStream in =
rf.writeDouble(47.0001); new DataInputStream(
rf.close(); new BufferedInputStream(
new FileInputStream("TestEof.java")));
rf = new RandomAccessFile("rtest.dat", "r"); while(in.available() != 0)
for(int i = 0; i < 10; i++) System.out.print((char)in.readByte());
System.out.println( }
"Value " + i + ": " + rf.readDouble()); }//:~
rf.close();
}
} //:~

V. Niculescu - MAP 333 V. Niculescu - MAP 334

82
10/12/2015

Testarea sfarsitului de fisier(2) Tokenizing input

• Tokenizing = procesul de impartire a unei secvente de caractere in secvente


import java.io.*;
de “tokens” (atomi) care sunt delimitati de un caracter special.
public class TestEOF {
public static void main(String[] args) • Exemplu: token = cuvant delimitat de spatii albe si punctuatie.
throws IOException {
try
DataInputStream in = • Doua clase pot fi folosite: StreamTokenizer si StringTokenizer.
new DataInputStream(
new BufferedInputStream(
new FileInputStream("TestEof.java"))); • Desi StreamTokenizer nu e derivat
while( true) din InputStream ori OutputStream,
System.out.print((char)in.readByte()); lucreaza doar cu obiecte de tip InputStream deci are legatura cu biblioteca
} de I/O.
catch(EOFException e){ System.out.println(“ready”);}
}//:~

V. Niculescu - MAP 335 V. Niculescu - MAP 336

import java.io.*;
Serializarea obiectelor
class App{
public static void main(String args[]) throws IOException{
FileReader f = null;
try{ • Persistenta = durata de viata a unui obiect nu e determinata de executia
f = new FileReader(“App.java”); unui program, obiectul “traieste” si intre doua executii ale programului
StreamTokenizer st= new StreamTokenizer(f);
st.parseNumbers();
int x; double v; • Serializarea obiectelor permite implementarea “lightweight persistence”
while( (x = st.nextToken()) != StreamTokenizer.TT_EOF) (obiectele pot fi usor stocate si incarcate).
{ if (x == StreamTokenizer.TT_NUMBER)
{ v = st.nval; • In Javas serializarea obiectelor permite transformarea unui obiect ce
System.out.println(v); implementeaza interfata Serializable intr-o secventa de octeti care poate fi
} ulterior retransformsta in obiectul initial.
else System.out.println(st.sval);
}
}//try • Mecanismul de serializare permite compensarea diferentelor existente intre
catch(IOException e){ diferite sisteme de operare.
System.out.println("****"+e.getMessage());
}//catch
finally{ if (f != null) f.close();}
}//main
}//:~

V. Niculescu - MAP 337 V. Niculescu - MAP 338

83
10/12/2015

Cum se foloseste… Exemplu


public class Name implements java.io.Serializable{
private String name;
• Pentru a serializa un obiect trebuie creat un obiect out de tip
OutputStream si apoi acesta trebuie “inclus” (“wrapped”) intr-un obiect private long id;
de tip ObjectOutputStream. private transient boolean hashSet = false;
private transient int hash;
private static long nextID = 0;
• Apoi se apeleaza metoda out.writeObject( e ) prin care, e, obiectul pe
care dorim sa-l serializam si este serializat si trimis stream-ului public Name(String name){
OutputStream. this.name = name;
id = nextID++;
}
• Pentru procesul invers un obiect de tip InputStream este “inclus” intr-un
obiect de tip ObjectInputStream si apoi se apeleaza readObject( ). public int hashCode(){
if (!hashSet){
hash = name.hashCode();
• Rezultatul este un Object, deci trebuie facut un downcast pentru a obtine hashSet = true;
obiectul dorit.
}
return hash;
• Nu se salveaza doar o imagine a obiectului ci si toate obiectele referite de }
acel obiect, s.a.m.d. (object graph) //. . .
}
V. Niculescu - MAP 339 V. Niculescu - MAP 340

try{
FileOutputStream fileOut = new FileOutputStream(“Names”);
ObjectOutputStream out = new ObjectOutputStream(fileOut); Reguli
ArrayList l = new ArrayList(); Name n =new Name(“Pop”);
l.add(n);
l.add(new Name(“Marin”));
• Campurile statice nu se salveaza pe stream.
out.writeObject(n); out.writeObject(l);
fileOut.close()
• Campurile “transient” nu se salveaza pe stream.
FileInputStream fileIn = new FileInputStream(“Names”);
ObjectInputStream in = new ObjectInputStream(fileIn);
n = (Name) in.readObject(); • Cand un obiect de tip Name este deserializat, campurile “transient” vor
l = (ArrayList) in.readObject();
if (n.equals( (Name)l.get(0)) System.out.println(“acelasi”); avea valori implicite corespunzatoare tipurilor lor.
fileIn.close();
}//try
• Un obiect este scris doar o data.
catch(NotSerializableException e){
System.out.println(“Obiect neserializabil”);
}
catch(ClassNotFoundException e){
System.out.println(e);
}

V. Niculescu - MAP 341 V. Niculescu - MAP 342

84
10/12/2015

Alte optiuni C#
Standard I/O Streams

• ObjectOutputStream implements DataOutput 


putem folosi writeInt(), writeDouble(), writeUTF(),…
impreuna cu writeObject()

• ObjectInputStream implements DataInput interface 


putem folosi readInt(), readDouble(), readUTF(),…
impreuna cu readObject()

V. Niculescu - MAP 343 V. Niculescu - MAP 344

namespace System.IO Metode ale clasei Directory

• Functionalitatea :
– creare, stegere, redenumire, mutare de fisiere sau directoare,
– listarea continutului unui director,
– listarea atributelor, etc.

• Clase: Directory, DirectoryInfo, File, FileInfo…

V. Niculescu - MAP 345 V. Niculescu - MAP 346

85
10/12/2015

Metode ale clasei File Clase folosite pentru citirea si scrierea datelor

V. Niculescu - MAP 347 V. Niculescu - MAP 348

Tipuri de stream-uri

1. MemoryStreams are the simplest streams and work with in-memory


data representations
2. FileStreams work with files and add functions for locking the file for
exclusive access.IsolatedStorageFileStream.
3. NetworkStreams are very helpful for network programming and
encapsulate (but provide access to) an underlying network socket.

Clase Decorator care sunt folosite pentru a adauga dinamic responsabilitati in plus
stream-urilor precum:

1. CryptoStreams can encode and decode any other streams, whether those streams
originate in memory, the file system, or over a network.
2. BufferedStreams improve the performance of most stream scenarios
by reading and writing bytes in large chunks, rather than one at a time.

V. Niculescu - MAP 349 V. Niculescu - MAP 350

86
10/12/2015

Text and binary


Clasa FileStream
- Decorator-
• Exista mai multe metode de obtinere a unui obiect de tip FileStream.

• Clasa are 9 constructori supraıncarcati:


Enumerarea FileMode -> (Append, Create, CreateNew, Open, OpenOrCreate,
Truncate).
• Exemplu: se creeaza un fisier nou (daca nu exista) sau se suprascrie unul existent:
FileStream f = new FileStream( @’’C:\temp\a.dat’’, FileMode.Create );
SAU
FileStream g = File.OpenWrite(@’’c:\temp\test.dat’’);
//deschidere doar pentru scriere
SAU printr-o instanta a clasei FileInfo:
FileInfo fi = new FileInfo(@’’c:\temp\test.dat’’);
FileStream fs = fi.OpenRead();
//deschidere doar pentru citire

V. Niculescu - MAP 351 V. Niculescu - MAP 352

Clasa MemoryStream
FileMode
• Un MemoryStream preia datele din memorie, care este vazuta ca un vector de octeti.
• Exista sapte constructori grupatiın doua categorii.
• Exemplu 2 :
byte[] b = {1, 2, 3, 4};
MemoryStream mem = new MemoryStream(b);

• Exemplu 2 :
using System;
using System.IO;
public class MemTest
{
public static void Main()
{
MemoryStream mem = new MemoryStream();// scrie intr–un tablou redimensionabil
byte[] bs = {1, 2, 3, 4, 5, 6};
mem.Write(bs, 0, bs.Length);
mem.Seek(3, SeekOrigin.Begin);
byte b = (byte)mem.ReadByte();
Console.WriteLine(‘‘Value: {0}’’, b.ToString());
//se va afisa 4
}
V. Niculescu - MAP 353 } V. Niculescu - MAP 354

87
10/12/2015

Clasa BufferedStream Clasele BinaryReader si BinaryWriter

• Se foloseste pentru a asigura o zona tampon in cazul opera¸tiilor I/O. • Cele doua clase sunt folosite pentru a accesa date mai complexe decat un byte: de
• Constructorul acestei clase primeste o instanta a clasei Stream. exemplu, pentru manipularea datelor de tip boolean, sau Decimal, sau int cu semn
• Exemplu: pe 64 de biti.
FileStream fs = new FileStream(@’’c:\temp\a.dat’’, FileMode.Open);
BufferedStream bs = new BufferedStream(fs); • Clasa BinaryWriter are o metoda
Write()
supraincarcata, care poate fi apelata pentru scrierea diferitelor tipuri de date.
• Important sa se foloseasca metoda Flush(), care forteaza golirea bufferului asociat
stream–ului. • Pt scrierea de string–uri si de caractere / vectori de caractere: caracterele pot fi
codificate in mai multe moduri (ex: ASCII, UNICODE, UTF7, UTF8), codificare
care se poate transmite ca argument pentru constructor.

V. Niculescu - MAP 355 V. Niculescu - MAP 356

Citire / scriere texte Clasele TextReader, TextWriter si descendentele lor

• Pentru manipularea sirurilor de caractere aflate ın fisiere, se pot folosi clasele


abstracte TextReader, TextWriter.
• System.Object
System.IO.TextReader • TextReader are subclasele neabstracte StreamReader si StringReader.
System.IO.StreamReader • TextWriter are subclasele neabstracte StreamWriter, StringWriter,
System.IO.StringReader System.Web.HttpWriter, System.Web.UI.HtmlTextWriter,
System.CodeDom.Compiler.IndentedTextWriter.

• System.Object • StreamReader si StreamWriter


System.IO.TextWriter StreamReader sr = new StreamReader(@’’C:\temp\siruri.txt’’);
System.IO.StreamWriter sau pe baza unui obiect de tip FileInfo:
System.IO.StringWriter FileInfo fi = new FileInfo(@’’c:\temp\siruri.txt’’);
StreamReader sr = fi.OpenText();
• Obiectele de tip StreamReader pot citi cate o linie la un moment dat folosind
metoda ReadLine().

V. Niculescu - MAP 357 V. Niculescu - MAP 358

88
10/12/2015

Exemplu Clasele StringReader si StringWriter -


permit atasarea unor fluxuri la siruri de caractere,
using System; folosite pe post de surse de date.
using System; using System.IO;
using System.IO;
string myString = ‘‘1234567890’’;
using System.Xml;
StringReader sr = new
class Test class Test
{
StringReader(myString);
{
static void Main() static void Main()
{
{
XmlDocument doc = new XmlDocument();
StreamReader sr = new StreamReader(‘‘c:\temp\siruri.txt’’);
String entry = ‘‘<book genre=’biography’’’ +
String line; ‘‘ ISBN=’12345678’><title>Yeager</title>’’ +
do { ‘‘</book>’’;
line = sr.ReadLine(); doc.LoadXml(entry);//salvare in doc. xml va afisa:
StringWriter writer = new StringWriter(); <?xml version=’’1.0’’ encoding=’’utf-
Console.WriteLine(line); 16’’>
doc.Save(writer);
//daca line==null, atunci se va afisa o linie vida <book genre=’’biography’’
string strXml = writer.ToString(); ISBN=’’12345678’’>
}while( line!=null); Console.WriteLine(strXml); <title>Yeager</title>
} } </book>
} }

V. Niculescu - MAP 359 V. Niculescu - MAP 360

Serializarea Crearea unui obiect serializabil

• C# foloseste metodele • Pentru ca o clasa definita de utilizator sa suport serializarea, este nevoie de a preciza atributul
[Serializable] ın fata declaratiei clasei respective,
– Serialize() – Atributul este definit ın clasa System.SerializableAttribute.
• Tipurile primitive sunt automat serializabile,
– Deserialize()
• Daca tipul definit de utilizator contine atribute de alte tipuri, atunci acestea la randul lor trebuie sa
ale clasei BinaryFormatter. poata fi serializate.

using System;
• Metoda Serialize() are 2 parametri: [Serializable]
– un stream in care sa scrie public class BookRecord
{
– obiectul pe care sa il serializeze. public String title;
public int asin;
public BookRecord(String title, int asin)
• Metoda de deserializare cere doar un stream din care sa citeasca si din care sa {
refaca un object (care poate fi convertit la tipul corespunzator). this.title = title;
this.asin = asin;
}
}

V. Niculescu - MAP 363 V. Niculescu - MAP 364

89
10/12/2015

Atribute Serializarea

• Atributele sunt folosite pentru a da o extra-informatie compilatorului de .NET. using System;


using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
• Java foloseste adnotari @ pentru a include informatie similara relativ la clase,
public class SerializeObject
metode, campuri sau parametri.
{
public static void Main()
• Aceste comentarii nu vor fi incluse ın bytecod-ul final, doar ın eventuala {
documentatie. BookRecord book = new BookRecord( "Building Robots with Lego Mindstorms",
1928994679);
• Folosind atributele, aceasta informatie poate fi stocata in codul compilat si FileStream stream = new FileStream(@"book.obj", FileMode.Create);
reutilizata ulterior la runtime. BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(stream, book);
stream.Close();
}
}

V. Niculescu - MAP 365 V. Niculescu - MAP 366

Operatii la deserializare
Date tranziente Interfata IDeserializationCallback -> metoda OnDeserialization
using System;
using System.Runtime.Serialization;
• campuri ale unui obiect care nu se vor salva: [Serializable]
public class BookRecord: IDeserializationCallback
– parola unui utilizator, {
– numarul de cont al unui client, etc. public String title;
public int asin;
[NonSerialized] public int sales_rank;
• Acest lucru se face specificand atributul public BookRecord(String title, int asin)
{
[NonSerialized] this.title = title;
this.asin = asin;
pentru campul respectiv. sales_rank = GetSalesRank();
}
public int GetSalesRank()
• Exemplu: {
[NonSerialized] int secretKey; Random r = new Random();
return r.Next(5000);
}
public void OnDeserialization(Object o)
{
sales_rank = GetSalesRank();
}
}
V. Niculescu - MAP 367 V. Niculescu - MAP 368

90
10/12/2015

Deserializare Stringuri verbatim

using System; • Pentru situatia ın care se utilizeaza masiv secvente escape


using System.Runtime.Serialization.Formatters.Binary; • Un literal de acest tip are simbolul "@" ınaintea ghilimelelor de ınceput.
using System.IO; • Pentru cazul ın care ghilimelele sunt ıntalnite ın interiorul sirului, ele se vor
dubla.
public class DeserializeObject • Un sir de caractere poate fi reprezentat pe mai multe randuri fara a folosi
{ caracterul \n.
public static void Main() • Sirurile verbatim sunt folosite pentru a face referiri la fi siere sau chei 370 ın
{ registri, sau pentru expresii regulate.
FileStream streamIn = new FileStream( @"book.obj", FileMode.Open); • Exemple:
BinaryFormatter bf = new BinaryFormatter(); String caleCompleta=@"\\minimax\protect\csharp";
BookRecord book = (BookRecord) bf.Deserialize (streamIn); //ghilimelele se dubleaza intr-un verbatim string
streamIn.Close(); String s=@"notiunea ""aleator"" se refera...";
Console.Write(book.title + " " + book.asin); //string multilinie reprezentat ca verbatim
} String dialog=@"-Alo? Cu ce va ajutam?
} -As avea nevoie de o informatie.";

V. Niculescu - MAP 369 V. Niculescu - MAP 370

Analiza si Proiectare Orientata pe Obiecte


Curs 9
• Scop: creare de sisteme informatice bine proiectate, robuste, usor de
intretinut folosind tehnologii OO.

Analiza si Proiectare OO vs.


Analiza si Proiectare Orientata pe Functii
–Analiza si Proiectare OO
• Descompunere (divide&conquer) strategia primara folosita pentru a
• Diagrame de interactiune stapani complexitatea sistemelor informatice.

– Analiza si proiectare structurata:


• descompunere bazata pe functii sau procese
Ref: Larman, C., Applying UML and Design Patterns: An
– Analiza si proiectare OO :
Introduction to OO Analysis and Design, Berlin: Prentice Hall, 2000. • descompunere bazata pe obiects sau concepte

V. Niculescu - MAP 371 V. Niculescu - MAP 372

91
10/12/2015

OOA si OOD Cazuri de Utilizare si Cicluri de Dezvoltare

• UML • Un caz de utilizare este o descriere narativa a unui proces al domeniului

1. Faza de specificare • Ciclurile de dezvoltare iterative sunt organizate in functie de cerintele


• Cicluri de dezvoltare iterative cazurilor de utilizare.
• Faze ale unui ciclu:
2. Faza de Analiza | • Partajarea cazurilor de utilizare
3. Faza de Proiectare | Faza de – se considera mai intai cazurile de utilizare care au o influenta
dezvoltare importanta asupra nucleului arhitecturii.

4. Faza de Constructie (implementare) |

V. Niculescu - MAP 373 V. Niculescu - MAP 374

Faza de specificare Studiu de caz: Magazin/Casa_de_marcat

• Artefacte: • Nivele arhitecturale


– Planificare: resurse, buget, orar,…
– Raport de Investigatii Preliminare: motivatii, alternative,..
– Prezentare (minor)
– Specificarea Cerintelor:
– Logica Aplicatiei
– Glosar: dictionar de termeni si informatie asociata.
• obiectele domeniului problemei (Vanzare, Plata,…)
– Prototip: un sistem prototip creat pentru a ajuta la intelegerea
problemelor, riscurilor si cerintelor. (primar)

– Cazuri de Utilizare: descrieri ale proceselor domeniului. • obiecte de serviciu (DatabaseBroker,SecurityManager)


(secundar)
– Diagrame ale Cazurilor de Utilizare: ilustrarea tuturor cazurilor de
utilizare si a relatiilor dintre ele. – Stocare

V. Niculescu - MAP 375 V. Niculescu - MAP 376

92
10/12/2015

Cerinte – Functii de baza Cerinte – Functii de plata


Ref# Functie Categorie
Ref# Functie Categorie
R1.1 Inregistreza vanzarea curenta – produsele evident
cumparate. R2.1 Executa plati cash – permite introducerea sumei evident
R1.2 Calculeaza suma curenta totala incluzand taxele evident date de client si calculeaza restul.
R2.2 Executa plati prin credit card, preia informatiile de la evident
R1.3 Obtine informatii despre produse din codul UPC. evident cititorul de carduri sau prin introducere manuala si
R1.4 Reduce cantitatile de inventar pentru produsele ascuns autorizeaza plata prin serviciul magazinului de
cumparate atunci cand vanzarea se termina. autorizari de credit, prin modem.
R1.5 Inregistreaza vanzarile finalizate. ascuns R2.3 Executa plati prin check si autorizeaza plata prin evident
R1.6 Casierul trebuie sa intre in sistem cu un ID si o parola. evident serviciul magazinului de autorizari de credit, prin
modem.
R1.7 Furnizeaza un mecanism de stocare persistenta. ascuns
R2.4 Inregistreaza platile prin credit pana la incasare. ascuns
R1.8 Furnizeaza un mecanism de comunicare inter- ascuns
process si inter-sistem.
R1.9 Afiseaza descrierea si pretul pentru produsele evident
inregistrate.
V. Niculescu - MAP 377 V. Niculescu - MAP 378

Cazuri de utilizare Caz de utilizare: Cumparare


• Caz de utilizare = un document narativ care descrie o secventa
de evenimente ale unui actor (un agent extern) care foloseste
sistemul pentru a realiza procesul. Caz de utilizare: Cumparare
Actori: Casier, Client (initiator)
• Ele ilustreaza si implica cerintele. Tip: primar
Descriere:
• UML:
Un client vine la casa de marcat cu produsele pe care vrea sa le
Cumparare cumpere. Casierul inregistreaza produsele si face plata. La
sfarsit clientul pleaca cu produsele.
• Un caz de utilizare este o descriere a unui proces de sine Referinte: Functii: R1.1, R1.2,R1.3, R1.7, R1.9, R2.1
statator relativ mare care in mod normal implica mai multi pasi
individuali.

V. Niculescu - MAP 379 V. Niculescu - MAP 380

93
10/12/2015

Descriere evenimentelor tipice


Diagrama cazurilor de utilizare
(pentru Cumparare)
Actiuni Actor Raspunri Sistem
1. Clientul ajunge la casa de matcat cu Log in
produsele.
2. Casierul inregistreaza fiecare 3. Determina pretul produselor si adauga
produs; daca sunt mai multe bucati informatia despre produs la vanvarea
din acelasi produs introduce si in tranzactie. Cashier Buy Items Customer

cantitatea.
4. La incheierea introducerii 5. Calculeaza si afiseaza suma totala.
produselor Casierul indica casei de Refund Purchased Items
marcat finalizarea Vanzarii.
6. Casierul informeaza Clientul despre
suma totala.
7. Clientul alege modul de plata: SystemAdministrat
Manage Users

a) Daca se alege Plata Cash se initiaza or

Plata Cash
b) Daca se alege Plata Credit se Start Up
Manager
initiaza Plata Credit
c) Daca se alege Plata Chec se initiaza
Plata Check

V. Niculescu - MAP 381 V. Niculescu - MAP 382

Identificarea Actorilor si a Cazurilor de Utilizare Ordonarea si Planificarea cazurilor de utilizare

• Ordonarea cazurilor de utilizare


• Daca este necesar se creaza versiuni simplificate ale unor cazuri de
Casier Intrare utilizare. (De exemplu, Cumparare doar cu plata cash.)
• Alocarea cazurilor de utilizare ciclurilor de dezvoltare.
Iesire
Client Cumparare Exemplu

Returnare produse Cazuri de utilizare: Prioritate


Manager Deschidere - Cumparare Mare
- Adaugare de noi utilizatori |
Inchidere - Intrare | Medie
Administrator Adaugare de - Returnare produse |
- Deschidere | Scazuta
utilizatori noi - Inchidere |

V. Niculescu - MAP 383 V. Niculescu - MAP 384

94
10/12/2015

Etapa de Analiza Un Model Conceptual pentru “Point-of-Sale”


Recors-sal e-of
Described-by

• Descompunerea problemei in concepte si obiecte


ProductCatal og Contai ns ProductSpecifi cation
1..n
• Model Conceptual = o reprezentare a conceptelor domeniului problemei
used-by
– concepte
descri bes

– asocieri intre concepte Sal esLi neItem Store Stocks Item

– atribute ale conceptelor


quantity Logs-compl eted address 0..n
1..n
+Houses
contained-in
POST started-by Manager
Sal e 0..n
O descriere a lucrurilor din lumea reala din domeniul problemei date captured-on
tim e
• Fara referire la ferestre, baze de date… Pai d-by
i ni tiated-by
Records-sales-on Cashi er
• Fara responsabilitati sau metode
Customer
Paym ent
am ount

V. Niculescu - MAP 385 V. Niculescu - MAP 386

Model Conceptual Comportamentul Sistemului


• = descriere a ceea ce face sistemul,
• Nu exista doar un singur model conceptual pentru o fara a se explica cum face.
problema. • Diagrame de secventa sistem

• Un model conceptual bun include abstractiile :System


Repeta pana cand
esentiale si informatiille necesare pentru intelegerea nu mai sunt elemente enterItem(UPC, quatity)
domeniului:
• O diagrama de secventa sistem arata endSale()
– conceptele lui un scenariu particular al unui caz de
utilizare:
– terminologia – evenimetele pe care actorii le
makePayment(amount)

– relatiile genereaza
– ordinea lor
– etc. – evenimentelr intersistem

V. Niculescu - MAP 387 V. Niculescu - MAP 388

95
10/12/2015

Contract pentru enterItem()


– Nume: enterItem(upc:number, quantity:number) Contract pentru endSale()
– Responsibilitati: Inregistrarea vanzarii unui produs si adaugarea lui la vanzare.
Afisarea descrierii produsului si a pretului
– Tip: Sistem • Nume: total = endSale()
– Referinte: R1.1, R1.3, R1.9, Caz de utilizare: Buy Items (Cumparare)
– Nota: Este necesar accesul la baza de date • Responsabilitati: inregistrarea finalizarii inregistrarii produselor si calularea
– Exception: UPC invalid sumei totale.
– Output: - • Tip: Sistem
– Preconditii: UPC este cunoscut de catre sistem • Referinte: R1.2, Caz de utilizare: Buy Items
– Postconditii: • Nota:
• Daca este o noua vanzare, un obiect Sale a fost creat • Exceptii: Daca nu exista o vanzare curenta se indica o eroare.
(creare de instanta).
• Daca este o noua vanzare, noul obiect Sale a fost asociat cu POST (Casa- • Output:
de-Marcat) (formare de asociere). • Pre-conditions: Un obiect Sale a fost creat. Obiectul Sale a fost asociat
• Un obiect SalesLineItem a fost creat (creare de instanta) cu obiectul POST.
• Obiectul SalesLineItem a fost asociat cu obiectul Sale (formare de
asociere). • Post-conditions:
• SalesLineItem.quantity a fost setat cu quantity (modificare de – Sale.isComplete a fost setat cu true (modificare atribut)
atribut)
• Obiectul SalesLineItem a fost asociat cu un obiect – total a fost setat la suma totala
ProductSpecification pe baza codulului de bare UPC (formare de
asociere).
V. Niculescu - MAP 389 V. Niculescu - MAP 390

Faza de proiectare Etapa de proiectare

• Creare de diagrame de interactiune separate pentru fiecare operatie  O solutie logica bazata pe paradigma OO
sistem.
• Pentru fiecare eveniment sistem se creeaza o diagrama cu mesajul de
start acel eveniment. • Diagrame de interactiune UML :
• Daca o diagrama devine prea complexa se imparte in mai multe. − secventa
• Se folosesc responsabilitatile si postconditiile descrise in contracte − colaborare
si descrierile cazurilor de utilizare, ca punct de plecare.
• Se aplica sabloanele GRASP si alte sabloane pentru a se ajunge la message()
:A :B
un bun design.
message1()
• Se creaza diagrama de clase (simultan).
message2()

V. Niculescu - MAP 391 V. Niculescu - MAP 392

96
10/12/2015

Exemplu
Diagrame de Colaborare

1: message1()
message() :A :B
2: message2()
• Sintaxa unui Mesaj
return:= message (par: parType):returnType
• Mesaj spre “this”

1: msg1()

message()
:A

V. Niculescu - MAP 393 V. Niculescu - MAP 394

Sintaxa Sintaxa

• Iterare: • Creare de instante: create


• Colectii –
msg() 1*: [i:=1..10]li:=nextItem():SalesLineItem
:POST :Sale

sales:Sales

• Mesaje conditionale: • Obiecte Clasa


1a:[test] msg1()
1b:[not test] msg2()
1:d1:=today():Date Date
:Sale

V. Niculescu - MAP 395 V. Niculescu - MAP 396

97
10/12/2015

Exemplul 1 Exemplul 2

V. Niculescu - MAP 397 V. Niculescu - MAP 398

GRASP Expert
• Responsabilitate = Un contract sau obligatie a unui tip ori clasa
Problema: Care este principiul de baza prin care sunt atribuite responsabilitatile in
• Metodele sunt implementate pentru indeplini responsabilitatile proiectarea OO?
Solutie: Atribuie responsabilitatea expertului care detine informatia - clasa care are
• General Responsibility Assignment Software Patterns GRASP informatia necesara pentru a indeplini responsabilitatea.
Exemplu: Cine ar trebui sa fie responsabil pentru calcularea sumei totale a unei
– Expert vanzari?
– Creator 1:*[for each] sli:=next( )
t:=total()
– High Cohesion : Sale

– Low Coupling 2:st:=subtotal()


– Controller
: SalesLineItem
sli :
– Polymorphism SalesLineItem

– Pure Fabrication 2.1: p:=price()


– Indirection
– Don’t talk with strangers : ProductSpecification

V. Niculescu - MAP 399 V. Niculescu - MAP 400

98
10/12/2015

Expert: Avantaje Creator


Problema: Cine ar trebui sa fie responsabil de crearea unui nou obiect?
• Este principiul de baza folosit in OOD. Solutie: Atribuie clasei B responsabilitatea crearii unei instante a clasei A daca este
adevarata una din urmatoarele situatii:
• Incapsularea este mentinuta, deoarece obiectele folosesc propria lor - B contine obiecte de tip A
informatie pentru a indeplini sarcinile. Determina cuplare slaba.
- B inregistreaza obiecte de tip A
- B foloseste obiecte de tip A
• Comportamentul este distribuit in clasele care au informatia necesara, si
aceasta incurajeaza clase cat mai coezive. Determina coeziune ridicata. - B detine datele de initializare necesare pentru crearea unui obiect de tip A (Expert).
Example: Cine ar trebui sa fie responsabil de crearea instantelor de tip SalesLineItem?
Este cunoscut si sub alte nume: “Place Responsibilities with data”, “That
which knows, does”, “Animation”, “Do it myself”
1: create(quantity)
makeLineItem(quantity) : Sale : SalesLineItem

V. Niculescu - MAP 401 V. Niculescu - MAP 402

Creator: Avantaje Low Coupling/ Cuplare slaba


Problema: Cum sa fie scazuta depenedenta dintre clase si sa se mareasca
reutilizabilitatea?
• Creator ghideaza atribuirea responsabilitatilor legate de crearea obiectelor, Solutie: Atribuie o responsabilitate astefl incat cuplarea sa ramana slaba.
care este o sarcina foarte comuna in sistemele OO. Cuplarea este o masura a gradului in care o clasa este conectata la, are cunostinta
despre, se bazeaza pe alte clase.
Pentru o clasa cu cuplare ridicata: schimbarile in clasele conexe forteaza schimbari
• Determina cuplarea slaba, care implica dependente scazuta in intretinere si locale, este dificil de inteles in izolare si dificil de reutilizat.
mari opotunitati de reutilizare. Exemplu: Cine ar trebui sa fie responsabil de crearea unei instante Payment?
Creator => POST
Low Coupling => Sale (better)
• Sabloane conecte: Low coupling, Whole-Part
1.2: addPayment(p)
1: makePayment()
: POST : Sale
1: create()
p : Payment
1.1 create()

2: addPayment(p) p : Payment
: POST : Sale

V. Niculescu - MAP 403 V. Niculescu - MAP 404

99
10/12/2015

Low Coupling : Avantaje High Cohesion/ Coeziune ridicata


Problema: Cum sa fie mentinuta complexitatea la cote gestionabile?
• Clasele sunt simplu de inteles in isolare. Solutie: Atribuie o responsabilitate astfel incat coeziunea clasei sa ramana
ridicata.
• Clasele nu sunt afectate de schimbari in alte clase. Cohesion este o masura a gradului in care responsabilitatile unei clase sunt
conectate intre ele si servesc unui scop bine precizat.
O clasa cu coeziune redusa este dificil de inteles, de reutilizat, de intretinut si
• Clasele sunt convenabil de reutilizat. este in mod constant afectata de schimbari.
Exemplu: Cine ar trebui sa fie responsabil de crearea unei instante Payment?
• Forme comune de cuplare: Creator => POST
– TypeX are un atribut care refera o instanta a lui TypeY sau clasa TypeY High Cohesion => Sale (better)
insasi. 1.2: addPayment(p)
1: makePayment()
: POST
– TypeX are o metoda care refera o instanta a lui TypeY sau clasa TypeY : Sale
insasi.
– TypeX este o subclasa directa ori indirecta a clasei TypeY. 1.1 create()
– TypeY este o interfata si TypeX implementeaza aceasta interfata.
p : Payment

V. Niculescu - MAP 405 V. Niculescu - MAP 406

High Cohesion : Avantaje Controller


Problema: Cine ar trebui sa fie responsabil de tratarea unui eveniment sistem
?
• Claritate si usurinta de intelegerii a proiectarii creste.
Solutie: Atribuie o responsabilitate pentru tratarea unui eveniment sistem unei
clase care reprezinta unul dintre urmatoarele:
• Intretinerea si extinderea sunt simplificate. - un “sistem” global (façade controller).
- o organization (façade controller).
- ceva din lunea reala care este activ (de exemplu rolul unei persoane) care
• Cuplarea slaba este determinata. poate fi implicata in acea sarcina (role controller).
- O clasa creata artificial care trateaza toate evenimentele sistem ale unui caz
de utilizare si care este numita in general <UseCaseName>handler (use-
• Cresterea potentialului de reutilizare, pentru ca o clasa cu case controller).
coeziune ridicata poate fi refolosita pentru un scop precis.
Corolar: Clasele cum sunt ferestrele, ‘applet’-uri, aplicatii, vederi,
documenete nu trebuie sa indeplineasca responsabilitati legate de
evenimentele sistem.

V. Niculescu - MAP 407 V. Niculescu - MAP 408

100
10/12/2015

Cine ar trebui sa fie responsabil de tratarea Bloated Controllers/


evenimentelor sistem? (Buy-Items) Controlori supraincarcati
Posibilitati (Controller pattern) System • Controlor cu coeziune slaba:
enterItem()
endSale()
– Trateaza prea multe arii de responsabilitati
makePayment()
• POST – reprezinta “sistem”
• Solutii:
• Store – reprezinta o organizatie – Se adauga mai multi controlori (façade controller, role
controller si use-cases controller).
• Cashier – reprezinta ceva din lumea reala care este activ (o – Se proiecteaza un controlor care deleaga alti controlori sau
persoana) care este implicata in vanzare. alte obiecte pentru indeplinirea fiecari responsabilitati.
• BuyItemsHandler – reprezinta un handler artificial pentru
toate evenimentele sistem ale cazului de utilizare.

V. Niculescu - MAP 409 V. Niculescu - MAP 410

Controller: Avantaje Faza de proiectare – exeplu Casa de Marcat

• Creste potentialul de refolosire a componenetelor. • Creare de diagrame de interactiune separate pentru fiecare operatie
sistem.
• Pentru fiecare eveniment sistem se creeaza o diagrama cu mesajul de
– O proiectare bazata pe interfata–ca-si-controlor reduce oportunitatea start acel eveniment.
de a reutiliza nivelul domeniu in viitor deoarece acesta este legat de o
• Daca o diagrama devine prea complexa se imparte in mai multe.
interfata particulara.
• Se folosesc responsabilitatile si postconditiile descrise in contracte
si descrierile cazurilor de utilizare, ca punct de plecare.
• Se poate analiza starea unui caz de utilizare; operatiilor sistem • Se aplica sabloanele GRASP si alte sabloane pentru a se ajunge la
pot fi fortate sa apara in ordinea legala. un bun design.

• Se creeaza diagrama de clase (simultan).

V. Niculescu - MAP 411 V. Niculescu - MAP 412

101
10/12/2015

Buy Items enterItem(upc, qty)

Posibilitati: • O noua instanta Sale este creata la introducerea primului produs.


enterItem(upc, quantity) :POST • Cine ar trebui sa fie responsabil?
– Creator=> POST (realizeaza vanzarile)
• O instanta Sale contine mai multe SalesLineItems
enterItem(upc, quantity)
:Store – Creator=> Sale va crea instante SaleLineItem
• Aflarea ProductSpecification in functie de UPC
– Expert => ProductCatalog
enterItem(upc, quantity)
:Cashier
• Cine ar trebui sa trimita mesajul de obtinerea a specificarii instantei
ProductCatalog?
– Post este asociat cu Store, si Store foloseste ProductCatalog
enterItem(upc, quantity) :BuyItemsHandler – Sau o noua asociere poate fi adaugata intre POST si ProductCatalog

V. Niculescu - MAP 413 V. Niculescu - MAP 414

enterItem(upc, qty) endSale()

by Creator 1: t:= total 1.1:*[for each] sli:=next( )


by Expert endSale() : POST : Sale :
SalesLineItem
1: [if new sale] create( ) 2: becomeComplete()
by Expert
enterItem(upc, qty) : POST : Sale
3: makeLineItem(spec,qty) by Expert
1.2: st:=subtotal()
sli :
2: spec:=getSpecification(upc) 3.1: sl:=create(spec,qty)
SalesLineItem
total(){
1.1: create() tot:=0;
: ProductCatalog becomeComplete(){ for each SaleLineItem sli
sl : 1.2.1: pr:=price()
isComplete:= true tot:=tot+sli.subtotal()
SalesLineItem
} return tot;
add(sl) } spec :
2.1: spec:=find(upc) ProductSpecification

: subtotal(){
: return quantity* spec.price();
ProductSpecification SalesLineItem
}

V. Niculescu - MAP 415 V. Niculescu - MAP 416

102
10/12/2015

Conectarea nivelului Prezentare cu


nivelulul Domeniu
Arhitectura clasica “Three-Tier Architecture”

• Pentru aplicatii client-


1: enterItem(upc,qty)
onEnterItem() Presentation server:
:POSTFrame :POST (1) Nivelurile Prezentare si
Model-View
Aplicatieti pe calculatorul
Separation
client, si nivelul servicii pe
calculatorul server
System event Domain

(2) Nivelul Prezentare pe


Presentation claculatorul client , si
Layer
Domain nivelurile Aplicatie si Servicii
Layer Services
pe calculatorul server

V. Niculescu - MAP 417 V. Niculescu - MAP 418

Nu exista vizibilitate directa spre ferestre Coordonator Aplicatie

• Vizibilitatea indirecta este aceptata! Callbacks • Mediaza legatura dintre interfata si nivelul domeniu/aplicatie.
• Folosirea sablonului Observer/ Publish-Subscribe
Responsabilitati:
• POSTFrame poate avea vizibilitate la obiectele domeniu cum sunt POST, – Deschide ferestrele si afiseaza informatia din obiectele domeniu
Sale. – Gestioneaza tranzactiile
– Raspunde la evenimentele primite de la interfata
• Obiectele POST si Sale vor ignora existenta ferestrei; nu sunt instructiuni – Mapeaza informatia intre obiecetele domeniu si cele interfata
in metodele din POST and Sale legate de afisare si de logica afisarii. – Permite abilitatea de a avea mai multe ferestre care afiseaza simultan
informatia unui singur model (nivel domeniu)
• O clasa EventManager (Pure-Fabrication) poate fi utilizata pe post de – Notifica ferestrele dependente cand informatia din model se schimba si
intermediar intre model si vederi. cand ferestrele trebuie sa-si actualizeze informatia afisata.

V. Niculescu - MAP 419 V. Niculescu - MAP 420

103
10/12/2015

Diagrama de clase Vizibilitatea

• Diagrama de clase se creeaza in paralel cu diagramele de interactiune • Pentru ca un obiect A sa trimita un mesaj la un obiect B,
B trebuie sa fie vizibil pentru A.
• Diagrama de clase ilustreza:
– clasele, asocierile, atributele, • 4 moduri de obtinere a vizibilitatii:
– interfetele, cu operatiile si constantele lor, – Vizibilitatea Atribut: B este un atribut al lui A;
– metodele, – Vizibilitatea Parametru: B este parametru a unei metode a lui A;
– Tipurile atributelor, – Vizibilitatea Locala: B este declarat ca obiect local intr-o metoda a
– navigabilitatea (directia vizibilitatii unui atribut), clasei lui A;
– Dependentele (indica vizibilitatea de tip non-atribut). – Vizibilitatea Globala: B este intr-un anume mod vizibil global.

V. Niculescu - MAP 421 V. Niculescu - MAP 422

Cateva reguli
Curs 10
• Clasele se gasesc din diagramele de interactiune.

• Metodele se gasesc din diagramele de interactiune.


GUI
• In general constructorii sunt omisi (pentru ca exista multiple interpretari
pentru “create” – C++, Java, etc.).

• Metodele de acces (set, get) pot fi omise – atunci cand toate atributele sunt
“private” si exista metode set si get pentru fiecare dintre acestea.

• Obiectele multiple se implementeaza in general folosind clase din biblioteci


predefinite ale limbajului si de aceea nu sunt afisate in diagrama de clase.

V. Niculescu - MAP 423 V. Niculescu - MAP 424

104
10/12/2015

JFC si Swing

• Java Swing • JFC = JavaTM Foundation Classes,


un grup de clase care permit construirea interfetelor grafice (GUI).

• Caracteristici:
– The Swing Components
– Pluggable Look and Feel Support
Se pot alege diferite “looks and feels”.
– Separare a datelor de modele
– ...

• Pachete:
– javax.swing
– javax.swing.event
– ...

V. Niculescu - MAP 425 V. Niculescu - MAP 426

Cele trei parti ale unei componente Swing


Componente Swing si Componente AWT

• Componentele AWT au fost furnizate de platformele JDK 1.0 si 1.1

• Componentele Swing sunt implementate fara a se folosi cod nativ.

• Deoarece componentele Swing nu sunt restrictionate la caracteristicile


de baza existente pe fiecare platforma pot avea o functionalitate mai
complexa decat componentele AWT.

• Avantaje ale componentelor Swing:


– Butoanele si etichetele pot avea nu numai text dar si imagini.
– Se pot adauga sau schimba usor margini in jurul componentelor Swing.
– Se poate schimba usor comportamentul si forma componentelor Swing
prin apelarea unor metode sau prin constructia uor clase derivate.
– Ccomponentele Swing pot sa nu fie rectangulare. JButton component have multiple delegates like “MetalButtonUI”
“WindowsButtonUI”, …

V. Niculescu - MAP 427 V. Niculescu - MAP 428

105
10/12/2015

Look and Feel Setarea “Look and Feel”


• Setting the Java Look&Feel
public static void main(String[] args) {
• Swing UI manage:. try {
UIManager.setLookAndFeel(
– Verifica daca utilizatorul a specificat un Look and Feel.
– Daca da, atunci incearca sa il incarce/foloseasca. UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) { }
– Daca nu, sau daca alegerea nu este valida, atunci UI manager
new SwingApplication(); //Create and show the GUI.
alege Java Look & Feel. }
• Setting the Windows Look & Feel
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel“)

• Setting the native Look&Feel for whatever platform


UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());

V. Niculescu - MAP 429 V. Niculescu - MAP 430

Partial JComponent hierarchy


Swing MVC

MVC:
• The model stores the data/ Modelul stocheaza datele.
• The view creates the visual representation from the data in the
model./
Vederea creeaza reprezentarea grafica
• The controller deals with user interaction and modifies the model
and/or the view/ controlorul gestioneaza interactiunea M-V

• Swing- MicroMVC
a collection of model/view/controller triads, each responsible for a
different GUI element.
Examples
• The Swing GUI system models almost all interface components as
individual MVC systems.
431
V. Niculescu - MAP 431 V. Niculescu - MAP 435

106
10/12/2015

Exemplu Containeri Swing “Top-level”

• Cel putin unul pentru fiecare aplicatie care foloseste GUI.

• JFrame, JDialog, ori JApplet.

• JFrame object -> main window,


JDialog object -> secondary window,
JApplet object -> an applet's display area within a browser window.

• Furnizeaza suport pentru componentele Swing sa se afiseze si pentru


tratarea evenimentelor.

V. Niculescu - MAP 436 V. Niculescu - MAP 437

Ierarhia containerilor
Exemplu - implementare
• Top-level container
• Intermediate container (panel): import javax.swing.*;
JPanel, JScrollPane, JTabbedPane) import java.awt.*;
import java.awt.event.*;
• Atomic components
public class SwingApplication {
...
• Diagrama ierarhiei pentru exemplu (SwingApplication). public static void main(String[] args) {
...
JFrame frame = new JFrame("SwingApplication");
//...create the components to go into the frame...
//...stick them in a container named contents...
frame.getContentPane().add(contents,
BorderLayout.CENTER);

//Finish setting up the frame, and show it.


frame.addWindowListener(...);
frame.pack();
frame.setVisible(true);
}
}
V. Niculescu - MAP 438 V. Niculescu - MAP 439

107
10/12/2015

Crearea Butoanelor si etichetelor Adaugarea componentelor in containeri

JButton button = new JButton("I'm a Swing button!"); JPanel pane = new JPanel();
button.addActionListener(...create an action listener...);
pane.setBorder(
BorderFactory.createEmptyBorder(
• 30, 30, 10, 30));
...//where instance variables are declared:
private static String labelPrefix =
pane.setLayout(new GridLayout(0, 1));
"Number of button clicks: "; pane.add(button);
private int numClicks = 0;
pane.add(label);
...//in GUI initialization code:
final JLabel label = new JLabel(labelPrefix + "0 ");

...//in the event handler for button clicks:


label.setText(labelPrefix + numClicks);

V. Niculescu - MAP 440 V. Niculescu - MAP 441

Adaugarea marginilor Layout Management

• Layout management este procesul de determinare a marimii si pozitiei


pane.setBorder( componentelor.
BorderFactory.createEmptyBorder(
30, //top
• Implicit fiecare container are un layout manager -- un obiect care
30, //left
realizeaza layout management pentru componentele din container.
10, //bottom
30) //right
);
• Trebuie sa se tina seama de layout manager atunci cand se adauga

(add) o componenta intr-un container.

V. Niculescu - MAP 442 V. Niculescu - MAP 443

108
10/12/2015

Setarea pentru Layout Manager


JPanel pane = new JPanel();
pane.setLayout(new BorderLayout()); BorderLayout
Caracteristicile unei componente • BorderLayout implicit pentru <content pane. >
• Dimensiuni
– setMinimumSize, setPreferredSize, setMaximumSize)
– sau se pot defini subclase care pot suprascrie metodele--
getMinimumSize, getPreferredSize, getMaximumSize.

• Aliniamente
Container contentPane = getContentPane();
– setAlignmentX setAlignmentY //contentPane.setLayout(new BorderLayout()); //unnecessary
getAlignmentX getAlignmentY contentPane.add(new JButton("Button 1 (NORTH)"),
BorderLayout.NORTH);
Spatiu intre componente contentPane.add(new JButton("2 (CENTER)"),
• Trei factori:: BorderLayout.CENTER);
contentPane.add(new JButton("Button 3 (WEST)"),
– Layout manager BorderLayout.WEST);
– Componente invisibile contentPane.add(new JButton("Long-Named Button 4 (SOUTH)"),
– Margini BorderLayout.SOUTH);
contentPane.add(new JButton("Button 5 (EAST)"),
BorderLayout.EAST);
V. Niculescu - MAP 444 V. Niculescu - MAP 445

FlowLayout GridLayout
• FlowLayout implicit pentru JPanel. • .

Container contentPane = getContentPane();


contentPane.setLayout(new FlowLayout());
contentPane.add(new JButton("Button 1")); Container contentPane = getContentPane();
contentPane.add(new JButton("2")); contentPane.setLayout(new GridLayout(0,2));
contentPane.add(new JButton("Button 1"));
contentPane.add(new JButton("Button 3")); contentPane.add(new JButton("2"));
contentPane.add(new JButton("Long-Named Button contentPane.add(new JButton("Button 3"));
contentPane.add(new JButton("Long-Named Button 4"));
4")); contentPane.add(new JButton("Button 5")); contentPane.add(new JButton("Button 5"));

V. Niculescu - MAP 446 V. Niculescu - MAP 447

109
10/12/2015

Event Handling • Fiecare eveniment este reprezentat de un obiect care furnizeaza informatie
despre eveniment si sursa acestuia.

Act that results in the event Listener type • Sursele sunt in general componente.
User clicks a button, presses Return ActionListener • Fiecare sursa de evenimente poate avea inregistrati mai multi “listeners”.
while typing in a text field, or chooses • Un singur listener poate fi inregistrat pentru mai multe surse.
a menu item
User closes a frame (main window) WindowListener
User presses a mouse button while the MouseListener
cursor is over a component
User moves the mouse over a MouseMotionListener
component
Component becomes visible ComponentListener
Component gets the keyboard focus FocusListener
Table or list selection changes ListSelectionListener

V. Niculescu - MAP 448 V. Niculescu - MAP 449

Implementarea unui Event Handler Informatii despre eveniment


• Exemplu : ActionListener
• EventObject.

public class MyClass implements ActionListener { • Object getSource()


– Returneaza obiectul sursa al evenimentului.
public void actionPerformed(ActionEvent e) {
...//code that reacts to the action...
} • Exemplu:

MouseEvent
• Inregistrare: furnizeaza informatii despre pozitia mouse-ului, numar de click-
someComponent.addActionListener( uri, etc.
instanceOfMyClass)

V. Niculescu - MAP 450 V. Niculescu - MAP 451

110
10/12/2015

Exemplu (ActionEvent)
Evenimente “low-level” si semantice
Object
 • Evenimente
java.util.EventObject – Low-level: window-system occurrences, low-level input,

java.awt.AWTEvent – Semantice toate celelalte.
 • Exemple:
java.awt.event.ActionEvent
– mouse, key, component, container, focus, and window events.
– action events, item events, list selection events.
ActionEvent

• Recomandare!!!!
+getActionCommand():String
+setActionCommand(String) Tratati evenimentele semantice daca e posibil nu ecele “low-level”!
+getSource():Object

V. Niculescu - MAP 452 V. Niculescu - MAP 453

Ascultatori suportati de toate componentele Swing Tratarea evenimentelor pentru SwingApplication

• Component listener
button.addActionListener(new ActionListener() {
– Schimbari de marime, pozitie si vizibilitate public void actionPerformed(ActionEvent e) {
• Focus listener numClicks++;
label.setText(labelPrefix + numClicks);
• Key listener }
});
...
• Mouse listener frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
• Mouse motion listener System.exit(0);
}
});

V. Niculescu - MAP 454 V. Niculescu - MAP 455

111
10/12/2015

Main Windows Window Listener


public class WindowEventDemo ... implements WindowListener {
public static void main(String s[]) { ...//where initialization occurs:
JFrame frame = new JFrame("FrameDemo"); //Create but don't show window.
window = new JFrame("Window Event Window");
frame.addWindowListener(new WindowAdapter() { window.addWindowListener(this);
window.getContentPane().add(
public void windowClosing(WindowEvent e) new JLabel("The frame listens to this window "
{System.exit(0);} + "for window events."),
}); BorderLayout.CENTER);
window.pack();
//...create a blank label, set its preferred size... }
public void windowClosing(WindowEvent e) {
frame.getContentPane().add( window.setVisible(false);
emptyLabel,BorderLayout.CENTER); displayMessage("Window closing", e);
}
public void windowClosed(WindowEvent e) {
frame.pack(); displayMessage("Window closed", e);
frame.setVisible(true); }
}

V. Niculescu - MAP 456 V. Niculescu - MAP 457

public void windowOpened(WindowEvent e) {


displayMessage("Window opened", e); Adaptori
}
public void windowIconified(WindowEvent e) {
displayMessage("Window iconified", e);
} class WindowAdapter implements WindowListener{
public void windowDeiconified(WindowEvent e) { public void windowClosing(WindowEvent e) {}
displayMessage("Window deiconified", e); public void windowClosed(WindowEvent e) {}
}
public void windowOpened(WindowEvent e) {}
public void windowActivated(WindowEvent e) {
displayMessage("Window activated", e);
public void windowIconified(WindowEvent e) {}
} public void windowDeiconified(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) { public void windowActivated(WindowEvent e) {}
displayMessage("Window deactivated", e); public void windowDeactivated(WindowEvent e) {}
} }
void displayMessage(String prefix, WindowEvent e) {
display.append(prefix + ": " Ex:
+ e.getWindow() frame.addWindowListener(new WindowAdapter() {
+ newline);
public void windowClosing(WindowEvent e) {
}
...
System.exit(0);
}
}
});

V. Niculescu - MAP 458 V. Niculescu - MAP 459

112
10/12/2015

SwingApplication-(2)
SwingApplication-(1)
button.addActionListener(new ActionListener() {
import javax.swing.*; public void actionPerformed(ActionEvent e) {
import java.awt.*; numClicks++;
import java.awt.event.*; s=new String(text.getText());
label.setText(labelPrefix + numClicks+ s );
public class SwingApplication { }
private static String labelPrefix = });
"Number of button clicks:";
private int numClicks = 0; label.setLabelFor(button);
private String s="";
JPanel pane = new JPanel();
public Component createComponents() {
final JLabel label = new JLabel(labelPrefix + "0 "); pane.setBorder(
BorderFactory.createEmptyBorder(20, 20, 50, 40) );
final JTextField text = new JTextField("cliks", 20); pane.setLayout(new GridLayout(3, 1));
pane.add(button);
JButton button = new JButton("I'm a Swing button!"); pane.add(label);
button.setMnemonic('i'); pane.add(text);

return pane;
}
V. Niculescu - MAP 460 V. Niculescu - MAP 461

SwingApplication-(3) Clasa AbstractButton


public static void main(String[] args) {
try {
UIManager.setLookAndFeel(
– Subclase:
UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) { }
• JButton, JMenuItem, JToggleButton

JFrame frame = new JFrame("SwingApplication"); • JToggleButton


SwingApplication app = new SwingApplication();
Component contents = app.createComponents(); Implementare a unui buton cu 2 stari.
frame.getContentPane().add(contents,
BorderLayout.CENTER);
– Subclase:
frame.addWindowListener(new WindowAdapter() { » JCheckBox, JRadioButton
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.pack();
frame.setVisible(true);
}
}
V. Niculescu - MAP 462 V. Niculescu - MAP 463

113
10/12/2015

Clasa JButton Class JTextField


• Constructori:
– JButton(Icon icon) • JTextField (Extinde JTextComponent)

– JButton(String text) • Constructori:


– JTextField(int columns)
– JButton(String text, Icon icon) .
– JTextField(String text)

class ImageIcon implements Icon {…} – JTextField(String text, int columns)


• Constructori:
– ImageIcon(Image image)
• Metode:
– ImageIcon(Image image, String description) – public String getText()
– public String getSelectedText()
– ImageIcon(String filename) – public void setText(String t)
– ImageIcon(String filename, String description) – public void setEditable(boolean b)

V. Niculescu - MAP 464 V. Niculescu - MAP 465

Clasa JTextArea Exemplu


import java.awt.*;
import java.awt.event.*;
• JTextArea. import javax.swing.*;
(Extinde JTextComponent) import java.lang.*;
• Constructori: :
– JTextArea(int rows, int columns) public class Actions extends JPanel implements ActionListener
{
– JTextArea(String text) int power=0;
JTextField field, fieldRez;
– JTextArea(String text, int rows, int columns) ImageIcon buttonImage;
JButton button;
JRadioButton radioButton;
ButtonGroup grp;
• Metode:
JCheckBox checkBox;
– void append(String str)
– void insert(String str, int pos) JLabel label1;
– void setColumns(int columns) JLabel label2;
JLabel label3;
– void setRows(int rows)

V. Niculescu - MAP 466 V. Niculescu - MAP 467

114
10/12/2015

public Actions() // Creates three radio buttons that specifies the exponent
{ grp = new ButtonGroup();
setLayout (new GridLayout(5,1,10,10));
setBackground (Color.lightGray); radioButton = new JRadioButton("One");
radioButton.addActionListener(this);
JPanel subPanel = new JPanel(); radioButton.setActionCommand("One Activated");
label1 = new JLabel("Number:"); grp.add(radioButton);
subPanel.add(label1); subPanel.add(new JLabel(""));
subPanel.add(radioButton);
// Creates a text field where the number is read
subPanel.add(label2);
field = new JTextField(10);
field.addActionListener (this); radioButton = new JRadioButton("Two");
label1.setLabelFor(field); radioButton.addActionListener(this);
subPanel.add(field); radioButton.setActionCommand("Two Activated");
add(subPanel); grp.add(radioButton);
subPanel.add(radioButton);
subPanel = new JPanel();
subPanel.setLayout(new GridLayout(3,2)); radioButton = new JRadioButton("Three");
radioButton.addActionListener(this);
label2 = new JLabel("Power:"); radioButton.setActionCommand("Three Activated");
grp.add(radioButton);
subPanel.add(new JLabel(""));
subPanel.add(radioButton);

V. Niculescu - MAP 468 add(subPanel); V. Niculescu - MAP 469

// Creates a checkbox that specifies if the square root is computed public void actionPerformed(ActionEvent e)
subPanel=new JPanel(); { if (e.getActionCommand().equals("One Activated"))
checkBox=new JCheckBox("Square Root"); power=1;
checkBox.addActionListener(this); if (e.getActionCommand().equals("Two Activated"))
subPanel.add(checkBox); power=2;
add(subPanel); if (e.getActionCommand().equals("Three Activated"))
power=3;
subPanel=new JPanel();
// Creates a button with an icon if (e.getActionCommand().equals("Button Activated"))
buttonImage = new ImageIcon("c:/temp/qs_cons.gif"); { double rez;
button = new JButton("Compute"); try{
button.setIcon(buttonImage); rez=Integer.parseInt(field.getText());
button.addActionListener(this); rez=Math.pow(rez,power);
button.setActionCommand("Button Activated"); if (checkBox.isSelected()) rez=Math.sqrt(rez);
subPanel.add(button); fieldRez.setText((new Double(rez)).toString());
add(subPanel); }
catch(NumberFormatException ee){
subPanel=new JPanel(); JOptionPane.showMessageDialog(
label3 =new JLabel("Result"); field,"Give an integer number!","Error",
subPanel.add(label3); JOptionPane.ERROR_MESSAGE ) ;
fieldRez = new JTextField(15); field.requestFocus();
fieldRez.setEditable(false); }
subPanel.add(fieldRez); }
add(subPanel); }
}
V. Niculescu - MAP 470 V. Niculescu - MAP 471

115
10/12/2015

public Dimension getPreferredSize()


{ return new Dimension(200, 400); Liste
}
public static void main(String s[])
{ • O componenta JList afiseaza un grup de elemente din
JFrame frame = new JFrame("Computer");
Actions panel = new Actions(); care utilizatorul poate alege.
frame.setForeground(Color.blue);
frame.setBackground(Color.lightGray);
frame.setLocation(100,100);
• Listele sunt incluse in general in ‘scroll pane’.
frame.addWindowListener(new WindowCloser());
frame.getContentPane().add(panel,"Center");
frame.pack();
frame.setVisible(true);
• Separare dintre date si afisare:
} – Model / View
} – Datele continute intr-o lista sunt pastrate intr-un ListModel
class WindowCloser extends WindowAdapter
{ public void windowClosing(WindowEvent e)
{
}
System.exit(0);

}

V. Niculescu - MAP 472 V. Niculescu - MAP 473

ListModel Setarea elementelor unei liste


• Interfata ListModel
– void addListDataListener(ListDataListener l) Method Purpose
Create a list with the initial list items specified.
– Object getElementAt(int index) JList(ListModel)
JList(Object[]) The second and third constructors implicitly
– int getSize() JList(Vector) create an immutable ListModel.
. void setModel(ListModel) Set or get the model that contains the contents of
– void removeListDataListener(ListDataListener l) ListModel getModel() the list.
void setListData(Object[]) Set the items in the list. These methods implicitly
• Clasa DefaultListModel void setListData(Vector) create an immutable ListModel

• Se pot creare propriile clase de tip ListModel prin


extinderea clasei AbstractListModel

V. Niculescu - MAP 474 V. Niculescu - MAP 475

116
10/12/2015

Tipuri de selectii Selectarea in liste


Method Purpose
Exemple void addListSelectionListener( Register to receive notification of
ListSelectionListener) selection changes.
Mod Descriere Set the current selection as indicated.
void setSelectedIndex(int) Use setSelectionMode to set what
SINGLE_SELECTION La un moment dat void setSelectedIndices(int[]) ranges of selections are acceptable. The
void setSelectedValue(Object, boolean) boolean argument specifies whether the
doar un element este void setSelectedInterval(int, int)
list should attempt to scroll itself so that
selectat. the selected item is visible.
int getSelectedIndex()
int getMinSelectionIndex()
int getMaxSelectionIndex() Get information about the current
SINGLE_INTERVAL_ La un moment dat pot int[] getSelectedIndices()
Object getSelectedValue()
selection as indicated.
SELECTION fi selectate mai multe Object[] getSelectedValues()

elemente consecutive. Set or get the selection mode.


Acceptable values are:
SINGLE_SELECTION,
void setSelectionMode(int)
int getSelectionMode() SINGLE_INTERVAL_SELECTION, or
MULTIPLE_INTERVAL_ (implicit) Orice MULTIPLE_INTERVAL_SELECTION (the
default), which are defined in
SELECTION combinatie de selectii. ListSelectionModel.
Deselectarea se face void clearSelection() Set or get whether any items are
boolean isSelectionEmpty() selected.
explicit.
boolean isSelectedIndex(int)
Determine whether the specified index
is selected.
V. Niculescu - MAP 476 V. Niculescu - MAP 477

Exemplu
private JButton addButton;
private JButton deleteButton;
import java.awt.*;
import java.awt.event.*; private JTextField nameField;
import javax.swing.*; private JTextArea log;
import javax.swing.event.*; static private String newline = "\n";

public class ListDemoSimple extends JFrame


implements ListSelectionListener {
ListDemoSimple(String s){
private JList list; super(s); // the constructor of JFrame
private DefaultListModel listModel; }

private static final String addString = "Add"; public Dimension getPreferredSize()


private static final String deleteString = "Delete"; { return new Dimension(600, 400);
}

V. Niculescu - MAP 478 V. Niculescu - MAP 479

117
10/12/2015

//Create the list and put it in a scroll pane.


list = new JList(listModel);
public JPanel init() { list.setSelectionMode(
ListSelectionModel.SINGLE_INTERVAL_SELECTION);
//Create and populate the list model.
listModel = new DefaultListModel(); list.setSelectedIndex(0);
list.addListSelectionListener(this);
listModel.addElement("Whistler, Canada");
listModel.addElement("Jackson Hole, Wyoming"); JScrollPane listScrollPane =
listModel.addElement("Squaw Valley, California"); new JScrollPane(list);
listModel.addElement("Telluride, Colorado");
listModel.addElement("Taos, New Mexico"); //Create the list modifying buttons.
listModel.addElement("Snowbird, Utah"); addButton = new JButton(addString);
listModel.addElement("Chamonix, France"); addButton.setActionCommand(addString);
listModel.addElement("Banff, Canada"); addButton.addActionListener(
new AddButtonListener());

listModel.addListDataListener( deleteButton = new JButton(deleteString);


new MyListDataListener()); deleteButton.setActionCommand(deleteString);
deleteButton.addActionListener(
new DeleteButtonListener());

V. Niculescu - MAP 480 V. Niculescu - MAP 481

//Create the text field for entering new names. //Create the log for reporting list data events.
nameField = new JTextField(15); log = new JTextArea(5, 2);
nameField.addActionListener( JScrollPane logScrollPane = new JScrollPane(log);
new AddButtonListener());

String name = listModel.getElementAt( //Create a split pane for the log and the list.
list.getSelectedIndex()).toString(); JSplitPane splitPane =
new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
nameField.setText(name); listScrollPane, logScrollPane);
//Create a control panel (uses the default FlowLayout). JPanel panel=new JPanel();
JPanel buttonPane = new JPanel(); panel.setLayout(new BorderLayout());
panel.add(buttonPane, BorderLayout.NORTH);
buttonPane.add(nameField); panel.add(splitPane, BorderLayout.CENTER);
buttonPane.add(addButton); return panel;
buttonPane.add(deleteButton); }

V. Niculescu - MAP 482 V. Niculescu - MAP 483

118
10/12/2015

class DeleteButtonListener implements ActionListener {


public void actionPerformed(ActionEvent e) {
class MyListDataListener implements ListDataListener {
ListSelectionModel lsm = list.getSelectionModel();
public void contentsChanged(ListDataEvent e) { int firstSelected = lsm.getMinSelectionIndex();
log.append("contentsChanged: " + e.getIndex0() + int lastSelected = lsm.getMaxSelectionIndex();
", " + e.getIndex1() + newline); listModel.removeRange(firstSelected, lastSelected);
}
public void intervalAdded(ListDataEvent e) { int size = listModel.size();
log.append("intervalAdded: " + e.getIndex0() +
", " + e.getIndex1() + newline); if (size == 0) {
} //List is empty: disable delete.
public void intervalRemoved(ListDataEvent e) { deleteButton.setEnabled(false);
log.append("intervalRemoved: " + e.getIndex0() + }
", " + e.getIndex1() + newline); else {
} //Adjust the selection.
} if (firstSelected == listModel.getSize()) {
//Removed item in last position.
firstSelected--;
}
list.setSelectedIndex(firstSelected);
} } }
V. Niculescu - MAP 484 V. Niculescu - MAP 485

class AddButtonListener implements ActionListener { //Listener method for list selection changes.
public void actionPerformed(ActionEvent e) { public void valueChanged(ListSelectionEvent e) {
if (nameField.getText().equals("")) { if (e.getValueIsAdjusting() == false) {
//User didn't type in a name... if (list.getSelectedIndex() == -1) {
Toolkit.getDefaultToolkit().beep(); //No selection: disable delete button.
return; deleteButton.setEnabled(false);
} nameField.setText("");
int index = list.getSelectedIndex(); }
int size = listModel.getSize(); else if (list.getSelectedIndices().length > 1) {
//If no selection or if item in last position is selected, //Multiple selection: disable add button.
//add the new one to end of list, and select new one. deleteButton.setEnabled(true);
if (index == -1 || (index+1 == size)) { addButton.setEnabled(false);
listModel.addElement(nameField.getText()); }
list.setSelectedIndex(size); else {
//Otherwise insert the new one after //Single selection: permit all operations.
// the current selection, and select new one. deleteButton.setEnabled(true);
} else { addButton.setEnabled(true);
listModel.insertElementAt(nameField.getText(), index+1); nameField.setText(
list.setSelectedIndex(index+1); list.getSelectedValue().toString());
} }
} } }
}
V. Niculescu - MAP 486 V. Niculescu - MAP 487

119
10/12/2015

public static void main(String args[]){ JScrollPanel - Decorator


ListDemoSimple frame=
new ListDemoSimple("Lista");
frame.setForeground(Color.blue);
frame.setBackground(Color.lightGray);
frame.setLocation(100,100);

frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e)
{System.exit(0);}
});
• Constructori
JPanel panel=frame.init();
frame.getContentPane().add(panel,"Center"); – JScrollPane()
Creaza un JScrollPane vid (fara viewport); bare de scroll
frame.setSize(panel.getPreferredSize()); orizontale si verticale apar cand este necesar.
frame.pack();
– JScrollPane(Component view)
frame.setVisible(true); Creaza a JScrollPane care afiseaza continutul componentei; bare
} de scroll orizontale si verticale apar daca componenta este mai mare.
}

V. Niculescu - MAP 488 V. Niculescu - MAP 489

Meniuri C#
• Clase:
– JMenuBar, JMenu, JMenuItem
• Exemplu
private JMenuItem addItem;
private JMenuItem deleteItem;

addItem = new JMenuItem(addString);


addItem.addActionListener(new AddButtonListener());

deleteItem = new JMenuItem(deleteString);


deleteItem.addActionListener(new DeleteButtonListener());

private JMenuBar menub = new JMenuBar();


private JMenu menu1 = new JMenu("menu1");
private JMenu menu2 = new JMenu("menu2");
menu1.add(addItem);
menu2.add(deleteItem);

menub.add(menu1);
menub.add(menu2);
frame.setJMenuBar(menub);
V. Niculescu - MAP 490 V. Niculescu - MAP 491

120
10/12/2015

Ex. From Thinking in C# Clasa Form

//:c14:FirstForm.cs Form -> subtip a clasei Control


using System.Windows.Forms;
class FirstForm : Form { Form : ContainerControl : ScrollableControl : Control).
public static void Main(){
Application.Run (new FirstForm()); Obiectele de tip Control au o proprietate numita Controls care contine o
} colectie de alte controale.
}
exemplu de folosire Composite design pattern,
//rezultat=>
Permite ca toate elementele de interfata (simple sau complexe ) sa fie tratate
uniform.

V. Niculescu - MAP 492 V. Niculescu - MAP 493

MVC
Curs 11 • Sablonul Model/View/Controller (MVC) este folosit in special pentru aplicatii cu
interfete utilizator.

• MVC consta in :
–Model-View-Controller Pattern
– Model defineste domeniul aplicatiei
–Observer Design Pattern
– View defineste interfata utilizator
–Publish-Subscribe Pattern – Controller defineste modul in care interactioneaza celelalte 2.
–Strategy Design Pattern
–Command Design Pattern
–Event Delegation

–Layered architectures

V. Niculescu - MAP 494 V. Niculescu - MAP 495

121
10/12/2015

Model–View–Controller (MVC) Separation of concerns

• MVC izoleaza • Model


– gestioneaza comportamentul si datele domeniului aplicatiei,
– "domain logic" – raspunde la cererile referitoare la informatii despre starea sa (in general de la view), si
de – raspunde la cererile pentru schimbare de stare (in general de la controller).
– “user interface”
In sistemele event-driven, modelul notifica observatorii (in general views) atunci cand sunt
schimbari astfel incat acestia sa poata reactiona.
si astel permite realizarea in mod independent a
• dezvoltarii, • View
– afiseaza informatii despre model intr-o forma adaptata interactiunii.
• testarii Pot exista mai multe vederi pentru un singur model.
• intretinerii
• Controller
acestora.
– primeste input si
– initiaza un raspuns prin apelarea unor obiecte din model.
Un controller accepta input de la utilizator si instruieste modelul sa realizeze actiuni in functie
de acest input.

V. Niculescu - MAP 496 V. Niculescu - MAP 497

exemplificare simpla… -linie solida = asociere directa,


-linie intrerupta = asociere indirecta (ex. prin observator)

V. Niculescu - MAP 498 V. Niculescu - MAP 499

122
10/12/2015

Exemplu simplu Relatia Views - Model

• protocol de tip “subscrie/notifica”

– O vedere trebuie sa asigure faptul ca reflecta intocmai starea modelului.

– Ori de cate ori modelul se schimba, modelul notifica vederile care depind de
ele. In urma acestei notificari fiecare vedere isi poate actualiza starea.

– Aceasta abordare permite atasarea mai multor vederi la un model.

– Se pot de asemenea crea noi vederi pentru model fara a fi nevoie ca modelul sa
fie rescris/modificat.

V. Niculescu - MAP 500 V. Niculescu - MAP 501

Observer Observer – Structura

• Scop
– Defineste o dependenta de tip unu-la-mai-multe intre obiecte, astfel incat atunci
cand un obiect isi schimba starea, toate obiectele dependente de el sunt
notificate si actualizate automat.
(o specializare a sablonului mai general Publish/Subscribe)

• Aplicabilitate:
– Cand o abstractizare are doua aspecte, unul depinzand de altul, incapsularea
acestor aspecte in obiecte separate ne permite sa le modificam si sa le refolosim
independent.
– Cand o modificare a unui obiect cere modificarea automata a altora si nu se
cunoaste exact cate obiecte trebuie sa fie schimbate.
– Cand un obiect trebuie sa poata sa instiinteze alte obiecte fara a cunoaste detalii
despre aceste obiecte. Cu alte cuvinte, cand nu dorim ca aceste obiecte sa fie
cuplate strans.

V. Niculescu - MAP 502 V. Niculescu - MAP 503

123
10/12/2015

Observer-Exemplu
Interactiuni Relatia Model – View

V. Niculescu - MAP 504 V. Niculescu - MAP 505

Observer in Java
Alt exemplu de folosire a sablonului Observer
• Interface Observer <<Interface>>
Observer
(from util)
void update(Observable o, Object arg)
Observable
(from util) + update()

• Class Observable
void addObserver(Observer o)
Licitatie Licitator
int countObservers() - offeredValue : Integer
- value : Integer
void deleteObserver(Observer o) - ... - ...
void deleteObservers() + update(arg0 : Observable, arg1 : Object) : void
+ setValue(v : Integer)
boolean hasChanged() + ...() + ...()

void notifyObservers()
void notifyObservers(Object arg) value=v; offeredValue:=arg1.intValue()
void setChanged() (protected) setchanged();
notifyObservers()

V. Niculescu - MAP 506 V. Niculescu - MAP 507

124
10/12/2015

Relatia View – Controller Strategy

• MVC permite de asemenea schimbarea modului in care o vedere raspunde inputului • Relatia View-Controller este un exemplu de folosire a sablonului de proiectare
utilizatorului fara a se schimba prezentarea vizuala. Strategy.

– Daca se doreste schimbarea modului in care sistemul raspunde la apasarea • Strategy este un obiect care reprezinta un algoritm.
tastelor (ex. jocuri: alte taste), sau folosirea unui meniu de tip pop-up in locul
tastaturii. • Este folositor
– atunci cand se doreste inlocuirea unui algoritm static sau chiar dinamic;
– MVC incapsuleaza mecanismul de raspuns intr-un obiect de tip Controller. – cand exista mai multe variante ale algoritmului,
• Se poate crea o ierarhie de clase de tip controller, aceasta facand posibila – sau atunci cand un algoritm are structuri de date complicate pe care doreste sa
simpla creare a unui nou controller ca o variatie a celui existent. le incorporeze.

V. Niculescu - MAP 508 V. Niculescu - MAP 509

Strategy – Structura Strategy - Aplicabilitate

• Cand mai multe clase difera doar in comportament. “Strategy” furnizeaza un mod
de a configura o clasa cu una sau mai multe functionalitati.

• Cand este nevoie de mai multe variante ale unui algoritm. “Strategy” este folosit
atunci cand aceste variante sunt implementate ca o ierarhie de clase de algoritmi.

• Cand un algoritm foloseste date pe care clientii nu ar trebui sa le cunoasca.


“Strategy” se foloseste pentru a evita expunerea structurilor de date complexe
specifice unui algoritm.

• Cand o clasa defineste mai multe comportamente si acestea apar in multiple


instructiuni conditionale. In loc de a folosi instructiuni conditionale complexe,
ramurile conditionale corespunzatoare se muta in clase Strategy.

V. Niculescu - MAP 510 V. Niculescu - MAP 511

125
10/12/2015

Strategy Example
public class Controller implements ActionListener // maybe other listeners Strategy based on Interfaces
{ public void actionPerformed(ActionEvent e){
// some action
}
….
}
public class SpecializedController extends Controller {
public void actionPerformed(ActionEvent e){
// some other action
}
//…
}
public class MyWindow extends JFrame{
private JButton buton;
private Controller ctr;
//…
public void changeResponse(Controller newCtr)
button.removeActionListener(ctr);
button.addActionListener(newCtr);
ctr=newCtr;
//…
}
//…
} V. Niculescu - MAP 512 V. Niculescu - MAP 514

Exemplu simplu -Java View.java

//Model.java import java.awt.*;


import java.util.*;
import java.awt.*;
import java.util.*; public class View extends Canvas implements Observer {
Color color;
public class Model extends Observable { public void paint(Graphics g) {
if (color == null) return;
public Color color = new Color(0x010000);
g.setColor(color);
private int count = 10; g.fillOval(0, 0, getWidth(), getHeight());
void doSomething() { }
if (--count <= 0) { public void update(Observable observable, Object arg) {
color = ((Model)observable).color;
color = color.brighter();
repaint();
count = 10; // }
setChanged(); }
notifyObservers();
}
}
}

V. Niculescu - MAP 515 V. Niculescu - MAP 516

126
10/12/2015

Controller.java micro MVC


import …
public class Controller { • O aplicatie MVC poate fi formata dintr-o
Model model ;
View view ;
colectie de triade
public Controller( Model m, View v) {
model/view/controller triads, fiecare
model = new Model(); responsabila cu un element GUI diferit.
view = new View();
model.addObserver(view);

for (int i = 0; i < 200; i++) {


model.doSomething();
Exemple:
}
• Aproape toate componentele Swing GUI sunt
}
modelate ca si sisteme MVC individuale.
}

518
V. Niculescu - MAP 517 V. Niculescu - MAP 518

Swing library Strategy based on Delegates

• Se face o decuplare intre datele vizualizate in


interfata utilizator si controalele interfetei prin
care acestea sunt vazute.

• Aproape toate componentele Swing au


asociate modele (care sunt specificate in
termeni corespunzatori Java ca interfete),
pentru care programatorul poate folosi
diferite implementari sau sa defineasca altele
noi.

• Framework-ul furnizeaza implementari V. Niculescu - MAP


519
519 V. Niculescu - MAP 520

implicite ale modelului interfetelor pentru


toate componentele sale concrete.

• In general, doar componentele complexe, 127


10/12/2015

Generalizarea sablonului Observer Publisher-Subscriber pattern - structure

Publish-Subscribe Pattern

• Problema:
– O schimbare in starea (sau un eveniment) apare in Publisher si toate
obiectele care sunt dependente sau interesate de acest tip de eveniment
sunt informate (Subscribers).
– Publisher nu trebuie sa aiba cunoasterea directa a obiectelor
Subscribers asociate (cunoasterea tipului concret).

• Solutie:
– Defineste un sistem de notificare a evenimentelor, astfel incat Publisher
poate indirect sa notifice Subscriberii.

V. Niculescu - MAP 521 V. Niculescu - MAP 522

Publisher-Subscriber - comportament Alt exemplu:

V. Niculescu - MAP 523 V. Niculescu - MAP 524

128
10/12/2015

layers

V. Niculescu - MAP 525 V. Niculescu - MAP 526

Abordare generalizata... Evenimente si EventManager


Dispatching Events

– Se defineste o clasa EventManager (Pure Fabrication)

– Un eveniment este publicat de catre Publisher prin trimiterea unui


mesaj signalEvent catre EventManager.

– EventManager cauta toti subscriberii care sunt interesati de


eveniment, si ii notifica - ideal printr-un mesaj parametrizat.

– Un eveniment este o instanta a clasei Event.


Event Delegation 
Un sistem prin care se defineste un obiect separat pentru tratarea
evenimentelor; acesta “asculta/asteapta” evenimente care pot apare in alte
obiecte (ex.: GUI Component)

V. Niculescu - MAP 528 V. Niculescu - MAP 529

129
10/12/2015

In Java modelul de delegare de evenimente este bazat


pe EventListeners = Subscribers

Folosirea unui obiect intermediar EventManager are


– avantajul minimizarii cuplarii intre publisher si responsabilitati
– dezavantajul minimizarii performantei deoarece provoaca o “gatuire”
bottleneck,

• Proiectarea clasica a lui Publish-Subscribe = Observer

V. Niculescu - MAP 530 V. Niculescu - MAP 531

Semantic Events si EventListeners

• Puteti defini propriile evenimente:


– StopEvent, etc.
=> noi clase derivate din EventObject

• Puteti defini proprii listeners pentru aceste evenimente speciale cu metode


speciale.
=> interfate care pot fi implementate de clase diferite

V. Niculescu - MAP 532 V. Niculescu - MAP 533

130
10/12/2015

Sisteme : Message Handling Command Pattern

• Se folosesc in special pentru aplicatii care nu folosesc interfete ci folosesc • Intent: Incapsuleaza o cerere ca si un obiect,
primesc mesaje de la alte sisteme externe.
permitand parametrizarea cu diferite cereri
• Solutie: sau cozi de mesaje si permitand operatii
undo.
– Defineste un singur Controller pentru toate mesajele de tip eveniment
sistem – • Structura:
(façade controller, ori use-case type controller)
(namit MessageHandler).

– Se foloseste sablonul Command pentru a rezolva o cerere.


• Pentru fiecare tip de mesaj => o comanda concreta

V. Niculescu - MAP 534 V. Niculescu - MAP 535

Aplicabilitate
• parametrizare cu actiunea care se realizeaza;

– in limbajele procedurale aceasta se poate exprima printr-o functie callback, care este o
functie care se inregistreaza undeva pentru a fi apoi apelata la un moment ulterior.

– Comenzile sunt inlocuitorii orientati-obiect pentru callbacks.

• specifica, salveaza in cozi si executa cereri la diferite memente de timp;

• suporta undo;

• suporta inregistrarea schimbarilor astefl incat acestea pot fi reaplicatein cazul in care apare
system crash.
Interfata Command poate fi imbunatatita cu operatiile load si store, se poate pastra un
persistent log al schimbarilor.

• structureaza sistemul in jurul operatiilor de nivel inalt construite pe baza operatiilor


primitive.
– o asemenea structura este comuna in sistemele care suporta transactions.
O tranzactie incapsuleaza un set de schimbari asupra datelor..

V. Niculescu - MAP 536 V. Niculescu - MAP 537

131
10/12/2015

Collaboration Diagram Exercitiu

• Considerati cazul unui calculator cu operatii undo.


c:
1a[ msgrec.type=1] create(msgRec) Command1 • Un asemenea calculator poate sa mentina o lista a tuturor operatiilor anterioare
handleMessage(msgRec) executate si astfel este posibil sa se retaureze valoarea de la inceput.
: MessageHandler
• Aceasta ar cauza ca obiectul-calculator sa devina prea mare si prea complex si
1b[type=2] create(msgRec)
“greu”.

• Aceasta functionalitate poate fi mutata in afara clasei calculator - manager class-


c:
Command2
care poate colecta starea interna a calculatorului si sa o salveze.
2: execute()

c:
Command

V. Niculescu - MAP 538 V. Niculescu - MAP 541

Memento pattern “Layers” ca si sablon arhitectural

Intent
• The intent of this pattern is to capture the internal state of an object without violating
encapsulation and thus providing a mean for restoring the object into initial state when • In proiectarea orientata-obiect,
needed. nivel (layer) = un grup de clase care au acelasi set de dependente la nivel
de modul, la momentul legarii cu alte module
(link-time module dependencies to other modules).

V. Niculescu - MAP 542 V. Niculescu - MAP 545

132
10/12/2015

N-tier architecture layer and tier

• Un model pentru a crea aplicatii •


– flexibile si
– reutilizabile
– a layer is a logical structuring mechanism for the elements that make
up the software solution, while
• Prin separarea pe nivele se poate
– modifica ori
– adauga un nivel specific, – a tier is a physical structuring mechanism for the system infrastructure.
in loc a se se rescrie intreaga aplicatie.

• Ar trebui sa existe cel putin:


– un nivel prezentare,
– un nivel business(domeniu),
– un nivel data-storage.

V. Niculescu - MAP 546 V. Niculescu - MAP 547

The three-tier architecture Comparatie cu arhitectura MVC


• the three tiers si model-view-controller (MVC) par similare dar sunt totusi
• Presentation tier topologic diferite.
– The presentation tier displays information related to such services as browsing
merchandise, purchasing, and shopping cart contents. It communicates with
other tiers by outputting results to the browser/client tier and all other tiers in • O regula fundamentala in the three tiers
the network.
– nivelul client (presentation) nu comunica niciodata cu data tier;
• Application tier (business logic, logic tier, data access tier, or middle tier) – toate comunicatiile trebuie sa se faca prin intermediul nivelului
– The logic tier is pulled out from the presentation tier and, as its own layer, it business.
controls an application’s functionality by performing detailed processing.
• Conceptual, arhitectura three-tier este liniara.
• Data storage tier
– This tier consists of database servers. Here information is stored and retrieved.
This tier keeps data neutral and independent from application servers or
business logic. Giving data its own tier also improves scalability and • Arhitectura MVC este triunghiulara :
performance.
• the view sends updates to the controller,
• the controller updates the model, and
• the view gets updated directly from the model.
V. Niculescu - MAP 548 V. Niculescu - MAP 549

133
10/12/2015

Middleware O perspectiva istorica...

• Middleware refera un software care conecteaza • Conceptul arhitecturii three-tier a aparut in anii 1990s din analizarea
– componente software ori sistemelor distribuite (e.g., web applications) unde nivelele prezentare,
– utilizatori de aplicatiile lor middleware si stocare se executa pe platforme diferite fizic.

Software-ul consta dintr-un set de servicii care permit mai multor procese care
se executa pe o masina sau pe mai multe, sa interactioneze • MVC apare mai inainte ( Xerox PARC 1970s - 1980s) si se bazeaza pe
(provide for interoperability) analizarea aplicatiilor care se executa o singura statie de lucru (single
graphical workstation);
– Este similar cu nivelul de mijloc din arhitectura three-tier cu exceptia Ulterior s-a extins aplicarea MVC la aplicatii distribuite.
faptului ca se intinde pe mai multe sisteme sau aplicatii (stretched
across multiple systems or applications)

V. Niculescu - MAP 550 V. Niculescu - MAP 551

Layered architecture
-domain isolation-
• Domain-Driven Design

• Four layers architecture

Reference: Eric Evans. Domain-Driven Design: Tackling Complexity in the Heart of Software.
Addison-Wesley, 2003
V. Niculescu - MAP 552 V. Niculescu - MAP 553

134
10/12/2015

Application Layer
User Interface (or Presentation Layer)
• The tasks this layer is responsible for are
– meaningful to the business or
Responsible for
– necessary for interaction with the application layers of other systems.
• showing information to the user and
• interpreting the user's commands. • This layer does not contain business rules or knowledge.

The external actor might sometimes be another computer system rather than a • Responsibilities:
human user. – coordinates tasks and
– delegates work to domain objects in the next layer down.

• It does not have state reflecting the business situation,


but it can have state that reflects the progress of a task for the user or the program.

• This layer is responsible for ordering the notification.

V. Niculescu - MAP 554 V. Niculescu - MAP 555

Domain Layer (or Model Layer) Infrastructure Layer

• Responsible for : • Provides generic technical capabilities that support the higher layers.
– representing concepts of the business, • Services:
– information about the business situation, and – message sending for the application,
– business rules. – persistence for the domain,
– Drawing widgets for the UI, and so on.
• State that reflects the business situation is controlled and used here, even
though the technical details of storing it are delegated to the infrastructure. • The infrastructure layer may also support the pattern of interactions
between the four layers through an architectural framework.

• This layer is the heart of business software.

V. Niculescu - MAP 556 V. Niculescu - MAP 557

135
10/12/2015

Design Rules
Remarks
• Partition a complex program into layers.

• Some projects don't make a sharp distinction between the • Develop a design within each layer that is cohesive and that depends only
– user interface layer and on the layers below.
– application layer.
• Follow standard architectural patterns to provide loose coupling to the
layers above.
• Others have multiple infrastructure layers.
• Concentrate all the code related to the domain model in one layer and
isolate it from the user interface, application, and infrastructure code.
• But the crucial separation of the domain layer enables
MODEL-DRIVEN DESIGN.
• The domain objects, free of the responsibility of displaying themselves,
storing themselves, managing application tasks, and so forth, can be
focused on expressing the domain model.

• This allows a model to evolve to be rich enough and clear enough to


capture essential business knowledge and put it to work.

V. Niculescu - MAP 558 V. Niculescu - MAP 559

Example: Funds Transfer Partitioning Services into Layers

• Application Funds Transfer App Service


– Digests input (such as an XML request).
– Sends message to domain service for fulfillment.
– Listens for confirmation.
– Decides to send notification using infrastructure service.

• Domain Funds Transfer Domain Service


– Interacts with necessary Account and Ledger objects, making appropriate
debits and credits.
– Supplies confirmation of result (transfer allowed or not, and so on).

• Infrastructure Send Notification Service


– Sends e-mails, letters, and other communications as directed by the application.

V. Niculescu - MAP 560 V. Niculescu - MAP 561

136
10/12/2015

Grasp - Pure Fabrication

• A Pure Fabrication is a class that does not represent a concept in the problem
domain.

• It is specially made up to achieve low coupling, high cohesion, and the reuse Curs 9
potential thereof derived (when a solution presented by the Information Expert
pattern does not).

• This kind of class is called "Service" in Domain-driven design. Fire de executie

V. Niculescu - MAP 562 V. Niculescu - MAP 563

Life Cycle of a Thread

V. Niculescu - MAP 564 V. Niculescu - MAP 565

137
10/12/2015

Race Conditions & Critical Sections


• Codul nu este executat ca si o instructiune atomica:
• Situatia in care 2 thread-uri incearca sa foloseasca aceeasi resursa, si ordinea in
care este folosita este importanta, se numeste race conditions. get this.count from memory into register
add value to register
• O sectiune de cod care conduce la race conditions se numeste critical section write register to memory
(sectiune critica).
• Exemplu de intretesere
public class Counter { this.count = 0;
protected long count = 0; A: reads this.count into a register (0)
public void add(long value){ B: reads this.count into a register (0)
this.count = this.count + value; B: adds value 2 to register
} B: writes register value (2) back to memory. this.count now equals 2
} A: adds value 3 to register
• Metoda add() este un exemplu de sectiune critica care conduce la race conditions. A: writes register value (3) back to memory. this.count now equals 3
• Race conditions pot fi evitate prin sincronizarea corecta a threadurilor in sectiunile
critice.

V. Niculescu - MAP 566 V. Niculescu - MAP 567

Thread Safety si Shared Resources Variabile Locale

• Codul care poate fi apelat simultat de mai multe threaduri se numeste thread safe. • Sunt stocate pe stiva de executie a fiecarui thread.
• Daca o bucata de cod este thread safe atunci nu contine race conditions. • Prin urmare nu sunt niciodata partajate.
• Race condition apare doar atunci cand mai multe threaduri updateaza resurse – => thread safe.
partajate.
– -care sunt acestea….? public void someMethod(){
long threadSafeInt = 0;
threadSafeInt++;
}

V. Niculescu - MAP 568 V. Niculescu - MAP 569

138
10/12/2015

Local Object References Exemplu: not thread safe


public class NotThreadSafe{ NotThreadSafe sharedInstance = new NotThreadSafe();
• Referinta poate fi locala si nu este partajata.
StringBuilder builder = new Thread(new MyRunnable(sharedInstance)).start();
• Obiectul referit poate fi partajat – shared heap new StringBuilder(); new Thread(new MyRunnable(sharedInstance)).start();

• Daca obiectul este folosit doar in interiorul threadului care il defineste => thread public add(String text){ public class MyRunnable implements Runnable{
safe.
this.builder.append(text); NotThreadSafe instance = null;
}
public void someMethod(){
} public MyRunnable(NotThreadSafe instance){
LocalObject localObject = new LocalObject();
this.instance = instance;
localObject.callMethod();
}
method2(localObject);
} public void run(){
public void method2(LocalObject localObject){ this.instance.add("some text");
localObject.setValue("value"); }
} }

V. Niculescu - MAP 570 V. Niculescu - MAP 571

The Thread Control Escape Rule Thread Signaling

• Permite trasnmiterea de semnale/mesaje de la unul thread la altul.

• Daca o resursa este creata, folosita si eliminata in interiorul controlului aceluiasi • Additionally, thread signaling enables threads to wait for signals from other threads.
thread atunci folosirea acelei resurse este thread safe. • For instance, a thread B might wait for a signal from thread A indicating that data is
ready to be processed.

V. Niculescu - MAP 572 V. Niculescu - MAP 573

139
10/12/2015

Signaling via Shared Objects Busy Wait


•Thread B asteapta ca data sa devina disponibila penrtu a o procesa.

public class MySignal{


• Setarea unei variabile partajate- • Altfel spus asteapta un semnal de la treadul A
comunicare prin variabile partajate. protected boolean hasDataToProcess = false; => hasDataToProcess() to return true.

public synchronized boolean hasDataToProcess(){


return this.hasDataToProcess; •Busy waiting nu implica o utilizare eficienta a CPU (cu exceptia situatiei
} in cate timpul mediu de asteptare este foarte mic).

public synchronized void


setHasDataToProcess(boolean hasData){
this.hasDataToProcess = hasData;
protected MySignal sharedSignal = ...
}
...
}
while(!sharedSignal.hasDataToProcess()){
//do nothing... busy waiting
}
V. Niculescu - MAP 574 V. Niculescu - MAP 575

wait(), notify() and notifyAll() Syncronized


public class MonitorObject{
}
• It would be smarter if the waiting thread could somehow sleep or become inactive
until it receives the signal it is waiting for. public class MyWaitNotify{

MonitorObject myMonitorObject = new MonitorObject();


• Java are definit un mecanism prin care se permite threadurilor sa devina inactive
public void doWait(){
atunci cand asteapta dupa un semnal. synchronized(myMonitorObject){
try{
myMonitorObject.wait();
• Un thread care apeleaza wait() pe orice obiect devine inactiv pana cand un alt } catch(InterruptedException e){...}
thread apeleaza notifica pe acel obiect }
}

• Pentru a apela wait sau notify threadul trebuie sa obtina mai intai blocarea pe acel public void doNotify(){
obiect. synchronized(myMonitorObject){
myMonitorObject.notify();
– Threadul apelant trebuie sa apeleze notify sau wait doar dintr-un bloc }
synchronized. }
}

V. Niculescu - MAP 576 V. Niculescu - MAP 577

140
10/12/2015

public class MyWaitNotify2{

Missed Signals MonitorObject myMonitorObject = new


MonitorObject();
boolean wasSignalled = false;

• Apelurile metodelor notify() si notifyAll() nu se salveaza in cazul in care nici un • Evitarea situatiei problema public void doWait(){
thread nu asteapta atunci cand sunt apelate. synchronized(myMonitorObject){
se poate face prin salvarea if(!wasSignalled){
try{
• Astfel semnalul notify se pierde. semnalelor in interiorul
myMonitorObject.wait();
clasei care le trimite. } catch(InterruptedException e){...}
• Acest lucru poate conduce la situatii in care nu thread asteapta nedefinit, pentru ca }
mesajul corespunzator de notificare se pierde. //clear signal and continue running.
wasSignalled = false;
}
}

public void doNotify(){


synchronized(myMonitorObject){
wasSignalled = true;
myMonitorObject.notify();
}
}
}
V. Niculescu - MAP 578 V. Niculescu - MAP 579

Deadlock Example
• A deadlock is when two or more threads are blocked waiting to obtain locks that public class TreeNode { public synchronized void setParent(TreeNode
parent){
some of the other threads in the deadlock are holding. TreeNode parent = null; this.parent = parent;
List children = new ArrayList(); parent.addChildOnly(this);
}
• Deadlock can occur when multiple threads need the same locks, at the same time, public synchronized void addChild(TreeNode
but obtain them in different order. child){ public synchronized void
if(!this.children.contains(child)) { setParentOnly(TreeNode parent){
this.children.add(child); this.parent = parent;
• For instance, if thread 1 locks A, and tries to lock B, and thread 2 has already child.setParentOnly(this); }
} }
locked B, and tries to lock A, a deadlock arises.
}
– Thread 1 can never get B, and thread 2 can never get A. In addition, neither of
them will ever know. public synchronized void
addChildOnly(TreeNode child){
– They will remain blocked on each their object, A and B, forever. if(!this.children.contains(child){
this.children.add(child);
}
Thread 1 locks A, waits for B }
Thread 2 locks B, waits for A

V. Niculescu - MAP 580 V. Niculescu - MAP 581

141
10/12/2015

Starvation and Fairness

• Daca unui thread nu I se aloca timp de executie CPU time pentru ca alte threaduri
folosesc CPU atunci exista o situatie numita "starvation".

• Thread este "starved to death" pentru ca alte threaduri au acces la CPU in locul lui.
Curs 14
• Situatia corecta "fairness" toate threadurile au sanse egale la folosire CPU.

Reflection

V. Niculescu - MAP 582 V. Niculescu - MAP 583

Reflection Java Reflection

• The ability of a computer program to • It is possible to inspect


– examine and – classes,
– modify – interfaces,
the structure and behavior of objects/classes at runtime: – fields and
– values, – methods
– meta-data, at runtime, without knowing the names of the classes, methods etc. at compile
– properties and time.
– functions
• It is also possible to
• Type introspection = the ability of a program to examine the type or properties of – instantiate new objects,
an object at runtime – invoke methods and
– get/set field values

V. Niculescu - MAP 584 V. Niculescu - MAP 585

142
10/12/2015

Object class
Advanced topics

• Arrays
– java.lang.reflect.Array Object
– Creating Arrays
– Accessing Arrays + Object()
– Obtaining the Class Object of an Array # Object clone()
– Obtaining the Component Type of an Array + boolean equals(Object obj)
# protected void finalize()
• Annotations
+ Class getClass()
– Class Annotations
+ int hashCode()
– Method Annotations + void notify()
– Parameter Annotations + void notifyAll()
– Field Annotations + String toString()
• Generics + void wait()
• Dynamic Proxies + void wait(long timeout)
• Dynamic Class Loading and Reloading + void wait(long timeout, int nanos)

V. Niculescu - MAP 586 V. Niculescu - MAP 587

Class<T>
java.lang.reflect
Interfaces Classes • java.lang.Class<T>
• AnnotatedElement
• GenericArrayType • AccessibleObject • Type Parameters:
• GenericDeclaration • Array – T - the type of the class modeled by this Class object. For example, the type of
• InvocationHandler
• Constructor String.class is Class<String>.
• Member
• ParameterizedType • Field – Use Class<?> if the class being modeled is unknown.
• Type • Method
• TypeVariable
• Modifier Ex.
• WildcardType
• Proxy
• ReflectPermission void printClassName(Object obj) {
Exceptions System.out.println("The class of " + obj +
• InvocationTargetException " is " + obj.getClass().getName());
• MalformedParameterizedTypeException
• UndeclaredThrowableException }
Errors
• GenericSignatureFormatError

V. Niculescu - MAP 588 V. Niculescu - MAP 589

143
10/12/2015

Class object Modifiers


Class aClass = ... //obtain Class object
int modifiers = aClass.getModifiers();

• Class myObjectClass = MyObject.class


• java.lang.reflect.Modifier:
– Modifier.isAbstract(int modifiers)
• Class class = Class.forName(className);
– Modifier.isFinal(int modifiers)
– className: String – Modifier.isInterface(int modifiers)
– ClassNotFoundException (->the class cannot be found on the classpath at – Modifier.isNative(int modifiers)
runtime. ) – Modifier.isPrivate(int modifiers)
– Modifier.isProtected(int modifiers)
• String className = aClass.getName(); – Modifier.isPublic(int modifiers)
(fully qualified class name (including package name) – Modifier.isStatic(int modifiers)
• String simpleClassName = aClass.getSimpleName(); – Modifier.isStrict(int modifiers)
– Modifier.isSynchronized(int modifiers)
– Modifier.isTransient(int modifiers)
– Modifier.isVolatile(int modifiers)

V. Niculescu - MAP 590 V. Niculescu - MAP 591

Implemented Interfaces
Members

Class aClass = ... //obtain Class object. • Constructors


Class[ ] interfaces = aClass.getInterfaces(); Constructor[] constructors = aClass.getConstructors();

• Interfaces are also represented by Class objects in Java Reflection. • Methods


Method[] method = aClass.getMethods();
• NOTE: Only the interfaces specifically declared implemented by a given class is
returned. If a superclass of the class implements an interface, but the class doesn't Fields
specifically state that it also implements that interface, that interface will not be Field[] method = aClass.getFields();
returned in the array. Even if the class in practice implements that interface, because
the superclass does.
(doar cele publice)

• To get a complete list of the interfaces implemented by a given class you will have
to consult both the class and its superclasses recursively.

V. Niculescu - MAP 592 V. Niculescu - MAP 593

144
10/12/2015

Constructors Methods

Class aClass = ...//obtain class object Method method = MyObject.class.getMethod("doSomething", String.class);


Constructor[] constructors = aClass.getConstructors();
Object returnValue = method.invoke(null, "parameter-value1");
Class aClass = ...//obtain class object
Constructor constructor =
aClass.getConstructor(new Class[]{String.class});

//get constructor that takes a String as argument


Constructor constructor = MyObject.class.getConstructor(String.class);

MyObject myObject = (MyObject)


constructor.newInstance("constructor-arg1");

V. Niculescu - MAP 594 V. Niculescu - MAP 595

Generic class - Class Advantages

• The class Class has a type parameter T, • Extensibility Features


– It stands for the type that the Class object is representing. – An application may make use of external, user-defined classes by creating
instances of extensibility objects using their fully-qualified names.
• For example, the type of String.class is Class<String>, and the type of Serializable • Class Browsers and Visual Development Environments
class is Class<Serializable>. – A class browser needs to be able to enumerate the members of classes. Visual
development environments can benefit from making use of type information
• This can be used to improve the type safety of the reflection code. available in reflection to aid the developer in writing correct code.
• Debuggers and Test Tools
• In particular, since the newInstance() method in Class returns a T, you can get more – Debuggers need to be able to examine private members on classes. Test
precise types when creating objects reflectively. harnesses can make use of reflection to systematically call a discoverable set
APIs defined on a class, to insure a high level of code coverage in a test suite.

V. Niculescu - MAP 596 V. Niculescu - MAP 597

145
10/12/2015

Drawbacks of Reflection
references

Reflection is powerful, but should not be used indiscriminately. • Tutorial:Trail: The Reflection API
http://docs.oracle.com/javase/tutorial/reflect/
If it is possible to perform an operation without using reflection, then it is preferable to
avoid using it. • Ira R. Forman and Nate Forman , Java Reflection in Action , Manning
Publications, 2004.
• Performance Overhead
– certain Java virtual machine optimizations can not be performed.
• Security Restrictions alte tutoriale...
• Exposure of Internals
– accessing private fields and methods,
– Reflective code breaks abstractions

V. Niculescu - MAP 598 V. Niculescu - MAP 599

146

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