poo all curses utcluj vicas

113
OOP1 - T.U. Cluj - M. Joldos 1 Programare orientată pe obiecte 1. Despre curs 2. Concepte şi paradigme în POO OOP1 - T.U. Cluj - M. Joldos 2 Obiectivele cursului Să vă ofere cunoştinŃe operaŃionale în dezvoltarea software folosind orientarea pe obiecte, cu accent pe conceptele, paradigmele şi atitudinile necesare scrierii de cod orientat pe obiecte de calitate Să vă permită să vă dezvoltaŃi îndemânarea în programare şi inginerie software, să învăŃaŃi să utilizaŃi efectiv un limbaj de programare orientat pe obiecte relevant din punctul de vedere al industriei software OOP1 - T.U. Cluj - M. Joldos 3 Despre POO Orele de curs: Marius Joldoş Marius.Joldoş@cs.utcluj.ro Laborator: veŃi afla cu cine Web: http://users.utcluj.ro/~jim/OOPR (public) http://t201:81/OOPR (accesibil numai in D3) 14 sesiuni de curs a 2 ore 14 sesiuni de laborator a 2 ore 5 credite Colocviu laborator, miniproiect, examen parŃial si final OOP1 - T.U. Cluj - M. Joldos 4 Rezultatele cursului (1) Privitoare la cunoştinŃe/înŃelegere Fundamentele POO Elementele principale în proiectarea, programarea, testarea şi documentarea soluŃiilor OO Metode de proiectare pentru programe Java de complexitate relativ redusă Elemente de bază ale UML A-PDF Merger DEMO : Purchase from www.A-PDF.com to remove the watermark

Upload: vladislav-apu

Post on 07-Feb-2016

67 views

Category:

Documents


0 download

DESCRIPTION

Toate cursurile de la POO

TRANSCRIPT

Page 1: POO all curses UTCLUJ VICAS

OOP1 - T.U. Cluj - M. Joldos 1

Programare orientată pe obiecte

1. Despre curs2. Concepte şi paradigme în POO

OOP1 - T.U. Cluj - M. Joldos 2

Obiectivele cursului

� Să vă ofere cunoştinŃe operaŃionale în dezvoltarea software folosind orientarea pe obiecte, cu accent pe conceptele, paradigmele şi atitudinile necesare scrierii de cod orientat pe obiecte de calitate

� Să vă permită să vă dezvoltaŃi îndemânarea în programare şi inginerie software, să învăŃaŃi să utilizaŃi efectiv un limbaj de programare orientat pe obiecte relevant din punctul de vedere al industriei software

OOP1 - T.U. Cluj - M. Joldos 3

Despre POO

� Orele de curs: Marius Joldoş� Marius.Joldoş@cs.utcluj.ro

� Laborator: veŃi afla cu cine� Web:

� http://users.utcluj.ro/~jim/OOPR (public)� http://t201:81/OOPR (accesibil numai in D3)

� 14 sesiuni de curs a 2 ore� 14 sesiuni de laborator a 2 ore� 5 credite� Colocviu laborator, miniproiect, examen parŃial si

final

OOP1 - T.U. Cluj - M. Joldos 4

Rezultatele cursului (1)

� Privitoare la cunoştinŃe/înŃelegere� Fundamentele POO� Elementele principale în proiectarea, programarea, testarea şi documentarea soluŃiilor OO

� Metode de proiectare pentru programe Java de complexitate relativ redusă

� Elemente de bază ale UML

A-P

DF

Merger D

EM

O : P

urchase from w

ww

.A-P

DF

.com to rem

ove the waterm

ark

Page 2: POO all curses UTCLUJ VICAS

OOP1 - T.U. Cluj - M. Joldos 5

Rezultatele cursului (2)

� AbilităŃi intelectuale� Să înŃelegeŃi specificaŃia unei probleme şi să o rezolvaŃi printr-un program pentru calculator în paradigma programării orientate pe obiecte.

� Să luaŃi o specificaŃie parŃială şi să luaŃi deciziile corespunzătoare asupra funcŃionalităŃii sistemului propus.

� Să dezvoltaŃi o specificaŃie în UML dintr-o descriere în limbaj natural

OOP1 - T.U. Cluj - M. Joldos 6

Rezultatele cursului (3)

� AbilităŃi practice � Să folosiŃi eficient conceptele de programare OO în Java

� Să dezvoltaŃi programe de complexitate relativ redusă în Java

� Să depanaŃi, testaŃi şi documentaŃi soluŃii folosind orientarea pe obiecte

� Să dezvoltaŃi applet-uri şi componente GUI relativ simple

OOP1 - T.U. Cluj - M. Joldos 7

Subiecte abordate� Concepte şi paradigme în

programarea orientată pe obiecte� AbstracŃiuni şi tipuri de date

abstracte� Caracteristicile limbajului Java� Tipurile de date primitive şi

structurile de control în Java� Clase şi obiecte� InterfeŃe Java� ExcepŃii şi tratarea lor� Principalele API-uri şi clase

predefinite în Java

� Reprezentarea în UML a claselor, obiectelor şi asociaŃiilor; diagrame de clase şi obiecte

� Programarea bazată pe clase şi obiecte

� Moştenirea şi polimorfismul� Programarea orientată pe obiecte� Scurtă introducere în

programarea condusă de evenimente

� Scurtă introducere în programarea applet-urilor şi a componentelor GUI

OOP1 - T.U. Cluj - M. Joldos 8

Evaluare. ReferinŃe� Evaluare

� Examen scris (E), evaluarea activităŃii de la laborator (L), evaluarea unui mini-proiect (P).

� Nota finală = 0.6E + 0.4(L+P)/2 � ReferinŃe

� Tănasă, S., Olaru, C, Andrei, Şt., Java de la 0 la expert, Ed. Polirom, 2003

� Călin Văduva, Programarea în Java, Ed. Albastră, 2004 (reeditare)

� Bruce Eckel, Thinking in Java, 3rd edition, Prentice Hall, 2002

� DocumentaŃia Java de la Sun Microsystems� Tutoriale UML introductive� DocumentaŃia BlueJ

Page 3: POO all curses UTCLUJ VICAS

OOP1 - T.U. Cluj - M. Joldos 9

Concepte şi paradigme în POO

� Temele de astăzi� Paradigme de programare (programarea imperativă şi programarea structurată)

� Abstractizarea datelor� Tipuri de date abstracte

� Paradigma POO� Concepte POO

� Obiecte şi clase� Încapsulare şi moştenire

OOP1 - T.U. Cluj - M. Joldos 10

Paradigme de programare

� Paradigmă (dict.): Un set de supoziŃii, concepte, valori şi practici care constituie o viziune a realităŃii pentru comunitatea care le adoptă, în special într-o disciplină intelectuală.

� Paradigmă de programare� Un model care descrie esenŃa şi structura computaŃiei� Oferă (şi determină) viziunea pe care o are

programatorul asupra execuŃiei programuluiExemple:

� în POO, programatorii pot concepe programele ca fiind o colecŃie de obiecte care interacŃionează

� în programarea funcŃională un program poate fi conceput ca fiind o secvenŃă de evaluări de funcŃii, fără stări

OOP1 - T.U. Cluj - M. Joldos 11

Paradigme de programare

OOP1 - T.U. Cluj - M. Joldos 12

Programarea imperativă� În modelul tradiŃional von Neumann, un calculator constă

dintr-o unitate centrală de prelucrare şi memorie şi el efectuează secvenŃe de instrucŃiuni atomice care accesează, operează asupra valorilor stocate locaŃii de memorie adresabile individual şi le modifică. Aici, o computaŃie este o serie de operaŃii aritmetice şi de efecte laterale, cum sunt atribuirile sau transferurile de date care modifică starea unităŃii de stocare, intrarea sau ieşirea

� Ne referim la acest ca paradigmă imperativă sauprocedurală.

� Este de subliniat importanŃa atribuirilor şi a variabilelor pe post de containere pentru paradigma imperativă

� Exemple de limbaje: Fortran, Pascal, C, Ada.

Page 4: POO all curses UTCLUJ VICAS

OOP1 - T.U. Cluj - M. Joldos 13

Programarea structurată

Bloc principal

valori de intrare

valoare/valori de ieşire

valori de intrare

Procedură

FuncŃie

OOP1 - T.U. Cluj - M. Joldos 14

Programarea structurată

� InterfaŃa� Date de intrare� Date de ieşire� Descrierea funcŃionalităŃii

� Implementarea� Date locale� SecvenŃe de instrucŃiuni

� Abstractizarea operaŃiilor� Structura unui modul

� Sintaxa limbajului� Organizarea codului în blocuri de instrucŃiuniDefiniŃii de funcŃii şi proceduri

� Extinderea limbajului cu noi operaŃiiApeluri la proceduri şi funcŃii noi

OOP1 - T.U. Cluj - M. Joldos 15

Beneficiile programării structurate

� Uşurează dezvoltarea software� Evită repetarea realizării aceluiaşi lucru� Munca de programare este descompusă în module independente

� Proiectare Top-down: descompunerea în subprobleme

� Facilitează întreŃinerea software� Codul este mai uşor de citit� IndependenŃa modulelor

� Favorizează reutilizarea softwareOOP1 - T.U. Cluj - M. Joldos 16

Programarea structurată. Exemplu

Page 5: POO all curses UTCLUJ VICAS

OOP1 - T.U. Cluj - M. Joldos 17

Abstractizarea datelor

� Abstractizarea datelor: impunerea unei separări clare între proprietăŃile abstracte ale unui tip de dată şi detaliile concrete ale implementării lui

� ProprietăŃi abstracte: acelea care sunt vizibile codului client care foloseşte tipul de dată – interfaŃa cu tipul de dată

� Implementarea concretă este păstrată in totalitate privată şi ea se poate într-adevăr schimba, spre exemplu pentru a incorpora îmbunătăŃiri ale performanŃelor în timp.

OOP1 - T.U. Cluj - M. Joldos 18

Tipuri abstracte de date

� Abstractizarea datelor + abstractizarea operaŃiilor� Un tip de dată abstract:

� Structură de date care stochează informaŃii pentru a reprezenta un anumit concept

� FuncŃionalitate: set de operaŃii care pot fi aplicate tipului de dată

� Sintaxa limbajului� Modulele sunt asociate tipurilor de date� Sintaxa nu este neapărat nouă faŃă de programarea modulară

OOP1 - T.U. Cluj - M. Joldos 19

Exemplu de tip de dată abstract în C

OOP1 - T.U. Cluj - M. Joldos 20

Extensibilitatea tipului de dată abstract

Page 6: POO all curses UTCLUJ VICAS

OOP1 - T.U. Cluj - M. Joldos 21

Beneficiile tipurilor de date abstracte

� Conceptele din domeniu sunt reflectate în cod� Încapsulare: complexitatea internă, datele şi

detaliile operaŃiilor sunt ascunse� Utilizarea tipului de dată este independentă de

implementarea sa internă� Oferă o mai mare modularitate� Sporeşte uşurinŃa întreŃinerii şi reutilizării codului

OOP1 - T.U. Cluj - M. Joldos 22

Paradigma orientată pe obiecte

� Paradigma programării structurate a avut iniŃial succes (1975-85)� Dar a început să eşueze la produse mai mari (>

50,000 LOC)� PS avea probleme de întreŃinere post-livrare (astăzi

această întreŃinere necesită, de la 70 la 80% din efortul total)

� Motivul: Metodele structurate sunt fie� orientate pe operaŃii (analiza fluxului de date) fie � orientate pe atribute (d.e. dezvoltarea cu metoda

Jackson)…� …dar nu amândouă

OOP1 - T.U. Cluj - M. Joldos 23

Paradigma orientării pe obiecte

� Paradigma folosită în limbaje: o simulare a domeniului unei probleme prin abstractizarea informaŃiilor de comportament şi stare din obiecte din lumea reală

� Conceptele de obiecte, clase, transmitere de mesaje şi moştenire sunt cunoscute ca făcând parte din paradigma orientării pe obiecte.

OOP1 - T.U. Cluj - M. Joldos 24

Paradigma orientării pe obiecte

� POO consideră că atât atributele cât şi operaŃiile au importanŃă egală

� O viziune simplistă a unui obiect poate fi: � Obiect = componentă software care incorporează

atât atributele cât şi operaŃiile care se pot efectua asupra atributelor şi care suportă moştenirea.

� Exemplu:� Cont bancar

� Date: soldul contului� AcŃiuni: depune, retrage, determină soldul

Page 7: POO all curses UTCLUJ VICAS

OOP1 - T.U. Cluj - M. Joldos 25

ComparaŃie între paradigma structurată şi cea obiectuală

� Ascunderea informaŃiei� Proiectarea dirijată de responsabilităŃi� Impact asupra întreŃinerii şi dezvoltării

depune

retrage

determinaSold

solduContului soldulContului

retrage depunemesaj

mesaj

mesaj

soldulContului

determinaSold

OOP1 - T.U. Cluj - M. Joldos 26

Ascunderea informaŃiei

� În versiunea orientată pe obiecte� Linia continuă din jurul lui soldulContului arată că în afara obiectului nu se ştie cum este implementat soldulContului

� În versiunea clasică� Toate modulele au detalii privind implementarea lui soldulContului

OOP1 - T.U. Cluj - M. Joldos 27

Punctele tari ale paradigmei OO

� Cu ascunderea informaŃiei, întreŃinerea post-livrare este mai sigură� Şansele apariŃiei erorilor regresive sunt reduse (în software nu se repetă erori cunoscute)

� Dezvoltarea este mai uşoară� Obiectele au în general corespondente fizice

� Acest lucru simplifică modelarea (un aspect cheie al paradigmei OO)

OOP1 - T.U. Cluj - M. Joldos 28

Punctele tari ale paradigmei OO (2)

� Obiectele bine proiectate sunt unităŃi independente� Tot ce se referă la obiectul real modelat este în obiect — încapsulare

� Comunicarea se face prin schimb de mesaje� Această independenŃă este augmentată prin proiectarea dirijată de responsabilitate

Page 8: POO all curses UTCLUJ VICAS

OOP1 - T.U. Cluj - M. Joldos 29

Punctele tari ale paradigmei OO (3)

� Un produs clasic constă d.p.d.v conceptual dintr-o singură unitate (deşi poate fi implementată ca un set de module)� Paradigma OO reduce complexitatea deoarece produsul constă, în general, din unităŃi independente

� Paradigma OO promovează reutilizarea� Obiectele sunt entităŃi independente

OOP1 - T.U. Cluj - M. Joldos 30

Programarea orientată pe obiecte

� Oferă suport sintactic pentru tipurile de date abstracte

� Oferă facilităŃi asociate cu ierarhiile de clase� Schimbă punctul de vedere: programele sunt apendice ale datelor

� Introduc un concept nou: obiect = tip de dată abstract cu stare (atribute) şi comportament (operaŃii)

OOP1 - T.U. Cluj - M. Joldos 31

Concepte OOP

� Ne ocupăm doar de datele care prezintă interes pentru problema noastră.

� Acest proces de filtrare a detaliilor neimportante ale obiectului astfel încât să rămână doar caracteristicile importante este cunoscut sub numele de abstractizare.

OOP1 - T.U. Cluj - M. Joldos 32

Abstractizare

istoric genetic

maşini vândute

talente

jurnalul creditului

istoric medical

familia

procentul comisionuluinumele

lumea reală

Page 9: POO all curses UTCLUJ VICAS

OOP1 - T.U. Cluj - M. Joldos 33

Abstractizare

Abstractizarea unei PersoanaVinzator pentru un

Sistem de urmărire a vânzărilor

maşini vânduteprocentul comisionului

numele

OOP1 - T.U. Cluj - M. Joldos 34

Abstractizare

istoric genetic

istoric medical

familia

Abstractizarea unui Pacient dintr-o baze de

date medicală

OOP1 - T.U. Cluj - M. Joldos 35

Ce sunt obiectele software?

� Blocurile de construcŃie a sistemelor software� un program este o colecŃie de obiecte care

interacŃionează� obiectele cooperează pentru a finaliza o sarcină� pentru aceasta, ele comunică trimiŃându-si “mesaje”

unul altuia

� Obiectele modelează lucruri tangibile� persoană� bicicletă� …

OOP1 - T.U. Cluj - M. Joldos 36

Ce sunt obiectele software?

� Obiectele modelează lucruri conceptuale� întâlnire� dată calendaristică

� Obiectele modelează procese� aflarea drumului printr-un labirint� sortarea unui pachet de cărŃi de joc

� Obiectele au� capabilităŃi: ce pot face, cum se comportă� proprietăŃi: trăsături (caracteristici) care descriu

obiectele

Page 10: POO all curses UTCLUJ VICAS

OOP1 - T.U. Cluj - M. Joldos 37

CapabilităŃile obiectelor: acŃiuni

�Obiectele au capabilităŃi (comportamente) care le permit să efectueze acŃiuni specifice� obiectele sunt deştepte — ele “ştiu” cum să facă anumite lucruri

� un obiect face ceva doar dacă un alt obiect îi spune să-şi folosească una dintre capabilităŃi

�CapabilităŃile pot fi:� constructori: stabilesc starea iniŃială a proprietăŃilor obiectului

� comenzi: modifică proprietăŃile obiectului� interogări: furnizează răspunsuri bazate pe proprietăŃile obiectului

OOP1 - T.U. Cluj - M. Joldos 38

CapabilităŃile obiectelor: acŃiuni

� Exemple: borcanele cu gem sunt capabile să efectueze acŃiuni specifice

•constructor: să fie creat•comenzi: adaugă gem, goleşte-te• interogări: răspunde dacă este închis sau deschis capacul, dacă borcanul este plin sau gol

OOP1 - T.U. Cluj - M. Joldos 39

ProprietăŃile obiectului: starea

� ProprietăŃile determină cum acŃionează un obiect� unele proprietăŃi pot fi constante, iar altele variabile� proprietăŃile însele sunt obiecte — pot şi primi mesaje� capacul borcanului cu gem şi gemul în sine sunt obiecte

� ProprietăŃile pot fi:� atribute: lucruri care ajută la descrierea unui obiect� componente: lucruri care sunt “parte a” unui obiect� asocieri: lucruri despre care ştie un obiect, dar care nu

sunt parte a acelui obiect

OOP1 - T.U. Cluj - M. Joldos 40

ProprietăŃile obiectului: starea

� Stare: colecŃie a tuturor proprietăŃilor obiectului; se schimbă dacă o proprietate se schimbă� unele nu se schimbă, d.e. volanul unei maşini� altele se schimbă, d.e. culoarea maşinii

� Exemplu: proprietăŃile borcanelor cu gem� atribute: culoare, material, miros� componente: capac, container, etichetă� asocieri: un borcan cu gem poate fi asociat cu încăperea în care se află

Page 11: POO all curses UTCLUJ VICAS

OOP1 - T.U. Cluj - M. Joldos 41

Clase şi instanŃe

� ConcepŃia noastră curentă: fiecare obiect corespunde direct unui anumit obiect din realitate, d.e., un atom sau un automobil anume

� Dezavantaj: este mult prea nepractic să lucrăm cu obiecte în acest fel deoarece� ele pot fi infinit de multe� nu dorim să descriem fiecare individ separat, deoarece

ei au multe lucruri în comun� Clasificarea obiectelor scoate în evidenŃă ce este

comun între mulŃimi de obiecte similare� mai întâi să descriem ce este comun� apoi să “ştampilăm” oricâte copii

OOP1 - T.U. Cluj - M. Joldos 42

Clase ale obiectelor

�Clasa unui obiect� categoria obiectului� defineşte capabilităŃile şi proprietăŃile comune unei mulŃimi de obiecte individuale� toate borcanele cu gem se pot deschide, închide şi goli

� defineşte un şablon pentru crearea de instanŃe de obiect� unele borcane cu gem pot fi din plastic, pot fi colorate, de o anumită mărime etc.

OOP1 - T.U. Cluj - M. Joldos 43

Clase ale obiectelor

� Clasele implementează capabilităŃile ca metode� secvenŃe de instrucŃiuni în Java� obiectele cooperează trimiŃând mesaje altor obiecte

� fiecare mesaj “invocă o metodă”� Clasele implementează proprietăŃile ca variabile instanŃă� locaŃie de memorie alocată obiectului, care poate păstra o valoare care se poate schimba

OOP1 - T.U. Cluj - M. Joldos 44

InstanŃe de obiect

�InstanŃele obiectelor sunt obiecte individuale� realizate din şablonul clasei� o clasă poate reprezenta un număr nedefinit de instanŃe de obiect

� realizarea unei instanŃe de obiect constituie instanŃierea obiectului respectiv

�Prescurtare:� clasă: clasa obiectului� instanŃă: instanŃa obiectului (a nu se confunda cu variabilele instanŃă)

Page 12: POO all curses UTCLUJ VICAS

OOP1 - T.U. Cluj - M. Joldos 45

InstanŃe de obiect

� InstanŃe diferite ale, d.e., clasei BorcanCuGem pot avea:� culoare şi poziŃie diferită� diverse tipuri de gem în interior

� Astfel că, variabilele instanŃă ale lor au valori diferite� Notă: instanŃele de obiect conŃin variabile instanŃă — două

moduri de folosire diferite, dar înrudite, a cuvântului instanŃă

� InstanŃele individuale au identităŃi individuale� aceasta permite altor obiecte să trimită mesaje unui obiect

dat� fiecare instanŃă este unică, chiar dacă are aceleaşi capabilităŃi

� gândiŃi-vă la clasa studenŃilor de la acest curs

OOP1 - T.U. Cluj - M. Joldos 46

Mesaje pentru comunicarea între obiecte

�Nici o instanŃă nu este o insulă — ea trebuie să comunice cu altele pentru a-şi realiza sarcina� proprietăŃile le permit să ştie despre alte obiecte

� InstanŃele trimit mesaje una alteia pentru a invoca o capabilitate (adică, pentru a executa o sarcină)� metoda reprezintă codul care implementează mesajul� spunem “apelează metoda” în loc de “invocă capabilitatea”

OOP1 - T.U. Cluj - M. Joldos 47

Mesaje pentru comunicarea între obiecte

� Fiecare mesaj necesită:� un emiŃător (expeditor): obiectul care iniŃiază acŃiunea� un receptor: instanŃa a cărei metode este invocată� numele mesajului: numele metodei apelate� opŃional parametri: informaŃii suplimentare necesitate de

metodă pentru a opera� mai multe mai târziu

� Receptorul poate (dar nu este nevoit) sa trimită un răspuns� vom trata tipurile returnate în detaliu, mai târziu

OOP1 - T.U. Cluj - M. Joldos 48

Încapsulare

�Un automobil încapsulează multă informaŃie� chiar literal, prin complexitatea construcŃiei sale

�Dar nu este nevoie să ştii cum funcŃionează o maşină pentru a o conduce� Volanul şi schimbarea vitezelor constituie interfaŃa

� motorul, transmisia, axul cardanic, roŃile, . . . , sunt implementarea (ascunsă)

Page 13: POO all curses UTCLUJ VICAS

OOP1 - T.U. Cluj - M. Joldos 49

Încapsulare

� Asemănător, nu e nevoie să ştim cum funcŃionează un obiect pentru a-i trimite mesaje

� Dar, este nevoie să ştim ce mesaje înŃelege (adică, care îi sunt capabilităŃile)� clasa instanŃei determină ce mesaje îi pot fi trimise

ImplementareInterfaŃă

TransmisieAx cardanic

OOP1 - T.U. Cluj - M. Joldos 50

Încapsularea

� Închiderea datelor într-un obiect� Datele nu pot fi accesate direct din afară

� Oferă securitatea datelor

Detalii de implementare private

API

publică

OOP1 - T.U. Cluj - M. Joldos 51

Vederile unei clase

�Obiectele separă interfaŃa de implementare�obiectul este “cutie neagră”; ascunde funcŃionarea şi părŃile interne

� interfaŃa protejează implementarea împotriva utilizării greşite

Capabilitate publică

Capabilitate publică

Capabilitate publică

Capabilitate publică

Capabilitate publică

Capabilitate publică

ProprietăŃi private

OOP1 - T.U. Cluj - M. Joldos 52

Vederile unei clase

� InterfaŃa: vedere publică� permite instanŃelor să coopereze unele cu altele fără a şti prea multe detalii

� ca un contract: constă dintr-o listă de capabilităŃi şi documentaŃie pentru cum să fie folosite

� Implementarea: vedere privată� proprietăŃile care ajută capabilităŃile să-şi îndeplinească sarcinile

Page 14: POO all curses UTCLUJ VICAS

OOP1 - T.U. Cluj - M. Joldos 53

Moştenirea

� O clasă (subclasă) poate moşteni atribute şi metode dintr-o altă clasă (superclasă)

� Subclasele furnizează comportament specializat

� Oferă reutilizarea codului � Evită duplicarea

datelor

Bicicleta

Bicicleta de munte Cursieră Bicicletă tandemOOP1 - T.U. Cluj - M. Joldos 54

Polimorfism

� Abilitatea de a lua multe forme� Aceeaşi metodă folosită într-o superclasă poate fi suprascrisă în subclase pentru a da o funcŃionalitate diferită

� D.e. Superclasa ‘Poligon’ are o metodă numită, aflaSuprafata

aflaSuprafata în subclasa ‘Triunghi’ � a=x*y/2

aflaSuprafata in subclasa ‘Dreptunghi’ � a=x*y

OOP1 - T.U. Cluj - M. Joldos 55

Concepte prezentate� Paradigme în programare

� structurată� orientată pe obiecte

� Abstractizare� tip de dată abstract

� Obiect� capabilităŃi(comportamente):

acŃiuni� constructor� comenzi� interogări

� proprietăŃi: stare� atribute� componente� asocieri

� instanŃă a unei clase

� Comunicarea între obiecte: mesaje

� Încapsulare� Clasă

� şablon pentru crearea obiectelor� capabilităŃile obiectelor:

implementate ca metode� proprietăŃile obiectelor: variabile

instanŃă� interfaŃă – vedere publică� implementare – vedere privată

� Moştenire� superclasă, subclasă

� Polimorfism

Page 15: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 1

Programare orientată pe obiecte

2. AbstracŃiuni şi tipuri de date abstracte3. Java

OOP2 - M. Joldoş - T.U. Cluj 2

Abstractizare

� Abstractizare înseamnă eliminare sau ascunderea deliberată a unor detalii ale unui proces sau artefact pentru a releva mai clar alte aspecte, detalii sau structura.

Problemă

Model

Abstractizare

OOP2 - M. Joldoş - T.U. Cluj 3

Nivele de abstractizare în programe OO

� La nivelul cel mai înalt, privim un program ca o comunitate de obiecte care interacŃionează.

� Aici caracteristicile importante sunt liniile de comunicare dintre diferiŃii agenŃi.

OOP2 - M. Joldoş - T.U. Cluj 4

Abstractizare în limbaje OO. Packages, namespaces

� Următorul nivel de abstractizare se regăseşte în unele limbaje OO. Un package (pachet), unit sau namespace(spaŃiu de nume) permite programatorului să înconjoare o colecŃie de obiecte (o comunitate mică în ea însăşi) cu un strat şi să-i controleze vizibilitatea din afara modulului.� Java are packages

Package "Utilities"

Page 16: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 5

Abstractizare în limbaje OO. ClienŃi şi servitori

� Următorul nivel de abstractizare consideră relaŃiile dintre obiectele individuale. Tipic, unul oferă un serviciu (server), iar celălalt foloseşte serviciul (client).

OOP2 - M. Joldoş - T.U. Cluj 6

Abstractizare în limbaje OO. InterfeŃe

� Putem examina acum doar agentul care oferă serviciul, independent de client. Definim natura serviciilor oferite, dar nu şi cum se realizează acele servicii.

� InterfeŃele sunt o cale de descriere a serviciilor la acest nivel de abstractizare.

interface Stack {public void push (Object val);public Object top () throws EmptyStackException;public void pop () throws EmptyStackException;

}

� Notă. OperaŃii auxiliare cu tipul stivă:� integer size(): returnează numărul de elemente stocate� boolean isEmpty(): indică dacă stiva este goală

OOP2 - M. Joldoş - T.U. Cluj 7

Nivele de abstractizare. O implementare

� Apoi privim serviciile oferite din perspectiva implementării lor:

public class ArrayStack implements Stack ... {public void pop () throws EmptyStackException { ... }...}

� Aici grija este pentru abordarea de nivel înalt a modului de furnizare a serviciului respectiv.

OOP2 - M. Joldoş - T.U. Cluj 8

Nivele de abstractizare. O metodă luată izolat

� În final, considerăm implementarea fiecărei metode luată separat.

public class ArrayStack implements Stack ... {...public Object pop() throws EmptyStackException {

if isEmpty() throw new EmptyStackException(“Empty stack: cannot pop”);

Object temp = S[top];S[top] = null;top = top – 1;return temp;

}...

}

� Fiecare nivel este important şi adesea trecem repede înainte şi înapoi pe nivele.

Page 17: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 9

Aflarea nivelului de abstractizarea corect

� O problemă critică în stadiile de dezvoltare incipiente:� să determinăm ce detalii sunt potrivite la fiecare nivel de abstractizare şi, (adesea mai important)

� ce detalii trebuie omise.

� Evident, nimeni nu doreşte � să elimine informaŃii importante, dar� nici să gestioneze prea multe informaŃii, sau ca volumul informaŃiei să ascundă detalii critice.

OOP2 - M. Joldoş - T.U. Cluj 10

Abstractizarea Is-a (este-o) şi Has-A(are-o)

� Divizarea în părŃi – abstractizarea Are-o� cunoscută şi sub numele de agregare –clasa conŃine altă/alte structuri

� Divizarea prin specializare –abstractizarea Este-o� cunoscută şi sub numele de specializare- noua clasă este o particularizare a uneia existente

� inversul specializării: generalizare

OOP2 - M. Joldoş - T.U. Cluj 11

Abstractizarea Are-o

� Are-o: ia un sistem complex şi îl împarte în părŃi componente, care pot fi tratate individual. � Caracterizată de propoziŃii care au cuvintele "are-o'', (are-un,) "conŃine", "cuprinde", "compusă din"

� Ne permite să scădem nivelul de complexitate atunci când considerăm componentele izolate.

� Exemple� Un autovehicul are-un motor şi are-o transmisie� O bicicletă are-o roată ☺� O fereastră (afişată pe ecran) are-o bară de meniu

OOP2 - M. Joldoş - T.U. Cluj 12

Abstractizarea Este-o

� Abstractizarea Este-o ia un sistem complex şi îl vede ca o instanŃa a unei abstracŃiuni mai generale. � Caracterizată de propoziŃii care conŃin cuvintele "este-o'' (este-un)

� Ne permite să clasificăm artefactele şi informaŃia şi să o facem aplicabilă la multe situaŃii diferite.

� Exemple� Un autoturism este un vehicul cu roŃi, care este un mijloc de transport

� O bicicletă este un vehicul cu roŃi� O căruŃă cu cai este un mijloc de transport

Page 18: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 13

Încapsulare şi interschimbabilitate

� Un aspect important a diviziunii în părŃi este caracterizarea conexiunii (interfeŃei) dintre componente.

� Ne permite să considerăm multiple implementări diferite ale aceleiaşi interfeŃe.� Spre exemplu, un automobil poate avea mai multe tipuri diferite de motoare şi un tip de transmisie

OOP2 - M. Joldoş - T.U. Cluj 14

Vederea ca serviciu

� O interfaŃă poate fi privită şi ca o modalitate de descriere a serviciilor pe care le oferă un obiect.

� InterfaŃa este un contract pentru servicii – dacă interfaŃa este suportată, atunci serviciul va fi furnizat conform descrierii.

OOP2 - M. Joldoş - T.U. Cluj 15

Alte tipuri de abstracŃiuni. CompoziŃia

� CompoziŃia este un alt exemplu de abstracŃiune importantă; ea este o formă de are-o, caracterizată de următoarele� Forme primitive� Reguli de combinare de valori pentru a obŃine noi valori

� Ideea că noile valori pot fi şi ele supuse combinării

� Exemple: sistemele de tipuri, ferestre, multe alte sisteme complexe.

OOP2 - M. Joldoş - T.U. Cluj 16

Forme generale de abstractizare

Page 19: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 17

Tip de dată abstract

� Un tip de dată abstract (TDA) constă din:� O interfaŃă – un set de operaŃii care se pot efectua

(cunoscută şi sub numele de barieră de abstractizare).� Comportamentele permise – modul în care instanŃele

TDA răspund la operaŃii.

� Implementarea unui TDA constă din:� O reprezentare internă – date stocate în variabile

instanŃa ale obiectului� Un set de metode care implementează interfaŃa.� Un set de invarianŃi ai reprezentării, adevăraŃi iniŃial şi

conservaŃi de toate metodele

OOP2 - M. Joldoş - T.U. Cluj 18

Tip de dată abstract

� Un tip de data abstract (TDA) � reprezintă un tip pentru încapsularea datelor înrudite

� este abstract în sensul ascunderii detaliilor de implementare

OOP2 - M. Joldoş - T.U. Cluj 19

De la TDA la cod sursă

OOP2 - M. Joldoş - T.U. Cluj 20

Exemplu de specificaŃie a unui TDATIP

TipTimp

DOMENIUFiecare valoare reprezintă un moment de timp în ore, minute şi secunde.

OPERAłIISetează timpulAfişează timpulIncrementează timpul cu o secundăCompară 2 timpi dacă sunt egaliDetermină dacă un timp este “mai mic decât” un altul

Page 20: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 21

Exemplu: TDA stivă� Operatori abstracŃi

� create :: Void → Stack a� destroy :: Stack a → Void� is_empty :: Stack a → boolean� top :: Stack → Element� push :: (Stack,Element) → Stack� pop :: Stack → Stack

� Invariant� pop(push (stack, e) ) = stack

� Acum ştim cum se implementează stiva. Ceea ce trebuie să respectăm este comportamentul datelor potrivit funcŃiilor definite.

OOP2 - M. Joldoş - T.U. Cluj 22

Java. Caracteristici

� James Gosling şi Patrick Naughton (conducătorii echipei care a dezvoltat limbajul), au definit limbajul Java ca fiind

"Un limbaj simplu, orientat pe obiecte, care "înŃelege" reŃelele de calculatoare, interpretat, robust, sigur, neutru faŃă de arhitecturi, portabil, de înaltă performanŃă, multi-fir, dinamic".

OOP2 - M. Joldoş - T.U. Cluj 23

Mediul Java

OOP2 - M. Joldoş - T.U. Cluj 24

Executarea programelor Java

� Java foloseşte un proces în doi paşi� Compilează programul în bytecodes

� bytecode este apropiat de formatul instrucŃiunilor în limbaj maşină, dar nu chiar la fel — este un "limbaj maşină" a generic

� nu corespunde nici unui procesor real

� Maşina virtuală (VM) interpretează bytecode în limbaj maşină nativ şi-l rulează� există maşini virtuale diferite pentru calculatoare

diferite, deoarece bytecode nu corespunde unei maşini reale

Page 21: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 25

Executarea programelor Java

� Se utilizează acelaşi bytecode Java pe calculatoare diferite fără a recompila codul sursă� fiecare VM interpretează acelaşi bytecode Java� aceasta permite să se execute programe Java prin

simpla obŃinere a bytecodes din pagini de Web

� Aceasta face codul Java să ruleze peste-platforme� marketing-ul spune, “Scrie o dată, rulează oriunde!”� adevărat pentru “Java pur”, nu pentru variante

OOP2 - M. Joldoş - T.U. Cluj 26

AplicaŃii Java

� Tipuri de aplicaŃii Java:� aplicaŃii de-sine-stătătoare şi applets/servlets

� Un aplicaŃie de-sine-stătoare sau un program "obişnuit" este o clasă care are o metodă numitămain� Când se lansează programul Java respectiv, sistemul de

execuŃie invocă automat metoda numită main� Toate applicaŃiile de-sine-stătătoare încep din metoda main

� Deja aŃi văzut asemenea aplicaŃii în exemplele BlueJ

OOP2 - M. Joldoş - T.U. Cluj 27

Applets

� Un applet Java (o aplicaŃie având caracteristici limitate, care necesită resurse de memorie limitate şi portabilă între sistemele de operare) este un program Java destinat a fi rulat dintr-un browserde Web� poate fi rulat dintr-o locaŃie de pe Internet� poate fi rulată şi din vizualizatorul de applet-uri

(appletviewer) pentru depanare� Applet-urile folosesc întotdeauna o interfaŃă cu ferestre

� AplicaŃiile de sine stătătoare pot folosi fie interfaŃa cu ferestre sau I/O consolă (adică în modul text)

� Deja aŃi văzut un applet în exemplele BlueJ

OOP2 - M. Joldoş - T.U. Cluj 28

Încărcătorul de clase

� Programele Java sunt divizate în unităŃi mai mici numite clase� Fiecare definiŃie de clasă este în mod normal într-un fişier separat şi compilată separat

� Încărcătorul de clase: un program care leagă bytecod-ul claselor necesare pentru a rula un program Java� în alte limbaje de programare, corespondentul său este editorul de legături (linkeditor)

Page 22: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 29

Cuvinte cheie Java (cuvinte rezervate)

� Cuvinte care nu pot fi folosite la altceva decât în modul predefinit din limbaj� abstract, assert, boolean, break, byte, case, catch, char, class, const, continue, default, do, double, else, extends, final, finally, float, for, goto, if, implements, import, instanceof, int, interface, long, native, new, package, private, protected, public, return, short, static, strictfp, super, switch, synchronized, this, throw, throws, transient, try, void, volatile, while

� null, true, false – predefinite ca literali

OOP2 - M. Joldoş - T.U. Cluj 30

Compilarea unui program sau a unei clase Java

� Fiecare definiŃie de clasă trebuie să se afle într-un fişier al cărui nume este numele clasei urmat de extensia . java� Exemplu: Clasa UnProgram trebuie să se afle în fişierul

numit UnProgram.java� Fiecare clasă este compilată folosind comanda javac urmată de numele fişierului care conŃine clasa

javac UnProgram.java� Rezultatul este un program în byte-code cu acelaşi

nume ca al clasei, urmat de extensia . classUnProgram.class

OOP2 - M. Joldoş - T.U. Cluj 31

Rularea unui program Java

� Un program Java poate fi rulat (java) după ce i-au fost compilate toate clasele� RulaŃi doar clasa care conŃine o metodă main(sistemul va încărca şi rula celelalte clase automat, dacă mai sunt)

� Metoda main începe cu linia:public static void main(String[ ] args)

� Comanda de lansare trebuie urmată doar de numele clasei (fără extensii)

java UnProgram

� VedeŃi Hello.java din exemplele BlueJOOP2 - M. Joldoş - T.U. Cluj 32

ConvenŃii pentru nume

� ÎncepeŃi numele de variabile, metode şi obiecte cu o literă mică, indicaŃi limitele "cuvintelor" cu o litera mare şi pentru celelalte caractere folosiŃi doar litere şi cifre ("camelcase")

vitezaMaxima rataDobinzii oraSosirii

� ÎncepeŃi numele de clase cu majusculă şi pentru restul identificatorului aplicaŃi regula de mai sus

UnProgram OClasa String

Page 23: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 33

Declararea variabilelor

� Fiecare variabilă dintr-un program Java trebuie declarată înainte de utilizare� DeclaraŃia informează compilatorul asupra tipului de

dată care va fi stocat în variabilă� Tipul variabilei este urmat de unul sau mai multe nume

separate de virgule şi terminat cu punct şi virgulă� Variabilele se declară de obicei chiar înainte de folosire

sau la începutul unui bloc (indicat de o acoladă deschisă { )

� Tipurile simple în Java sunt numite tipuri primitiveint numarulDeCai;

double oLungime, lungimeaTotala;

OOP2 - M. Joldoş - T.U. Cluj 34

Modificatori de acces pentru variabile/metode

� private� variabila/metoda este vizibilă local în cadrul clasei.� "Vizibilă doar mie".

� protected� variabila/metoda poate fi văzută din toate clasele, subclasele şi

celelalte clase din acelaşi pachet (package).� "Vizibilă în familie".

� public� variabila/metoda poate fi văzută din toate clasele� "Vizibilă tuturor".

� Modificatorul de acces implicit, nu are cuvânt cheie.� public pentru ceilalŃi membrii din acelaşi pachet.� private pentru oricine din afara pachetului� numită şi acces în pachet.� "Vizibilă în vecinătate"

OOP2 - M. Joldoş - T.U. Cluj 35

Tipuri Java

OOP2 - M. Joldoş - T.U. Cluj 36

Tipuri primitive

Tip primitiv

Biţi

Toate tipurile numerice sunt cu semn.

Page 24: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 37

Compatibilitate la asignare

� Mai general, o valoare de orice tip din lista următoare poate fi asignată unei variabile de orice alt tip care apare la dreapta eibyte→→→→short→→→→int→→→→long→→→→float→→→→double

char

� Gama valorilor de la dreapta este mai largă

� Este necesară o conversie de tip explicită (type cast ) pentru a asigna o valoare de un tip la o variabilă care apare la stânga ei în lista de mai sus (d.e., double la int)

� ObservaŃi că în Java un int nu poate fi asignat la o variabilă de tip boolean, nici un boolean la o variabilă de tip int

OOP2 - M. Joldoş - T.U. Cluj 38

Operatori aritmetici şi expresii

� Ca în majoritatea limbajelor, şi în Java se pot forma expresii folosind variabile, constante şi operatori aritmetici� Operatori aritmetici; + (adunare), - (scădere), *(înmulŃire), / (împărŃire), % (modulo, rest)

� Se poate folosi o expresie oriunde este legal să se folosească o valoare de tipul produs de expresie

OOP2 - M. Joldoş - T.U. Cluj 39

Operatori aritmetici şi expresii

� Dacă se combină un operator aritmetic cu operanzi de tipul int, atunci tipul rezultat este int

� Dacă se combină un operator aritmetic cu unul sau doi operanzi de tipul double, atunci tipul rezultat este double

� La combinarea de operanzi de tip diferit, tipul rezultat este cel mai din dreapta din lista de mai jos care se află în expresiebyte→→→→short→→→→int→→→→long→→→→float→→→→doublechar� ExcepŃie: Dacă tipul rezultat este byte sau short

(potrivit regulii date), atunci tipul produs va fi de fapt un int

OOP2 - M. Joldoş - T.U. Cluj 40

Reguli de precedenŃă şi asociativitate

� La determinarea ordinii operaŃiilor adiacente, operaŃia cu precedenŃă mai mare (şi argumentele sale aparente) este grupată înaintea operaŃiei de precedenŃă mai mică

base + rate * hours se evaluează cabase + (rate * hours)

� La precedenŃă egală, ordinea operaŃiilor este determinată de regulile de asociativitate

Page 25: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 41

Reguli de precedenŃă şi asociativitate

� Operatorii unari de precedenŃa egală sunt grupaŃi de la dreapta la stânga+-+rate se evaluează ca +(-(+rate))

� Operatorii binari de precedenŃă egală sunt grupaŃi de la stânga la dreaptabase + rate + hours se evaluează ca(base + rate) + hours

� ExcepŃie: Un şir de operatori de asignare este grupat de la dreapta la stângan1 = n2 = n3; se evaluează ca n1 = (n2 = n3);

OOP2 - M. Joldoş - T.U. Cluj 42

Posibilă problemă: Erorile de rotunjire la numerele în virgulă mobilă

� Numerele în virgulă mobilă sunt, în general, doar valori aproximative� Matematic, numărul în virgulă mobilă1.0/3.0 este egal

cu 0.3333333 . . .� Un calculator are o cantitate limitată de memorie

� Poate stoca 1.0/3.0 ca ceva în genul lui 0.3333333333, puŃin mai puŃin decât o treime

� De fapt numerele sunt stocate binar, dar consecinŃele sunt aceleaşi: numerele în virgulă mobilă pot pierde precizie

OOP2 - M. Joldoş - T.U. Cluj 43

ÎmpărŃirea întreagă şi cea în virgulă mobilă

� Dacă unul sau amândoi operanzii sunt în virgulă mobilă, împărŃirea dă un rezultat în virgulă mobilă15.0/2 se evaluează la 7.5

� Cum ambii operanzi întregi, împărŃirea dă un întreg� O eventuală parte fracŃionară este ignorată� Nu se fac rotunjiri

15/2 se evaluează la 7

� AveŃi grijă ca cel puŃin un operand să fie în virgulă mobilă dacă este nevoie de partea fracŃionară

OOP2 - M. Joldoş - T.U. Cluj 44

Conversia de tip explicită

� O conversie de tip explicită (type cast) ia o valoare de un tip şi produce o valoare "echivalentă" de celălalt tip� Dacă n şi m sunt întregii de împărŃit şi e nevoie de

partea fracŃionară, atunci cel puŃin un operand trebuie să fie în virgulă mobilă înainte de efectuarea operaŃieidouble ans = n / (double)m;

� La fel ca în C, tipul dorit este pus între paranteze imediat înaintea variabilei de convertit

� Tipul şi valoarea variabilei de convertit nu se schimbă

Page 26: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 45

Conversia de tip explicită� La conversia explicită de la virgulă mobilă la întreg,

numărul este trunchiat, nu rotunjit� (int)2.9 se evaluează la 2, nu 3

� La asignarea valorii unui întreg la o variabilă în virgulă mobilă, Java realizează o conversie explicită de tip automată numită coerciŃie de tip

double d = 5;

� Nu este legal să se atribuie un double la un int fără o conversie explicită

int i = 5.5; // Ilegal

int i = (int)5.5 // Corect

OOP2 - M. Joldoş - T.U. Cluj 46

Operatorii increment şi decrement

� Când oricare dintre operatorii ++ sau – – precede o variabilă şi este o parte a expresiei, expresia este evaluată folosind valoarea modificată a variabilei� Dacă n este 2, atunci 2*(++n) se evaluează la 6

� Când oricare dintre operatori urmează unei variabile şi este parte a expresiei, expresia este evaluată folosind valoarea originală şi abia apoi se schimbă valoarea variabilei� Dacă n este 2, atunci 2*(n++) se evaluează la 4

OOP2 - M. Joldoş - T.U. Cluj 47

Clase "învelitoare" pentru tipurile primitive

� Clasele învelitoare (wrapper) furnizează câte un tip clasă corespunzător fiecărui tip primitiv� Astfel este posibil să existe clase care se comportă

cumva asemănător tipurilor primitive� Clasele pentru tipurile primitive byte, short, long,float, double, şi char sunt (în ordine) Byte, Short,Long, Float, Double, şi Character

� Aceste clase conŃin şi un număr de constante predefinite utile, precum şi metode statice utile

OOP2 - M. Joldoş - T.U. Cluj 48

Clase învelitoare

� Boxing (împachetare): procesul de trecere de la o valoare primitivă la un obiect al clasei sale învelitoare� Pentru a converti valoarea la una "echivalentă" de tip

clasă, creaŃi un obiect de tipul corespunzător folosind valoarea primitivă ca argument

� Noul obiect va conŃine o variabilă instanŃă care stochează o copie a valorii primitive

� Spre deosebire de alte clase, clasele învelitoare nu au constructori fără argumenteInteger integerObject = new Integer(42);

Page 27: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 49

Clase învelitoare� Unboxing (despachetare): procesul de trecere

de la un obiect al unei clase învelitoare la valoarea corespunzătoare a unui tip primitiv� Metodele de convertire a unui obiect din clasele Byte, Short, Integer, Long, Float, Double, şi Character la valorile primitive corespunzătore sunt (în ordine) byteValue, shortValue,intValue, longValue, floatValue,doubleValue, şi charValue

� Nici una dintre aceste metode nu necesită argumenteint i = integerObject.intValue();

OOP2 - M. Joldoş - T.U. Cluj 50

Boxing şi Unboxing automat

� Începând cu versiunea 5.0, Java poate face automat Împachetare/despachetare

� În loc să creăm un obiect din clasa învelitoare (ca mai înainte), se poate face o conversie de tip automată:Integer integerObject = 42;

� În loc să trebuiască să invocăm metoda corespunzătoare (ca intValue, doubleValue, charValue etc.) pentru a converti un obiect din clasa învelitoare la tipul său asociat, valoarea primitivă poate fi recuperată automat

int i = integerObject;

OOP2 - M. Joldoş - T.U. Cluj 51

Constante şi metode statice în clasele învelitoare

� Constante pentru valori maxime şi minime pentru tipurile primitive� Exemple: Integer.MAX_VALUE,Integer.MIN_VALUE, Double. MAX_VALUE, Double.MIN_VALUE etc.

� Clasa Boolean are nume pentru două constante de tipul Boolean� Boolean.TRUE şi Boolean.FALSE sunt obiectele booleene corespunzătoare valorilor true şi false ale tipului primitiv boolean

OOP2 - M. Joldoş - T.U. Cluj 52

Constante şi metode statice în clasele învelitoare

� Metode statice pentru conversia unei reprezentări corect formate ca şi de caractere a unui număr la numărul de un tip dat� Metodele Integer.parseInt, Long.parseLong, Float.parseFloat şi Double.parseDouble sunt pentru (în ordine) int, long, float şi double

� Metode statice pentru conversia duală celei anterioare� Exemplu. Expresia

Double.toString(123.99); returnează valoarea şir "123.99"

� Clasa Character conŃine un număr de metode utile la prelucrarea şirurilor

Page 28: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 53

ReferinŃe Java

� Toate obiectele sunt create în memorie� Pentru a accesa datele dintr-un obiect sau a lucra

cu un obiect, este nevoie de o variabilă pe stiva, variabila care poate stoca o referinŃă la adresa obiectului.

� Despre variabilele care stochează referinŃe la adrese de obiecte se spune că păstrează tipul de date referinŃă

� Exemplu:PlatitorTaxe t = newPlatitorTaxe(1111111120633, 30000);

OOP2 - M. Joldoş - T.U. Cluj 54

Clasa String

� Nu există un tip primitiv pentru şiruri în Java� Clasa String este o clasă Java predefinită folosită la

stocarea şi prelucrarea şirurilor� Obiectele de tipul String sunt compuse din şiruri de

caractere scrise între ghilimele� Orice şir între ghilimele este de clasa String

"Fiti fericiti cu Java."

� Unei variabile de tipul String i se poate da valoarea unui obiect StringString binecuvintare = "Fiti fericiti cu Java.";

OOP2 - M. Joldoş - T.U. Cluj 55

Concatenarea şirurilor

� Concatenare: folosind operatorul + operator aplicat asupra a două şiruri pentru a le conecta şi a forma un şir mai lung� Dacă salut este egal cu "Bună ziua, ", şi javaClass este egal cu "viitori colegi", atunci salut + javaClass este egal cu "Bună ziua, viitori colegi"

� Orice număr de şiruri pot fi concatenate� La combinarea unui şir cu aproape orice alt tip,

rezultatul este un şir� "Răspunsul este " + 42 se evaluează la

" Răspunsul este 42"

OOP2 - M. Joldoş - T.U. Cluj 56

Metode al clasei string String

� Clasa String conŃine multe metode utile la aplicaŃiile care prelucrează şiruri� O metodă a clasei String se apelează prin numele unui

obiect String, un punct, numele metodei şi o pereche de paranteze între care sunt cuprinse argumentele (dacă sunt)

� O valoare returnată de o metodă String se poate folosi oriunde se poate folosi o valoare de tipul returnatString greeting = "Hello";

int count = greeting.length();

System.out.println("Length is " + greeting.length());

� PoziŃia sau indexul unui caracter într-un şir se numără întotdeauna de la zero

Page 29: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 57

Metode ale clasei String

true dacă s se termină cu ts. endsWith(t)b =

true dacă t apare începând cu indexul is. startsWith(t, i)b =

true dacă s începe cu ts. startsWith(t)b =

la fel ca mai sus, dar fără a Ńine seama de majuscule/minuscule

s. equalsIgnoreCase(t)b =

true dacă cele două şiruri au valori egales. equals(t)b =

la fel ca mai sus, dar fără a Ńine seama de majuscule/minuscule

s. compareToIgnoreCase(t)

i =

compară cu s. Returnează <0 dacă s<t, 0 dacă ==, >0 dacă s>t

s. compareTo(t)i =ComparaŃii (note: folosiŃi aceste metode în loc de == şi !=)

lungimea şirului s.s. length()i =Lungimea şirului

OOP2 - M. Joldoş - T.U. Cluj 58

Metode ale clasei String

indexul ultimei apariŃii a lui t pe sau înainte de poziŃia i în s.

s. lastIndexOf(t, i)i =

indexul ultimei apariŃii lui t în s.s. lastIndexOf(t)i =

indexul ultimei apariŃii lui c pe sau înainte de poziŃia i în s.

s. lastIndexOf(c, i)i =

indexul ultimei apariŃii lui c în s.s. lastIndexOf(c)i =

indexul caracterului c la sau după poziŃia i din s.s. indexOf(c, i)i =

indexul primei apariŃii caracterului c în s.s. indexOf(c)i =

indexul lui String t la sau după poziŃia i în s.s. indexOf(t, i)i =

indexul primei apariŃii lui String t in s.s. indexOf(t)i =

Căutare - Notă : Toate metodele "indexOf" returnează -1 dacă şirul/caracterul nu este găsit

OOP2 - M. Joldoş - T.U. Cluj 59

Metode ale clasei String

nou String cu toate c2-urile înlocuite prin c1.s. replace(c1, c2)s1 =

nou String fără spaŃii albe la început şi sfârşits. trim()s1 =

nou String cu toate caracterele majuscules. toUpperCase()s1 =

nou String cu toate caracterele minuscules. toLowerCase()s1 =

Crearea unui nou şir din original

subşirul de la indexul i până ÎNAINTE de indexul jdin s.

s. substring(i, j)s1 =

subşirul de la indexul i până la sfârşitul lui s.s. substring(i)s1 =

caracterul de la poziŃia i din s.s. charAt(i)c =

ObŃinerea de părŃi

OOP2 - M. Joldoş - T.U. Cluj 60

Metode ale clasei String

[Java >=5] Foloseşte formatul f pentru a converti un număr variabil de parametri, x la un şir.

String. format(f, x...)s =

Converteşte x la String, unde x esteorice valoare de tip (primitiv sauobiect).

String. valueOf(x)s =

Metode statice pentru conversia la String

� Lista nu este exhaustivă.

Page 30: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 61

Prelucrarea şirurilor

� Un obiect String nu se poate schimba (eng. immutable), caracterele pe care le conŃine nu pot fi schimbate

� Clasa StringBuffer are metode prin care se pot edita obiectele sale şir

� Se poate totuşi modifica valoarea unei variabile String prin asignare

String nume = "Ionescu";

nume = "Ion " + nume;

OOP2 - M. Joldoş - T.U. Cluj 62

Seturi de caractere

� ASCII: Set de caractere folosit de multe limbaje de programare, care conŃine toate caracterele folosite în mod normal pe o tastatură pentru limba engleză plus câteva caractere speciale� Fiecare caracter este reprezentat de un cod numeric

� Unicode: Set de caractere folosit limbajul Java care include tot setul ASCII plus multe dintre caracterele folosite cu alfabete nelatine� Exemple: char c='\u0103'; // litera 'ă'String s="\u00eencoto\u015fm\u0103ni\u0163i";// încotoşmăniŃi

OOP2 - M. Joldoş - T.U. Cluj 63

O porŃiune din codul Unicode

OOP2 - M. Joldoş - T.U. Cluj 64

Numirea constantelor

� În loc de numere "anonime", declaraŃi constante simbolice (cu nume) şi folosiŃi-le numelepublic static final double CM_PER_INCH = 2.54;

public static final int HOURS_PER_DAY = 24;

� Previne schimbarea nedorită a valorii� Uşurează modificarea valorii� ConvenŃia de nume pentru constante: toate literele

majuscule, limitele de cuvinte marcate prin liniuŃa de subliniere

Page 31: POO all curses UTCLUJ VICAS

OOP2 - M. Joldoş - T.U. Cluj 65

Comentariile

� Comentariu de o linie: începe cu simbolurile // şi provoacă ignorarea a ceea ce urmează până la sfârşitul liniei� Folosit de cel care scrie codul sau de cel care îl modifică

� Comentariul bloc este la fel ca în C (perechea /*, */)

� Furnizează documentaŃie utilizatorilor programului

OOP2 - M. Joldoş - T.U. Cluj 66

Documentarea programului

� Java include programul javadoc care extrage automat documentaŃia din comentariile bloc din clasele definite, dacă� Începutul comentariului are un asterisc

suplimentar (/**)

� Un program bine scris este autodocumentat� Structura sa se clarifică prin alegerea numelor de

identificatori şi modelul de indentare

OOP2 - M. Joldoş - T.U. Cluj 67

Rezumat

� AbstracŃiuni în programele OO � nivele: pachet,

client/server, interfeŃe, implementări, metode (considerate separat)

� Are-o (agregare)� Este-o (specializare)� CompoziŃie� TDA

� Java� mediul (compilator, încărcător

de clase, interpretor, JIT, sistem de execuŃie etc.)

� convenŃii de numire� declaraŃii şi modificatori de

acces� Tipuri primitive (boolean,

char, short, int, long, float, double) şi clase învelitoare

� Operatori aritmetici� Clasa String

Page 32: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 1

Programare orientată pe obiecte

1. Câteva observaŃii despre operatori2. Structuri de control în Java3. Clase şi Obiecte

OOP3 - M. Joldoş - T.U. Cluj 2

Operatori

� Sunt trataŃi în detaliu la laborator� Câteva diferenŃe faŃă de C:

� Operatorul pe biŃi >>> � D.e. n >>> p; // deplasează biŃii lui n spre dreapta

cu p poziŃii. În poziŃiile de rang superior se inserează zerouri.

� Concatenarea pentru String: operatorul +� Operatori pentru lucrul cu obiecte – îi vom trata

în detaliu mai târziu

OOP3 - M. Joldoş - T.U. Cluj 3

Despre precedenŃa operatorilor

PrecedenŃa operatorilor . [] (args) post ++ -- ! ~ unary + - pre ++ -- (type) new * / % + - << >> >>> < <= > >= instanceof == != & ^ | && || ?: = += -= etc

TineŃi minte precedenŃa pentru operatorii unari, * / % + - comparaŃii && || = asignări FolosiŃi paranteze () pentru ceilalŃi

OOP3 - M. Joldoş - T.U. Cluj 4

InstrucŃiunea if

� InstrucŃiunea if specifică ce bloc de cod să se execute în funcŃie de rezultatul evaluării unei condiŃii numite expresie booleană.

if (<expresie boolean ă>)

<then bloc>

else

<else bloc>

� <expresie boolean ă> este o expresie condiŃională care se evaluează la true sau false.� Sintaxă similară limbajului C, dar atenŃie la ce este o

expresie booleană în Java

Page 33: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 5

Compararea obiectelor

� La compararea a două variabile, se compară conŃinutul lor.

� În cazul obiectelor, conŃinutul este adresa unde este stocat obiectul (adică se vor compara referinŃele).� Şirurile în Java sunt obiecte ale clasei String� Clasa String furnizează metode de comparare (am

văzut deja)� Cea mai bună metodă în ceea ce priveşte

compararea obiectelor este să definim metode de comparare pentru clasa respectivă.

OOP3 - M. Joldoş - T.U. Cluj 6

Sugestii pentru if� ÎncepeŃi testul cu cazul cel mai relevant

� Face codul mai uşor de citit� Nu uitaŃi de clauza else!� EvitaŃi condiŃiile complicate� DivizaŃi condiŃiile în variabile/funcŃii booleene� ÎncercaŃi să folosiŃi condiŃii pozitive� Exemplu – se preferă a doua variantă

if (!node.isFirst() && node.value() != null) instr1

else instr2if (node.isFirst() || node.value() == null)

instr2else instr1

OOP3 - M. Joldoş - T.U. Cluj 7

Sugestii pentru lanŃuri de if

// Cod bunif (rnd < 0) {// Error!} else if (rnd < 0.1) {// ...} else if (rnd < 0.5) {// ...} else if (rnd < 1.0) {// ...} else// Error!

// Cod rauif (screen.needsRepaint()) {

// redeseneaz ă ecranul} else if (p1.canMove()) {

// ia mutarea de la p1} else if (p2.canMove()) {

// ia mutarea de la p2} else {

// blocaj! }

� Toate condiŃiile ar trebui să fie înrudite apropiat� PuneŃi cazurile comune mai întâi (acolo unde se poate)� FolosiŃi switch dacă se poate

OOP3 - M. Joldoş - T.U. Cluj 8

InstrucŃiunea switch

� Sintaxa pentru instrucŃiunea switch:switch ( < expresie aritmetic ă>){

<case eticheta_1>: <case corp 1>

...

<case eticheta_n>: <case corp n>

}

� Tipul de dată al <expresie aritmetic ă> trebuie să fie char, byte, short, sau int.

� Valoarea lui <expresie aritmetic ă> se compară cu constanta eticheta_i din <case eticheta_i> .

Page 34: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 9

InstrucŃiunea switch

� Dacă există o valoare care se potriveşte cu valoarea expresiei, atunci se execută corpul acesteia. Altfel execuŃia continuă cu instrucŃiunea care urmează instrucŃiunii switch

� InstrucŃiunea break face să nu se execute porŃiunea care urmează din switch, ci să se continue cu ceea ce vine după switch.

� break este necesar pentru a executa instrucŃiunile dintr-un caz, şi numai unul.� iarăşi, ca în C

OOP3 - M. Joldoş - T.U. Cluj 10

Sugestii pentru switch

� OrdonaŃi cazurile (logic sau alfabetic)� PrevedeŃi întotdeauna cazul

implicit (default )� Întotdeauna folosiŃi break

între cazuri� ÎncercaŃi să păstraŃi mică

dimensiunea instrucŃiunii switch

� DivizaŃi cazurile de mari dimensiuni în funcŃii

switch (file.getType()) {

// caz cu tratare comuna// Non-breaking casecase IMAGE_PNG:case IMAGE_JPG:openWithPaint(file);break;

case IMAGE_WMF:displayWMF(file);break;

default:// Tip necunoscutbreak;

}

OOP3 - M. Joldoş - T.U. Cluj 11

InstrucŃiuni repetitive

� InstrucŃiunile repetitive controlează un bloc de cod de executat un număr fixat de ori sau până la îndeplinirea unei anumite condiŃii

� Ca şi C, Java are trei instrucŃiuni repetitive:� while

� do-while

� for

� InstrucŃiunile repetitive sunt numite şi instrucŃiuni de ciclare, blocul de instrucŃiuni care se repetă (<instructiuni> în cele ce urmează) este cunoscut sub numele de corpul ciclului.

OOP3 - M. Joldoş - T.U. Cluj 12

InstrucŃiunea while

� În Java, instrucŃiunile while au formatul general:while ( <expresie booleana> )

<instructiuni>

� Cât timp <expresie booleana> este true, se execută corpul ciclului.

� Într-o buclă controlată prin contor, corpul ciclului este executat de un număr fixat de ori.

� Într-o buclă controlată printr-o santinelă, corpul ciclului este executat în mod repetat până când se întâlneşte o valoare stabilită, numită santinelă.

Page 35: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 13

Capcane în scrierea instrucŃiunilor repetitive

� La instrucŃiunile repetitive este important să se asigure terminarea ciclului la un moment dat.

� Tipurile de probleme potenŃiale de Ńinut minte:� Bucla infinită

int item = 0;

while (item < 5000) {

item = item * 5;

}

� Deoarece item este iniŃializat la 0, item nu va fi niciodată mai mare de 5000 (0 = 0 * 5), astfel că bucla nu se va termina niciodată.

OOP3 - M. Joldoş - T.U. Cluj 14

Capcane în scrierea instrucŃiunilor repetitive

� Bucla infinităint count = 1;while (count != 10) {

count = count + 2;}

� În acest exemplu, (al cărui instrucŃiune whileeste în buclă infinită), contorul va fi 9 şi 11, dar nu 10.

� Eroarea prin depăşire de capacitate apare atunci când se încearcă asignarea unei valori mai mari decât valoarea maximă pe care o poate stoca variabila

OOP3 - M. Joldoş - T.U. Cluj 15

Capcane în scrierea instrucŃiunilor repetitive

� Depăşirea de capacitate� În Java, o depăşire a capacităŃii de reprezentare nu

provoacă terminarea programului. � La tipurile float şi double se atribuie variabilei o valoare care

reprezintă infinit. � La tipul int, o valoare pozitivă devine negativă, iar una

negativă devine pozitivă, ca şi cum valorile ar fi plasate pe un cerc cu maximul şi minimul învecinate.

� Numerele reale nu se folosesc în teste exacte sau incrementări, deoarece valorile lor sunt reprezentate cu aproximaŃie

� Eroarea prin depăşire cu unu este o alta capcană frecventă.

OOP3 - M. Joldoş - T.U. Cluj 16

Sugestii pentru ciclurile while

// Cod r ău

stmts_A

while (boolExp) {

stmts_B

stmts_A

}

// Cod bun

while (true) {

stmts_A

if (!boolExp)

break;

stmts_B

}

� Se folosesc pentru ciclări mai complicate� EvitaŃi să aveŃi mai mult de o ieşire din buclă� Sunt permise ieşirile forŃate (pentru e evita duplicarea

codului)

Page 36: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 17

InstrucŃiunea do-while

� InstrucŃiunea while este o buclă cu pre-testare(testul se face la intrarea în buclă). De aceea, corpul buclei poate să nu fie executat niciodată.

� InstrucŃiunea do-while este o buclă cu post-testare. Corpul ciclului este executat cel puŃin o dată.

� Formatul instrcuŃiunii do-while este:do<instructiuni>

while (<expresie boolean ă>);� <instructiuni> se execută până când

<expresie boolean ă> devine false.OOP3 - M. Joldoş - T.U. Cluj 18

Controlul repetitiv o buclă-şi-jumătate (buclă infinită întreruptă)

� AtenŃie la două lucruri la folosirea buclelor întrerupte:� Pericolul ciclării infinite. Expresia booleană a

instrucŃiunii while este true întotdeauna. Dacă nu există o instrucŃiune if care să forŃeze ieşirea din ciclu, rezultatul va fi o buclă infinită.

� Puncte de ieşire multiple. Se poate totuşi, chiar dacă e mai complicat să se scrie un control buclă cu mai multe ieşiri (break ). Practica recomandă pe cât posibil curgerea o-intrare o-ieşire a controlului.

OOP3 - M. Joldoş - T.U. Cluj 19

InstrucŃiunea for

� Formatul instrucŃiunii for este:for (<initializare>; <expresie boolean ă>;

<increment>)<instruc Ńiuni>

� Exemplu:int sum = 0;for (int i = 1 ; i <=100 ; i++){

sum += i; }

� Variabila i din exemplu se numeşte variabilă de control. ea contorizează numărul de repetiŃii.

� <increment > poate fi orice cantitate.� Din nou, ca în C

OOP3 - M. Joldoş - T.U. Cluj 20

Sugestii pentru ciclurile for

� Sunt ideale atunci când numărul de iteraŃii este cunoscut� FolosiŃi o instrucŃiune pentru fiecare parte� DeclaraŃi variabilele de ciclu în antet (reduce

vizibilitatea şi interferenŃa)� Nu se recomandă modificarea variabilei de

control în corpul ciclului

Page 37: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 21

break cu etichetă

� break se foloseşte în bucle şi switch� semnificaŃiile sunt diferite

� break poate fi şi urmat de o etichetă, L� încearcă să transfere controlul la o instrucŃiune

etichetată cu L� Un break cu etichetă se termină întotdeauna anormal;

dacă nu există instrucŃiuni etichetate cu L, apare o eroare de compilare

� Un break cu etichetă permite ieşirea din mai multe bucle imbricate

� Eticheta trebuie să preceadă bucla cea mai exterioară din care se doreşte ieşirea

� Această formă nu există în c

OOP3 - M. Joldoş - T.U. Cluj 22

Exemplu pentru break cu etichetăint n;read_data:while(…) {

…for (…) {

n= Console.readInt(…);if (n < 0) // nu se poate continua

break read_data; // break out of data loop…

}}// verifica dac ă este succes sau esecif (n < 0) {

// trateaza situatiile cu probleme}else {

// am ajuns aici normal}

OOP3 - M. Joldoş - T.U. Cluj 23

continue cu etichetă

� Forma etichetată a instrucŃiunii continue sare peste iteraŃia curentă a unei bucle exterioare marcate cu o etichetă dată.

� Eticheta trebuie să preceadă bucla cea mai exterioară din care se doreşte ieşirea

OOP3 - M. Joldoş - T.U. Cluj 24

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

String searchMe = "Look for a substring in me";String substring = "sub";boolean foundIt = false;

int max = searchMe.length() - substring.length();test:

for (int i = 0; i <= max; i++) {int n = substring.length();int j = i;int k = 0;while (n-- != 0) {

if (searchMe.charAt(j++)!= substring.charAt(k++)) {

continue test;}

}foundIt = true;

break test;}System.out.println(foundIt ? "Found it" : "Didn't find it");

}}

continue cu etichetă – exemplu de la Sun

Page 38: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 25

for pentru iteraŃii peste colecŃii şi tablouri

� Creat special pentru iteraŃii peste colecŃii şi tablouri (vom reveni asupra instrucŃiunii) – Java 5

� Nu funcŃionează oriunde (d.e. nu se pot accesa indicii de tablouri)

� Exemplu de la Sun:public class ForEachDemo {

public static void main(String[] args) {int[] arrayOfInts = { 32, 87, 3, 589, 12,

1076, 2000, 8, 622, 127 };

for (int element : arrayOfInts) {System.out.print(element + " ");

}System.out.println();

}}

OOP3 - M. Joldoş - T.U. Cluj 26

Sugestii generale pentru bucle

� RulaŃi bucla în minte (verificaŃi cazurile din capete)� FolosiŃi nume cu semnificaŃie

� FolosiŃi nume ca i, j, n doar în buclele scurte unde variabila de ciclu este doar un index

� EvitaŃi mai mult de trei cicluri imbricate (lucru valabil şi pentru imbricările de if)� RestructuraŃi sau divizaŃi în funcŃii ajutătoare

� Nu folosiŃi variabila ciclului după sfârşitul buclei

OOP3 - M. Joldoş - T.U. Cluj 27

InstrucŃiuni de tratare a excepŃiilor� Deocamdată doar semnificaŃia (în detaliu, ulterior)

� throw – aruncă o excepŃie� try-catch , and finally – folosite la tratarea

excepŃiilor � try – identifică blocul de instrucŃiuni unde poate fi

aruncată o excepŃie� catch – asociată cu try ; identifică un bloc de

instrucŃiuni care pot trata un anumit tip de excepŃie; se execută dacă apare o excepŃie în blocul try

� finally – asociată cu try ; identifică un bloc de instrucŃiuni care se execută indiferent de apariŃia sau nu a unei erori în blocul try .

� ExcepŃiile nu trebuie folosite pentru a simula un goto!OOP3 - M. Joldoş - T.U. Cluj 28

Metode

Constructori

Variabile instanŃă (câmpuri)Antetul claseipublic class Taxi{

private int km;

public Taxi(){

km = 0;

}

public int getKm(){

return km;

}

public void drive(int km){

this.km += km;

}

}

Anatomia unei clase

Page 39: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 29

Constructor:

Cel mult o dată pe obiect; invocat de operatorul "new"

# de apelări

La fel cu numele clasei. Prima literă mare, stil "cămilă"

Nume

> Taxi cab;

> cab = new Taxi() ;Utilizare

0 sau mai mulŃi parametriIntrare

Nu este tip de retur în antetIeşire

public Taxi(){

}

Cod

IniŃializează starea unui obiectScop

OOP3 - M. Joldoş - T.U. Cluj 30

Constructori multipli

> Taxi cab2;

> cab2 = new Taxi(10,”Jim”) ;

> Taxi cab1;

> cab1 = new Taxi() ;

O operaŃie “new” încununată de succes creează un obiect pe heap şi execută constructorul al cărui lista de parametri “corespunde” listei sale de argumente (canumăr, tip, ordine).

public class Taxi{

private int km;

private String driver;

public Taxi(){

km = 0;

driver = “Unknown”;

}

public Taxi(int km,String d){

this.km = km;

driver = d;

}

OOP3 - M. Joldoş - T.U. Cluj 31

Folosirea corespunzătoare a constructorilor

� Un constructor ar trebui întotdeauna să creeze obiectele într-o stare validă� Constructorii nu trebuie să facă nimic altceva decât să

creeze obiecte

� Dacă un constructor nu poate garanta că obiectul construit este valid, atunci ar trebui să fie private şi accesat prin intermediul unei metode de fabricare

� Notă: în general, termenul de metodă de fabricare este folosit pentru a se referi la orice metodă al cărei scop principal este crearea de obiecte

OOP3 - M. Joldoş - T.U. Cluj 32

Folosirea corespunzătoare a constructorilor

� O metodă de fabricare (factory method) este o metodă statică care apelează un constructor

� Constructorul este de obicei private

� Metoda de fabricare poate determina dacă să invoce sau nu constructorul

� Metoda de fabricare poate arunca o excepŃie, sau poate face altceva potrivit în cazul în care i se dau argumente ilegale sau nu poate crea un obiect valid

public static Person create(int age) { //exemplu: metodă de fabricare

if (age < 0) throw new IllegalArgumentException("Tooyoung!");

else return new Person(age);}

Page 40: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 33

Metodă:

nelimitat pentru un obiect# de apelări

Un verb;Începe cu literă mică, stil “cămilă”

Nume

> cab. turnLeft();Uutilizare

0 sau mai mulŃi parametriIntrare

Pentru ieşire este nevoie de un tip returnat

Ieşire

public void turnLeft(){

}

Cod

Execută comportamentul obiectuluiScop

OOP3 - M. Joldoş - T.U. Cluj 34

Ce poate face o metodă?

� O metodă poate:� Schimba starea obiectului său� Raporta starea obiectului său� Opera asupra numerelor, a textului, a fişierelor, graficii,

paginilor web, hardware, …� Crea alte obiecte� Apela o metodă a unui alt obiect: obiect.metoda(args)

� Apela o metodă din aceeaşi clasă:this.metoda(args);

� Se poate autoapela (recursivitate)� …

OOP3 - M. Joldoş - T.U. Cluj 35

Declararea unei metodepublic tip_returnat numeMetoda(0+ parametri){..}public int getKM() {..}public void increaseSpeed(int accel, intlimit){..}

� Nume: Verb care începe cu literă mică, stil “cămilă”� Ieşire: e nevoie de un tip returnat.� Intrare: 0 sau mai mulŃi parametri� Corp:

� Între acolade� ConŃine un # arbitrar de instrucŃiuni (asignare, “if”, return,

etc.).� Poate conŃine declaraŃii de “ variabile locale”

� Cum se apelează: operatorul “punct”:numeObiect.numeMetoda(argumente)cab1.increaseSpeed(5, 50)

OOP3 - M. Joldoş - T.U. Cluj 36

Metode accesoare şi mutatoare

> Taxi cab1;

> cab1 = new Taxi();

> cab.getKm()

0

> cab.setKm(500);

> cab.getKm()

500

Apeluri de metode accesoare (de obŃinere)/mutatoare(de setare)

public class Taxi{private int km;

public Taxi(){ km = 0;

}

// raporteaz ă # kmpublic int getKm(){

return km;}

// seteaz ă (schimb ă) # kmpublic void setKm(int m){

km = m;}

}

Page 41: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 37

Intrarea pentru o metodă� O metodă poate primi 0 sau mai multe intrări.� Intrările pe care le aşteaptă o metodă sunt specificate via

lista de “parametri formali” (tip nume1, tip nume2, …)

� La apelul unei metode, numărul, ordinea şi tipul argumentelor trebuie să se potrivească cu parametrii corespunzători.

obj.meth3(3,4,cab)

public int meth3(int x,int y,Taxi t){..}

obj.meth2(true)public int meth2(boolean b){..}

obj.meth1()public void meth1(){..}

Apelul metodei

(cu argumente)

Declararea metodei

(cu parametri)

OOP3 - M. Joldoş - T.U. Cluj 38

Ieşirea unei metode� O metodă poate să nu aibă ieşire (void) sau să aibă ceva. � Dacă nu returnează nimic (nu are ieşire), tipul returnat

este “void”public void setKm(int km){..}

� Dacă are ieşire: � Tipul returnat este non-void (d.e. int, boolean, Taxi)

public int getkm(){..}

� Trebuie să conŃină o instrucŃiune return cu o valoare// valorea returnată trebuie să se

// potriveasc ă cu tipul returnat

return km;

OOP3 - M. Joldoş - T.U. Cluj 39

Modificatori de acces pentru metode

� public- cel mai frecvent folosit; metoda este vizibilă tuturor

� private – nu poate fi folosită de toate clasele; metoda este vizibilă doar în cadrul clasei

� protected – nu poate fi folosită de toate clasele; metoda este vizibilă doar în pachetul din care face parte

� static – nu e nevoie de obiecte pentru a folosi acest fel de metode� Dacă declaraŃia metodei conŃine modificatorul static,

este vorba de o metodă la nivelul clasei.� Metodele la nivelul clasei pot accesa doar constantele şi

variabilele claseiOOP3 - M. Joldoş - T.U. Cluj 40

Clasă instanŃiabilă

� O clasă este instanŃiabilă dacă putem crea instanŃe ale clasei respective.

� Exemple: clasele "învelitoare: ale tipurilor primitive, String, Scanner,… sunt toate instanŃiabile, în timp ce clasa Math nu este.

� Fiecare obiect este membru al unei clase� catedra este un obiect membru al clasei Catedra� relaŃii de tipul este-o

Page 42: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 41

Utilitatea conceptului de clasă

� Conceptul este util deoarece:� Obiectele moştenesc atribute din clase� Toate obiectele au atribute predictibile deoarece

obiectele sunt membre ale anumitor clase

� Trebuie:� Să creaŃi clase din care să se instanŃieze obiectele (d.e.

clasa Taxi)� Să scrieŃi alte clase care să folosească obiectele (se scrie

un program/o clasă pentru a conduce taxiul la aeroport; foloseşte d.e. clasa Taxi pentru a crea un obiect automobil de condus)

OOP3 - M. Joldoş - T.U. Cluj 42

Crearea unei clase

� Trebuie:� Să daŃi un nume clasei� Să determinaŃi ce date şi metode vor fi parte a clasei

� Modificatorii de acces pentru clase cuprind:� public

� Cel mai folosit; clasa este vizibilă tuturor� Clasa poate fi extinsă sau folosită ca bază pentru alte clase

� final – folosit doar în circumstanŃe speciale (clasa este complet definită şi nu sunt necesare definiri de subclase)

� abstract – folosit doar în circumstanŃe speciale (clasa este incomplet definită – conŃine o metodă neimplementată)

� Ultimii doi îi vom trata mai târziu

OOP3 - M. Joldoş - T.U. Cluj 43

Şablon de program pentru codul unei clase

OOP3 - M. Joldoş - T.U. Cluj 44

Blocuri şi vizibilitate (scop)

� Bloc: în orice clasă sau metodă, codul inclus între o pereche de acolade

� PorŃiunea de program în care se poate referi o variabilă constituie domeniul de vizibilitate(scop) al variabilei

� O variabilă există, sau devine vizibilă la declarare� O variabila încetează să existe sau devine invizibilă

la sfârşitul blocului în care a fost declarată� Dacă declaraŃi o variabilă într-o clasă şi folosiŃi

acelaşi nume pentru a declara o variabilă într-o metodă a clasei, variabila declarată în metodă are precedenŃa sau suprascrie, prima variabilă

Page 43: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 45

Supraîncărcarea unei metodeSupraîncărcare:� Implică folosirea unui termen pentru a indica semnificaŃii

diverse� Scrierea unei metode cu acelaşi nume, dar cu argumente

diferite� Supraîncărcarea unei metode Java înseamnă că scrieŃi mai

multe metode cu acelaşi nume� Exemplu:

public int test(int i, int j){return i + j;

}public int test(int i, byte j){

return i + j;}

OOP3 - M. Joldoş - T.U. Cluj 46

Ambiguitate la supraîncărcare � La supraîncărcarea unei metode există riscul ambiguităŃii

� O situaŃie ambiguă este când compilatorul nu poate determina ce metodă să folosească

� Exemplu:public int test(int units, int pricePerUnit){

return units * pricePerAmount;}public long test(int numUnits, int weight){

return (long)(units * weight);}

OOP3 - M. Joldoş - T.U. Cluj 47

Argumente pentru constructori� Java furnizează automat un constructor la crearea unei clase� Programatorii pot scrie constructori proprii, inclusiv constructori care

primesc argumente� Asemenea argumente sunt folosite la iniŃializare atunci când valorile

obiectelor pot diferi� Exemplu:

class Client {private String nume;private int numarCont;public Client(String n) {

nume =n;}public Client(String n, int a) {

nume =n;numarCont = a;

}

OOP3 - M. Joldoş - T.U. Cluj 48

Supraîncărcarea constructorilor

� Dacă o clasă este instanŃiabilă, Java furnizează automat un constructor

� Dar, la crearea unui constructor propriu, constructorul furnizat automat încetează să existe

� Ca şi la alte metode, constructorii pot fi supraîncărcaŃi� Supraîncărcarea constructorilor oferă o cale de a

crea obiecte cu sau fără argumente iniŃiale, după necesităŃi.

Page 44: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 49

ReferinŃa this

� Clasele pot creşte foarte repede� Fiecare clasa poate avea multe câmpuri de

date şi multe metode

� La instanŃierea multor obiecte ale unei clase, cerinŃele de memorie pot fi substanŃiale� Nu este nevoie să se stocheze o copie

separată a fiecărei variabile şi metode la fiecare instanŃiere a unei clase

OOP3 - M. Joldoş - T.U. Cluj 50

ReferinŃa this

� Compilatorul accesează câmpurile de date corespunzătoare ale obiectului, deoarece i se trimite implicit o referinŃă this la metodele claselor

� Metodele statice (metodele la nivel de clasă) nu au o referinŃă this deoarece nu au un obiect asociatpublic getStudentID()

{

return studentID;}

public getStudentID()

{

return this.studentID;

}

OOP3 - M. Joldoş - T.U. Cluj 51

Variabile la nivel de clasă

� Variabile la nivel de clasă: variabile care sunt partajate de fiecare instanŃă a unei clase

� Numele instituŃiei = "T.U. Cluj-Napoca"� Fiecare angajat al unei instituŃii lucrează

pentru aceeaşi instituŃieprivate static String COMPANY_ID =

"T.U. Cluj-Napoca";

� Se poate dar nu este recomandat să se declare o variabilă vizibilă în afara clasei

OOP3 - M. Joldoş - T.U. Cluj 52

Folosirea constantelor şi metodelor importate automat, de bibliotecă

� Creatorii limbajului Java au creat cca. 500 clase � Exemple: System, Scanner, Character, Boolean, Byte,

Short, Integer, Long, Float şi Double sunt clase� Aceste clase sunt stocate în pachete (biblioteci) de clase.� Un pachet este un instrument de grupare convenabilă a

claselor cu funcŃionalitate înrudită� java.lang – pachetul este importat implicit în fiecare

program Java care conŃine clase fundamentale (de bază) –d.e. System, Character, Boolean, Byte, Short, Integer, Long, Float, Double, String

Page 45: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 53

Folosirea metodelor importate, de bibliotecă

� Pentru a folosi oricare dintre clasele de bibliotecă (altele decât java.lang):� FolosiŃi întreaga cale împreună cu numele claseiarea = Math.PI * radius * radius;

sau� ImportaŃi clasasau� ImportaŃi pachetul care conŃine clasa pe care o folosiŃi

� Pentru a importa un întreg pachet folosiŃi simbolul de nume global, *

� Exemplu:� import java.util.*;� Reprezintă toate clasele dintr-un pachet

OOP3 - M. Joldoş - T.U. Cluj 54

Metode statice

public class ArrayWorks {public static double medie(int[] arr) {

double total = 0.0;for (int k=0; k!=arr.length; k++) {

total = total + arr[k];}

return total / arr.length;}

}

� În Java se pot declara metode şi variabile care să aparŃină clasei, nu obiectului. Aceasta se face prin declararea lor ca static.

� Metodele statice sunt declarate inserând cuvântul cheie “static” imediat după specificatorul de vizibilitate (public, private sau protected).

OOP3 - M. Joldoş - T.U. Cluj 55

Metodele statice� Metodele statice sunt apelate folosind numele clasei în locul unei

referinŃe la un obiect.double myArray = {1.1, 2.2, 3.3};...double media = ArrayStuff.medie(myArray);� Exemple metode statice utile: in clasa Java standard, numită Math.public class Math {

public static double abs(double d) {...}public static int abs(int k) {...}public static double pow(double b, double exp) {...}public static double random() {...}public static int round(float f) {...}public static long round(double d) {...}…

}

OOP3 - M. Joldoş - T.U. Cluj 56

RestricŃii asupra metodelor statice� Corpul unei metode statice nu poate referi nici o variabilă

instanŃă (nestatică).� Corpul unei metode statice nu poate invoca nici o metodă

ne-statică.� Dar, corpul unei metode statice poate instanŃia obiecte.public class go {

public static void main(String[] args) {

Greeting greeting = new Greeting();

}}

� AplicaŃiile Java de sine stătătoare, trebuie să-şi iniŃieze execuŃia dintr-o metodă statică numită întotdeauna main şi care are un singur tablou de String-uri ca parametru.

Page 46: POO all curses UTCLUJ VICAS

OOP3 - M. Joldoş - T.U. Cluj 57

Variabile statice

� Orice variabilă instanŃă poate fi declarata staticprin includerea cuvântului-cheie “static” imediat înainte de specificarea tipului săupublic class StaticStuff {

public static double staticDouble;

public static String staticString;

. . .}

� O variabilă statică :� Poate fi referită fie de clasă fie de obiect� InstanŃierea unui nou obiect de acelaşi tip nu sporeşte

numărul de variabile statice.

OOP3 - M. Joldoş - T.U. Cluj 58

Example cu variabile statice

StaticStuff s1, s2;

s1 = new StaticStuff();

s2 = new StaticStuff();

s1.staticDouble = 3.7;

System.out.println( s1.staticDouble );

System.out.println( s2.staticDouble );

s1.staticString = “abc”;

s2.staticString = “xyz”;

System.out.println( s1.staticString );

System.out.println( s2.staticString );

OOP3 - M. Joldoş - T.U. Cluj 59

De ce metode şi variabile statice?� Metodele statice sunt utile în situatii în care datele trebuie partajate

între mai multe obiecte de acelaşi tip.� Un exemplu bun de utilitate a unei metode statice este în clasa

standard Java numită Colorpublic class Color {

public static final Color black = new Color(0,0,0);public static final Color blue = new Color(0,0,255);public static final Color darkGray = new

Color(64,64,64);. . .

}� Constantele Color sunt şi static şi final => le putem compara

Color myColor;...if (myColor == Color.green) ...

OOP3 - M. Joldoş - T.U. Cluj 60

Rezumat

� Controlul execuŃiei� if, switch, while, for, do

–while� break/continue cu

etichetă� for each

� Metode: � tipuri (accessoare,

mutatoare)� intrare, ieşire� modificatori de acces� supraîncărcare

� Clase� constructori� clase instanŃiabile� creare, supraîncărcarea

constructorilor� referinŃa this

� Variabile la nivel de clasă

� Static � metode� variabile

Page 47: POO all curses UTCLUJ VICAS

OOP4 - M. Joldoş - T.U. Cluj 1

Programare orientată pe obiecte

1. Clase şi obiecte2. Tablouri

OOP4 - M. Joldoş - T.U. Cluj 2

Metode: cum funcŃionează un apel// Autor : Fred Swartzimport javax.swing.*;public class KmToMiles {private static double convertKmToMi(double kilometri) {return kilometri * 0.621; // sunt 0.621 mile intr-un kilometru.

}public static void main(String[] args) {//... variabile localeString kmStr; // String km înainte de conversia la double.double km; // Număr of kilometri.double mi; // Număr of mile.//... IntrarekmStr = JOptionPane.showInputDialog(null, "Introduceti kilometri.");km = Double.parseDouble(kmStr);//... Calculemi = convertKmToMi(km) ; //... OutputJOptionPane.showMessageDialog(null, km + " kilometri sunt " + mi + " mile.");

}}

OOP4 - M. Joldoş - T.U. Cluj 3

Metode: cum funcŃionează un apel

� ConsideraŃi atribuirea mi = convertKmToMi(km);

� Paşii pentru procesarea acestei instrucŃiuni sunt:1. Evaluează argumentele de-la-stânga-la-dreapta2. Depune un nou cadru de stivă (stack frame) pe stiva de apeluri. SpaŃiu pentru parametri şi variabilele locale (parametrul kilometri doar, aici). Starea salvată a metodei apelante (include adresa de retur)

3. IniŃializează parametri. La evaluarea argumentelor, acestea sunt asignate parametrilor locali din metoda apelată.

4. Execută metoda.5. Revino din metodă. Memoria folosită pentru cadrul de stivă pentru metoda apelata este extrasă de pe stivă.

OOP4 - M. Joldoş - T.U. Cluj 4

Crearea obiectelor

� Java are trei mecanisme dedicate asigurării iniŃializării corespunzătoare a obiectelor:� iniŃializatori de instanŃă (numiŃi şi blocuri de iniŃializare de

instanŃă),� iniŃializatori de variabile instanŃă, şi� constructori.

� Toate cele trei mecanisme rezultă în cod executat automat la crearea unui obiect.

� La alocarea memoriei pentru un nou obiect folosind operatorul new sau metoda newInstance() a clasei Class, JVM asigură executarea codului de iniŃializare înainte de folosirea zonei alocate.

Page 48: POO all curses UTCLUJ VICAS

OOP4 - M. Joldoş - T.U. Cluj 5

Crearea obiectelor

� La invocarea operatorului new :� Se alocă memorie (se rezervă spaŃiu pentru obiect). Variabilele instanŃă sunt iniŃializate la valorilor implicite

� Se execută iniŃializarea explicită. Variabilele iniŃializate la declararea atributelor primesc valorile declarate.

� Se execută un constructor. Valorile variabilelor pot fi schimbate de constructor

� Se atribuie variabilei o referinŃă la obiect.

� Exemple:Automobil beetle = new Automobil("Volskwagen

Beetle", Color.orange, 80, 160, 10);

OOP4 - M. Joldoş - T.U. Cluj 6

Valori iniŃiale implicite pentru câmpuri

nullreferinŃă la obiect

0.0ddouble

0.0ffloat

\u0000char

0Llong

0int

(short) 0short

(byte) 0byte

falseboolean

ValoareTip

OOP4 - M. Joldoş - T.U. Cluj 7

IniŃializarea câmpurilor� Atribuire simplă

� Dacă putem da o valoare iniŃială unui câmp la declararea sa.� D.e.

� public static int capacity = 10; //initialize to 10 � private boolean full = false; //initialize to false

� Blocuri de iniŃializare statice� Bloc normal de cod între acolade, { } şi precedat de cuvântul cheie

static � D.e.

� static { // codul necesar iniŃializării se scrie aici}

� Folosit la iniŃializarea variabilelor la nivel de clasă� Blocurile de iniŃializare statice sunt executate în ordinea in care

apar in sursă

OOP4 - M. Joldoş - T.U. Cluj 8

IniŃializarea câmpurilor

� Alternativă la blocurile statice: metodă statică privată:

� D.e. � class Oricare { public static varType myVar = initializeClassVariable(); private static varType initializeClassVariable() { //codul de iniŃializare se pune aici}

}

Page 49: POO all curses UTCLUJ VICAS

OOP4 - M. Joldoş - T.U. Cluj 9

IniŃializarea câmpurilor

� IniŃializarea membrilor instanŃelor� Asemănătoare blocurilor statice, dar nu static� Compilatorul java copiază blocurile de iniŃializare în fiecare constructor

� D.e.{// codul pentru iniŃializare, aici

}

OOP4 - M. Joldoş - T.U. Cluj 10

IniŃializarea câmpurilor

� IniŃializarea membrilor instanŃelor� Se foloseşte o metodă final pentru iniŃializarea unei variabile instanŃă:

class Oricare { private varType myVar = initializeInstanceVariable(); protected final varType initializeInstanceVariable() { //initialization code goes here }

} � Folositoare mai ales dacă subclasele doresc să refolosească metoda de iniŃializare.

� Metoda este final deoarece apelul metodelor non final lainiŃializarea instanŃelor pot cauza probleme

OOP4 - M. Joldoş - T.U. Cluj 11

Crearea obiectelor

� La apelul unui constructor:� Se alocă spaŃiu pe heap pentru obiect� Fiecare obiect primeşte spaŃiu propriu (propria copie a variabilelor instanŃă)

� Starea obiectului este iniŃializată potrivit codului (definit de programator) clasei

� ObservaŃi că declararea unei variabile ca fiind de un tip de obiect produce o referinŃă la obiect şi nu obiectul în sine. Pentru a obŃine obiectul în sine folosiŃi new şi un constructor pentru clasă

OOP4 - M. Joldoş - T.U. Cluj 12

Crearea obiectelor

� PuteŃi combina declararea şi iniŃializareaPerson neighbor = new Person();

� exact aşa cum puteŃi face pentru tipurile primitiveint total = 25;

Page 50: POO all curses UTCLUJ VICAS

OOP4 - M. Joldoş - T.U. Cluj 13

Asignarea obiectelor şi alias-uri� SemnificaŃia asignării este diferită pentru obiecte faŃă de

tipurile primitiveint num1 = 5;

int num2 = 12;

num2 = num1; // num2 con Ńine acum 5

//---------------------------------------------Person neighbor = new Person(); // creeaz ă object1

Person friend = new Person(); // creeaz ă object2

friend = neighbor;

� La sfârşit atât friend cât şi neighbor se referă la object1 (ele sunt alias unul pentru celălalt) şi nimic nu se mai referă la object2 (acesta este inaccesibil)

OOP4 - M. Joldoş - T.U. Cluj 14

Asignarea obiectelor şi alias-uri

� Java va colecta automat reziduul (zona de memorie nefolosită) object2

OOP4 - M. Joldoş - T.U. Cluj 15

ComplexTrivial

-real: double-img: double

<<constructor>>+ComplexTrivial(r: double, i: double)<<mutator>>+aduna(cvalue: ComplexTrivial)<<mutator>>+scade(cvalue: ComplexTrivial)

O clasă "Complex" foarte simplăpublic class ComplexTrivial{

//Propriet ăŃi private double real; private double img; // Constructor care // ini Ńializeaz ă valorile public ComplexTrivial (double r, double i) { real = r; img = i; }// Define şte o metod ă pentru adunarepublic void aduna(ComplexTrivial cvalue) {

real = real + cvalue.real;img = img + cvalue.img;

}// Define şte o metod ă pentru sc ădere

public void scade(ComplexTrivial cvalue){real = real - cvalue.real;img = img - cvalue.img;

}}

Notă. Codul din prezent ări nu respect ă în totalitate stilul recomandat din lips ă de spa Ńiu. Codul scris de Dvs. TREBUIE s ă respecte regulile de stil.

OOP4 - M. Joldoş - T.U. Cluj 16

O clasă "comutator" simplă// Un comutator on/off simplu (ne ataşat de// nimic).class ComutatorSimplu { // Comută pe închis. public void inchideComutator(){

System.out.println("Inchidecomutatorul");seteazaInchis(true);

} // Comută pe deschis. public void deschideComutator(){

System.out.println(" Deschide comutatorul"); seteazaInchis(false);

} // Raportează dacă comutatorul este închis // sau nu. public boolean esteComutatorulInchis (){ return obtineStareInchis();

}

// Returnează starea comutatoruluiprivate boolean obtineStareInchis(){ return inchis; } // Seteaza starea comutatorului. private void seteazăInchis(boolean o){inchis = o;

} // Daca comutatorul este inchis sau nu// true inseamna inchis, fals inseamnă// deschis. private boolean inchis = false;

}

� Obs. javadoc NU va genera o documentaŃie corespunzătoarepentru acest mod de comentare

Page 51: POO all curses UTCLUJ VICAS

OOP4 - M. Joldoş - T.U. Cluj 17

Un joc Tic Tac Toepublic class TicTacToe{// Variabile instanŃă/* tablou bidimensional de caractere pentru

tabla*/private char[][] tabla;

/** Constructor – crează o tablă în care fiecare pătrat conŃine un caracter subliniere '_'.

*/public TicTacToe(){tabla = new char[3][3];for (int rind = 0; rind < 3; rind ++){for (int col = 0; col < 3; col++){tabla[rind][col] = '_';

} // sfârşit bucla interioară} // sfârşit bucla exterioară

}

/** Pune caracterul c pe poziŃia [rind][col] a * tablei de joc dacă rind, col şi c sunt valide* şi pătratului de la [rind][col] nu i-a fost * atribuită deja o valoare ( alta decât valoarea * implicită, '_').* @param rind rindul de pe tabla* @param col coloana de pe tabla* @param c caracter folosit la marcare* @return true dacă reuşeşte, alfel false*/public boolean set(int rind, int col, char c){if (rind >= 3 || rind < 0) return false;if (col >= 3 || col < 0) return false; if (tabla[rind][col] != '_')return false;if ( !(c == 'X' || c == 'O'))return false;// asserŃiune: rind, col, c sunt validetabla[rind][col] = c;return true;

} OOP4 - M. Joldoş - T.U. Cluj 18

Un joc Tic Tac Toe (continuare)/*** @return caracterul din poziŃia [rind][col] de pe tabla.* @param rind rindul de pe tabla* @param col coloana de pe tabla*/public char get(int rind, int col){return tabla[rind][col];

} /** Tipăreşte starea tablei, d.e.* _ _ _* _ X O* O _ X*/public void print(){for (int rind = 0; rind < 3; rind ++){for (int col = 0; col < 3; col++){System.out.print(tabla[rind][col] + " ");} // sfârşit bucla interioarăSystem.out.println();} // sfârşit bucla exterioară }}

ExerciŃii:

� completaŃi jocul pentru al face jucabil (poate mai definiŃi clase?)

� modificaŃi clasa astfel încât să permită dimensiuni mai mari ale tablei de joc

OOP4 - M. Joldoş - T.U. Cluj 19

Exemplu de program: Jocul Hammurabi

� Un joc care simulează funcŃionarea unei societăŃi bazate pe agricultură, primitive.

� Scop. Utilizatorul, care tocmai a devenit conducătorul unui regat, vrea să-şi rezerve locul în istorie prin faptul că are cea mai mare populaŃie de Ńărani. Simularea Ńine timp de cinci ani sau până când toŃi au murit de foame.

� Grânele sunt resursa de bază. În fiecare an, conducătorul este întrebat cum să folosească stocul de grâne.� Câte chintale să fie folosite pentru a hrăni populaŃia.� Câte chintale să se folosească ca sămânŃă pentru recolta anului

viitor. � Grâul care mai rămâne este păstrat ca rezervă în caz că anul viitor

aduce o recoltă proastă.

OOP4 - M. Joldoş - T.U. Cluj 20

Exemplu de program: Jocul Hammurabi

� CondiŃii iniŃiale. � Programul trebuie să creeze un Regat cu următoarele valori: o zonă

de 600 ha, o populaŃie de 100 şi cu 1400 chintale de grâu din recolta precedentă.

� Reguli pentru alimente şi populaŃie� Fiecare persoană necesită un minimum de 6 chintale de grâu pe an

pentru a supravieŃui.� Înfometarea. Dacă conducătorul nu alocă destulă mâncare pentru

toŃi, unii vor muri de foame. PopulaŃia se va reduce cu numărul celor decedaŃi.

� Apar imigranŃi dacă e belşug. Dacă oamenii primesc mai mult de 6 chintale pe persoană, vor fi atraşi imigranŃi din regatele învecinate ceea ce cauzează o creştere a populaŃiei.

� Formula. Această idee simplificată asupra mărimii populaŃiei se poate calcula simplu prin împărŃirea cantităŃii totale de alimente la cantitatea necesara pe persoană.

populatiaMea = griuConsum/GRIU_NECESAR_UNEI_PERSOANE

Page 52: POO all curses UTCLUJ VICAS

OOP4 - M. Joldoş - T.U. Cluj 21

Exemplu de program: Jocul Hammurabi� Agricultura

� SămânŃa pentru plantare. Nu se poate folosi tot grâul pentru consum. O parte trebuie folosită pentru însămânŃarea recoltei anului viitor. E nevoie 0.9 chintale pentru fiecare hectar. Pentru tot e nevoie de 0.9 * suprafaŃa.

� Recolta. Exista variaŃii ale vremii de la un an la altul. Recolta variază între 0.9 şi 2.4 chintale pe hectar cultivat. Acest număr se generează în fiecare an.

� Principiu de proiectare: Separarea responsabilităŃilor – scopul fiecărei clase este diferit.� Unul dintre principalele scopuri ale separării unui program în clase diferite este să se grupeze datele şi metodele care Ńin una de alta şi să nu se amestece diferitele responsabilităŃi ale claselor.

OOP4 - M. Joldoş - T.U. Cluj 22

// Author : Fred Swartzimport javax.swing.*;public class Hammurabi {

public static void main(String[] args) {//... IniŃializareRegat samaria = new Regat(); // Create a new Regat

//... Execută simularea timp de 5 ani sau până când mor toŃi de foame.while (samaria.ceAn() <= 5) {

//... Afişează starea regatului la începutul fiecărui an.JOptionPane.showMessageDialog(null, samaria.toString());//DEFACUT: Întreabă conducătorul cât să se dea oamenilor.int griuConsum = 0; // Substitut temporar pentru intrebare.//.. Întreabă conducătorul cât să se reŃină pentru sămânŃă.String plantStr = JOptionPane.showInputDialog(null,"Gloriosule Conductor, câte chintale din griul ramas "+ (samaria.citGriu()-griuConsum) + " sa fie plantate?");

int saminta = Integer.parseInt(plantStr); //... DEFACUT: Verifică dacă este destul grâu pentru această cerere

// si dacă este necesar intreabă din nou//... Actualizează grâul şi populatia acestui Regat.samaria.simuleazaUnAn(griuConsum, saminta);

} //... Arată starea finală.

JOptionPane.showMessageDialog(null, "În final " + samaria.toString());}

}

OOP4 - M. Joldoş - T.U. Cluj 23

Exemplu de program: Jocul Hammurabi. Clasa Regat

// Author : Fred Swartzclass Regat {private final static float MIN_GRIU_PENTRU_SUPRAVIETUIRE = (float)0.8;private final static float MAX_TEREN_CULTIVABIL_PER_PERSOANA = (float)6.0;private final static float SAMINTA_NECESARA_PER_HA = (float)0.9;private float griulMeu = 1400; // Chintale de grâu în stoc.private int suprafataMea = 600; // SuprafaŃa Regatului în hectare. Obs.

// suprafataMea nu este folosita deocamdată // dar va fi dacă adăugaŃi verificarea cantităŃii totale

// de pământ care poate fi cultivat.private int anulMeu = 0; // Ani de la fondarea Regatului.private float recoltaMea = 0; // Ultima recoltă în chintale.public float citGriu() { return griulMeu; }public int ceAn() { return anulMeu; }public String toString() {// DEFACUT: Nu uitaŃi să adăugaŃi şi aici populaŃiareturn "Starea Regatului în anul " + anulMeu + ", ultima recolta = " +

recoltaMea + ", total grine = " + griulMeu;}

OOP4 - M. Joldoş - T.U. Cluj 24

Exemplu de program: Jocul Hammurabi. Clasa Regat (continuare)

public void simuleazaUnAn(float griuConsum, float saminta){

//DEFACUT: Trebuie calculata populaŃia pe baza grânelor. //... Redu stocul de grâu cu cantitatea folosită ca aliment şi ca sămânŃă

griulMeu = griulMeu - griuConsum - saminta;//... CalculaŃi noua recoltă// 1. Câte hectare pot fi plantate cu saminta.

// 2. Recolta la hectar este variabilă (0.9-2.4)// 3. Recolta este rezultat pe hectar * suprafata plantată.float hectarePlantate = saminta / SAMINTA_NECESARA_PER_HA;// DEFACUT: VerificaŃi că sunt destui oameni şi este destul pământ

// pentru a cultiva acel număr de hectare.float recoltaLaHectar = (float)(0.9 + 1.5 * Math.random());recoltaMea = recoltaLaHectar * hectarePlantate;//... Calculează noua cantitate de grâu din stoc.griulMeu += recoltaMea; // Noua cantitate de grâu din stocanulMeu++; // A mai trecut un an.

}// DEFACUT: de verificat potrivirea tipurilor de variabile (float, int, etc) // cu modul în care sunt folosite

}

Page 53: POO all curses UTCLUJ VICAS

OOP4 - M. Joldoş - T.U. Cluj 25

Exemplu de program: Jocul Hamurabi. Temă în continuare

� Extensii suplimentare:� Vânzarea şi cumpărarea de teren. Se poate cumpăra pământ de la

regatele învecinate (şi li se poate vinde) pentru 9 chintale pe hectar. Planul anual ar trebui să cuprindă şi cât pământ să se cumpere/vândă pe lângA alocarea mâncării şi a seminŃei. Permiterea adăugării de pământ este singura cale ca populaŃia să crească cu adevărat.

� Limitări la cultivare. Cantitatea cultivabilă de un Ńăran trebuie limitată la 6 hectare. dacă scade populaŃia, s-ar putea să nu se mai cultive toată suprafaŃa.

� Revolta. Dacă mai mult de 45% din populaŃie moare de foame, apare revolta şi conducător este alungat – jocul se termină

� SoldaŃi. Pot juca un rol important, dar Dvs. decideŃi ce anume (d.e. înăbuşe revolte, ocupă teren etc.). Dar poate trebuie alimentaŃi mai bine decât Ńăranii.

� FluctuaŃii aleatoare suplimentare� Şobolani. În fiecare an, şobolanii mănâncă între 0-10% din grâul pe care

îl aveŃi. � Ciuma. Există o şansă de 15% pentru izbucnirea unei ciume în fiecare an.

Dacă se întâmplă, moare o jumătate din populaŃie.OOP4 - M. Joldoş - T.U. Cluj 26

Sugestii pentru proiectarea claselor� PăstraŃi private datele întotdeauna

� Schimbările în reprezentarea datelor nu vor afecta utilizatorii claselor; erorile sunt mai uşor de detectat

� IniŃializaŃi datele întotdeauna� Java nu va iniŃializa variabilele locale, dar va iniŃializa variabilele

instanŃa ale obiectelor. Nu vă bazaŃi pe valorile implicite, ci iniŃializaŃi variabilele explicit

� Nu folosiŃi prea multe tipuri într-o clasă� ÎnlocuiŃi folosirile multiple înrudite ale tipurilor de bază cu alte clase.

Spre exemplu:

private String strada;private String oras;private String stat;private String tara;private int codPostal;

class Adresa {private String strada;private String oras;private String stat;private String tara;private int codPostal;. . .

}

OOP4 - M. Joldoş - T.U. Cluj 27

Sugestii pentru proiectarea claselor

� Nu toate câmpurile necesită accesori şi mutatori individuali� E.g. Angajat – obŃine şi setează salariul, dar nu şi data încadrării (nu se schimbă o dată creată)

� FolosiŃi o formă standard pentru definirea claselor, de exemplu� caracteristici publice (public)� caracteristici vizibile în pachet (package scope) � caracteristici private

OOP4 - M. Joldoş - T.U. Cluj 28

Sugestii pentru proiectarea claselor

� FolosiŃi o formă standard pentru definirea claselor şi, pentru fiecare secŃiune, scrieŃi în ordine� constante� constructori� metode� metode statice � variabile instanŃă� variabile statice

� De ce? Utilizatorii sunt mai interesaŃi de interfaŃa publică decât de datele private şi mai mult de metode decât de date.

Page 54: POO all curses UTCLUJ VICAS

OOP4 - M. Joldoş - T.U. Cluj 29

Sugestii pentru proiectarea claselor� DivizaŃi clasele cu prea multe responsabilităŃi, de exemplu

class PachetCarti { // nu e binepublic void PachetCarti() { . . . }public void amesteca() { . . . }public void obtineValoareaMaxima() { . . . }public void ob ŃineFelulMaxim() { . . . }public void rangulMaxim() { . . . }public void deseneaza() { . . . }

private int[] valoare;private int[] fel;private int carti;

} // crea Ńi clasa Carte!

OOP4 - M. Joldoş - T.U. Cluj 30

Sugestii pentru proiectarea claselor

� FaceŃi numele claselor şi metodelor să reflecte responsabilităŃile acestora

� O convenŃie bună este:� Numele clasei: substantiv (d.e. Comanda) sau substantiv+adjectiv (e.g. comandaUrgenta)

� Numele metodelor: verbe; accesorii încep cu "get"; mutatorii încep cu "set"

OOP4 - M. Joldoş - T.U. Cluj 31

Elemente de bază despre tablouri

� În Java, un tablou este o colecŃie indexată de date de acelaşi tip.

� Tablourile sunt utile la sortări şi la manipularea unei colecŃii de valori.

� În Java, un tablou este un tip de dată referinŃă. � Se foloseşte operatorul new pentru a aloca memorie pentru stocarea valorilor într-un tablou.precipitatii = new double [12]; //creeaz ă un tablou de m ărime 12.

� Folosim o expresie indexată pentru a ne referi la elemente individuale din colecŃie.

� Tablourile folosesc indexarea de la zero.

OOP4 - M. Joldoş - T.U. Cluj 32

Elemente de bază despre tablouri� Un tablou are o constantă publică length care conŃine

dimensiunea tabloului.� Nu confundaŃi valoarea length a unui tablou cu metoda length a unui obiect String.

� length este metodă pentru un obiect String, deci folosim sintaxa pentru metodă.String str = "acesta este un sir";

int size = str.length();

� Pe de altă parte, un tablou este un tip de dată referinŃă, nu un obiect. De aceea nu folosim apel de metodă.int size = precipitatii.length;

Page 55: POO all curses UTCLUJ VICAS

OOP4 - M. Joldoş - T.U. Cluj 33

Elemente de bază despre tablouri� Folosirea constantelor pentru declararea dimensiunilor

tablourilor nu duce întotdeauna la folosirea eficientă a spaŃiului.

� Declararea cu dimensiuni fixe poate pune două probleme:� Insuficientă capacitate pentru sarcina de îndeplinit� SpaŃiu irosit.

� Java, nu este limitat la declararea cu dimensiune fixă. � După creare însă, un tablou este o structură de lungime fixă. � Indiferent de tipul de tablou cu care se lucrează, variabila

tablou este o referinŃă la un obiect creat pe heap. � Accesul la datele din tablou se fac prin acest obiect tablou.

Obiectul tablou are o variabilă identificator unică.

OOP4 - M. Joldoş - T.U. Cluj 34

Elemente de bază despre tablouri� Codul următor cere utilizatorului dimensiunea unui tablou şi

declară un tablou de dimensiunea cerută:int size;

int[] number;

size= Integer.parseInt(JOptionPane.showInputDialog( null ,

“Marimea tabloului:"));

number = new int[size];

� Orice expresie aritmetică validă este permisă la specificarea dimensiunii unui tablou:

size = Integer.parseInt(

JOptionPane.showInputDialog(null,””));

number = new int[size*size + 2* size + 5];

� Tablourile nu sunt limitate la tipurile de date primitive

OOP4 - M. Joldoş - T.U. Cluj 35

Tablourile sunt obiecte

int[] info = new int[]{6, 10, 12, 0, 0};

int[] info = {6, 10, 12, 0, 0};

IniŃial, toŃi cei cinci int sunt 0. Aici, la doi dintre ei li se atribuie alte valori.

Operatorul new face să se aloce pe heap o zonă de memorie destul de mare pentru 5 int. Aici, lui data i se asigneazăo referinŃă la adresa din heap.

data este o variabilă referinŃă al cărei tipeste int[], însemnând “tablou de int”. În acest moment valoarea sa este null.

data[0] = 6;

data[2] = 12;

data = new int[5];

int[] data;

OOP4 - M. Joldoş - T.U. Cluj 36

ExcepŃii de depăşire a limitelor tablourilor

public class ArrayTool{public int sum(int[] data){

int sum = 0;for (int i = 0; i < data.length; i++){

sum += data[i];}return sum;

}public int sum2(int[] data){

int sum = 0;for (int i = 0; i <= data.length; i++){

sum += data[i];}return sum;

} }

Folosirea acestei comparaŃii produce aruncarea unei excepŃii ArrayIndexOutOfBoundsException

Page 56: POO all curses UTCLUJ VICAS

OOP4 - M. Joldoş - T.U. Cluj 37

int[] data;

data = new int[3];

data[0] = 5;

data[1] = 10;

Tablouri de tipuri primitive

OOP4 - M. Joldoş - T.U. Cluj 38

Tablouri de alte tipuri primitive

char[] tampon = new char[500];deschide un fi şier pentru citirewhile (mai sunt caractere în fi şier & tampon nu este plin)

tampon[i++] = caracter din fi şier

boolean[] raspunsuri = new boolean[6];. . .if (raspunsuri[0])

faCeva();

double[] temps;temps = new double[24];temps[0] = 18.5;temps[1] = 24.2;

OOP4 - M. Joldoş - T.U. Cluj 39

� Tablourile pot avea 2, 3, sau mai multe dimensiuni� La declararea unei variabile pentru un astfel de tablou, folosiŃi câte o pereche de paranteze pătrate pentru fiecare dimensiune

� Pentru tablourile bidimensionale, elementele sunt indexate [rind][coloana]

� Exemplu: char[][] tabla;

tabla = new char[3][3];

tabla[1][1] = ‘X’;

tabla[0][0] = ‘O’;

tabla[0][1] = ‘X’;

Tablouri bidimensionale

OOP4 - M. Joldoş - T.U. Cluj 40

O clasă contorpublic class Contor{ private int numar; /** * Constructor. Initializeaza

contorul la zero.*/ public Contor() {

numar = 0; } /** * @return valoarea curenta a * contorului*/ public int obtineNumar() {

return count; }

/** * Incrementeaza contorul* curenta cu unu*/ public void increment() {

numar ++; } /** * Reseteaza contorul* la zero*/public void reset() {

numar = 0;}

}

Page 57: POO all curses UTCLUJ VICAS

OOP4 - M. Joldoş - T.U. Cluj 41

Tablouri de obiecte

counters[0]=new Counter();

counters[0].increment();

counters[1]=new Counter();

Counter[] counters;

counters = new Counter[3];

OOP4 - M. Joldoş - T.U. Cluj 42

�Aşa cum putem folosi cicluri pentru a traversa tablouri de tipuri primitive, putem face şi cu tablourile de obiecte

� ExerciŃiu. ScrieŃi o metodă care:� ia un singur argument: un tablou de contoare

� returnează suma numerelor conŃinute în contoare

� mai întâi, presupuneŃi că fiecare element de tablou se referă la un contor valid

� Apoi rescrieŃi metoda astfel ca să poată prelucra tablouri în care unele /toate elementele sunt null

“Traversarea” tablourilor de obiecte

OOP4 - M. Joldoş - T.U. Cluj 43

Capcană: un tablou de caractere nu este un String

� Totuşi, un tablou de caractere nu este un obiect de clasaStringchar[] a = {'A', 'B', 'C'};

String s = a; //Ilegal!

� Un tablou de caractere poate fi convertit la un obiect de clasa String

� Un tablou de caractere este conceptual o listă de caractere şi de aceea conceptual ca un şir

� Clasa String are un constructor cu un singur parametru de tip char[]String s = new String(a);

� Obiectul s va avea aceeaşi secvenŃă de caractere ca întregul tablou a ("ABC" ), dar este o copie independentă

OOP4 - M. Joldoş - T.U. Cluj 44

Capcană: un tablou de caractere nu este un String

� Un alt constructor al String foloseşte o subgamăa tabloului de caractereString s2 = new String(a,0,2);

� Fiind dat a ca mai înainte, noul obiect şir este "AB"

� Un tablou de caractere are ceva în comun cu obiectele String

� D.e., un tablou de caractere poate fi tipărit folosindprintln

System.out.println(a);

� Dat fiind a ca mai înainte, se va tipăriABC

Page 58: POO all curses UTCLUJ VICAS

OOP4 - M. Joldoş - T.U. Cluj 45

Tablouri de tipuri primitive:� int[] info1 = { 2000, 100, 40, 60};� int[] info2 = new int[]{ 2000, 100, 40, 60};

� char[] choices1 = { 'p', 's', 'q'};

� char[] choices2 = new char[]{ 'p', 's', 'q'};

� double[] temps1 = {75.6, 99.4, 86.7};

� double[] temps2 = new double[] {75.6, 99.4, 86.7};

Prescurtări la iniŃializarea tablourilor

OOP4 - M. Joldoş - T.U. Cluj 46

Prescurtări la iniŃializarea tablourilor

Tablouri de obiecte:� Person[] people = {new Person("jo"),new Person("flo" )};� Person[] people = new Person[] {new Person("jo"),

new Person("flo")};� Point p1 = new Point(0,0);� Point[] points1 = {p1, new Point(0, 10)};� Point[] points2 = new Point[] {p1, new Point(0, 10) };

Notă: Construc Ńia sintactic ă “new type[ ]” poate fi folosită la o asignare care nu este si o declara Ńie de variabil ă

OOP4 - M. Joldoş - T.U. Cluj 47

Transmiterea tablourilor ca parametri

� Atunci când spre un obiect nu mai există nici o referinŃă, sistemul va şterge obiectul şi va disponibiliza memoria ocupată de acesta.

� Ştergerea unui obiect se numeşte dealocareamemoriei.

� Procesul de dealocare a memoriei se numeşte colectarea reziduurilor. Aceasta se face automat în Java.

� La transmiterea ca parametru a unui tablou spre o metodă, se transmite doar o referinŃă spre tabloul respectiv

� Nu se creează o copie a tabloului în metodă.

OOP4 - M. Joldoş - T.U. Cluj 48

Exemplu: "baza de date" PersonDBpublic class Person{

private String nume;private int virsta;public Person(String nume, int virsta){

this.nume = nume;this. virsta = virsta;

}public Person(String nume){

this(name, 5);}public int obtineVirsta() { return virsta; }public String obtineNume() { return nume; }

}

Page 59: POO all curses UTCLUJ VICAS

OOP4 - M. Joldoş - T.U. Cluj 49

Tablouri de obiecte

Person[] people;

people = new Person[3];

people[0]=new Person(“jo”);

people[1]=new Person(“flo”);

OOP4 - M. Joldoş - T.U. Cluj 50

public class PersonDB{ private Person[] people; public PersonDB(){

people = new Person []{new Person("geta",25), new Person("lili",18),new Person("veta", 19)};

}

/** Calculeaz ă şi returneaz ă media de vârst ă */public double getVirstaMedie(){

return 0; // DIY }

/** Returneaz ă true dacă numele este în baz ă, altfel false */public boolean esteInBaza(String numeDeCautat){

return false; // DIY}

}

Exemplu: "baza de date" PersonDB

OOP4 - M. Joldoş - T.U. Cluj 51

Copierea tablourilor

� Clasa System are o metoda numită arraycopy

� Folosită la copierea eficientă a datelor între tablouri

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, intlength)

OOP4 - M. Joldoş - T.U. Cluj 52

Rezumat

� Metode: cum funcŃionează apelul

� Crearea obiectelor� Clase exemplu + ceva de făcut

� Jocul Hamurabi cu temă pentru laborator

� Sugestii pentru proiectarea claselor

� Tablouri:� Fundamente� Tablouri de tipuri primitive

� Tablouri de obiecte� Traversarea� IniŃializarea� Transmiterea ca parametri

Page 60: POO all curses UTCLUJ VICAS

OOP5 - M. Joldoş - T.U. Cluj 1

Programare orientată pe obiecte

1. InterfeŃe Java2. Pachete (packages)3. Moştenire (I)

OOP5 - M. Joldoş - T.U. Cluj 2

Nevoia de specificaŃii� Un program este asamblat dintr-o colecŃie de clase care

trebuie să "lucreze împreună" sau să "se potrivească una cu alta"� Ce înseamnă că doua clase se potrivesc una cu alta?

� Exemplu: � Un radio portabil – are nevoie de baterii pentru a funcŃiona. Ce fel

de baterii?� "Două baterii AA (R6)" – o specificaŃie� Scopurile acestei specificaŃii:

� pentru utilizator: îi spune ce componentă trebuie pusă în aparat pentru a funcŃiona

� pentru fabricantul aparatului: ce dimensiuni trebuie să aibă compartimentul bateriilor şi ce tensiune şi curent să folosească pentru alimentarea circuitelor

� pentru producătorul bateriilor: mărimea, tensiunea şi curentul pentru baterii astfel ca alŃii să le poată folosi

OOP5 - M. Joldoş - T.U. Cluj 3

SpecificaŃiile şi Java

� Limbajul şi compilatorul Java ne pot ajuta să:� Scriem specificaŃii de clase şi să � Verificăm că o clasă satisface corect (implementează)

specificaŃiile sale� Vom studia:

� construcŃia interface – ne permite să codificăm în Java informaŃia pe care o specificăm, d.e. într-o diagramă de clasă

� construcŃia extends – ne permite să codificăm o clasă prin adăugarea de metode la o clasa existentă

� construcŃia abstract class – ne permite să codificăm o clasă incompletă care poate fi încheiată (terminată) printr-o altă clasă

OOP5 - M. Joldoş - T.U. Cluj 4

Un exemplu� Doua persoane lucrează la acelaşi proiect, în acelaşi timp:

� o persoană modelează un cont bancar� o alta scrie o clasă pentru plăŃi lunare din cont

� Pentru a realiza acest lucru, cei doi trebuie să se înŃeleagă cu privire la interfaŃă, de exemplu:

/** SpecificatieContBancar specifica modul de comportare al contului bancar. */

public interface SpecificatieContBancar{

/** depune adauga bani in cont* @param suma – suma de bani de depus, un intreg nenegativ */public void depune(int suma);/** retrage scoate bani din cont daca se poate* @param suma – suma de retras, un intreg nenegativ* @return true, daca retragerea a avut succes;* return false, in caz contrar. */public boolean retrage(int suma);

}

Page 61: POO all curses UTCLUJ VICAS

OOP5 - M. Joldoş - T.U. Cluj 5

Ce este o interfaŃă?� InterfaŃa spune că, indiferent de clasa scrisa pentru a

implementa o SpecificatieContBancar , clasa respectivă trebuie să conŃină doua metode, depune şi retrage , care să se comporte aşa cum s-a precizat

� În general, o interfaŃă este un dispozitiv sau un sistem pe care entităŃi ne-înrudite îl folosesc pentru a interacŃiona. Exemple:� O telecomandă reprezintă interfaŃa dintre Dvs. şi televizor, � Limba română este o interfaŃă între două persoane care o vorbesc� Protocolul de comportament din armată reprezintă interfaŃa dintre

indivizii de diferite grade� etc.

OOP5 - M. Joldoş - T.U. Cluj 6

Ce este o interfaŃă?

� Java: o interfaŃă este un tip, aşa cum şi o clasă este un tip.� Asemănător unei clase, o interfaŃă defineşte metode. � Spre deosebire de o clasă, o interfaŃă nu implementează

niciodată metode;� În loc de aceasta, clasele care implementează interfaŃa

implementează metodele definite de interfaŃă. � O clasă poate implementa mai multe interfeŃe.

� O interfaŃă se foloseşte pentru a defini un protocol de comportament care poate fi implementat de către orice clasă de oriunde din ierarhia de clase.

OOP5 - M. Joldoş - T.U. Cluj 7

DefiniŃie. Utilitate� DefiniŃie: o interfaŃă este o colecŃie de definiŃii de metode,

fără implementări, colecŃie care are un nume.� O interfaŃă nu este o clasă, ci un set de cerinŃe pentru

clasele care doresc să se conformeze interfeŃei.� InterfeŃele sunt folositoare pentru următoarele:

� ReŃinerea asemănărilor între clase ne-înrudite fără a forŃa o relaŃie de clasă

� Declararea de metode pe care una sau mai multe clase ar trebui să le implementeze

� Dezvăluirea interfeŃei de programare a unui obiect fără ai dezvălui clasa

� Modelarea moştenirii multiple, care permite ca o clasă să aibă mai mult de o superclasă

OOP5 - M. Joldoş - T.U. Cluj 8

Definirea unei interfeŃe

� DefiniŃia unei interfeŃe are două componente: declaraŃia interfeŃei şi corpul interfeŃei� DeclaraŃia interfeŃei defineşte diferitele atribute

ale interfeŃei, cum sunt numele şi dacă ea extinde alte interfeŃe.

� Corpul interfeŃei conŃine declaraŃiile de constante şi de metode pentru interfaŃa respectivă.

Page 62: POO all curses UTCLUJ VICAS

OOP5 - M. Joldoş - T.U. Cluj 9

O clasa care referă o interfaŃă Java/** CalculatorPlatiIpoteca face plati de ipoteca */

public class CalculatorPlatiIpoteca

{

private SpecificatieContBancar contBancar; // pastreaza adresa

// unui obiect care implementeaza SpecificatieContBancar

/** Constructor CalculatorPlatiIpoteca initializeaza calculatorul.

* @param cont – adresa contului bancar in/din care se fac

* depuneri/retrageri */

public CalculatorPlatiIpoteca(SpecificatieContBancar cont)

{ contBancar = cont; }

/** faPlataIpoteca efectueaza o plata de ipoteca din contul bancar.

* @param suma – suma de platit */

public void faPlataIpoteca(int suma)

{

boolean ok = contBancar.retrage(suma);

if ( ok )

{ System.out.println("Plata efectuata: " + suma); }

else { ... error ... }

}

...

}

OOP5 - M. Joldoş - T.U. Cluj 10

O clasă care implementează o interfaŃă Java

/** ContBancar gestioneaza un singur cont bancar; cum este precizat* in antetul sau, el implementeaza SpecificatieContBancar: */public class ContBancar implements SpecificatieContBancar{

private int sold; // soldul contului/** Constructor ContBancar initializeaza contul */public ContBancar() { sold = 0; }// observati ca metodele depune si retrage au acelasi nume cu metodele// din interfata SpecificatieContBancar:public void depune(int suma) { sold = sold + suma; }public boolean retrage(int suma) {

boolean rezultat = false;if ( suma <= sold ) {

sold = sold - suma;rezultat = true;

}return rezultat;

}/** cerSold raporteaza soldul curent* @return soldul */public int cerSold() { return sold; }

}

OOP5 - M. Joldoş - T.U. Cluj 11

�Pentru a conecta cele două clase – scrieŃi o metodă de lansare cam aşa:ContBancar contulMeu = new contBancar();

CalculatorIpoteca calc = new CalculatorIpoteca(contulMeu);

. . .

calc.faPlataIpoteca(500);

OOP5 - M. Joldoş - T.U. Cluj 12

RestricŃii pentru interfeŃe

� RestricŃii referitoare la interfeŃe:� Toate metodele unei interfeŃe trebuie să fie metode de

instanŃă abstract; nu se permit metode statice.� Toate variabilele definite într-o interfaŃa trebuie să fie

static final, adică constante. � Valorile se pot stabili la compilare sau se pot calcula la

încarcarea clasei.� Variabilele pot fi de orice tip.

� Nu sunt permise blocuri de iniŃializare statice. � Fiecare iniŃializare trebuie să fie o line pentru o variabilă. � Nu sunt permise metode auxiliare, statice, pentru iniŃializare în

interfaŃă. Dacă aveŃi nevoie de ele, atunci acestea trebuie definite în afara interfeŃei.

Page 63: POO all curses UTCLUJ VICAS

OOP5 - M. Joldoş - T.U. Cluj 13

InstanŃierea

� Metodele din interfaŃă sunt întotdeauna metode ale instanŃei. � Pentru a le putea folosi, trebuie să existe un

obiect asociat care implementează interfaŃa. � Nu puteŃi instanŃia o interfaŃă direct, dar puteŃi

instanŃia o clasă care implementează interfaŃa. � ReferinŃele la un obiect se pot face via

� numele clasei, � unul dintre numele superclaselor sale sau � unul dintre numele interfeŃelor sale.

OOP5 - M. Joldoş - T.U. Cluj 14

Ce se pune într-o interfaŃă� Este considerat stil prost a scrie o interfaŃă numai cu

constante (static final). � De obicei aceşti calificatori sunt omişi. Scriem doar, d.e.:

interface MyConstants{double PI = 3.141592;double E = 1.7182818;

}

� O interfaŃă ar trebui să aibă cel puŃin o metoda abstractă. � Daca tot ce doriŃi este o colecŃie de constante, folosiŃi o

clasă obişnuită cu import static

Pot fi accesate fie ca MyConstants.PI sau doarPI de orice clasă care implementează interfaŃa

OOP5 - M. Joldoş - T.U. Cluj 15

Un alt exemplu. O "bază de date"� ProiectaŃi o clasă numită Database , care să păstreze o

colecŃie de obiecte "înregistrare" (record), fiecare având o cheie (key) unică pentru identificare

� Comportamente esenŃiale – o specificaŃie neformală:� Database păstrează o colecŃie de obiecte Record , unde fiecare

Record are un obiect Key. Restul structurii oricărei Record nu are importanŃă şi nu este cunoscut bazei de date

� Database va avea metode insert, find şi delete� Înregistrările – Record – indiferent de structura lor internă, vor

avea o metodă getKey care returnează obiectul cheie (Key) al înregistrării (Record )

� Obiectele Key vor avea o metodă equals care să compare două chei dacă sunt egale şi să returneze true sau false

OOP5 - M. Joldoş - T.U. Cluj 16

InterfeŃe pentru Record şi Key

/** Record esle un element de date care poate fi stocat intr-o baza de date */public interface Record{

/** getKey returneaza cheia care identifica in mod unic * inregistrarea* @return obiectul de tip Key din inregistrare */public Key getKey();

}/** Key reprezinta o valoare pentru identificare, o "cheie" */public interface Key{

/** equals compara pe sine cu o alta cheie, m, ca sa* determine daca sunt egale* @param m – celalalta cheie* @return true, daca aceasta cheie si m au aceeasi valoare a cheii;* returneaza false, in caz contrar */public boolean equals(Key m);

}

Page 64: POO all curses UTCLUJ VICAS

OOP5 - M. Joldoş - T.U. Cluj 17

Exemplul în BlueJ

� BlueJ demo şi discuŃie

OOP5 - M. Joldoş - T.U. Cluj 18

Diagrama de clase cu interfeŃe

Database<<class>>

+insert(r: Record): boolean+find(k: Key): Record+delete(k: Key): boolean

BankAccount<<class>>

+deposit(amount: int)+getBalance(): int+getKey(): Key

Key<<interface>>

+equals(m: Key): boolean

Record<<interface>>

+getKey(): Key

IntegerKey<<class>>

+equals(m: Key): boolean+getInt(): int

OOP5 - M. Joldoş - T.U. Cluj 19

Diagrama de sintaxă pentru declararea unei interfeŃe

OOP5 - M. Joldoş - T.U. Cluj 20

SuperinterfeŃe� Dacă este furnizată o clauză extends, atunci

interfaŃa în curs de declarare extinde fiecare dintre celelalte interfeŃe numite şi din acest motiv moşteneşte metodele şi constantele fiecăreia dintre celelalte interfeŃe numite.

� Aceste alte interfeŃe numite sunt superinterfeŃedirecte ale interfeŃei în curs de declarare.

� Orice clasă care implementează – implements -interfaŃa declarată se consideră că implementează toate interfeŃele pe care aceasta interfaŃă le extinde şi care sunt accesibile clasei. � Vom reveni asupra interfeŃelor când vom discuta

moştenirea

Page 65: POO all curses UTCLUJ VICAS

OOP5 - M. Joldoş - T.U. Cluj 21

Super/sub interfeŃe. Exemplupublic interface Colorable {

void setColor(int color); int getColor();

} public interface Paintable extends

Colorable { int MATTE = 0, GLOSSY = 1; void setFinish(int finish); int getFinish();

} class Point {

int x, y; } class ColoredPoint extends Point

implements Colorable { int color; public void setColor(int

color) { this.color = color;

} public int getColor() {

return color; }

}

class PaintedPoint extends ColoredPoint implements Paintable { int finish; public void setFinish(int finish)

{ this.finish = finish;

} public int getFinish() {

return finish; }

}

� RelaŃiile sunt astfel:� InterfaŃa Paintable este o

superinterfaŃă a clasei PaintedPoint. � InterfaŃa Colorable este o superinterfaŃă

a clasei ColoredPoint şi a claseiPaintedPoint.

� InterfaŃa Paintable este o subinterfaŃă a interfeŃei Colorable, iar Colorable este o superinterfaŃă a lui Paintable

OOP5 - M. Joldoş - T.U. Cluj 22

Super/sub interfeŃe. Exemplu (continuare)

� Diagrama de clase pentru exemplul precedent

OOP5 - M. Joldoş - T.U. Cluj 23

Cum se folosesc interfeŃele

� Nu există un singur răspuns simplu� Ca pentru orice caracteristică semantică dintr-un

limbaj de programare, nu există reguli prestabilite şi rapide referitoare la situaŃiile în care se potrivesc cel mai bine.

� Există totuşi reguli ghid şi strategii generale (altfel această caracteristică nu ar fi fost inclusă).

� Vom sugera câteva modalităŃi de utilizare tipice..

OOP5 - M. Joldoş - T.U. Cluj 24

Câteva moduri de folosire a interfeŃelor

1. Pentru a clarifica funcŃionalitatea asociată cu o anume abstractizare.

2. Pentru a abstractiza funcŃionalitatea într-o metodă şi a o generaliza (cum este cazul pointerilor la funcŃii în C – vedeŃi exemplele de la sortare).

3. Pentru a implementa callbacks, cum se face în programarea GUI

4. Pentru a scrie cod mai general, dependent de implementare, uşor de extins şi întreŃinut.

5. Pentru a simula constante globale.

Page 66: POO all curses UTCLUJ VICAS

OOP5 - M. Joldoş - T.U. Cluj 25

Clarificarea funcŃionalităŃii

� Adeseori scriem cod sa facă ceva anume. Nu va face niciodată altceva. Nu suntem preocupaŃi de extensibilitatea codului respectiv.

� Chiar şi în acest caz poate fi util să organizăm programul folosind interfeŃe. Aceasta face codul mai uşor de citit şi clarifică intenŃia autorului.

OOP5 - M. Joldoş - T.U. Cluj 26

Callbacks

� Callback-urile sunt o tehnică generală de programare în care o metodă apelează o alta metodă care, la rândul său apelează metoda apelantă (de obicei pentru a informa apelantul că a avut loc o acŃiune).

� Exemple relevante: TimerActionListeners din Swing.

OOP5 - M. Joldoş - T.U. Cluj 27

Pentru a scrie implementări mai generale

� O metodă care operează asupra unei variabile de tip interfaŃă funcŃionează automat pentru orice sub-tip al interfeŃei respective.

� Acest lucru este mult mai general decât a scrie programul ca să opereze asupra unui anumit sub-tip.

OOP5 - M. Joldoş - T.U. Cluj 28

Abstractizarea funcŃionalităŃii

� O metodă poate fi adesea făcuta mai generală prin adaptarea a ceea ce face pe baza implementării altor metode pe care le apelează.

� sort(...) este un exemplu bun. O funcŃie sort() poate sorta orice listă de articole dacă i se spune cum să compare oricare doua articole.

� Metodele numerice de rezolvare a ecuaŃiilor diferenŃiale depinde adeseori de derivarea discretă: putem face o asemenea rutină să fie generală prin specificarea independentă a tehnicii de derivate.

Page 67: POO all curses UTCLUJ VICAS

OOP5 - M. Joldoş - T.U. Cluj 29

Organizarea claselor înrudite în pachete

� Pachet (package): set de clase înrudite� Pentru a pune clase într-un pachet, trebuie scrisă o

linie de genul

package numePachet;

ca primă instrucŃiune în fişierul sursă care conŃine clasele

� Numele pachetului constă din unul sau mai mulŃi identificatori separaŃi prin puncte

OOP5 - M. Joldoş - T.U. Cluj 30

Organizarea claselor înrudite în pachete

� Spre exemplu, pentru a pune clasa Database prezentată anterior într-un pachet numit oop.examples , fişierul Database.java trebuie să înceapă astfel: package oop.examples;public class Database{

. . .

}

� Pachetul implicit nu are nume, deci nu are o specificare package

� BlueJ demo

OOP5 - M. Joldoş - T.U. Cluj 31

Organizarea claselor înrudite în pachete

IntHolderCommon Object Request Broker Architecture

org.omg.CORBA

JButtoninterfaŃa utilizator swingjava.swing

ResultSetaccesul la baze de datejava.sql

SocketNetworkingjava.net

AppletAppletsjava.applet

ColorAbstract Windowing Toolkitjava.awt

PrintScreenintrare şi ieşirejava.io

Randomutilitarejava.util

Mathsuport pentru limbajjava.lang

Exemplu de clasă

ScopPachet

OOP5 - M. Joldoş - T.U. Cluj 32

Importul pachetelor� Se poate folosi întotdeauna o clasă fără importjava.util.Scanner s = new java.util.Scanner(System.in );

� Dar e greoi să folosim nume calificate complet

� Import ne permite să folosim nume mai scurte pentru claseimport java.util.Scanner;. . .

Scanner in = new Scanner(System.in)

� Putem importa toate clasele dintr-un pachetimport java.util.*;

� Nu este nevoie să importăm java.lang � Nu este nevoie să importăm alte clase din acelaşi pachet

Page 68: POO all curses UTCLUJ VICAS

OOP5 - M. Joldoş - T.U. Cluj 33

Nume de pachete şi determinarea locului unde se află clasele

� FolosiŃi pachete pentru a evita conflictele de numejava.util.Timer vs. javax.swing.Timer

� Numele de pachete trebuie să fie neambigue

� Recomandare: începeŃi cu numele invers al domeniului, e.g.ro.utcluj.cs.jim: pentru clasele lui jim ([email protected])

OOP5 - M. Joldoş - T.U. Cluj 34

Nume de pachete şi determinarea locului unde se află clasele

� Numele căii trebuie să se potrivească cu numele pachetuluioop/examples/Database.java

� Numele căii începe cu calea spre claseexport CLASSPATH=/home/jim/lib:.set CLASSPATH=D:\Documents and

Settings\cr11\Desktop;.

� Calea spre clase conŃine directoarele de bază care pot conŃine directoare de pachet

OOP5 - M. Joldoş - T.U. Cluj 35

Directoare de bază şi subdirectoare pentru pachete

set CLASSPATH=C:\Documents and Settings\cr11\Desktop; .

Directorul de Directorul de bazăbază

Calea se Calea se potrivepotriveşşte cu te cu

numele numele pachetuluipachetului

OOP5 - M. Joldoş - T.U. Cluj 36

1) PuneŃi o linie cu numele pachetului la începutul fiecărei clase.

2) StocaŃi fişierele Java din pachet într-un director comun.

package pachetDulciuri;public class Ciocolata {

. . .

}package pachetDulciuri;public class Jeleu {

. . .

}package pachetDulciuri;public class Drops {

. . .

}

dulciuri

Ciocolata.java

Jeleu.java

Drops.java

Cum se construieşte un pachet

Page 69: POO all curses UTCLUJ VICAS

OOP5 - M. Joldoş - T.U. Cluj 37

3) CompilaŃi toate fişierele.

dulciuri

pachetDulciuri

Ciocolata.java

Jeleu.java

Drops.java Ciocolata.class

Jeleu.class

Drops.class

4) ImportaŃi pachetul după nevoi.

import dulciuri.pachetDulciuri.*;

public class ConsumatorDulciuri { . . .

Cum se construieşte un pachet

OOP5 - M. Joldoş - T.U. Cluj 38

Cum să refolosim codul?� Putem scrie clase de la început – fără a refolosi nimic (o

extremă).� Ceea ce unii programatori doresc să facă întotdeauna

� Putem găsi o clasa existentă care se potriveşte exact cerinŃelor problemei (o altă extremă).� Cel mai uşor lucru pentru programator

� Putem construi clase din clase existente bine testate şi bine documentate.� Un fel de refolosire foarte tipic, numit refolosire prin compoziŃie!

� Putem refolosi o clasă existentă prin moştenire� Necesită mai multe cunoştinŃe decât refolosirea prin compoziŃie.

OOP5 - M. Joldoş - T.U. Cluj 39

Introducere în moştenire

� Moştenirea este una din tehnicile principale ale programării orientate pe obiecte

� Folosind această tehnică:� se defineşte mai întâi o formă foarte generală de clasă şi

se compilează, apoi� se definesc versiuni mai specializate ale clasei prin

adăugarea de variabile instanŃă şi de metode

� Despre clasele specializate se spune că moştenescmetodele şi variabilele instanŃă ale clasei generale

OOP5 - M. Joldoş - T.U. Cluj 40

Introducere în moştenire� Moştenirea modelează relaŃii de tipul “este o(un)”

� Un obiect “este un” alt obiect dacă se poate comporta în acelaşi fel

� Moştenirea foloseşte asemănările şi deosebirile pentru a modela grupuri de obiecte înrudite

� Unde există moştenire, există şi o ierarhie de moştenirea claselor

Page 70: POO all curses UTCLUJ VICAS

OOP5 - M. Joldoş - T.U. Cluj 41

Introducere în moştenire

� Moştenirea este un mod de:� organizare a informaŃiei� grupare a claselor similare� modelare a asemănărilor între clase� creare a unei taxonomii de obiecte

� Vehicul este numit superclasă� sau clasă de bază sau clasă părinte

� VehiculTerestru este numit subclasă� sau clasă derivată sau clasă fiică

� Oricare clasă poate fi de ambele feluri în acelaşi timp� D.e., VehiculTerestru este superclasă pentru Camion şi

subclasă pentru Vehicul

OOP5 - M. Joldoş - T.U. Cluj 42

Introducere în moştenire� În Java se poate moşteni de la o singură superclasă

� altminteri, nu există limite pentru adâncimea sau lăŃimea ierarhiei de clase

� C++ permite unei subclase să moştenească de la mai multe superclase (lucru care are tendinŃa de a produce erori)

� În Java fiecare clasă extinde clasa Object fie direct, fie indirect

� O clasă are în mod automat toate variabilele instanŃă şi metodele clasei de bază şi poate avea şi metode suplimentare şi/sau variabile instanŃă

� Moştenirea este avantajoasă deoarece permite să se refolosească codul, fără a fi nevoie să fie copiat în definiŃiile claselor derivate

OOP5 - M. Joldoş - T.U. Cluj 43

Exemplu. O parte a ierarhiei componentelor interfeŃei utilizator Swing

JComponent

JPanel JTextComponent JLabel AbstractButton

JTextField JTextArea JToggleButton JButton

JCheckBox JRadioButton

� Superclasa JComponent are metodele getWidth , getHeight

� Clasa AbstractButton are metode pentru a seta/obŃine textul şi icoana unui buton

OOP5 - M. Joldoş - T.U. Cluj 44

O ierarhie mai simplă: ierarhia unor conturi bancare

� Ierarhia de moşteniri:

� Demo în BlueJ

BankAccount

-balance: double

<<create>>+BankAccount()<<create>>+BankAccount(initialBalance: double)+deposit(amount: double)+withdraw(amount: double)+getBalance(): double+transfer(amount: double, other: BankAccount)

CheckingAccount

-transactionCount: int-FREE_TRANSACTIONS: int = 3-TRANSACTION_FEE: double = 2.0

<<create>>+CheckingAccount(initialBalance: double)+deposit(amount: double)+withdraw(amount: double)+deductFees()

SavingsAccount

-interestRate: double

<<create>>+SavingsAccount(rate: double)+addInterest()

Page 71: POO all curses UTCLUJ VICAS

OOP5 - M. Joldoş - T.U. Cluj 45

O ierarhie mai simplă: ierarhia unor conturi bancare

� Scurtă specificaŃie� Toate conturile bancare suportă metoda getBalance –

obŃine soldul contului � Toate conturile bancare suportă metodele deposit

(depune) şi withdraw (retrage), dar implementările diferă

� Contul de cecuri (CheckingAccount ) are nevoie de o metodă pentru deducerea taxelor de prelucrare –deductFees ; contul de economii (SavingsAccount ) are nevoie de o metodă pentru adăugarea dobânzii –addInterest

OOP5 - M. Joldoş - T.U. Cluj 46

Clase derivate

� Cum un cont de economii este un cont bancar, el este definit ca o clasă derivată a clasei BankAccount� O clasă derivată se defineşte prin adăugarea de variabile şi/sau

metode la o clasă existentă� Fraza extends BaseClass trebuie adăugată în definiŃia clasei

derivate:public class SavingsAccount extends BankAccount

� Sintaxa pentru moştenire:class NumeSubclasa extends NumeSuperclasa

{ metode câmpuri de instan Ńă

}

OOP5 - M. Joldoş - T.U. Cluj 47

Componentele moştenite ale

superclasei sunt parte a subclasei

OOP5 - M. Joldoş - T.U. Cluj 48

Un exemplu: Employees

� Demo cu BlueJ

Page 72: POO all curses UTCLUJ VICAS

OOP5 - M. Joldoş - T.U. Cluj 49

Clase derivate

� La definirea unei clase derivate, ea moşteneşte variabilele instanŃă şi metodele clasei de bază pe care o extinde� Clasa Employee (angajat) defineşte variabilele instanŃă

name (nume) şi hireDate (data angajării) în definiŃia sa

� Clasa HourlyEmployee (ziler) are şi aceste variabile instanŃă, dar ele nu sunt specificate în definiŃia sa

� Clasa HourlyEmployee are variabile instanŃă suplimentare wageRate (salariu pe oră) şi hours (ore lucrate) în definiŃia sa

OOP5 - M. Joldoş - T.U. Cluj 50

Clase derivate

� Aşa cum moşteneşte variabilele clasei Employee , clasa HourlyEmployee moşteneşte şi toate metodele superclasei� Clasa HourlyEmployee moşteneşte metodele

getName , getHireDate , setName , şi setHireDate

(obŃine numele, obŃine data angajării, setează numele şi setează data angajării) din clasa Employee

� Orice obiect de clasa HourlyEmployee poate invoca una dintre aceste metode, exact ca pe oricare altă metodă

OOP5 - M. Joldoş - T.U. Cluj 51

Clase derivate (subclase)

� O clasă derivată, numită şi subclasă, este definită pornind de la o altă clasă definită deja, numită clasă de bază sau superclasă, prin adăugarea (şi/sau modificarea) de metode, variabile instanŃă şi de variabile statice� Clasa derivată moşteneşte toate metodele publice, toate variabilele

instanŃă publice şi private, precum şi toate variabilele statice publice şi private din clasa de bază

� Clasa derivată poate adăuga variabile instanŃă, variabile statice şi/sau metode

� DefiniŃiile variabilelor şi metodelor moştenite nu apar în clasa derivată� Codul este reutilizat fără a fi nevoie să fie copiat explicit, cu

excepŃia cazului în care creatorul clasei derivate nu redefineşte una sau mai multe dintre metodele clasei

OOP5 - M. Joldoş - T.U. Cluj 52

Clase părinŃi şi clase copii

� O clasă de bază este numită adesea clasă părinte� Clasa derivată se mai numeşte şi

clasă fiică (copil)

� Aceste relaŃii sunt adesea extinse astfel că o clasă este părintele unui părinte . . . al unei alte clase şi se numeşte clasă strămoş� Dacă clasa A este un strămoş al

clasei B, atunci clasa B poate fi numită clasă descendentă a clasei A

Page 73: POO all curses UTCLUJ VICAS

OOP5 - M. Joldoş - T.U. Cluj 53

Rezumat

� InterfeŃe Java� definiŃii� declarare� utilitate� restricŃii� exemple

� Pachete Java� organizarea claselor înrudite� API-uri Java

� Moştenire� Superclase� Subclase (clase derivate)

Page 74: POO all curses UTCLUJ VICAS

OOP6 - M. Joldoş - T.U. Cluj 1

Programare orientată pe obiecte

1. Moştenire (II)2. Polimorfismul2. Clasele Object şi Class

OOP6 - M. Joldoş - T.U. Cluj 2

Clase abstracte

� O metodă sau o clasă abstractă se declară folosind cuvântul cheie abstract. De exemplu

public abstract double calcPay( doublehours );

� Dintr-o clasă abstractă nu se poate instanŃia nici un obiect� Fiecare subclasă a unei clase abstracte care va fi folosită

pentru a instanŃia obiecte trebuie să ofere implementări pentru toate metodele abstracte din superclasă.

� Clasele abstracte economisesc timp, deoarece nu trebuie să scriem cod “inutil” care n-ar fi executat niciodată.

� O clasa abstractă poate moşteni metode abstracte� dintr-o interfaŃă sau � dintr-o clasă.

OOP6 - M. Joldoş - T.U. Cluj 3

ObjectCircle

Triangle

Shape

Rectangle

Exemplu: O clasă numită Shape (formă)Superclasă: conŃine metodele abstractecalculateArea(calculează suprafaŃa) şi calculatePerimeter.

Subclase: implementează metodele concrete calculteArea şi calculatePerimeter.

OOP6 - M. Joldoş - T.U. Cluj 4

Exemplu: O clasă numită Shape

DefiniŃia superclasei.ObservaŃi că această clasă este declarată abstract.

DefiniŃii de metode abstracte. ObservaŃi că este declarat doar antetul. Aceste metode trebuie suprascrise (overridden) în toate clasele concrete.

Page 75: POO all curses UTCLUJ VICAS

OOP6 - M. Joldoş - T.U. Cluj 5

Exemplu: subclasa Circle

DefiniŃii de metode concrete.ObservaŃi că aici este declarat corpul metodei.

Clasă concretă.Clasa nu trebuie să conŃină sau să moştenească metode abstracte. Metodele abstracte moştenite trebuie suprascrise.

OOP6 - M. Joldoş - T.U. Cluj 6

Exemplu: subclasa Triangle

DefiniŃii de metode concrete. ObservaŃi că corpurile metodelor sunt diferite de cele din Circle, dar semnăturile metodelor sunt identice.

Clasă concretă. Clasa nu trebuie să conŃină sau să moştenească metode abstracte. Metodele abstracte moştenite trebuie suprascrise.

Alte subclase ale lui Shapevor suprascrie şi ele metodele abstracte area şi perimeter

OOP6 - M. Joldoş - T.U. Cluj 7

Exemplu: clasa TestShape

Apelează metodele area şi perimeter . Este apelată automat versiunea corespunzătoare a fiecărei metode pentru fiecare obiect.

Creează obiecte ale subclaselor folosind referinŃe la superclasă.

OOP6 - M. Joldoş - T.U. Cluj 8

Variabile instanŃă� Ca şablon general, subclasele:

� Moştenesc capabilităŃile public (metode)� Moştenesc proprietăŃile private (variabile instanŃă)

dar nu au acces la ele� Moştenesc variabilele protected şi le pot accesa

� O variabila declarată protected de o superclasă devine parte a moştenirii� variabila devine disponibilă pentru subclase, care o pot

accesa ca şi cum ar fi proprie� spre deosebire de aceasta, dacă o variabilă instanŃă

este declarată private într-o superclasă, subclasele nu vor avea acces la ea� superclasa poate totuşi oferi acces protejat la variabilele

instanŃă private via metode accesoare şi mutatoare

Page 76: POO all curses UTCLUJ VICAS

OOP6 - M. Joldoş - T.U. Cluj 9 OOP6 - M. Joldoş - T.U. Cluj 10

Variabile instanŃă protected faŃa de variabile instanŃă private

� Cum putem decide între private şi protected ?� folosiŃi private dacă doriŃi ca o variabilă

instanŃă să fie încapsulată de către superclasă� d.e., uşile, ferestrele, bujiile unei maşini

� folosiŃi protected dacă doriŃi ca variabila instanŃă să fie accesibilă subclaselor pentru a o modifica (şi nu doriŃi să faceŃi variabila mai general accesibilă prin metode accesoare/mutatoare)

� d.e., motorul unei maşini

OOP6 - M. Joldoş - T.U. Cluj 11

protected , Exemplupublic class Vehicle1 {

protected String make;protected String model ;public Vehicle1() { make = ""; model = "";}public String toString() {

return "Make: " + make + " Model: " + model;}public String getMake(){ return make;}public String getModel() { return model;}

}public class Car1 extends Vehicle1 {

private double price;public Car1() { price = 0.0; } public String toString() {

return "Make: " + make + " Model: " + model+ " Price: " + price;

} public double getPrice(){ return price; }

}

Vehicle1

#make: String#model: String

+Vehicle1()+toString(): String+getMake(): String+getModel(): String

Car1

-price: double

+getPrice(): double+toString(): STring

OOP6 - M. Joldoş - T.U. Cluj 12

Suprascrierea unei definiŃii de metodă

� Deşi o clasă derivată moşteneşte metode din clasa de bază, ea poate să le modifice – să le suprascrie dacă este necesar� Pentru a suprascrie o definiŃie de metodă, se pune pur şi simplu o

definiŃie nouă în definiŃia clasei, exact ca pentru orice altă metodă adăugată clasei derivate

� De obicei, tipul returnat nu poate fi schimbat la suprascrierea unei metode

� Totuşi, dacă tipul este un tip clasă, atunci tipul returnat poate fi schimbat la acela al oricărei clase descendente al tipului returnat

� Acest lucru se cunoaşte sub numele de tip returnat covariant � Tipurile returnate covariant sunt introduse în Java 5.0; ele nu sunt

permise în versiuni anterioare de Java

Page 77: POO all curses UTCLUJ VICAS

OOP6 - M. Joldoş - T.U. Cluj 13

Tipul returnat covariant

� Fiind dată următoarea clasă de bază:public class BaseClass{ . . .

public Employee getSomeone(int someKey). . .

� Este permisă următoarea modificare a tipului returnat în Java 5.0:public class DerivedClass extends BaseClass{ . . .

public HourlyEmployee getSomeone(int someKey). . .

OOP6 - M. Joldoş - T.U. Cluj 14

Schimbarea permisiunii de acces a unei metode suprascrise

� Permisiunea de acces a unei metode suprascrise poate fi schimbată de la private în clasa de bază la public (sau alt acces mai permisiv) în clasa derivată

� Totuşi, permisiunea de acces a unei metode suprascrise nu poate fi modificată de la public în clasa de bază la o permisiune de acces mai restrictivă în clasa derivată� Adică, putem relaxa permisiunile de acces într-o clasă

derivată, nu o putem restrânge

OOP6 - M. Joldoş - T.U. Cluj 15

Schimbarea permisiunii de acces a unei metode suprascrise

� Fiind dat următorul antet de metodă într-o clasă de bază:private void doSomething()

� Următorul antet de metodă este valid într-o clasă derivată:

public void doSomething ()

� Invers (din public în privat) nu se poate� Fiind dat următorul antet de metodă într-o clasă de bază:

public void doSomething()

� Antetul de metodă următor nu este valid într-o clasă derivată:private void doSomething()

OOP6 - M. Joldoş - T.U. Cluj 16

Capcană: Suprascriere faŃa de supraîncărcare

� Nu confundaŃi suprascrierea (overriding) unei metode într-o clasă derivată cu supraîncărcarea (overloading) numelui unei metode� Când o metodă este suprascrisă, noua definiŃie de

metodă dată în clasa derivată are exact acelaşi număr şi tipuri de parametri ca în clasa de bază

� Când o metodă este într-o clasă derivată are o semnătură diferită în comparaŃie cu metoda din clasa de bază, atunci avem de-a face cu supraîncărcarea

� ObservaŃi că atunci când clasa derivată suprascrie metoda originală, ea totuşi moşteneşte şi metoda originală din clasa de bază

Page 78: POO all curses UTCLUJ VICAS

OOP6 - M. Joldoş - T.U. Cluj 17

Modificatorul final

� Dacă se pune modificatorul final în faŃa definiŃiei unei metode, atunci metoda respectivă nu poate fi redefinită într-o clasă derivată

� Dacă modificatorul final este pus în faŃa definiŃiei unei clase, atunci clasa respectivă nu mai poate fi folosită pe post de clasă de bază pentru a deriva alte clase

OOP6 - M. Joldoş - T.U. Cluj 18

Constructorul super

� O clasă derivată foloseşte un constructor al clasei de bază pentru a iniŃializa toate datele moştenite din clasa de bază� Pentru a invoca un constructor al clasei de bază, se

foloseşte o sintaxă specială:public DerivedClass(int p1, int p2, double p3)

{

super(p1, p2);

instanceVariable = p3;

}

� În exemplul de mai sus, super(p1, p2); este un apel al constructorului clasei de bază

OOP6 - M. Joldoş - T.U. Cluj 19

Constructorul super

� Un apel al unui constructor al clasei de bază nu poate folosi numele clasei respective, ci foloseşte în schimb cuvântul cheie super

� Apelul lui super trebuie să fie întotdeauna prima acŃiune efectuată în definiŃia unui constructor

� Nu se pot folosi variabile instanŃă ca argumente ale lui super

� Oare de ce acest lucru nu este permis?

OOP6 - M. Joldoş - T.U. Cluj 20

Constructorul super

� Dacă într-o clasă derivată nu este prezentă o invocare a lui super , atunci constructorul fără argumente al clasei de bază va fi apelat automat� Aceasta poate cauza o eroare dacă clasa de bază nu are

definit un constructor fără argumente

� Cum variabilele instanŃă moştenite ar trebui iniŃializate, iar menirea constructorului clasei de bază este să facă acest lucru, întotdeauna ar trebui folosit un apel explicit al lui super

Page 79: POO all curses UTCLUJ VICAS

OOP6 - M. Joldoş - T.U. Cluj 21

Constructori şi subclase

� Cuvântul cheie this este folosit pentru a invoca un alt constructor al aceleiaşi clase. Exemplu:

public class Circle extends ClosedFigure{

private int radius;public Circle(int radius){

super();this.radius = radius;

}public Circle(){

this(1); // invoca constructorul cu argumentul 1}

…}

OOP6 - M. Joldoş - T.U. Cluj 22

Accesul la o metodă redefinită din clasa de bază

� În definiŃia unei metode dintr-o clasă derivată, versiunea suprascrisă a unei metode a clasei de bază poate totuşi fi invocată� Pur şi simplu prefixaŃi numele metodei cu super şi un punctpublic String toString(){

return (super.toString() + "$" + wageRate);}

� Cu toate acestea, la folosirea unui obiect al clasei derivate în afara definiŃiei clasei, nu există nici o cale de invocare a versiunii unei metode suprascrise din clasa sa de bază

OOP6 - M. Joldoş - T.U. Cluj 23

Nu puteŃi folosi mai mulŃi super

� super poate fi folosit pentru a invoca o metodă doar din-tr-un părinte (strămoş direct)� Repetarea lui super nu va invoca o metodă din vreo altă clasă

strămoş

� Spre exemplu, dacă clasa Employee ar fi fost derivată din clasa Person , iar clasa HourlyEmployee ar fi fost derivată din clasa Employee , nu ar fi fost posibil să invocăm metoda toString a clasei Person dintr-o metodă a clasei HourlyEmployee

super.super.toString() // ILEGAL!

OOP6 - M. Joldoş - T.U. Cluj 24

Constructorul this

� În definiŃia unui constructor pentru o clasă, thispoate fi folosit ca nume pentru invocarea unui alt constructor din aceeaşi clasă� Se aplică aceleaşi restricŃii de folosire ca pentru super

şi pentru this

� Daca este necesar să fie apelat atât super cât şi this , trebuie efectuat mai întâi apelul care foloseşte this , iar apoi constructorul invocat cu this trebuie să invoce super ca primă acŃiune a sa

Page 80: POO all curses UTCLUJ VICAS

OOP6 - M. Joldoş - T.U. Cluj 25

Constructorul this

� Adesea, un constructor fără argumente foloseşte this pentru a invoca un constructor cu valori explicite� Constructor fără argumente (invocă un constructor cu

valori explicite folosind this şi argumente implicite):public ClassName(){

this(argument1, argument2);

}

� Constructor cu valori explicite (primeşte valori implicite):public ClassName( type1 param1, type2 param2){

. . .

}

OOP6 - M. Joldoş - T.U. Cluj 26

Constructorul this

public HourlyEmployee()

{

this("No name", new Date(), 0, 0);

}

� Constructorul de mai sus va determina invocarea constructorului cu următorul antet:public HourlyEmployee(String theName, Date

theDate, double theWageRate, doubletheHours)

OOP6 - M. Joldoş - T.U. Cluj 27

Un obiect al unei clase derivate are mai mult de un tip

� Un obiect al unei clase derivate are tipul clasei derivate şi are şi tipul clasei de bază

� Mai general, un obiect al unei clase derivate are tipul fiecăruia dintre clasele din ascendenŃa sa� De aceea, un obiect dintr-o clasă derivată poate fi

asignat unei variabile de tipul oricărui părinte/strămoş al său

OOP6 - M. Joldoş - T.U. Cluj 28

Un obiect al unei clase derivate are mai mult de un tip

� Un obiect al unei clase derivate poate fi folosit ca parametru în locul oricăruia dintre clasele părinte/strămoş ale sale

� De fapt, un obiect dintr-o clasă derivată poate fi folosit în orice loc în care se poate folosi un obiect de tipurile părintelui/strămoşilor săi

� ObservaŃi, totuşi, că relaŃia nu merge şi invers� Un tip strămoş/părinte nu poate fi niciodată folosi în

locul unuia dintre tipurile derivate din el

Page 81: POO all curses UTCLUJ VICAS

OOP6 - M. Joldoş - T.U. Cluj 29

Capcană: termenii "subclasă" şi "superclasă"

� Uneori termenii subclasă şi superclasă sunt inversaŃi din greşeală� O superclasă / clasă de bază este mai generală

şi mai cuprinzătoare, dar mai puŃin complexă� O subclasă / clasă derivată este mai

specializată, mai puŃin cuprinzătoare şi mai complexă

� Pe măsură ce sunt adăugate mai multe variabile şi metode, numărul obiectelor care pot satisface definiŃia clasei devine mai restrâns

OOP6 - M. Joldoş - T.U. Cluj 30

Folosirea claselor abstracte

� O clasă abstractă contribuie la implementarea subclaselor sale concrete.

� Este folosită pentru a exploata polimorfismul. � Pentru funcŃionalitatea specificată în clasele părinte se

pot da implementări corespunzătoare fiecărei subclase concrete.

� Clasele abstracte trebuie să fie stabile.� Orice schimbare într-o clasă abstractă se propagă la

subclase şi la clienŃii lor.

� O clasă concretă poate extinde doar o singură clasă (abstractă)

OOP6 - M. Joldoş - T.U. Cluj 31

InterfeŃe, clase abstracte şi clase concrete

� O interfaŃă� se foloseşte pentru a specifica funcŃionalitatea cerută de

un client. � O clasă abstractă

� oferă o bază pe care să se construiască clase server concrete.

� O clasă concretă� completează implementarea server-ului care a fost

specificată de o interfaŃă;� furnizează obiecte la momentul execuŃiei;� nu este, în general, potrivită ca bază pentru extindere.

OOP6 - M. Joldoş - T.U. Cluj 32

Folosirea interfeŃelor

� InterfeŃele sunt abstracte prin definiŃie.� separă implementarea unui obiect de specificarea sa.� nu fixează nici un aspect al unei implementări.

� O clasă poate implementa mai mult de o interfaŃă.� InterfeŃele permit o folosire mai generalizată a

polimorfismului; instanŃe din clase relativ neînrudite pot fi tratate ca identice într-un scop anume.

� În programe, folosiŃi� interfeŃe pentru a partaja comportament comun.� moştenirea pentru a partaja cod comun.

Page 82: POO all curses UTCLUJ VICAS

OOP6 - M. Joldoş - T.U. Cluj 33

InterfeŃe, clase abstracte şi clase concrete

Depictable

«interface»

Rectangle

GeometricFigure

public boolean isIn (Location point, Depictable figure)

{Location l = figure.getLocation();Dimension d = figure.getDimension();…

}

OOP6 - M. Joldoş - T.U. Cluj 34

InterfeŃe, clase abstracte şi clase concrete

� Pot fi folosite instanŃe ale lui WordBalloon ca parametri ai lui isIn .

Depictable«interface»

Rectangle

GeometricFigure

ArtClip

WordBalloon

public boolean isIn (Location point, Depictable figure)

{Location l = figure.getLocation();Dimension d = figure.getDimension();…

}

OOP6 - M. Joldoş - T.U. Cluj 35

public class Base {protected int theInt = 100;

...public void printTheInt() {

System.out.println( theInt );}

}public class Doubler extends Base {...public void printTheInt() {

System.out.println( theInt*2 );}

}public class Tripler extends Base {

...public void printTheInt() {

System.out.println( theInt*3 );}

}public class Squarer extends Tripler {

...public void printTheInt() {

System.out.println( theInt*theInt );}

}

Exemplu de polimorfism

OOP6 - M. Joldoş - T.U. Cluj 36

Squarer

Doubler Tripler

Base

Polimorfismul subtipurilorPe măsură ce apare legarea

dinamică comportamentul (adică metodele) urmează obiectele

Base theBase;theBase = new Base();theBase.printTheInt();theBase = new Doubler();theBase.printTheInt();theBase = new Tripler();theBase.printTheInt();theBase = new Squarer();theBase.printTheInt();theBase = new Base();theBase.printTheInt();...

100

200

300

10000

100

Exemplu de polimorfism

Page 83: POO all curses UTCLUJ VICAS

OOP6 - M. Joldoş - T.U. Cluj 37

Base theBase ;theBase = new Doubler();theBase = new Squarer();theBase.printTheInt();

Polimorfism� O variabilă polimorfică poate părea a-şi schimba tipul prin

legare dinamică. � Compilatorul înŃelege întotdeauna tipul unei variabile

potrivit declaraŃiei.� Compilatorul permite o anume flexibilitate prin modul de

conformare la tip. � La execuŃie, comportamentul unui apel de metodă depinde

de tipul de obiect , nu de variabilă.� Exemplu:

OOP6 - M. Joldoş - T.U. Cluj 38

public class AView {...public double calcArea() {

return 0.0;}

}public class ARectangle extends AView {...public double calcArea() {

return getWidth() * getHeight();}

}

Sa presupunem ca AView include o metoda area , ca mai sus.

Atunci ARectangle trebuie scris ca ...

iar AOval trebuie scris ca ...

public class AOval extends AView {...public double calcArea() {

return getWidth()/2. * getHeight()/2. * Math.PI;}

}

ConsideraŃi acumpublic double coverageCost( AView v, double costPerSqUnit) {

return v.area() * costPerSqUnit;}

De ce este util polimorfismul?� Polimorfismul permite unei

superclase sa reŃină ceea ce este comun, lăsând specificitatea sa fie tratata de subclase.

OOP6 - M. Joldoş - T.U. Cluj 39

Cum se decide care este metoda de executat

1. Dacă există o metodă concreta în clasa curenta, se executa aceea.

2. În caz contrar, se verifică în superclasa directă daca există acolo o metodă; dacă da, se execută.

3. Se repetă pasul 2, verificând în sus pe ierarhie până când se găseşte o metodă concretă şi se execută.

4. Dacă nu s-a găsit nici o metodă, atunci este eroare• În Java şi C++ programul nu se compilează

OOP6 - M. Joldoş - T.U. Cluj 40

Legarea dinamică

� Apare atunci când decizia privind metoda de executat nu se poate lua decât la execuŃia programului� Este nevoie de ea atunci când:

� Variabila este declarată ca având tipul superclasei şi

� Există mai mult de o metoda polimorfică care se poate executa între tipul variabilei şi subclasele sale

Page 84: POO all curses UTCLUJ VICAS

OOP6 - M. Joldoş - T.U. Cluj 41

Moştenirea din clasa Object

� Fiecare clasă din Java extinde o alta clasă. � Dacă nu specificaŃi explicit clasa pe care clasa Dvs.

o extinde, atunci se va extinde automat clasa numită Object.

� Toate clasele în Java sunt într-o ierarhie în care clasa numita Object este rădăcina ierarhiei.

� Unele clase extind Object direct, în timp ce altele sunt subclase ale lui Object mai jos în ierarhie.

� Clasa Object este definită în java.lang

OOP6 - M. Joldoş - T.U. Cluj 42

Metode din clasa Object

� Object defineşte versiuni implicite ale următoarelor metode:� toString() – returnează un String (reprezentare "citibilă" a

obiectului)� equals(Object obj) – trebuie să fie suprascrisă pentru

egalitatea de conŃinut� hashCode() – returnează valoarea codului de dispersie pentru

obiect; valorile sunt diferite pentru obiecte diferite� getClass() – returnează un obiect de tipul Class; există un obiect

de tipul Class pentru fiecare clasă dintr-o aplicaŃie� notify(), notifyAll(), wait(), wait(long timeout),

wait(long timeout, int nanos) – folosite la multithreading� clone() – creează şi întoarce o copie a acestui obiect.

SemnificaŃie lui "copie" poate depinde de clasa obiectului. � finalize() – destinat a efectua acŃiuni de "curăŃare" înainte ca

obiectul să fie irevocabil abandonat.

OOP6 - M. Joldoş - T.U. Cluj 43

Egalitatea� Există două feluri diferite de egalitate:

� Egalitatea de identitate care înseamnă că două expresii au aceeaşi identitate. (Adică reprezintă acelaşi obiect.)

� Egalitatea de conŃinut care înseamnă că două expresii reprezintă obiecte cu aceeaşi valoare/conŃinut.

� Exemplu:AOval ov1, ov2;ov1 = new AOval(0, 0, 100, 100);ov2 = new AOval(0, 0, 100, 100);if (ov1 == ov2){ System.out.println("identity equality");}

else {System.out.println("content equality");}

� Metoda equals din Object poate fi folosită pentru a verifica egalitatea de conŃinut.

Simbolul == testează egalitatea de identitate atunci când este aplicat datelor referinŃă.

OOP6 - M. Joldoş - T.U. Cluj 44

Clasa Class

� Clasa Class este definită astfel: public final class Class extends Object

implements Serializable, …

� InstanŃele clasei Class reprezintă clase şi interfeŃe dintr-o aplicaŃie Java în curs de execuŃie.

� Un obiect de tipul Class conŃine informaŃii despre clasa a cărei instanŃe este obiectul care apelează

� Nu are constructor propriu� Obiectele Class sunt construite la execuŃie de către JVM� Există două moduri pentru a construi obiecte de acest tip:

� getClass() din clasa Object

� forName() din clasa Class (metodă statică)

Page 85: POO all curses UTCLUJ VICAS

OOP6 - M. Joldoş - T.U. Cluj 45

Clasa Class

� Metode:� public String getName()

� returnează un String care reprezintă numele entităŃii reprezentate de obiectul Class this

� entitatea poate fi: clasă, interfaŃă, tablou, tip primitiv, void� public static Class forName(String

className) throws ClassNotFoundException� returnează un obiect de tipul Class care conŃine informaŃii

despre clasa obiectului� public Class[] getClasses()

� returnează un tablou de obiecte de tip Class ; � toate clasele şi interfeŃele, membri publici ai clasei reprezentate

de acest obiect Class

OOP6 - M. Joldoş - T.U. Cluj 46

Clasa Class

� Metode (continuare)� Field[] getFields

� returnează un tablou care conŃine obiecte Field care reflectă toate câmpurile accesibile public ale clasei sau interfeŃei reprezentate de acest obiect Class

� Method[]getMethods()� returnează un tablou care conŃine obiecte Method care reflectă

toate metodele publice membre ale clasei sau interfeŃei reprezentate de acest obiect Class , inclusiv cele declarate de clasă sau interfaŃă şi cele moştenite din superclase şi superinterfeŃe.

� Constructor[]getConstructors()� returnează un tablou care conŃine obiecte Constructor care

reflectă toŃi constructorii publici ai clasei sau interfeŃei reprezentate de acest obiect Class .

OOP6 - M. Joldoş - T.U. Cluj 47

Operatorul instanceof

� Operatorul instanceof verifică dacă un obiect este de tipul dat ca al doilea argument al săuObiect instanceof NumeClasa

� Va returna true dacă Obiect este de tipul NumeClasa ; altfel va returna false

� ObservaŃi că aceasta înseamnă că va returna true dacă Obiect are tipul oricărei clase care este descendentă a lui NumeClasa

OOP6 - M. Joldoş - T.U. Cluj 48

Metoda getClass()

� Fiecare obiect moşteneşte aceeaşi metodă getClass() din clasa Object� Această metodă este marcată final , deci nu poate fi

suprascrisă� O invocare a lui getClass() pe un obiect

returnează o reprezentare numai pentru clasa care a fost folosită cu operatorul new pentru a crea obiectul� Rezultatele a oricare două asemenea invocări pot fi

comparate cu == sau != pentru a determina dacă ele reprezintă sau nu aceeaşi clasă

(obiect1.getClass() == obiect2.getClass())

Page 86: POO all curses UTCLUJ VICAS

OOP6 - M. Joldoş - T.U. Cluj 49

instanceof şi getClass()

� Atât operatorul instanceof cât şi metoda getClass() se pot folosi pentru a verifica clasa unui obiect

� Totuşi, metoda getClass() este mai exactă� Operatorul instanceof doar testează clasa unui obiect� Metoda getClass() folosită într-un test cu == or !=

testeza dacă doua obiecte au fost create din aceeaşi clasă

OOP6 - M. Joldoş - T.U. Cluj 50

Exemple� Afişarea numelui unei clase folosind un obiect de tip Classvoid printClassName(Object obj) {

System.out.println(obj + " is of class " + obj.getClass().getName());

}

� Alte exempleCircle c = new Circle(5);printClassName(c);Class c1 = c.getClass();System.out.println(c1.getName()); // tipareste "Circ le"Triangle t = new Triangle(7);printClassName(t);try {

Class c2 = Class.forName("Triangle");System.out.println(c2.getName()); // tipareste "Tria ngle"

}catch (ClassNotFoundException e) {

System.err.println("No class for \"Triangle\"" + e.getMessage());

}

OOP6 - M. Joldoş - T.U. Cluj 51

Rezumat

� Moştenire� clasă de bază,

superclasă� clasă derivată, subclasă� ierarhii� constructorii super şi

this

� accesul la variabilele instanŃă

� suprascrierea vssupraîncărcarea unei metode

� InterfeŃe, clase abstracte, clase concrete

� Polimorfism� Clasa Object

� toate moştenesc din clasa Object

� metode de suprascris

� Clasa Class� metode utile

� Operatorul instanceofvs metoda getClass()

Page 87: POO all curses UTCLUJ VICAS

OOP7 - M. Joldoş - T.U. Cluj 1

Programare orientată pe obiecte

1. Dezvoltarea aplicaŃiilor OO2. Diagrame de clase şi obiecte în UML3. AserŃiuni

OOP7 - M. Joldoş - T.U. Cluj 2

Ciclul de viaŃă al software

� Cuprinde toate activităŃile de la analiza iniŃială până când nu se mai foloseşte – e învechit

� Procesul formal pentru dezvoltarea de software� Descrie fazele procesului de dezvoltare� Oferă linii de ghidare pentru modul în care trebuie

desfăşurate fazele� Procesul de dezvoltare

� Analiză � Proiectare � Implementare � Testare � Desfăşurare sistematică (deployment)

OOP7 - M. Joldoş - T.U. Cluj 3

Analiza

� Se decide ce anume trebuie să facă proiectul

� NU se gândeşte cum îşi va îndeplini programul sarcinile

� Ce rezultă: documentul care cuprinde cerinŃele� Descrie ce va face programul o dată terminat� Manualul de utilizare: spune cum va opera

utilizatorul programul� Criterii de performanŃă

OOP7 - M. Joldoş - T.U. Cluj 4

Proiectare. Implementare

� Proiectare� Plănuim cum să implementăm sistemul� Descoperim structurile care stau la baza problemei de

rezolvat� Decidem ce clase şi ce metode sunt necesare� Ce rezultă:

� Descrierea claselor şi a metodelor� Diagrame care arată relaŃiile dintre clase

� Implementare� Scriem şi compilăm codul sursă� Codul implementează clase şi metode descoperite în

faza de proiectare� Ce rezultă: un program finalizat

OOP7 - M. Joldoş - T.U. Cluj 5

Testare. Desfăşurare sistematică

� Testare� Rulăm teste pentru a verifica faptul că

programul funcŃionează corect� Ce rezultă: un raport asupra testelor şi

rezultatelor lor

� Desfăşurare sistematică� Utilizatorii instalează programul � Utilizatorii folosesc programul în scopul în care a

fost construit

OOP7 - M. Joldoş - T.U. Cluj 6

Proiectarea orientată pe obiecte

1. Descoperim clasele2. Determinăm responsabilităŃile fiecărei clase3. Descriem relaŃiile dintre clase

Page 88: POO all curses UTCLUJ VICAS

OOP7 - M. Joldoş - T.U. Cluj 7

Unified Modeling Language (UML)

� UML este notaŃia internaŃională standard pentru analiza şi proiectarea orientată pe obiecte.

� Este definit de Object Management Group (OMG)� UML 2.0 defineşte treisprezece tipuri de diagrame,

împărŃite în trei categorii: � şase tipuri de diagrame reprezintă structura statică a aplicaŃiei; � trei reprezintă tipuri generale de comportament; � patru reprezintă diferite aspecte ale interacŃiunilor

� Diagramele de structură cuprind diagrama de clase, diagrame de obiecte, diagrama de componente, diagrama de structură compozită, diagrama de pachete şi diagrama de desfăşurare sistematică.

OOP7 - M. Joldoş - T.U. Cluj 8

Descoperirea claselor

� O clasă reprezintă un concept util� EntităŃi concrete: conturi bancare, elipse, produse� Concepte abstracte: fluxuri (streams) şi ferestre

� Găsim clasele căutând substantive în descrierea sarcinii

� Definim comportamentul fiecărei clase� Găsim metodele căutând verbe în descrierea

sarcinii

OOP7 - M. Joldoş - T.U. Cluj 9

RelaŃii între entităŃile reprezentate

� Asociere� Agregare� CompoziŃie

� DependenŃă� Generalizare� Realizare

OOP7 - M. Joldoş - T.U. Cluj 10

Profesor UniversitateLucrează pentru

Clasă

Asociere

Numele asocierii

Profesor UniversitateAngajatorAngajat

Nume de roluri

RelaŃii: Asociere

� Modelează o conexiune semantică între clase

OOP7 - M. Joldoş - T.U. Cluj 11

Folosirea asocierilor� Trei scopuri generale:

� Pentru a reprezenta o situaŃie în care un obiect de o clasă foloseşte serviciile unui alt obiect, sau ele îşi folosesc reciproc serviciile – adică un obiect îi trimite mesaje celuilalt sau îşi trimit mesaje între ele.. (În primul caz, navigabilitatea poate fi unidirecŃională; în cel de al doilea, ea trebuie să fie bidirecŃională.)

� Pentru a reprezenta agregarea sau compoziŃia – unde obiecte de o clasă sunt întregi compuşi din obiecte de cealaltă clasă ca părŃi. În acest caz, o relaŃie de tip foloseşte este implicit prezentă – întregul foloseşte părŃile pentru a-şi îndeplini funcŃia, iar părŃile pot si ele avea nevoie să folosească întregul.

� Pentru a reprezenta o situaŃie în care obiectele sunt înrudite, chiar dacă nu schimbă mesaje. Aceasta se întâmplă de obicei când cel puŃin unul dintre obiecte este folosit în esenŃă la stocare de informaŃie.

OOP7 - M. Joldoş - T.U. Cluj 12

RelaŃii: Agregare

� O formă specială de asociere care modelează relaŃia parte–întreg între un agregat (întregul) şi părŃile sale

Student OrarCurs

Întreg

Agregare

Parte

Page 89: POO all curses UTCLUJ VICAS

OOP7 - M. Joldoş - T.U. Cluj 13

Student Note

Întreg

Agregare

Parte

RelaŃii: compunere

� O formă de agregare cu posesiune puternicăşi durate de viaŃă care coincid� PărŃile nu pot supravieŃui întregului/agregatului

OOP7 - M. Joldoş - T.U. Cluj 14

Asociere: Multiplicitate şi navigare

� Multiplicitatea defineşte câte obiecte participă într-o relaŃie� Numărul de instanŃe ale unei clase în raport cu una

instanŃă a celeilalte clase� Specificat pentru fiecare capăt al asocierii

� Asocierile şi agregările sunt implicit bidirecŃionale, dar adesea este de dorit să se restrângă navigarea la o singură direcŃie� Dacă navigarea este restricŃionată, se adaugă o săgeată

pentru a indica direcŃia de navigare

OOP7 - M. Joldoş - T.U. Cluj 15

Asociere: multiplicitate

2..4

0..1

1..*

0..*

1

*

� Nespecificată

� Exact una

� Zero sau mai multe (multe, nelimitat)

� Una sau mai multe

� Zero sau una

� Gama specificată

� Game multiple, disjuncte 2, 4..6

OOP7 - M. Joldoş - T.U. Cluj 16

Student OrarCurs1 0..*

Multiplicitate

Navigare

Exemplu: multiplicitate şi navigare

OOP7 - M. Joldoş - T.U. Cluj 17

Exemple de asocieri

CompoziŃie

“parte a”

Agregare

“are o”

Motor

Automobil

Motor

Persoana

Sofer

OOP7 - M. Joldoş - T.U. Cluj 18

ObservaŃii� Teste pentru relaŃii parte-întreg adevărate

� » transitivittate: dacă “A parte a lui B” & “B part a lui C” atunci “A parte a lui C”

� “Unghia este parte a degetului, degetul este parte a mâinii; mâna este parte a extremităŃii superioare a corpului”

� O problemă a unei părŃi este o problemă a întregului� O rană la unghie este o rană a corpului

� “PoziŃiile sunt parte a sistemului electric al automobilului. Un defect al poziŃiilor este un defect al automobilului”

� Este-parte-a e diferit de� esteConŃinutÎn : camăşi, pantaloni,... --- valiza [observaŃi ca

testul de defectare nu Ńine aici: pantalonii stricaŃi nu înseamnă valiză stricată]

� esteLegatDE : valiză --- persoană (care o duce)� esteRamurăA : artera iliacă,... --- aorta� seAflaÎn : casă... --- stradă

Page 90: POO all curses UTCLUJ VICAS

OOP7 - M. Joldoş - T.U. Cluj 19

Când să folosim agregarea

� Ca regulă generală, se poate marca o asociere ca agregare, dacă sunt adevărate următoarele:� Se poate spune că

� PărŃile ‘sunt parte’ a agregatului� sau agregatul ‘este compus din’ părŃi

� Când ceva deŃine sau controlează agregatul, atunci acel ceva deŃine sau controlează părŃile

OOP7 - M. Joldoş - T.U. Cluj 20

Agregare şi compoziŃie

CompoziŃie

•Protejează integritatea configuraŃiei

•FuncŃionează ca un singur tot

•Controlul se face printr-un obiect– propagarea este în jos

Agregare

Fiecare parte poate fi membru al unui singur obiect agregat

AsociereObiectele ştiu unul despre altul astfel încât pot lucra împreună

OOP7 - M. Joldoş - T.U. Cluj 21

Client Furnizor

Pachet

PachetClient PachetFurnizor

Client Furnizor

Clasa

RelaŃie de dependenŃă

RelaŃie de dependenŃă

Componentă

RelaŃii: dependenŃă� O relaŃie între două elemente ale modelului în care o

schimbare în unul dintre elemente poate cauza o schimbare în celălalt

� RelaŃie nestructurală, de tip “foloseşte”

OOP7 - M. Joldoş - T.U. Cluj 22

RelaŃii: generalizare

� O relaŃie între clase în care o clasă partajează structura şi/sau comportamentul uneia sau mai multor clase

� Defineşte o ierarhie de abstracŃiuni în care o subclasă moşteneşte de la una sau mai multe superclase� Moştenire simplă/de la o singură clasă� Moştenire multiplă

� Generalizarea este o relaŃie de tipul “este-un-fel-de”

OOP7 - M. Joldoş - T.U. Cluj 23

Cont-sold-nume-număr

+retrage()+creeazaDovada()

ContDeCecuri

+retrage()

ContDeEconomii

+cerDobinda()+retrage()

Superclasă (părinte)

Subclase

RelaŃie de generalizare (moştenire)

Strămoş

DescendenŃi

Exemplu: Moştenirea simplă

� O clasă moşteneşte de la alta

OOP7 - M. Joldoş - T.U. Cluj 24

Componentă

InterfaŃă

Caz de utilizare Realizare de caz de utilizare

Forma prescurtată

Clasă

InterfaŃăSubsistem

InterfaŃă

Formă canonică

RelaŃii: realizare

� Un clasificator serveşte pe post de contract pe care celălalt este de acord să-l îndeplinească

� Regăsit între:� InterfeŃele şi clasificatorii care le realizează

� Cazurile de folosire (use case) şi colaborările care le realizează

Page 91: POO all curses UTCLUJ VICAS

OOP7 - M. Joldoş - T.U. Cluj 25

Vinzare

AgentVinzari Client Produs Vehicul

PersoanaJuridica PersoanaFizica Camion Tren

~vinzator ~cumparator ~articol vindut ~mijloc de livrare

Avion

Efectul schimbării cerinŃelorPresupunând că e nevoie de un nou mijloc de livrare

Schimbarea implică adăugarea unei noi subclase

OOP7 - M. Joldoş - T.U. Cluj 26

IntretineFormularDePlanificarePoate exista cel mult un obiect IntretineFormularDePlanificarepentru o sesiune utilizator.

Note (adnotări)

� Se poate adăuga o notă (adnotare) la orice element UML

� Notele se pot adăuga pentru a furniza informaŃii suplimentare în diagramă

� Este un dreptunghi cu “ureche de câine” � Nota poate fi ancorată la un element cu o linie

întreruptă

OOP7 - M. Joldoş - T.U. Cluj 27

unObiect : ClasaA{location=server}

Valori etichetate

� Sunt extensii ale proprietăŃilor sau ale anumitor atribute ale unui element UML

� Unele proprietăŃi sunt definite de UML� PersistenŃa� Localizarea (d.e., client, server)

� ProprietăŃile pot fi create de modelori UML în orice scop

ClasaPersistenta{persistence}

OOP7 - M. Joldoş - T.U. Cluj 28

Profesor CatedraMembru

Sef catedra{subset}

1..*

1

1

1

Constrângeri

� Suportă adăugarea de reguli noi sau modificarea regulilor existente

� Această notaŃie este folosită pentru a surprinde două relaŃii între obiecte de tip Profesor şi obiecte de tip Catedra, unde una dintre relaŃii este un subset al celeilalte.

� Arată cum se pot croi diagramele UML pentru a modela corect relaŃii exacte

OOP7 - M. Joldoş - T.U. Cluj 29

Cartela CRC

� Cartela CRC: descrie o clasă, responsabilităŃile şi colaboratorii săi

� Se foloseşte o cartelă pentru fiecare clasă� Alegem clasa care trebuie să fie

răspunzătoare de fiecare metodă (verb) � Scriem responsabilitatea pe cartela clasei� Indicăm ce alte clase sunt necesare pentru a

îndeplini responsabilitatea (colaboratorii)

OOP7 - M. Joldoş - T.U. Cluj 30

Cartela CRC. RelaŃii între clase

� Cartela CRC

� RelaŃii între clase� Moştenire � Agregare � DependenŃă

Page 92: POO all curses UTCLUJ VICAS

OOP7 - M. Joldoş - T.U. Cluj 31

Moştenire

� RelaŃie de tipul este-o/un� RelaŃie între o clasa mai generală (superclasă) şi

una mai specializată (subclasă) � Exemple:

� Orice cont de economii este un cont bancar� Orice cerc este o elipsă (cu lăŃime şi înălŃime egale)

� Uneori se abuzează de această relaŃie� Ar trebui să fie clasa Anvelopa o subclasă a lui Cerc ? � RelaŃia are-o ar fi mai potrivită aici

OOP7 - M. Joldoş - T.U. Cluj 32

Agregare� RelaŃie de tipul are-o/un� Obiectele unei clase conŃin referinŃe la obiectele altei clase� Folosesc variabile instanŃă

� O anvelopă are un cerc pe post de contur:

� Fiecare automobil are o anvelopă (de fapt are patru)

class Anvelopa {. . .private String catalogare;private Cerc contur;

}

class Automobil extends Vehicul{. . .private Anvelopa[] anvelope;

}

OOP7 - M. Joldoş - T.U. Cluj 33

DependenŃă

� RelaŃie de tip foloseşte� Exemplu: multe dintre aplicaŃiile noastre

depind de clasa Scanner pentru a citi intrarea

� Agregarea este o formă mai puternică de dependenŃă

� Folosim agregarea pentru a Ńine minte un alt obiect între apelurile metodelor

OOP7 - M. Joldoş - T.U. Cluj 34

Simboluri UML pentru relaŃii

DeschisăÎntrerupt DependenŃă

RombSolidAgregare

TriunghiÎntreruptImplementare de interfaŃă

TriunghiSolidMoştenire

Forma vârfului

Stil de linie

SimbolRelaŃie

OOP7 - M. Joldoş - T.U. Cluj 35

Agregare şi asociere

� Asocierea: o formă mai generală de relaŃie între clase

� Se foloseşte de timpuriu în faza de proiectare� O clasă este asociată cu o alta dacă putem naviga

de la obiectele unei clase la obiectele celeilalte clase

� Fiind dat un obiect a Banca , putem naviga la obiecte Client

Banca Clientserveste

OOP7 - M. Joldoş - T.U. Cluj 36

Diagramă de clase� Reprezintă un set de clase, interfeŃe, colaborări şi alte

relaŃii� Reflectă proiectul static al unui sistem� Poate genera confuzii dacă este folosit pentru a explica

dinamica sistemului; folosiŃi în loc diagramele de obiecte care sunt mai puŃin abstracte

Shape

-origin: Point

+move(p: Point)+resize(s: Scale)+display()#invalidateRegion()

vizibilitate

atribute

nume

semnătură

operaŃii

vizibilitate

pentru obiecte: subliniatpentru clase abstracte: cursiv

Page 93: POO all curses UTCLUJ VICAS

OOP7 - M. Joldoş - T.U. Cluj 37

Diagrame de obiecte

� Reprezintă un set de obiecte (instanŃe de clase) şi relaŃiile dintre acestea.

� Un instantaneu static al unei vederi dinamice a sistemului.

� Reprezintă cazuri reale sau cazuri prototip.� Foarte utile înainte de dezvoltarea

diagramelor de clase.� Merită salvate ca elaborări ale diagramelor

de clase.

OOP7 - M. Joldoş - T.U. Cluj 38

Diagrame de obiecte

� Utile în explicarea de părŃi mici cu relaŃii complicate, mai ales în cazul relaŃiilor recursive

� Fiecare dreptunghi din diagrama de obiecte corespunde unei singure instanŃe.

� Numele instanŃelor (numele obiectelor) sunt subliniate în diagramele UML.

Această mică diagramă de clase arată că un departament poate conŃine multe alte subdepartamente.

OOP7 - M. Joldoş - T.U. Cluj 39

Diagrame de obiecte� Diagrama de obiecte de mai jos este o instanŃiere a diagramei

de clase, clasele fiind înlocuite de exemple concrete� Numele de clase sau instanŃe pot fi omise dacă semnificaŃia

diagramei rămâne clară.nume de clasănume de instanŃă

OOP7 - M. Joldoş - T.U. Cluj 40

Alt exemplu de diagramă de obiecte

obiectvaloare de atribut

legătură

obiect anonim

OOP7 - M. Joldoş - T.U. Cluj 41

Alt exemplu de diagramă de obiecte

OOP7 - M. Joldoş - T.U. Cluj 42

Procesul de dezvoltare în cinci paşi

� Colectăm cerinŃele� Folosim cartele CRC pentru a determina

clasele, responsabilităŃile şi colaboratorii� Folosim diagrame UML pentru a înregistra

relaŃiile dintre clase� Folosim javadoc pentru a documenta

comportamentul metodelor� Implementăm programul

Page 94: POO all curses UTCLUJ VICAS

OOP7 - M. Joldoş - T.U. Cluj 43

Reguli pentru determinarea claselor

� Între 3 şi 5 responsabilităŃi pe clasă� Nu există clase singuratice� FeriŃi-vă de multe clase mici� FeriŃi-vă de puŃine clase mari� FeriŃi-vă de “functoizi” – un functoid este de fapt o

funcŃie procedurală normală deghizată în clasă.� FeriŃi-vă de clase omnipotente

� Căutati clase care au “system” sau “controller” în nume!

� EvitaŃi arborii de moştenire adânci

OOP7 - M. Joldoş - T.U. Cluj 44

Exemplu: factură simplificată

OOP7 - M. Joldoş - T.U. Cluj 45

Exemplu: factură simplificată

� Clase care vin în minte: Factura , Rind , şi Client

� Este o idee bună să păstrăm o listă de clase candidate

� Folosim brainstorming-ul, pur şi simplu punem toate ideile de clasă în listă

� Le putem tăia pe cel inutile ulterior

OOP7 - M. Joldoş - T.U. Cluj 46

Determinarea claselor� łineŃi minte următoarele puncte:

� Clasele reprezintă mulŃimi de obiecte cu acelaşi comportament

� EntităŃile cu apariŃii multiple în descrierea problemei sunt candidaŃi buni pentru obiecte

� AflaŃi ce au în comun� ProiectaŃi clasele pentru a surprinde ce este comun

� ReprezentaŃi unele entităŃi ca obiecte, iar altele ca tipuri primitive

� Ar trebui să facem Adresa o clasă sau să folosim un String?

� Nu toate clasele pot fi descoperite în faza de analiză� Unele clase pot exista deja

OOP7 - M. Joldoş - T.U. Cluj 47

Tipărirea unei facturi – cerinŃe� Sarcina: tipărirea unei facturi� Factura: descrie preŃurile pentru un set de produse în

anumite cantităŃi� Omitem lucrurile mai complicate – aici

� Date, taxe şi codurile de factură şi de client

� Tipărim factura cu� Adresa clientului, toate rândurile, suma de plătit

� Rândul conŃine � Descriere, preŃ unitar, cantitatea comandată, preŃul total

� Pentru simplitate nu creăm interfaŃa cu utilizatorul� Programul de test: adaugă rânduri în factură şi apoi o

tipăreşte

OOP7 - M. Joldoş - T.U. Cluj 48

Tipărirea unei facturi – cartele CRC

� Descoperim clasele� Substantivele identifică

clasele posibileFacturaAdresaRândProdusDescrierePreŃCantitateTotalSuma de plătit

Page 95: POO all curses UTCLUJ VICAS

OOP7 - M. Joldoş - T.U. Cluj 49

Tipărirea unei facturi – cartele CRC� Analizăm clasele

� Clasele după un proces de eliminare

FacturaAdresaRând // Înregistreaz ă produsul şi cantitateaProdusDescriere // Câmp al clasei produsPret // Câmp al clasei produsCantitate // Nu este un atribut al unui ProdusTotal // Calculat, nu se memorează

Suma de pl ătit // Calculat ă, nu se memoreaz ă

FacturaAdresaRândProdus

OOP7 - M. Joldoş - T.U. Cluj 50

Motive pentru rejectarea unei clase candidate

Ar trebui divizată în mai multe clase, câte una pentru fiecare abstracŃiune

Clasă care acoperă câteva abstracŃiuni

Poate fi un caz de “taxomanie”Clasă cu zero sau foarte puŃine atribute (dar care moşteneşte de la părinŃi)

Poate fi o informaŃie opacă, nu un TDA, sau poate fi un TDA la care s-au omis rutinele

Clasă fără metode

Poate să nu fie o abstracŃiune propriu-zisăClasă descrisa ca “efectuează” ceva

Poate fi o subrutina, nu o clasaClasa cu o singura metodă

Poate fi o subrutina, nu o clasaClasa cu nume verb (infinitiv sauimperativ)

MotivSemnal

OOP7 - M. Joldoş - T.U. Cluj 51

Cartelele CRC pentru tipărirea unei facturi

� Atât Factura cât şi Adresa trebuie să se poată autoformata – responsabilităŃi: � Factura formatează factura şi � Adresa formatează adresa

� Adăugăm colaboratori pe cartela facturii: Adresa şi Rind

� Pentru cartela Produs – responsabilităŃi: obŃine descrierea, obŃine preŃul unitar

� Pentru cartela CRC Rind – responsabilităŃi: formatează articolul, obŃine preŃul total

OOP7 - M. Joldoş - T.U. Cluj 52

Cartelele CRC pentru tipărirea unei facturi

� Factura trebuie populată cu produse şi cantităŃi:

OOP7 - M. Joldoş - T.U. Cluj 53

Tipărirea unei facturi – diagrama UML

Factura Adresa

Produs Rind

OOP7 - M. Joldoş - T.U. Cluj 54

Instrumente pentru realizarea diagramelor UML

� ArgoUML: � http://argouml.tigris.org� rulează pe orice platformă Java

� StarUML� http://staruml.sourceforge.net/en/� proiect "open source"

� Poseidon for UML Community Edition� http://gentleware.com/downloadcenter.0.html

� Multe produse comerciale

Page 96: POO all curses UTCLUJ VICAS

OOP7 - M. Joldoş - T.U. Cluj 55

Tipuri de specificaŃii

� Diagrame de clase� Diagrame de obiecte� Diagrame de activităŃi (diagrame de curgere

a controlului)� AserŃiuni (precondiŃii, postcondiŃii,

invarianŃi)� Altele

� ReŃineŃi că primele trei sunt specificaŃii incomplete

OOP7 - M. Joldoş - T.U. Cluj 56

Specificarea claselor� O specificaŃie software indică sarcina (sau un

aspect al sarcinii) care se presupune a fi efectuată la execuŃia software respectiv

� O specificaŃie de clasă defineşte semantica (comportamentul) unei clase prin:� invariant de clasă care descrie ceea ce este întotdeauna

adevărat pentru obiectele clasei.� specificaŃii pentru fiecare dintre metodele clasei.

� Fiecare specificaŃie de metodă constă din� o precondiŃie (opŃional),� o clauză modifică (opŃional), şi� o postcondiŃie.

OOP7 - M. Joldoş - T.U. Cluj 57

Specificarea metodelor

� O precondiŃie declară condiŃiile care sunt necesare pentru ca metoda să se execute în mod corespunzător

� O clauză modifică reprezintă o listă de obiecte care ar putea fi modificate prin execuŃia metodei.

� O postcondiŃie declară ce este adevărat atunci când metoda şi-a finalizat execuŃia

OOP7 - M. Joldoş - T.U. Cluj 58

AserŃiune� O aserŃiune este o declaraŃie a unui fapt care este

presupus adevărat relativ la o locaŃie/locaŃii din cod. Exemplu

// assert: str este String si str.length > 2char firstChar, secondChar, bigChar;firstChar = str.charAt(0);secondChar = str.charAt(1);if (firstChar > secondChar) {

bigChar = firstChar;} else {

bigChar = secondChar;}/* assert:

str.length > 2and (str.charAt(0) > str.charAt(1)

implies bigChar == str.charAt(0))and (str.charAt(0) ≤ str.charAt(1)

implies bigChar == str.charAt(1)) */

OOP7 - M. Joldoş - T.U. Cluj 59

.

Notarea aserŃiunilor

� AserŃiunile sunt bazate pe logică şi anumite notaŃii din program (adică referinŃe la variabile şi, posibil, apeluri de metode non-void).

� AserŃiunile NU trebuie să conŃină verbe de acŃiune� Operatori logici

• not SubAssertion1 – sub-aserŃiunea trebuie să fie falsă.• SubAssertion1 and SubAssertion2 – ambele sub-

aserŃiuni trebuie să fie adevărate.• SubAssertion1 or SubAssertion2 – una sau amândouă

sub-aserŃiunile sunt adevărate.• SubAssertion1 implies SubAssertion2 – când prima

sub-aserŃiune este adevărată şi cea de a doua trebuie să fie adevărată

OOP7 - M. Joldoş - T.U. Cluj 60

Notarea aserŃiunilor

� Altă notaŃie logică, cuantificarea, permite exprimarea aserŃiunilor referitoare la structuri de date.

� Cuantificarea universală� forAll (tip var : condiŃieLimită | SubAserŃiune )� Exemplu:

forAll (Integer j : 0≤j≤2 | arr1[j] > 0 )

semnificaŃie: arr1[0] > 0 and arr1[1] > 0 and arr1[2] > 0

Page 97: POO all curses UTCLUJ VICAS

OOP7 - M. Joldoş - T.U. Cluj 61

Notarea aserŃiunilor

� Cuantificarea existenŃială� exists (tip var : condiŃieLimită | SubAserŃiune )� Exemplu:

exists (Integer j : 0≤j≤2 | arr1[j] == 5 )

semnificaŃie: arr1[0] ==5 or arr1[1] == 5 or arr1[2] == 5

OOP7 - M. Joldoş - T.U. Cluj 62

Exemple de cuantificări

� Fie două tablouri de double: a1 şi a2 şi a1.length == a2.length == 4forAll (Integer r : 0 ≤ r ≤ 3 | a1[r] < a1[r+1] )forAll (Integer w : 0 ≤ w ≤ 3 | a1[w] == a2[w] )exists (Integer k : 0 ≤ k ≤ 3

| a1[k] == 22 and a2[k] == 22 )exists (Integer k : 0 ≤ k ≤ 3

| ( a1[k] < 0 and forAll (Integer j : k < j ≤ 3 | a2[k] == a1[j]) ) )

forAll (j,k : 0 ≤ j,k ≤ 3 and j != k | a1[j] != a2[k] )

OOP7 - M. Joldoş - T.U. Cluj 63

Unde se pun aserŃiunile

� Locuri posibile� Invariantul clasei� PostcondiŃia metodei� PrecondiŃia metodei� Invariantul de buclă

OOP7 - M. Joldoş - T.U. Cluj 64

Exemple de aserŃiuni/** invariant de clasă

distanceInMiles > 0 and timeInSeconds > 0 */public class LapTime {

private double distanceInMiles, timeInSeconds;

/** pre: d > 0 and t > 0 post: distanceInMiles == d and timeInSeconds == t */

public LapTime(double d, double t) {distanceInMiles = d;timeInSeconds = t;

}

/** post: distanceInMiles == 60and timeInSeconds == 3600 */

public void setTo60MPH() {distanceInMiles = 60;timeInSeconds = 3600;

}}

OOP7 - M. Joldoş - T.U. Cluj 65

NotaŃii speciale pentru postcondiŃii� Valoare returnată (rezultat)

// Within LapTime class/** post: result == distanceInMiles / (timeInSeconds* 3600) */

public double milesPerHour() {double velocity;velocity = distanceInMiles/(timeInSeconds*60*60);return velocity

}

� Valoare anterioară (@pre)// Within LapTime class/** post: distanceInMiles == distanceInMiles @pre * 2 */public void doubleTheMileage() {

distanceInMiles = distanceInMiles * 2;}

OOP7 - M. Joldoş - T.U. Cluj 66

Proiectarea prin contract

� Apelantul metodei garantează...� precondiŃia & invariantul clasei (la momentul

apelului metodei)

� Metodei i se cere să asigure...� postcondiŃia & invariantul clasei (la momentul

revenirii din metodă)

� Anexă: o clauză "modifică" poate stipula ce modificări sunt permise

Page 98: POO all curses UTCLUJ VICAS

OOP7 - M. Joldoş - T.U. Cluj 67

Legături utile� OMG UML Resource Pages

� http://www.uml.org� IBM UML Resource Center

� http://www-306.ibm.com/software/rational/uml/� Practical UML: A Hands on introduction for developers

� http://bdn.borland.com/article/0,1410,31863,00.html� Robert Martin: UML Class Diagrams for Java Programmers

� http://www.phptr.com/articles/article.asp?p=336264&seqNum=2&rl=1� UML by Examples

� http://www.geocities.com/siliconvalley/network/1582/uml-example.htm� Holub Associates: UML Reference Card

� http://www.holub.com/goodies/uml� Visual Case Tool - UML Tutorial

� http://www.visualcase.com/tutorials/class-diagram.htm

Page 99: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 1

Programare orientată pe obiecte

1. Erori şi excepŃii în Java

OOP8 - M. Joldoş - T.U. Cluj 2

Probleme în cursul execuŃiei� Un program întâlneşte adesea probleme în cursul execuŃiei

sale: � poate avea probleme la citirea datelor, � pot exista caractere nepermise în date sau� indexul unui tablou poate depăşi limitele acestuia.

� ExcepŃiile şi erorile Java permit programatorului să trateze astfel de probleme. � Putem scrie programe care îşi revin la întâlnirea erorilor şi îşi

continuă execuŃia.� Programele nu trebuie să eşueze atunci când utilizatorul face o

greşeală! � În special intrarea şi ieşirea sunt susceptibile la erori. � Tratarea excepŃiilor este esenŃială pentru programarea I/E

OOP8 - M. Joldoş - T.U. Cluj 3

Exemplu de apariŃie a unei excepŃii� Programul:import java.util.Scanner;public class InputMismatchExceptionDemo {

public static void main(String[] args) {Scanner keyboard = new Scanner(System.in);System.out.print("Enter one integer:"); int inputNumber = keyboard.nextInt();System.out.println("The square of " + inputNumber + " is " +

inputNumber * inputNumber); }

}

� Cu intrarea: Enter one integer:h1

� Dă rezultatul:java.util.InputMismatchExceptionat java.util.Scanner.throwFor(Scanner.java:819)at java.util.Scanner.next(Scanner.java:1431)at java.util.Scanner.nextInt(Scanner.java:2040)at java.util.Scanner.nextInt(Scanner.java:2000)at InputMismatchExceptionDemo.main(InputMismatchExceptionDemo.java:11)

OOP8 - M. Joldoş - T.U. Cluj 4

DiscuŃie asupra exemplului

� Programul nu este greşit. � Problema este că nextInt nu poate converti şirul de caractere "h1" la un int.

� În momentul în care nextInt a întâlnit problema, metoda a aruncat o excepŃie de tipul InputMismatchException.

� Sistemul de execuŃie Java a interceptat (a "prins") excepŃia, a oprit programul şi a tipărit mesajele de eroare

Page 100: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 5

ExcepŃii şi erori� O excepŃie: o problemă care apare în cursul execuŃiei unui program.� La apariŃia unei excepŃii, JVM creează un obiect de clasa Exception care conŃine informaŃii despre problema apărută.

� Însuşi programul Java poate intercepta (catch) o excepŃie. Apoi poate folosi obiectul de tipul excepŃie pentru aşi reveni după problemă.

� Şi o eroare este o problemă care apare la rularea unui program.

� O eroare este reprezentată de un obiect de clasa Error. � Dar o eroare este prea severă pentru a fi tratată de un program. Programul trebuie să-şi înceteze execuŃia.

OOP8 - M. Joldoş - T.U. Cluj 6

Ierarhia Throwable ("aruncabil")

� Atât clasa Exception cât şi clasa Error descind din Throwable. � O metodă Java poate "arunca" un

obiect de clasa Throwable.

� D.e. Integer.parseInt("zzz") aruncă o excepŃie atunci când încearcă să convertească "zzz" într-un întreg.

� ExcepŃii != Erori: se pot scrie programele astfel încât să-şi revină după excepŃii, dar nu se pot scrie astfel încât să-şi revină după erori

OOP8 - M. Joldoş - T.U. Cluj 7

Introducere în tratarea excepŃiilor

� Software de bibliotecă Java (sau codul definit de câtre programator) furnizează un mecanism care semnalizează când se întâmplă ceva neobişnuit� Aceasta se numeşte aruncarea unei excepŃii

� În alt loc din program, programatorul trebuie să scrie cod care tratează cazul excepŃional� Aceasta se numeşte tratarea excepŃiei

OOP8 - M. Joldoş - T.U. Cluj 8

Mechanismul try-throw-catch� Calea fundamentală pentru tratarea excepŃiilor în Java

constă din trio-ul try-throw-catch� Blocul try conŃine codul pentru algoritmul

implementat� Acest cod spune ce se face atunci când totul merge şnur

� Se numeşte bloc try deoarece el "încearcă" să execute cazul în care totul merge aşa cum a fost planificat

� De asemenea acest bloc poate conŃine cod care aruncă o excepŃie dacă se întâmplă ceva neobişnuittry {

CodCarePoateAruncaOExceptie}

Page 101: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 9

Mechanismul try-throw-catch

throw new

NumeleClaseiExceptie(PosibilArgumente);

� La aruncarea unei excepŃii, execuŃia blocului try în care a fost aruncată excepŃia se opreşte� Normal, controlul este transferat unei alte porŃiuni de cod, blocul catch (blocul de interceptare)

� Valoarea aruncată este argumentul operatorului throw; ea este întotdeauna un obiect aparŃinând unei clase excepŃie� ExecuŃia unei instrucŃiuni throw se numeşte aruncare a unei excepŃii

OOP8 - M. Joldoş - T.U. Cluj 10

Mechanismul try-throw-catch

� O instrucŃiune throw seamănă cu un apel de metodă:throw new NumeClasaExceptie(UnString);

� În exemplul de mai sus, obiectul de clasa NumeClasaExceptie este creat folosind ca argument un şir de caractere

� Acest obiect, care este argument pentru operatorul throw, este obiectul excepŃie aruncat

� În loc să apeleze o metodă, instrucŃiunea throw apelează un bloc catch

OOP8 - M. Joldoş - T.U. Cluj 11

Mechanismul try-throw-catch

� La aruncarea unei excepŃii se începe executarea blocului catch� Blocul catch are un parametru� Obiectul excepŃie aruncat este transmis ca parametru al blocului catch

� ExecuŃia blocului catch se numeşte interceptarea/"prinderea" excepŃiei, sau tratarea excepŃiei� Ori de câte ori se aruncă o excepŃie, ea trebuie până la urmă tratată (interceptată – "prinsă") de un bloc catch

OOP8 - M. Joldoş - T.U. Cluj 12

Mechanismul try-throw-catchcatch(Exception e) {

CodDeTratareAExceptiei}

� Un bloc catch arată ca o definiŃie de metodă care are un parametru de tipul clasei Exception� Dar nu este, totuşi, o definiŃie de metodă

� Un bloc catch este o porŃiune de cod separată care se execută atunci când un program întâlneşte şi execută o instrucŃiune throw în blocul tryprecedent� Un bloc catch este numit adesea bloc de tratare a excepŃiei

� El poate avea cel mult un parametru

Page 102: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 13

Mechanismul try-throw-catchcatch(Exception e) { . . . }

� Identificatorul e din blocul catch de deasupra se numeşte parametru al blocului catch

� Parametrul blocului catch îndeplineşte două roluri:1. Specifică tipul de obiect excepŃie aruncat pe care blocul

catch îl poate intercepta (d.e., mai sus este un obiect de clasa Exception)

2. Oferă un nume (pentru obiectul care este interceptat) care să fie folosit în blocul catch– ObservaŃie: adesea se foloseşte identificatorul e prin

convenŃie, dar se poate folosi orice identificator care nu este cuvânt cheie

OOP8 - M. Joldoş - T.U. Cluj 14

Mechanismul try-throw-catch

� La executarea unui bloc try se pot întâmpla două lucruri:1. Nu este aruncată nici o excepŃie în blocul try

– Codul din blocul try este executat până la sfârşitul blocului

– Blocul catch este sărit

– ExecuŃia continuă de la codul amplasat după blocul catch

OOP8 - M. Joldoş - T.U. Cluj 15

Mechanismul try-throw-catch

2. Este aruncată o excepŃie în blocul try şi interceptată în blocul catch

– Restul codului din blocul try este sărit– Controlul se transferă la un bloc catch următor (în cazurile simple)

– Obiectul aruncat este transmis ca parametru al blocului catch

– Se execută codul din blocul catch– Se execută codul care urmează după blocul catch respectiv (dacă există)

OOP8 - M. Joldoş - T.U. Cluj 16

Mechanismul try-throw-catch

Page 103: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 17

Exemplu cu două excepŃiipublic class DublaGreseala {

public static void main(String[] args) {int num = 5, denom = 0, result;int[] arr = {7, 21, 31};try{

result = num / denom;result = arr[num];

}catch (ArithmeticException ex) {

System.out.println(“Eroare aritmetica");}catch (IndexOutOfBoundsException ex) {

System.out.println(“Eroare de indice");}

}}

ObservaŃie. Cea de a doua excepŃie nu va fi aruncată niciodată. De ce?

OOP8 - M. Joldoş - T.U. Cluj 18

Mechanismul try-throw-catch� La aruncarea unei excepŃii de către o instrucŃiune blocul trytrytrytry{}{}{}{},

blocurile catch{}catch{}catch{}catch{} sunt examinate unul câte unul începând cu primul.

� Un singur bloc catch{}catch{}catch{}catch{} este ales.� Dacă nici un bloc catch{}catch{}catch{}catch{} nu se potriveşte cu excepŃia, atunci

nu este ales nici unul, iar execuŃia părăseşte metoda respectivă (exact ca în lipsa blocului catch{}catch{}catch{}catch{}.)

� Primul bloc catch{}catch{}catch{}catch{} care se potriveşte cu tipul de excepŃie aruncată obŃine controlul.

� Cele mai specifice tipuri de excepŃie trebuie să apară la început, urmate de tipurile mai generale de excepŃie.

� InstrucŃiunile din blocul catch{}catch{}catch{}catch{} ales sunt executate secvenŃial. După executarea ultimei instrucŃiuni, controlul ajunge la prima instrucŃiune care urmează după structura trytrytrytry/catch/catch/catch/catch.

� Controlul nu se întoarce în blocul trytrytrytry.

OOP8 - M. Joldoş - T.U. Cluj 19

Exemplu de intrare "prietenoasă"import import import import java.langjava.langjava.langjava.lang.* ;.* ;.* ;.* ;import java.io.* ;import java.io.* ;import java.io.* ;import java.io.* ;

public public public public classclassclassclass SquareUserSquareUserSquareUserSquareUser{{{{public static public static public static public static voidvoidvoidvoid mainmainmainmain ( ( ( ( StringStringStringString[] a ) [] a ) [] a ) [] a ) throwsthrowsthrowsthrows

IOExceptionIOExceptionIOExceptionIOException{{{{BufferedReaderBufferedReaderBufferedReaderBufferedReader stdinstdinstdinstdin = = = =

newnewnewnew BufferedReaderBufferedReaderBufferedReaderBufferedReader ( ( ( ( newnewnewnewInputStreamReaderInputStreamReaderInputStreamReaderInputStreamReader( ( ( ( System.inSystem.inSystem.inSystem.in ) );) );) );) );

StringStringStringString inDatainDatainDatainData = = = = nullnullnullnull;;;;intintintint num = 0;num = 0;num = 0;num = 0;boolean boolean boolean boolean inputOKinputOKinputOKinputOK = false;= false;= false;= false;whilewhilewhilewhile ( !( !( !( !inputOKinputOKinputOKinputOK )))){{{{System.out.printSystem.out.printSystem.out.printSystem.out.print((((““““IntroducetiIntroducetiIntroducetiIntroduceti un un un un intregintregintregintreg:");:");:");:");inDatainDatainDatainData = = = = stdin.readLinestdin.readLinestdin.readLinestdin.readLine();();();();

trytrytrytry{{{{

num = num = num = num = Integer.parseIntInteger.parseIntInteger.parseIntInteger.parseInt( ( ( ( inDatainDatainDatainData););););

inputOKinputOKinputOKinputOK = = = = truetruetruetrue;;;;}}}}catch (catch (catch (catch (NumberFormatExceptionNumberFormatExceptionNumberFormatExceptionNumberFormatException ex )ex )ex )ex ){{{{System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println((((““““AtiAtiAtiAti introdusintrodusintrodusintrodus

date date date date invalideinvalideinvalideinvalide." );." );." );." );System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println((((““““VaVaVaVa rogrogrogrog sasasasa

reincercatireincercatireincercatireincercati....\\\\n" );n" );n" );n" );}}}}

}}}}System.out.printlnSystem.out.printlnSystem.out.printlnSystem.out.println((((““““PatratulPatratulPatratulPatratul luiluiluilui " + " + " + " + inDatainDatainDatainData + " + " + " + " esteesteesteeste " + num*num );" + num*num );" + num*num );" + num*num );

}}}}}}}}

OOP8 - M. Joldoş - T.U. Cluj 20

Clauza finally

� ExcepŃia provoacă terminarea metodei curente� Pericol: se poate sări peste o porŃiune de cod esenŃială� Exemplu:

� Trebuie executat reader.close() chiar dacă apare o excepŃie

� Folosim clauza finally pentru codul care trebuie executat "indiferent de ce se întâmplă" (necondiŃionat)

reader = new FileReader(filename); Scanner in = new Scanner(reader); readData(in); reader.close(); // s-ar putea sa nu ajunga aici// niciodata

Page 104: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 21

Clauza finally

� Exemplu BlueJ (ExceptFinallyEx)

OOP8 - M. Joldoş - T.U. Cluj 22

Clauza finally

� Executată la ieşirea din blocul try: � După ultima instrucŃiune din blocul try � După ultima instrucŃiune din blocul catch, dacă în acest bloc try a apărut o excepŃie

� La aruncarea unei excepŃii în blocul try,excepŃie care nu a fost interceptată

� Cay Horstmann recomandă: nu amestecaŃi clauzele catch şi finally în acelaşi bloc try

OOP8 - M. Joldoş - T.U. Cluj 23

Blocuri catch multiple şi clauza finally

� Dacă există clauze catch asociate blocului try, atunci trebuie să punem clauza finally după toate clauzele catch. Exemplu:

try {// Bloc de cod cu puncte de iesire multiple

}catch (OneException e) {

System.out.println(“Am interceptat OneException!");}catch (OtherException e) {

System.out.println(" Am interceptat OtherException!");}catch (AnotherException e) {

System.out.println(" Am interceptat AnotherException!");}finally {

// Bloc de cod executat intotdeauna la iesirea din blocul,// indiferent de cum s-a iesit din try.System.out.println("Finally este executat intotdeauna");

}

OOP8 - M. Joldoş - T.U. Cluj 24

Clase excepŃie� Există mai multe clase excepŃie pe lângă clasa Exception� Există mai multe clase excepŃie în bibliotecile standard Java

� Pot fi definite noi clase excepŃie exact ca orice alte clase� Toate clasele excepŃie predefinite au următoarele

proprietăŃi:� Posedă un constructor cu un singur argument de tipul String

� Clasa are o metoda accesoare, getMessage(), care poate recupera şirul dat ca argument constructorului la crearea obiectului excepŃie

� Toate clasele definite de programator ar trebui să aibă aceleaşi proprietăŃi

Page 105: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 25

Clase excepŃie din pachetele standard

� Există numeroase clase excepŃie predefinite care sunt incluse în pachetele standard livrate cu Java. Spre exemplu:

IOExceptionNoSuchMethodExceptionFileNotFoundException

� Multe clase excepŃie trebuie importate pentru a le putea utiliza. Exemplu:import java.io.IOException;

� Clasa predefinită Exception este clasa rădăcină pentru toate excepŃiile� Fiecare clasă excepŃie este descendentă din clasa Exception� Deci clasa Exception poate fi folosită: direct sau pentru a defini o

clasă derivată� Se află în pachetul java.lang şi, nu trebuie clauză import

OOP8 - M. Joldoş - T.U. Cluj 26

Folosirea metodei getMessage. . . // codul metodeitry{

. . .throw newException(StringArgument);. . .

}catch(Exception e){

String message = e.getMessage();System.out.println(message);System.exit(0);

} . . .

� Fiecare excepŃie are o variabilă instanŃă de tipul String care conŃine un mesaj� Acest şir identifică de obicei

motivul apariŃiei excepŃiei

� StringArgument este folosit ca valoare pentru variabila instanŃă de tip şir a excepŃiei e� De aceea, apelul de metodă e.getMessage() returnează acest şir

OOP8 - M. Joldoş - T.U. Cluj 27

Definirea claselor excepŃie

� O instrucŃiune throw poate arunca un obiect excepŃie de oricare clasă excepŃie

� Clasele excepŃie pot fi şi definite de către programator� Acestea pot fi croite astfel încât să conŃină exact tipurile de informaŃie necesare în blocul catch

� Putem defini un tip de excepŃie diferit pentru a identifica fiecare situaŃie excepŃională

OOP8 - M. Joldoş - T.U. Cluj 28

Definirea claselor excepŃie� Fiecare clasă excepŃie care urmează să fie definită trebuie

să fie o clasă derivată dintr-o clasă excepŃie deja definită� derivată din oricare clasă excepŃie definită în bibliotecile standard

Java sau definită de către programator

� Constructorii sunt membrii cei mai importanŃi în definirea unei clase excepŃie� Constructorii trebuie să se comporte corespunzător în raport cu

variabilele şi metodele moştenite din clasa de bază� Adesea, nu există alŃi membri cu excepŃia celor moşteniŃi din clasa

de bază

� Clasa care urmează nu efectuează decât aceste sarcini fundamentale

Page 106: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 29

O clasă excepŃie definită de către programator

public class DivisionByZeroException extends Exception{

public DivisionByZeroException(){

super("Division by zero.");}public DivisionByZeroException(String message){

super(message);}

}

Se poate face mai mult într-un constructor de excepŃie, dar aceasta este o formă uzuală.

super invocă constructorul clasei de bază Exception

OOP8 - M. Joldoş - T.U. Cluj 30

Caracteristicile obiectului Exception

� Cele mai importante două lucruri referitoare la un obiect excepŃie sunt tipul său (adică, clasa excepŃie) şi mesajul pe care îl poartă� Mesajul este transmis împreună cu obiectul excepŃie ca variabilă instanŃă

� Acest mesaj poate fi recuperat cu metoda accesoare getMessage, astfel că blocul catchpoate folosi mesajul

OOP8 - M. Joldoş - T.U. Cluj 31

IndicaŃii pentru clasele excepŃie definite de programator

� Clasele excepŃie pot fi definite de către programator, dar fiecare asemenea clasă trebuie să fie derivată dintr-o clasă excepŃie existentă deja

� Clasa Exception poate fi folosită pe post de clasă de bază, cu excepŃia cazului în care o altă clasă excepŃie este mai potrivită

� Trebuie definiŃi cel puŃin doi constructori, iar uneori mai mulŃi

� ExcepŃia trebuie să Ńină seama că metoda getMessage() este moştenită

OOP8 - M. Joldoş - T.U. Cluj 32

Să păstreze getMessage� Pentru toate clasele excepŃie predefinite, getMessage returnează şirul de caractere transmis ca argument constructorului său� Sau să returneze un şir implicit dacă nu s-a transmis nici un argument constructorului

� Acest comportament trebuie păstrat în toate clasele excepŃie definite de către programator� Trebuie inclus un constructor care are un parametru şirde caractere şi al cărui corp începe cu un apel la super. Apelul la super trebuie să folosească parametrul ca argument al său

� Trebuie inclus şi un constructor fără argumente al cărui corp începe cu un apel la super. Acest apel la super trebuie să folosească şirul implicit ca argument

Page 107: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 33

Blocuri catch multiple� Un bloc try poate arunca potenŃial orice număr de

valori excepŃie, iar acestea pot fi de tipuri diferite� În oricare execuŃie a unui bloc try, poate fi aruncată cel mult o excepŃie (de vreme ce instrucŃiunea throw termină execuŃia blocului try)

� La execuŃii diferite ale blocului try pot fi aruncate valori diferite

� Fiecare bloc catch poate intercepta valorile de tipul de clasă excepŃie date în antetul blocului catch

� Se pot intercepta tipuri diferite de excepŃii punând mai multe blocuri catch după un bloc try� Se pot pune oricâte blocuri catch, dar în ordinea corectă

OOP8 - M. Joldoş - T.U. Cluj 34

Capcană: InterceptaŃi mai întâi cea mai specifică excepŃie

� La interceptarea de excepŃii multiple, ordinea blocurilor catch este importantă� La aruncarea unei excepŃii într-un bloc try, blocurile catch sunt examinate în ordinea apariŃiei

� Este executat primul bloc care se potriveşte cu tipul de excepŃie aruncat

catch (Exception e){ . . . }catch (NegativeNumberException e){ . . . }

� Deoarece NegativeNumberException este un tip de Exception, toate NegativeNumberExceptions vor fi interceptate de către primul bloc catch înainte de a ajunge vreodată la cel de-al doilea� Blocul catch pentru NegativeNumberException nu va fi folosit!

� Pentru ordine corectă, inversaŃi cele două blocuri

OOP8 - M. Joldoş - T.U. Cluj 35

Aruncarea unei excepŃii într-o metodă

� Uneori are sens să se arunce o excepŃie într-o metodă fără a o intercepta în metoda respectivă� Unele programe care folosesc o anume metodă ar trebui să se termine pur şi simplu la aruncarea unei excepŃii, iar altele nu

� În atare cazuri, programul care foloseşte invocarea metodei ar trebui să o includă într-un bloc try şi să intercepteze excepŃia într-un bloc catch care urmează

� În acest caz, metoda în sine nu va include blocuri try şi catch� Totuşi, trebuie să conŃină o clauză throws

OOP8 - M. Joldoş - T.U. Cluj 36

Declararea excepŃiilor în clauza throws

� Dacă o metodă poate arunca o excepŃie, dar nu o interceptează, atunci ea trebuie să furnizeze un avertisment� Acest avertisment se numeşte clauză throws� Procesul de includere a unei clase excepŃie într-o clauză throws se numeşte declararea excepŃieithrows OExceptie //clauza throws

� Următorul cod declară că invocarea lui oMetoda poate cauza aruncarea lui OExceptiepublic void oMetoda() throws OExceptie

� main( ) este o metodă care poate avea şi ea specificarea unei excepŃii:

public static void main(String[] args) throws Exception

Page 108: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 37

Declararea excepŃiilor în clauza throws

� Dacă o metodă poate arunca mai mult de un fel de excepŃie, atunci tipurile se separă prin virgulepublic void oMetoda() throws

OExceptie, AltaExceptie

� Dacă o metodă aruncă o excepŃie şi nu o interceptează, atunci apelul metodei se termină imediat

OOP8 - M. Joldoş - T.U. Cluj 38

Regula "prinde sau declară"

� Cele mai obişnuite excepŃii care ar putea fi aruncate într-o metodă trebuie tratate în unul dintre următoarele două moduri:1. Codul care poate arunca o excepŃie este pus

într-un bloc try, iar excepŃia care poate apărea este interceptată într-un bloc catchdin aceeaşi metodă

2. ExcepŃia posibilă poate fi declarată la începutul definiŃiei metodei punând numele clasei excepŃie într-o clauză throws

OOP8 - M. Joldoş - T.U. Cluj 39

Regula "prinde sau declară"

� Prima dintre tehnici tratează o excepŃie într-un bloc catch

� Cea de a doua tehnică este o modalitate de a deplasa răspunderea pentru tratarea excepŃiei la metoda care a invocat-o pe cea care a aruncat excepŃia

� Metoda apelantă trebuie să trateze excepŃia, cu excepŃia cazului în care foloseşte aceeaşi tehnică de "pasare"

� Într-un sfârşit, fiecare excepŃie ar trebui interceptată de un bloc catch din vreo metodă care nu numai declară într-o clauză throws ci şi interceptează clasa de excepŃie respectivă

OOP8 - M. Joldoş - T.U. Cluj 40

Regula "prinde sau declară"

� În oricare metodă, ambele tehnici pot fi amestecate� Unele excepŃii pot fi interceptate, iar altele declarate în clauza throws

� Cu toate acestea, tehnicile menŃionate trebuie folosite consistent pentru o excepŃie dată� Dacă o excepŃie nu este declarată, atunci ea trebuie tratată în

metodă� Dacă este declarată excepŃia, atunci responsabilitatea pentru

tratarea ei este pasată unei alte metode care o apelează� ObservaŃi că dacă definiŃia unei metode include invocarea unei a

doua metode, iar cea de a doua poate arunca o excepŃie şi nu o interceptează, atunci prima metodă trebuie să o declare sau să o intercepteze

Page 109: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 41

ExcepŃii verificate şi neverificate

� ExcepŃiile care sunt supuse regulii "prinde sau declară" sunt numite excepŃii verificate� Compilatorul verifică pentru a vedea dacă excepŃiile sunt luate în considerare fie într-un bloc catch, fie într-o clauză throws

� Clasele Throwable, Exception, precum şi toŃi descendenŃii clasei Exception constituie excepŃii verificate

� Toate celelalte excepŃii sunt neverificate� Clasa Error şi toate clasele care descind din ea sunt numite clase eroare � Clasele eroare nu sunt supuse regulii "prinde sau declară"

OOP8 - M. Joldoş - T.U. Cluj 42

ExcepŃii de la regula "prinde sau declară"

� ExcepŃiile verificate trebuie să respecte regula "prinde sau declară"� Programele în care pot fi aruncate aceste excepŃii nu se vor compila până când excepŃiile respective nu sunt tratate corespunzător

� ExcepŃiile neverificate nu sunt supuse regulii "prinde sau declară"� Programele în care apar astfel de excepŃii trebuie pur şi simplu corectate întrucât au erori de alt fel, dacă compilatorul semnalează erori

OOP8 - M. Joldoş - T.U. Cluj 43

ExcepŃii verificate şi neverificate

ExcepExcepExcepExcepţţţţii neverificateii neverificateii neverificateii neverificate ExcepExcepExcepExcepţţţţii verificateii verificateii verificateii verificate

Notă. Aici este o mică parte a ierarhiei.

OOP8 - M. Joldoş - T.U. Cluj 44

Ierarhia obiectelor Throwable(aruncabile)

Observa Ńie: To Ńi descenden Ńii clasei Throwable pot fi arunca Ńi şi intercepta Ńi într-un bloc catch

Excep Ńii verificate

Page 110: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 45

Clauza throws în clase derivate

� La suprascrierea unei metode într-o clasa derivată, aceasta trebuie să aibă aceleaşi clase excepŃie precum cele listate în clauza throws din clasa de bază� sau un subset al acestora

� O clasă derivată nu poate adăuga excepŃii la clauza throws� dar poate şterge câteva

OOP8 - M. Joldoş - T.U. Cluj 46

Ce se întâmplă dacă o excepŃie nu este interceptată?

� Dacă fiecare metodă până la, şi inclusiv, metoda main include o clauză throws, excepŃia respectivă poate fi aruncată, dar poate să nu fie interceptată niciodată� Într-un program GUI (adică un program cu o interfaŃa cu ferestre, grafică) nu se întâmplă nimic – atâta doar că utilizatorul poate fi lăsat într-o situaŃie ne-explicată, iar programul poate să nu mai fie sigur

� În programe non-GUI, aceasta face ca programul să se termine cu un mesaj de eroare care dă numele clasei excepŃie

� Fiecare program bine scris trebuie în cele din urmă să intercepteze fiecare excepŃie printr-un bloc catch în una dintre metodele sale

OOP8 - M. Joldoş - T.U. Cluj 47

Propagarea excepŃiei

OOP8 - M. Joldoş - T.U. Cluj 48

Un alt exemplupublic void doFileWork(String

filename) throwsDatabaseException{

FileOutputStream fos = null;ObjectOutputStream oos = null;try{fos = newFileOutputStream(filename);oos = newObjectOutputStream(fos);oos.writeObject(obj);}catch(IOException e){throw new DatabaseException("Problem while working with"+filename+": "+e.getMessage());

}

finally{try{if(oos!=null){oos.close();}if(fos!=null){fos.close();}}catch(IOException e){throw new DatabaseException("Problem while working with

"+filename+": "+e.getMessage());

}}}

Page 111: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 49

ExplicaŃii pentru exemplu

OOP8 - M. Joldoş - T.U. Cluj 50

Când să folosim excepŃiile

� ExcepŃiile trebuie rezervate pentru situaŃiile în care o metodă întâlneşte un caz neobişnuit sau neaşteptat, care nu poate fi tratat cu uşurinŃă în vreun alt mod

� Atunci când trebuie folosită tratarea excepŃiilor, folosiŃi aceste recomandări:� IncludeŃi instrucŃiuni throw şi precizaŃi clasele excepŃie într-o clauză throws din definiŃia metodei respective

� PlasaŃi blocurile try şi catch într-o metodă diferită

OOP8 - M. Joldoş - T.U. Cluj 51

Când să folosim excepŃiile� Iată un exemplu de metodă din

care este aruncată o excepŃie:

public void oMetoda()

throws OExceptie {

. . .

throw new

OExceptie(UnArgument);

. . .

}

� Atunci când oMetoda este folosită de altaMetoda, altaMetoda trebuie să trateze excepŃia:

public void altaMetoda()

{

try {

oMetoda();

. . .

}

catch (OExceptie e) { CodPentruTratareaExceptiei

}

. . .

}

OOP8 - M. Joldoş - T.U. Cluj 52

Ghid pentru excepŃii

� Dacă metoda întâlneşte o condiŃie anormală pe care nu o poate trata, atunci trebuie să arunce o excepŃie.

� EvitaŃi folosirea excepŃiilor pentru a indica situaŃii care pot fi aşteptate ca parte a funcŃionării normale a metodei.

� Dacă metoda descoperă că clientul şi-a încălcat obligaŃiile contractuale (spre exemplu, prin transmiterea de date de intrare neconforme specificaŃiei), atunci aruncaŃi o excepŃie neverificată.

Page 112: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 53

Ghid pentru excepŃii

� Dacă metoda nu-şi poate îndeplini contractul, atunci aruncaŃi fie o excepŃie verificată, fie una neverificată.

� Dacă aruncaŃi o excepŃie pentru o situaŃie anormală despre care consideraŃi că programatorii trebuie să decidă în mod conştient cum să o trateze, atunci aruncaŃi o excepŃie verificată.

� DefiniŃi sau alegeŃi o clasă excepŃie care există deja pentru fiecare fel de condiŃie anormală care poate face ca metoda Dvs. să arunce o excepŃie.

OOP8 - M. Joldoş - T.U. Cluj 54

Re-aruncarea excepŃiilor� După interceptarea unei excepŃii, ea poate fi re-aruncată

dacă e cazul. � La re-aruncarea unei excepŃii putem alege locaŃia din care

se va vedea ca aruncat obiectul în trasarea stivei de execuŃie. � Putem face ca excepŃia re-aruncată să pară a fi aruncată din locul

excepŃiei originale sau� din locul re-aruncării.

� Pentru a re-arunca o excepŃie cu indicarea locaŃiei originale, pur şi simplu o aruncăm din nou:

try {cap(0);

} catch(ArithmeticException e) {throw e;

}

OOP8 - M. Joldoş - T.U. Cluj 55

Re-aruncarea excepŃiilor� Pentru a avea locaŃia reală din care a fost re-aruncată

apelăm metoda fillInStackTrace() a excepŃiei. � Metoda setează informaŃia din trasarea stivei pe baza contextului de

execuŃie curent. Exemplu:try {

cap(0);} catch(ArithmeticException e) {

throw (ArithmeticException)e.fillInStackTrace();}

� Apelăm fillInStackTrace() pe linia cu instrucŃiunea throw – astfel numărul de linie din trasare este la fel cu cel unde apare instrucŃiunea throw. � Metoda fillInStackTrace() returnează o referinŃă la clasa Throwable, aşa că e nevoie de o conversie de tip la tipul real de excepŃie.

OOP8 - M. Joldoş - T.U. Cluj 56

� Exemplu BlueJ (DataSetReader)

Page 113: POO all curses UTCLUJ VICAS

OOP8 - M. Joldoş - T.U. Cluj 57

Rezumat

� ExcepŃii şi erori� ExcepŃii verificate şi neverificate� InstrucŃiunile try şi catch� Clauza finally � Regula "prinde sau declară"� Clauza throws� InstrucŃiunea throw