Curs2 - java programming

14
24 Programarea obiectuală în Java Java este un limbaj de referinţă în ceea ce priveşte programarea obiectuală. Limbajul implementează toate caracteristicile de bază ale acestei tehnici de programare: moştenirea polimorfismul încapsularea abstractizarea, ş.a. Definiţii Clasa defineşte un ansamblu de variabile de stare şi un set de funcţii denumite metode (de la eng. methods) . Variabilele de stare ale clasei, denumite şi câmpuri, caracterizează starea instanţelor create iar metodele definesc comportamentul acestora. Clasa este deci o machetă care va fi folosită la crearea instanţelor. De regulă funcţiile unei clase servesc la modificarea valorilor variabilelor clasei sau la preluarea valorilor instantanee ale acestora. Obiectele sau instanţele claselor sunt entităţi software caracterizate prin stare şi comportament. Starea este memorată în variabilele de stare ale clasei instanţiate. De exemplu un obiect din clasa Om ar putea fi caracterizat prin nume, prenume, adresa şi CNP. La crearea unei noi instanţe, variabilelor de stare li se alocă spaţiu în memoria calculatorului şi primesc valorile particulare specifice obiectului creat. Exemplu: Om Pop = new Om("Pop", "Paul", "Str. Albac nr. 12, Cluj", 1820314123272L); În acelaşi timp, instanţierea unui obiect înseamnă crearea acestuia în memoria calculatorului şi preluarea adresei zonei ocupate de acesta. Adresa unui obiect este o variabilă de tip referinţă. Deci, ca şi tip de dată, Pop este o referinţă. Spre deosebire de variabilele simple, a căror lungime de reprezentare în memorie poate varia de la 1 la 8 octeţi, variabilele de tip referinţă ocupă o lungime fixă, 4 sau 8 octeţi, în funcţie de procesorul virtual Java pe care se execută. În exemplul dat, Om("Pop", "Paul", "Str. Albac nr. 12, Cluj", 1820314123272) este apelul unei funcţii particulare a clasei Om destinată creării unei instanţe. În programarea obiectuală, o astfel de funcţie poată numele de constructor. Dar o variabilă de tip referinţă poate primi valoare şi fără apelul unui constructor. Exemplu: Om Pop, Marcel;

description

java programare curs 2

Transcript of Curs2 - java programming

  • 24

    Programarea obiectual n Java

    Java este un limbaj de referin n ceea ce privete programarea obiectual. Limbajul

    implementeaz toate caracteristicile de baz ale acestei tehnici de programare:

    motenirea

    polimorfismul

    ncapsularea

    abstractizarea, .a.

    Definiii

    Clasa definete un ansamblu de variabile de stare i un set de funcii denumite metode (de la

    eng. methods) . Variabilele de stare ale clasei, denumite i cmpuri, caracterizeaz starea instanelor

    create iar metodele definesc comportamentul acestora. Clasa este deci o machet care va fi folosit

    la crearea instanelor.

    De regul funciile unei clase servesc la modificarea valorilor variabilelor clasei sau la

    preluarea valorilor instantanee ale acestora.

    Obiectele sau instanele claselor sunt entiti software caracterizate prin stare i

    comportament. Starea este memorat n variabilele de stare ale clasei instaniate. De exemplu un

    obiect din clasa Om ar putea fi caracterizat prin nume, prenume, adresa i CNP. La crearea unei noi

    instane, variabilelor de stare li se aloc spaiu n memoria calculatorului i primesc valorile

    particulare specifice obiectului creat.

    Exemplu:

    Om Pop = new Om("Pop", "Paul", "Str. Albac nr. 12, Cluj", 1820314123272L);

    n acelai timp, instanierea unui obiect nseamn crearea acestuia n memoria calculatorului

    i preluarea adresei zonei ocupate de acesta. Adresa unui obiect este o variabil de tip referin.

    Deci, ca i tip de dat, Pop este o referin. Spre deosebire de variabilele simple, a cror lungime de

    reprezentare n memorie poate varia de la 1 la 8 octei, variabilele de tip referin ocup o lungime

    fix, 4 sau 8 octei, n funcie de procesorul virtual Java pe care se execut.

    n exemplul dat, Om("Pop", "Paul", "Str. Albac nr. 12, Cluj", 1820314123272) este apelul unei

    funcii particulare a clasei Om destinat crerii unei instane. n programarea obiectual, o astfel de

    funcie poat numele de constructor. Dar o variabil de tip referin poate primi valoare i fr

    apelul unui constructor. Exemplu:

    Om Pop, Marcel;

  • 25

    Pop = new Om("Pop", "Paul", " Str. Albac nr. 12, Cluj ", 1820314123272); Marcel = Pop;

    Dup rularea secvenei de mai sus, Pop i Marcel sunt iniializate cu valori identice, deci sunt

    referine spre acelai obiect.

    Structura unei clase

    Variabilele clasei

    O clas poate conine trei categorii de variabile:

    variabile de stare (sau cmpuri), care vor caracteriza instanele clasei. Aceste variabile sunt declarate nafara metodelor clasei ;

    variabile locale, declarate n metodele clasei;

    variabile ale clasei, declarate folosind cuvntul cheie static.

    Metodele clasei

    1. Constructorii

    Un constructor al unei clase este o metod special, destinat iniializrii variabilelor de

    stare. O clas poate avea mai muli constructori, acetia difereniindu-se prin lista de parametri

    formali. Java construiete pentru fiecare clas un constructor implicit, fr parametri, care

    iniializeaz cu 0 toate variabilele numerice ale clasei i cu null toate variabilele de tip referin.

    Exemplu de clas:

    public class Autoturism{ String marca; String combustibil; int anFabricatie; String culoare;

    public Autoturism(String marca, String combustibil, int an, String culoare){ this.marca = marca; this.combustibil = combustibil; this.anFabricatie = an; this.culoare = culoare; } }

    Pentru a crea o instan a clasei Autoturism se va folosi cuvntul rezervat new. Crearea

    presupune:

  • 26

    Declararea unei variabile de tip Autoturism;

    Instanierea noului obiect folosind new;

    Iniializarea obiectului, prin apelul unui constructor al clasei. Exemplu:

    // Clasa principala public class Excursie {

    public static void main(String []args){ Autoturism masina = new Autoturism("Dacia", "benzin", 2011, "alb"); System.out.println("Avem o masin " + masina.marca); } }

    Pentru testare se va crea n NetBeans un proiect nou denumit Excursie. La creare se va

    selecta opiunea "Create main class" a mediului de dezvoltare, efectul fiind crearea clasei principale

    (Excursie).

    Dup crearea proiectului se va selecta cu butonul drept al mouse-ului numele acestuia n

    panoul Projects i, n meniul contextual, se va selecta New / Java Class...

    n continuare, folosind interfaa afiat, se creaz clasa Autoturism. n final se va executa

    aplicaia, la consol afindu-se urmtorul mesaj:

    Accesul la variabile de stare i la metode

    Variabilele de stare i metodele unei clase sunt accesibile prin intermediul referinelor la

    instanele clasei. Exemplu:

    public class Prieten {

    int varsta; String nume;

    public Prieten(String nume, int varsta) { this.nume = nume; this.varsta = varsta; }

  • 27

    public void setNume(String nume) { this.nume = nume; }

    public void setVarsta(int varsta) { this.varsta = varsta; }

    public String getNume() { return nume; }

    public int getVarsta() { return varsta; }

    public static void main(String[] args) { /* Creez un obiect din clasa Prieten */ Prieten p1 = new Prieten("Marius", 42);

    /* Modific varsta */ p1.setVarsta(24);

    /* Afisez datele prietenului p1 */ System.out.println(p1.getNume() + " are " + p1.getVarsta() + " ani."); } }

    Dup crearea unei instane a clasei prin apelul constructorului acesteia, variabila p1 de tip

    referin este iniializat i va putea fi folosit ulterior la apelul metodelor clasei Prieten.

    Reguli de declarare a fiierelor surs din aplicaiile Java

    1. n fiecare fiier Java poate fi o singur clas declarat public.

    2. ntr-un fiier coninnd o clas declarat public pot fi declarate un numr oarecare de clase care nu sunt publice.

    3. Numele clasei publice va coincide cu numele fiierului surs n care aceasta va fi memorat. Fiierul surs va avea extensia .java.

    4. Clasele unei aplicaii pot fi organizate n pachete (eng. packages). Declaraia pachetului cruia i aparine o clas va fi coninut n prima linie din fiierul surs.

    5. Metodele clasei pot folosi obiecte din clase care nu aparin proiectului, dar care sunt coninute n diverse pachete accesibile mediului de programare. Clasele cunoscute implicit sunt cele incluse ntr-un pachet denumit java.lang, care nu trebuie inclus n fiierele surs. Pentru a folosi clase Java care nu sunt incluse n java.lang, la nceputul fiierului surs se vor insera directive import care vor preciza pachetele necesare.

    Exemplu:

    package javasocket;

    import java.util.logging.Level;

  • 28

    import java.util.logging.Logger; import org.jwebsocket.api.WebSocketPacket; import org.jwebsocket.config.JWebSocketConfig; import org.jwebsocket.factory.JWebSocketFactory; import org.jwebsocket.kit.WebSocketServerEvent; import org.jwebsocket.listener.WebSocketServerTokenEvent; import org.jwebsocket.listener.WebSocketServerTokenListener; import org.jwebsocket.server.TokenServer; import org.jwebsocket.token.Token;

    public class JavaSocket implements WebSocketServerTokenListener { . . .

    Studiu de caz

    Se consider o aplicaie denumit Loturi care trebuie s gestioneze parcelele deinute de

    locuitorii unui sat. Pentru fiecare proprietar n aplicaie se va memora numele, prenumele i CNP-ul

    iar pentru fiecare parcel se va memora CNP-ul proprietarului i suprafaa n hectare. Aplicaia va

    afia o list cu toate parcelele, gupate pe proprietari.

    Soluie:

    Pentru memorarea datelor specifice entitilor evideniate (proprietar i parcel), se vor

    declara dou clase. Fiecare clas va avea un constructor care va iniializa variabilele clasei i o

    metod destinat afirii valorilor acestora.

    Crearea obiectelor i afiarea listei propuse se poate face n funcia main(). n Java funcia

    main() este doar punctul de intrare n aplicaie i poate fi plasat n oricare dintre clasele publice ale

    aplicaiei. n aplicaia considerat ea va fi coninut ntr-o clas suplimentar denumit Main creat

    de altfel automat de mediul de programare.

    Crearea proiectului

  • 29

    Se observ c mediul creaz n proiectul Loturi clasa principal denumit tot Loturi dar i un

    pachet pentru aceasta denumit loturi. n acelai pachet vor fi memorate i celelalte dou clase,

    Proprietar i Parcela.

    Clasa Proprietar

    n continuare se adaug clasei create dou variabile, CNP i nume avnd ca tipuri long

    respectiv referin spre String.

    Pentru adugarea unui constructor se va folosi o opiune a mediului de programare. Astfel

    se poate plasa cursorul mouse-ului pe o linie goal n punctul n care se dorete inserarea acestuia i

    se apas butonul drept. n meniul contextual se selecteaz Insert Code... i apoi, n fereastra afiat

    se selecteaz Constructor.

  • 30

    n continuare se vor preciza parametrii constructorului. n cazul dat se vor selecta casetele

    de validare din faa celor dou variabile ale clasei deoarece la crearea unei instane noi constructorul

    trebuie s iniializeze ambele variabile.

    Dup adugarea constructorului, clasei Proprietar i se va aduga o metod suplimentar

    denumit afiez care afieaz pe consol datele unui proprietar. n final clasa Proprietar va fi

    urmtoarea:

    public class Proprietar { long CNP; String nume;

    public Proprietar(long CNP, String nume) { this.CNP = CNP; this.nume = nume; }

    public void afisez() { System.out.println(CNP + " " + nume); } }

  • 31

    Clasa Parcela

    Similar se va aduga aplicaiei clasa Parcela. Aceasta va avea coninutul urmtor:

    public class Parcela { long CNP; double suprafata;

    public Parcela(long CNP, double suprafata) { this.CNP = CNP; this.suprafata = suprafata; } public void afisez() { System.out.println(suprafata + "ha"); } }

    Funcia main() din clasa principal Loturi ar putea avea codul urmtor:

    public static void main(String[] args) { // Generez sirul proprietarilor Proprietar prop[]; prop = new Proprietar[4]; prop[0] = new Proprietar(1670812123234L, "Ionescu Paul"); prop[1] = new Proprietar(1631110442351L, "Moldovan Ioan"); prop[2] = new Proprietar(2720314774121L, "Georgescu Laura"); prop[3] = new Proprietar(1780407352179L, "Rancea Emil"); // Generez parcelele Parcela parc[] = new Parcela[7]; parc[0] = new Parcela(2720314774121L, 0.78); parc[1] = new Parcela(1780407352179L, 1.35); parc[2] = new Parcela(1631110442351L, 2.07); parc[3] = new Parcela(2720314774121L, 0.53); parc[4] = new Parcela(1780407352179L, 3.12); parc[5] = new Parcela(2720314774121L, 2.); parc[6] = new Parcela(1670812123234L, 1.25); // Afisez parcelele grupate pe proprietari for(Proprietar p : prop) { p.afisez(); for(Parcela a : parc) { if(p.CNP==a.CNP) a.afisez(); } System.out.println(""); // O linie goala } }

    n main() variabilele prop i parc sunt iruri de referine la obiecte din clasele Proprietar

    respectiv Parcela. Ele sunt iniializate prin apelul constructorilor corespunztori.

    Rularea aplicaiei va afia la consol urmtoarele informaii:

  • 32

    Comunicarea ntre obiecte

    Declararea referinelor i apoi iniializarea lor cu valori obinute prin apelul constructorilor

    este o soluie fundamental n programarea obiectual. n exemplul urmtor se va prezenta ns i o

    alt situaie, frecvent ntlnit n cazul aplicaiilor Java reale.

    Dac afiarea suprafeelor parcelelor din aplicaia precedent ar trebui s se poat realiza n

    diverse uniti de msur (ha, ari, Km2) sau n uniti uzuale anglosaxone: acri sau mile ptrate clasa

    principal, Loturi, ar trebui s aib dou variabile suplimentare, respectiv un coeficient de conversie

    i un String care va conine numele unitii de msur corespunztoare. Pentru a le aduga ca

    variabile ale clasei i nu ca variabile locale n main(), clasa principal trebuie reconstruit conform

    machetei urmtoare.

    public class Loturi { double coefTransf; String unitateMasura; Proprietar prop[]; Parcela parc[];

    // Constructorul clasei public Loturi() { . . .

    }

    /** * @param args the command line arguments */ public static void main(String[] args) { Loturi L = new Loturi(); } }

    Practic toat logica aplicaiei este mutat n constructorul clasei principale, rolul funciei

    main() reducndu-se la acela de a crea o instan a clasei Loturi prin apelul constructorului acestuia.

  • 33

    In funcia afiez() din clasa Parcela valorile variabilelor coefTransf i unitateMasura ar trebui

    s fie disponibile. O soluie de rezolvare a problemei (nu singura!) presupune declararea clasei

    Parcela astfel:

    public class Parcela { long CNP; double suprafata; Loturi ref;

    public Parcela(long CNP, double suprafata) { this.CNP = CNP; this.suprafata = suprafata; }

    void setRef(Loturi reflot) { this.ref = reflot; }

    public void afisez() { System.out.println(suprafata*ref.coefTransfer + ref.unitateMasura); } }

    Se observ c n noua versiune, clasa Parcela are o variabil suplimentar, ref. Aceasta este

    o referin spre un obiect din clasa principal, Loturi. Variabila ref primete valoare n metoda

    setRef(). Apelul acesteia se va face din constructorul clasei Loturi, pentru fiecare obiect de tip

    Parcela dup crearea acestuia, astfel:

    public Loturi() { // Generez sirul proprietarilor prop = new Proprietar[4]; prop[0] = new Proprietar(1670812123234L, "Ionescu Paul"); prop[1] = new Proprietar(1631110442351L, "Moldovan Ioan"); prop[2] = new Proprietar(2720314774121L, "Georgescu Laura"); prop[3] = new Proprietar(1780407352179L, "Rancea Emil"); // Generez parcelele parc = new Parcela[7]; parc[0] = new Parcela(2720314774121L, 0.78); parc[1] = new Parcela(1780407352179L, 1.35); parc[2] = new Parcela(1631110442351L, 2.07); parc[3] = new Parcela(2720314774121L, 0.53); parc[4] = new Parcela(1780407352179L, 3.12); parc[5] = new Parcela(2720314774121L, 2.); parc[6] = new Parcela(1670812123234L, 1.25); // Initializez variabilele ref for (Parcela p : parc) { p.setRef(this); } // Iniializez coefTransf si unitateMas coefTransf = 2.47105381; unitateMasura = "acri"; // Afisez parcelele grupate pe proprietari for (Proprietar p : prop) { p.afisez(); for (Parcela a : parc) {

  • 34

    if (p.CNP == a.CNP) { a.afisez(); } } System.out.println(""); // O linie goala } }

    Secvena evideniat iniializeaz variabila ref a instanelor clasei Parcela cu valoarea this. n

    Java this este referina spre obiectul curent, n care este folosit. Aceast referin particular a fost

    folosit i n cazul constructorilor claselor Parcela i Proprietar, pentru iniializarea variabilelor

    acestora. n acest caz utilizarea referinei this este justificat pentru a elimina confuzia cauzat de

    coincidena dintre numele parametrului formal din linia de definire a constructorului i variabila

    iniializat. Exemplu:

    public Parcela(long CNP, double suprafata) { this.CNP = CNP; this.suprafata = suprafata; }

    Rezultatul rulrii aplicaiei n noua versiune:

    Soluia prezentat este folosit n aplicaii n care datele sunt concentrate ntr-o clas de

    baz i accesate din oricare dintre metodele claselor acesteia. Practic ntre obiectul din clasa de baz

    i instanele diferitelor clase se creaz legturi n ambele sensuri.

    variabila clasei param. formal

  • 35

    Metode statice

    Pentru a se executa codul dintr-o metod a unei clase, aceasta trebuie apelat. Apelul se

    realizeaz de regul din alt metod a aceleiai clase sau a altei clase aparinnd aplicaiei. La

    apelarea unei metode dintr-o alt clas, numele acesteia este precedat fie de referina spre obiectul

    ale crui date trebuie prelucrate fie de numele clasei creia i aparine metoda. Al doilea caz se

    refer la metode care prelucreaz eventual parametrii transmii n momentul apelului, ca n cazul

    metodelor care implementeaz funcii matematice (sin, cos etc.).

    Metodele de acest ultim fel sunt denumite metode statice i sunt declarate folosind

    declaraia static.

    n concluzie, pentru a apela o metod se va scrie:

    - metod(); dac aceasta este coninut n aceeai clas,

    - referin.metod(); dac metoda este coninut ntr-o alt clas sau

    - clas.metod(); dac metoda aparine unei alte clase i este declarat static. Exemple:

    p1.translatez(3, 10); // p1 este o referin y = r * Math.sin(x); // sin() este o metod static a clasei Math k = Integer.parseInt(args[1]); // parseInt() este o met. static a clasei // Integer

    Vizibilitatea variabilelor

    Vizibilitatea unei variabile se definete ca zona din program n care aceasta este cunoscut

    deci poate fi accesat. Regulile privind vizibilitatea variabilelor n cadrul claselor Java pot fi deduse

    din schema urmtoare:

    public class Vizibilitate { declaraii pentru variabilele clasei

    public void metoda1(declaratii parametri formali) { declaratii variabile locale

    } }

    Din punct de vedere al locului declarrii, o variabil poate fi membr a clasei (declarat n

    afara oricrei metode) sau local (declarat n interiorul unei metode, de obicei la la nceputul

    acesteia sau la nceputul unui bloc din interiorul acesteia).

    Zona de vizib. a variabilelor clasei, a parametrilor metodei i a variabilelor locale

  • 36

    Variabilele locale aparinnd unor blocuri separate i care nu sunt incluse unul n altul, sunt

    diferite, chiar dac poart acelai nume. Se recomand totui folosirea unor nume de variabile

    distincte i mai ales sugestive, care s ajute programatorul n urmrirea logicii programului.

    Variabilele locale exist pe timpul execuiei blocului n care au fost declarate i i nceteaz

    existena n momentul ieirii din acesta.

    Modificarea accesului la clase sau la membrii acestora folosind specificatorii public i

    private

    n exemplele date, denumirile claselor erau precedate de specificatorul de acces public.

    Acelai specificator s-a folosit sistematic naintea numelor funciilor. n Java acest specificator se

    folosete pentru a permite accesul direct la entitatea respectiv din toate clasele aplicaiei.

    Opusul regimului de acces impus prin public se poate obine folosind specificatorul private.

    O clas declarat private poate exista n interiorul unei clase declarat public i poate fi instaniat

    numai n interiorul acesteia. Ea este invizibil din alte clase ale aplicaiei. Aceast soluie apare rar

    n aplicaii obinuite.

    Metodele clasei sunt i ele declarate sistematic ca fiind publice. O metod declarat private

    poate fi apelat doar n interiorul clasei n care este inclus i nu este vizibil din alte clase. Este

    cazul metodelor create cu rol de funcii ajuttoare n cazul metodelor al cror cod tinde s fie prea

    mare sau conine zone care se repet.

    Specificatorul de acces private se folosete cel mai des la declararea variabilelor claselor.

    Pentru accesul la fiecare dintre variabilele astfel declarate trebuie inserat cte o pereche de funcii

    destinate iniializrii (set) i prelurii valorii (get). Crearea acestora se poate realiza folosind o

    facilitate a mediului de programare. Exemplu:

  • 37

    Rezultat:

    public long getCNP() { return CNP; }

    public void setCNP(long CNP) { this.CNP = CNP; } . . .

    Dup aceste modificri, accesul la variabila CNP din clasa Parcela se va realiza n metodele

    altei clase a aplicaiei doar prin apelul funciilor setCNP() i geCNP() create.

    O a treia situaie ntlnit frecvent este lipsa oricrei declaraii deacces (public sau private) n

    faa variabilelor clasei. n aceast situaie, din clasele aceluiai pachet (package) variabilele vor

    putea fi accesate fr restricii, ca i cum ar fi fost declarate folosind public.

    O prezentare succint a limbajului Java i a programrii obiectuale n acest limbaj se poate

    accesa la adresa http://www.tutorialspoint.com/java/index.htm