Sunteți pe pagina 1din 31

CAP.

7 Construirea obiectelor
Termenul obiecte are un inteles larg in limbajul Java.Toate structurile limbajului sunt proiectate pentru a folosi secvente mici de cod, autocontinute, numite obiecte. Obiectele folosesc elemente de baza, precum declaratii si expresii, pentru efectuarea operatiilor cerute de program. Accentul cade pe folosirea acestor secvente de cod in mod corespunzator, astfel incat sa nu fiti nevoit sa le rescrieti de fiecare data. Este motivul pentru care acest tip de programare se numeste orientat pe obiecte. (Conceptul este discutat in capitolul 1, Prezentarea limbajului Java.) Cea mai mica unitate logica a limbajului Java este obiectul. Orice alceva reprezinta o grupare de obiecte.Acest capitol descrie modul de creare si de folosire a obiectelor, explorand structura limbajului Java mai in detaliu decat capitolul precedent.Capitolul 6, Elemente de baza ale limbajului Java, a prezentat cele mai mici parti ale obiectelor, cum ar fi tipurile de date primitive si cuvintele cheie pentru controlul fluxului;capitolul de fata va arata cum sa puneti aceste elemente la lucru intr-un cadru de dezvoltare structural. Pentru crearea unei aplicatii Java, este necesar sa intelegeti cum se imbina partile componente.In acest capitol veti studia modul de grupare a obiectelor in clase.Clasele primesc caracteristici prin mostenire. Bibliotecile de clase sunt grupuri de clase.Pachetele sunt grupuri de biblioteci de clase.Metodele sunt functii care executa anumite operatii in cadrul claselor.Metodele pot avea sabloane, gestionate prin interfete. Acestea sunt concepte abstracte.Java confera o mare flexibilitate aplicatiilor, dar terminologia limbajului va poate inhiba.In acest capitol, veti gasi numeroase exemple care concretizeaza aceste concepte si va ajuta sa le intelegeti.Pentru ilustrarea structurii limbajului Java, de-a lungul intregului capitol se foloseste exemplul conceptual al unui bloc de locuinte. La sfarsitul acestui capitol, ar trebui sa aveti o idee clara despre relatiile dintre diferitele parti ale limbajului Java si despre modul de folosire a acestora.

Prezentarea conceptului de clase


Clasele sunt formate din obiecte.Este un lucru usor de inteles, daca sunteti familiarizat cu programarea orientata pe obiecte.Pentru cei care nu fac parte din acesta categorie, vom explica ce este un obiect.Ganditi-va la un obiect ca la o entitate formata din unitati mai mici.Imaginati-va un bloc de locuinte.Acesta este format din mai multe apartamente.Fiecare apartament are probabil usi, ferestre, o bucatarie, un dormitor, o baie si altele.Fiecare apartament reprezinta o unitate.Se poate spune ca un bloc este format din mai multe unitati. Apartamentele nu sunt identice.Unele sunt la etaj, altele la parter, unele sunt orientate catre sud, altele au fost renovate recent.Unele apartamente au doua dormitoare, altele, unul singur.Fiecare apartament are o cutie postala cu propria adresa.Chiar daca sunt diferite, toate sunt insa apartamente. Apartamentele sunt obiectele din acest exemplu.Chiar daca se compun din elemente mai mici si nu sunt identice, fiecare dintre ele reprezinta o unitate. Blocul de locuinte este clasa formata din obiecte sau unitati.Aceste obiecte nu sunt identice, dar au suficient de multe caracteristici comune pentru a putea fi clasate impreuna. Un alt termen folosit in programarea orientata pe obiecte este instanta.Blocul 3 este o instanta.Este ceva concret.O instanta este un anumit obiect dintr-o clasa de obiecte.

Fiecare apartament mai prezinta si alte informatii interesante.Unele apartamente sunt nelocuite.Faptul ca un apartament este locuit sau nu reprezinta starea apartamentului.Pe baza acestei stari, o aplicatie pentru gestionarea inchirierilor ar putea tine evidenta apartamentelor disponibile.Clasa va avea o metoda care sa testeze starea apartamentului. Sa trecem acum la un alt nivel de abstractizare.Locuiti cumva intr-un cartier de blocuri?In cartier sunt mai multe blocuri, fiecare fiind format din mai multe apartamente.Cartierul are un nume, cum ar fi Countrybrook, sau un alt nume sugestiv si romantic.Cartierul este, in acest caz, suma conceptuala a tuturor blocurilor din zona, chiar daca acestea nu sunt identice, au adrese diferite si o serie de caracteristici care le individualizeaza. Cartierul de blocuri este un exemplu de clasa formata dintr-o biblioteca de clase.O biblioteca este un set de clase.Bibliotecile grupeaza clase care efectueaza operatii asemanatoare, si totusi distincte.Nu uitati ca intregul cartier de apartamente reprezinta o clasa. Sa presupunem ca in apropiere se afla un complex comercial.Acesta este format din mai multe unitati magazine.Complexul comercial este o alta clasa din biblioteca.Reprezinta tot o cladire, dar cu o alta structura si alte functii decat blocurile de locuinte.Poate fi configurat ca o clasa distincta a bibliotecii. Java contine mai multe biblioteci de clase pentru sarcini diferite, cum ar fi operatiile de intrare/iesire, afisarea pe ecran si tratarea clicurilor de mouse.Bibliotecile de clase reprezinta forta motrice a limbajului Java.De fapt, acest subiect este atat de important, incat ocupa cinci capitole din aceasta carte.(A se vedea partea a IV-a, Interfata Java de programare a aplicatiilor, pentru mai multe informatii despre bibliotecile de clase.) In acest moment, este important sa intelegeti conceptele de obiecte, clase, biblioteci de clase, si pachete.Acestea formeaza structura limbajului Java.

Clase
Clasele sunt formate din mai multe elemente diferite, cum ar fi metodele si variabilele.Ganditi-va la exemplul cu apartamentul.Clasa este un sablon pentru informatii despre un grup de elemente, chiar daca acestea difera in anumite privinte.De asemenea, clasele contin metode pentru obtinerea informatiilor despre starea unui membru.Fiecare membru real al unei clase se numeste instanta. Metodele sunt functii care reprezinta o stare.Ele pot returna o valoare, cum ar fi un numar intreg sau o valoare de tip boolean.Metodele pot fi apelate si de clase diferite de cea din care fac parte. O superclasa este clasa de pe nivelul cel mai inalt al unei aplicatii.In Java, aceasta este intotdeauna clasa Object.Prin urmare, daca pentru o clasa nu este declarata superclasa sau clasa de pe nivelul imediat superior, atunci aceasta este in mod automat o subclasa a clasei Object.(Despre declaratii vom discuta in sectiunea Declararea unei clase.)Fiecare instanta a unei clase reimplementeaza logica si definitiile create de superclasa. Subclasele extind superclasa si creeaza o noua varianta a acesteia. Subclasele mostenesc toate caracteristicile clasei parinte.

Declararea unei clase


Fiecare clasa trebuie sa aiba un nume de identificare valid.Acest nume poate incepe cu o litera, cu liniuta de subliniere sau cu simbolul dolar.Dupa ce alegeti un nume adecvat, folositi urmatoarea sintaxa pentru declararea unei clase:

class MySuperClass { //corpul clasei }

Corpul clasei este declarat intre acolade.Remarcati faptul ca numele clasei este precedat de numele superclasei si de caracterul punct.(In acest mod, este evidentiata si mostenirea clasei, fenomen despre care vom discuta mai tarziu.)Aceasta sintaxa permite compilatorului sa afle unde gaseste informatii despre clasa respectiva. Numele asociat unei clase trebuie sa respecte aceleasi conditii ca si numele de identificare: sa inceapa cu o litera, cu liniuta de subliniere sau cu simbolul dolar.Prin conventie, numele claselor incep incep cu o litera mare.In acest fel, clasele pot fi deosebite cu usurinta de metode, variabile si alti identificatori.Este recomandabil sa respectati aceasta conventie pentru clasele Java.

O privire generala asupra claselor pentru aplicatii si miniaplicatii


Cu ajutorul limbajului Java, pot fi create doua tipuri de programe:aplicatii si miniaplicatii.Aplicatiile sunt programe independente, care pot fi rulate direct din linia de comanda.Miniaplicatiile au nevoie de un program extern care sa le asigure interfata cu utilizatorul.Browserele Web si programul de vizualizare din setul de dezvoltare Java (JDK) sunt exmple de interfete care permit rularea miniaplicatiilor. Miniaplicatiile Java prezinta restrictii si din punctul de vedere al operatiilor pe care le pot executa.Deoarece browserele Web constituie o metoda uzuala de acces la miniaplicatii, actiunea acestora asupra sistemului local reprezinta o problema de securitate.Ca urmare, miniaplicatiile nu pot scrie si nu pot citi fisiere de pe hard-discul local, nu au acces direct la memorie si nu pot deschide conexiuni cu alte miniaplicatii in afara celor care se afla pe acelasi server. Aceste restrictii asigura o protectie elementara, impiedicand o miniaplicatie dintr-o pagina Web necunoscuta sa citeasca fisierul local de parole si sa il transmita autorului miniaplicatiei.Java permite insa ca unele dintre aceste restrictii sa fie eliminate.Folosind programul de vizualizare , puteti acorda unei miniaplicatii permisiunea de a scrie sau de a citi intr-un anumit director sau intrun set de directoare.Aceste diminuari ale securitatii constituie o sursa de pericole si impun precautie. Observatie:Mecanismul care asigura securitatea face parte,de fapt, din aplicatia client care ruleaza miniaplicatia (de exemplu, browserul sau programul de vizualizare a miniaplicatiilor).Acest mecanism este, de obicei, gestionarul de securitate al miniaplicatiilor.Pentru mai multe informatii despre gestionarul de securitate al miniaplicatiilor, cititi capitolul 5, Instrumente Java si setul JDK:abecedar. Aplicatiile nu au asemenea restrictii.Utilizatorii care ruleaza aplicatii Java au acces normal la orice fisier, zona de memorie sau resursa de retea.

Clase pentru aplicatii


Aplicatiile Java sunt aplicatii reale, asemenea celor dezvoltate in alte limbaje de programare, cum ar fi C sau C++.In momentul scrierii acestei carti, miniaplicatiile Java erau deja foarte populare;in schimb, aplicatiile Java nu au avut parte de aceeasi publicitate.Sun Microsystems incearca sa schimbe aceasta situatie.Sun estimeaza ca, din mai multe motive, Java va inlocui in curand

limbajul C++ in preferintele programatorilor.Primul motiv consta in faptul ca Java este un limbaj direct si aproape la fel de puternic ca C++.Limbajul Java a fost elaborat de catre o organizatie, conform unor specificatii;nu s-a dezvoltat ad-hoc, ca alte limbaje de programare.Ca urmare, componentele limbajului Java sunt mai bine integrate.De asemanea, Java a eliminat o parte din redundantele limbajului C++. Un alt motiv este independenta de platforma a limbajului Java, in ceea ce priveste programarea si intretinerea codului.O organizatie poate scrie aplicatii Java care sa fie rulate pe orice platforma pentru care a fost creat un interpretor Java.Acesta este un mare castig pentru companiile care lucreaza pe mai multe platforme. Ganditi-va la modul de lucru in firmele actuale.Pribabil ca sunt folosite mai multe platforme.Este posibil ca firma sa vanda produse soft unor clienti care folosesc, de asemenea, mai multe platforme.Nu sunt rare situatiile cand pe acelasi birou puteti vedea terminale pentru accesul la diferite aplicatii.Imaginati-va ca scrieti o aplicatie care poate fi rulata pe un PC, pe un Macintosh, pe un calculator mainframe, pe sisteme UNIX si pe orice alt sistem existent in cadrul companiei.Acest lucru este posibil in Java. Desigur, va intrebati care este reversul medaliei.Problema reala este viteza.Aplicatiile Java ruleaza cu mult mai incet decat aplicatii compilate in cod nativ, care transforma codul sursa in cod masina.Performantele depind de mai multi factori.Totusi, este greu ca un limbaj interpretat sa concureze cu un cod compilat nativ. Problemele de performanta vor fi probabil depasite in viitorul apropiat, prin crearea unor interpretoare optimizate sau prin folosirea compilatoarelor JIT(just-in-time), care si-au facut deja aparitia.Se mai vorbeste despre aparitia unor compilatoare native care sa permita stocarea codului in sisteme locale.(Sunteti amator?)Problema care apare este faptul ca se pierde posibilitatea de actualizare instantanee oferita de Java.De asemenea, este posibil ca scaderile de performanta sa fie acceptabile, in lumina portabilitatii limbajului.Cu ceva vreme in urma, renuntarea la performantele oferite de codul masina in favoarea usurintei de dezvoltare a limbajelor de nivel inalt, precum C, a fost considerata si ea acceptabila, desi unii puritani au protestat.Acum este momentul trecerii la urmatorul nivel al limbajelor de programare, nu al lamentarilor pentru pierderea C-ului. Observatie:Unul dintre seturile de instrumente care include un compilator JIT pentru Java este Symantec Cafe.Multe alte companii producatoare de soft si-au propus includerea acestor compilatoare.Cine stie?Poate ca tendinta de integrare a limbajului Java in sistemele de operare va determina si generalizarea rapidelor compilatoare JIT(just-in-time) Din punct de vedere structural, aplicatiile Java sunt asemanatoare cu miniaplicatiile.Singurele diferente majore sunt metoda de declarare si de lansare in executie a programului.Ati vazut deja mai multe exemple de declaratii.Este posibil, insa, ca modalitatea prin care programul isi incepe executia sa nu fie atat de evidenta;aceasta se realizeaza prin intermediul metodei main ( ).

main ( )
Toate aplicatiile Java trebuie sa defineasca o metoda numita main ( ) , similara functiei main ( ) din C si C++.Atunci cand se lanseaza in executie o aplicatie Java, interpretorul Java cauta metoda main ( ) si incepe executia de la aceasta.Daca metoda main ( )nu a fost declarata, compilatorul afiseaza o eroare. Metodele main ( ) trebuie sa fie declarate publice.Ar fi imposibil pentru un program care nu se bazeaza pe limbajul Java sa lsnseze o aplicatie Java, daca metoda main ( ) nu ar fi declarata publica.

Declararea metodei main ( ) trebuie sa respecte un anumit format:


public static void main (String args [ ] ){ ... corpul metodei main ... }

Declararea publica a metodei main ( ) permite programelor externe accesul la aceasta.Cuvantul cheie static semnifica faptul ca aceasta metoda nu poate fi modificata de subclase.Cuvantul cheie void semnifica faptil ca metoda nu returneaza nici o valoare. main ( ) este numele obligatoriu al metodei.(String args [ ] )indica faptul ca metoda main ( ) accepta ca argument in linia de comanda o matrice de obiecte de tip String .Aceasta matrice contine argumentele specificate in linia de comanda la lansarea aplicatiei. Iata cum o aplicatie Java de salut standard Hello World!:
public class HelloWorld { public static void main (String args[ ] ) System.out.println (Hello World!); } } {

Pentru compilarea acestui exemplu, introduceti urmatoarea comanda:


javac HelloWorld.java

Dupa ce compilatorul isi incheie sarcina, apelati interpretorul Java cu urmatoarea comanda:
java HelloWorld

Aplicatia ar trebui sa afiseze urmatorul rezultat:


Hello World!

Clase pentru miniaplicatii


Miniaplicatiile constituie latura cea mai cunoscuta a limbajului de programare Java, in acest moment.Java este asociat cu sistemul World Wide Web;miniaplicatiile Java au capacitatea de a transforma o pagina statica Web intr-o prezentare multimedia interactiva. Miniaplicatiile Java se bazeaza pe programe externe care le asigura interfata cu utilizatorul.Ele nu pot fi rulate independent.Browserul Web care recunoaste limbajul Java si programul de vizualizare a miniaplicatiilor (appletviewer) din setul JDK sunt doar doua dintre aceste programe. Miniaplicatiile constituie o extensie a unei clase existente, java.applet.Applet.O miniaplicatie este, de fapt, un exemplu de subclasa.Pentru declararea unei miniaplicatii , folositi cuvantul cheie class, la care se adauga modificatorul extends.Acesta semnaleaza compilatorului ca miniaplicatia este o subclasa a altei clase (in acest caz, a clasei java.applet.Applet ).Iata un exemplu de declaratie:
import java.awt.*; // importa bibliotecile de clase import java.awt.image.*; import java.applet.*; public class HelloWorldApplet extends Applet { public void paint (Graphics g) { g.drawString(Hello World!, 10, 10); }

Dupa compilarea codului sursa al miniaplicatiei, trebuie sa creati un document HTML care sa fie folosit de browserul Web sau de programul de vizualizare pentru afisarea miniaplicatiei.Iata un exemplu de document HTML pentru miniaplicatia HelloWorldApplet:
<HTML> <HEAD> <TITLE>HelloWorldApplet</TITLE> </HEAD> <BODY> <APPLET CODE=HelloWorldApplet WIDTH=300 HEIGHT=300></APPLET> </BODY> </HTML>

In general, miniaplicatiile trebuie sa fie mult mai sigure (blindate) decat aplicatiile, datorita mediului in care lucreaza.Nu numai ca trebuie sa ruleze, dar ele trebuie si sa poata trata evenimente precum clicurile de mouse, redesenarea, intreruperea si altele.Multe dintre elementele care par sa fie gestionate de browser cad, de fapt, in sarcina miniaplicatiei. Un exemplu edificator este urmatoarea secventa de evenimente: o miniaplicatie afiseaza o imagine pe ecran.Utilizatorul activeaza o alta fereastra , care acopera partial imaginea initiala, apoi inchide noua fereastra.Cine se ocupa de redesenarea imaginii miniaplicatiei?Nu browserul, ci chiar miniaplicatia. Browserul va informa miniaplicatia ca este necesara redesenarea, dar operatiunea propriu-zisa cade in sarcina miniaplicatiei. Miniaplicatiile incep executia altfel decat aplicatiile.Executia programului unei aplicatii incepe prin apelarea metodei main ( ) , folosesc metodele init ( ) si start ( ).De fiecare data cand miniaplicatia este lansata in executie, browserul apeleaza mai intai metoda init ( ), apoi metoda start( ).Aceste metode nu trebuie sa fie declarate explicit in cadrul miniaplicatiei. Sa revenim la exemplul HelloWorldApplet.Remarcati ca nu exista nici un apel explicit al metodei paint ( ) , si totusi desenarea ecranului se realizeaza.Intr-o miniaplicatie Java, multe lucruri se petrec in spatele scenei.Acesta este un exemplu de miniaplicatie care incepe executia fara o declarare explicita a metodelor init ( ) si start( ) , bazandu-se pe implementarea prestabilita a acestora.Metoda prestabilita start ( ) apeleaza automat metoda repaint ( ) care, printre altele, apeleaza metoda paint ( ).Aceasta trebuie sa fie declarata explicit pentruorice afisare pe ecran. Iata un rezumat al evenimentelor care se petrec atunci cand un program de vizualizare apeleaza o miniaplicatie.Este important sa intelegeti aceasta secventa de operatii, pentru cazul cand una dintre metodele de lansare in executie a miniaplicatiei este redefinita.Miniaplicatia nu va fi executata corespunzator daca omiteti vreuna dintre aceste operatii.Atunci cand un program de vizualizare apeleaza o miniaplicatie, aceasta apeleaza mai intai metoda init ( ). Metoda init ( ) poate fi declarata explicit sau poate fi poate fi cea prestabilita.Apoi, programul de vizualizare apeleaza metoda start ( ) care, la randul ei, poate fi declarata explicit sau implicit.In cadrul metodei start ( ) ,este apelata metoda repaint ( ) , care contine un apel al metodei paint ( ) .Metoda paint ( ) prestabilita nu va afisa nimic pe ecran, asa ca trebuie sa fie redefinita.

init ( )
Metoda init ( ) este apelata numai cand miniaplicatia este incarcata pentru prima data intr-un program de vizualizare.In cadrul metodei init ( ) , initializarile se fac o singura data.Acesta este locul potrivit pentru preluarea argumentelor din linia de comanda, transmise de pagina HTML din care a fost apelata miniaplicatia.(Despre argumentele din linia de comanda vom discuta in sectiunea Declararea unui pachet.)

Metoda init( ) are un format fix. Trebuie sa fie intotdeauna numita init( ) , sa returneze tipul void (adica sa nu returneze nici o valoare), sa fie declarata publica si sa nu aiba argumente. Iata o ilustrare a metodei init ( ):
public void init ( ) counter = 0; } {

Singura operatie executata in acest exemplu este stabilirea variabilei counter la valoarea 0. Declararea metodei init ( ) nu este necesara.Daca este declarata, aceasta metoda redefineste metoda init ( ) din clasa java.applet.Applet;este motivul pentru care numele, tipul returnat si celelalte informatii sunt fixe.

start ( )
Metoda start ( ) este apelata dupa metoda init ( ) , atunci cand miniaplicatia este incarcata pentru prima data intr-un program de vizualizare sau cand executia miniaplicatiei a fost suspendata si trebuie sa fie reluata.In cazul in care compilatorul nu gaseste o metoda start ( ) declarata explicit in cadrul miniaplicatiei, va apela in mod prestabilit metoda start ( ) din clasa java.applet.Applet.Iata o ilustrare a metodei start ( ):
public void start ( ) { run=true; while (run==true) { counter +=1; repaint ( ); // remarcati apelul explicit al metodei repaint ( ) try {Thread.sleep (100) ; } catch (InterruptedException e ) { } } }

Metoda start ( ) din exemplul de mai sus atribuie variabilei run valoarea true, apoi intra intr-o bucla while care este executata atata timp cat variabila run are valoarea true.Bucla while incrementeaza valoarea counter, care a fost stabilita la 0 in metoda init.Apelul metodei repaint ( ) determina redesenarea ecranului la fiecare incrementare a variabilei counter.Instructiunile try si catch determina o pauza de 1000 milisecunde in executia programului, dupa fiecare incrementare a variabilei counter.(Despre instructiunile try si catch vom discuta in capitolul 8, Integrarea tuturor elementelor : fire de executie, exceptii si altele.) Declararea metodei start ( ) nu este necesara.Ca si in cazul metodei init ( ) , daca este declarata , metoda redefineste metoda start ( ) prestabilita din clasa java.applet.Applet.Si aceasta metoda are un format fix, asa cum ati vazut in exemplul anterior.

stop ( )
Metoda stop ( ) este apelata de fiecare data cand o miniaplicatie trebuie sa fie oprita sau suspendata.Fara aceasta metoda, miniaplicatia ar continua sa ruleze, consumand resursele sistemului, chiar dupa ce utilizatorul a parasit pagina miniaplicatiei.S-ar putea ca uneori continuarea executiei sa fie necesara , dar , in general, nu este.Iata o ilustrare a metodei stop ( ) :
public void stop ( ) run=false; } {

Metoda atribuie variabilei run valoare false.Aceasta valoare determina iesirea din bucla while a metodei start ( ) prezentate in exemplul anterior, ajungandu-se astfel la sfarsitul metodei.Rezultatul este faptul ca executia miniaplicatiei inceteaza.Remarcati ca nu se modifica decat variabila run. Ca si in cazul metodelor init ( ) si start ( ) , declararea metodei stop ( ) nu este necesara.Metoda redefineste metoda stop ( ) prestabilita din clasa java.applet.Applet si are un format fix , asa cum ati vazut in exemplul anterior.

paint ( )
Metoda paint ( ) este folosita pentru desenarea sau redesenarea ecranului.Ea este apelata automat de metoda repaint ( ) , dar poate fi apelata si explicit de miniaplicatie.Aceasta se intampla de fiecare data cand browserul cere redesenarea ecranului, de exemplu atunci cand o miniaplicatie care a fost acoperita de o alta fereastra este adusa din nou in prim-plan. Metoda paint ( ) are un format fix.Trebuie sa fie intotdeauna numita paint, sa returneze tipul void ( adica sa nu returneze nici o valoare ) si sa fie declarata publica.Spre deosebire de metodele init ( ) si start ( ) , are un argument , de tip Graphics.Acesta este un tip predefinit in Java , care contine mai multe metode pentru desenarea imaginilor si a textului pe ecran.Iata o ilustrare a metodei paint ():
public void paint (Graphics g ) { g.drawstring(counter = + counter , } 10, 10 ) ;

Aceasta metoda afiseaza pe ecran valoarea variabilei counter, de fiecare data cand este apelata.Incercati sa o combinati cu metodele start ( ) si repaint ( ). Metoda start ( ) incrementeaza variabila counter, apoi apeleaza metoda repaint ( ).Pe ecran este afisata noua valoare a variabilei counter, de fiecare data cand aceasta este actualizata. Declararea metodei paint ( ) nu este ceruta de compilator.Metoda redefineste o metoda prestabilita, furnizata da clasa java.applet.Applet.Dar daca nu redefineste aceasta metoda, nu puteti afisa nimic pe ecran.

Un exemplu de folosire a metodelor start ( ) , init ( ) , paint ( ) si stop ( )


import java.awt.Graphics; public class Counter extends java.applet.Applet { int counter; boolean run; public void init( ) { counter = 0; } public void start ( ) { run = true; while (run == true) { counter++; repaint ( ); try ( Thread.sleep(1000);} catch (InterruptedException e) {} } } public void stop( ) { run = false; } public void paint(Graphics g) { g.drawString(counter = + counter, 10, 10);

Acest cod nu va putea fi rulat in forma de mai sus;mai este nevoie de fire de executie si de exceptii despre care vom discuta in capitolul 8.

Modificatori
Modificatorii schimba unele aspecte ale claselor.Ei sunt specificati in declaratia clasei, inainte de numele acesteia.In exemplele din acest capitol , au fost folositi mai multi modificatori. Modificatorii de clasa sunt folositi pentru specificarea a doua aspecte ale claselor:modul de acces si tipul. Modificatorii de acces sunt folositi pentru stabilirea modului intern si extern de utilizare a clasei.Modificatorii de tip declara implementarea unei clase.O clasa poate fi folosita fie ca un sablon pentru subclase, fie ca o clasa propriu-zisa.Acesti modificatori vor fi descrisi in detaliu in sectiunile urmatoare.

Declararea securitatii clasei


In ceea ce priveste securitatea , clasele pot fi declarate astfel incat accesul la ele sa fie permis si claselor din afara propriului pachet, prin folosirea cuvantului cheie public.Daca acesta nu este folosit explicit la declararea clasei, accesul la clasa respectiva este permis numai claselor din acelasi pachet.Daca in declaratia clasei este folosit orice alt modificator de acces, cum ar fi private sau protected, va fi generata o eroare de compilare, deoarece acesti modificatori sunt rezervati pentru metode. Iata cateva exemple de declarare a securitatii claselor:
public class nume_clasa } class nume_clasa } { {// accesul la clasa este permis si claselor din afara // propriulu pachet // accesul la clasa este permis numai claselor din //acelasi pachet

Acesta este un alt exemplu de refolosire a codului in aceeasi aplicatie sau in aplicatii Java diferite. Datorita structurii limbajului Java, acest lucru este usor de realizat si permite si folosirea unor elemente de protectie.

Tipuri de clase: abstracte sau prestabilite


Exista doua tipuri de clase : abstracte sau prestabilite. Clasele abstracte trebuie sa fie declarate in mod explicit. Modificatorul abstract este folosit pentru crearea claselor sablon. Acestea sunt folosite , de obicei, pentru furnizarea superclasei pentru alte clase.O clasa abstracta poate sa contina declaratii de metode si variabile, dar nu si codul necesar pentru crearea unor noi instante. O clasa abstracta poate contine si metode abstracte. Aceste metode definesc tipul returnat, numele metodei si argumentele , dar nu contin corpul metodei.Subclasele trebuie sa implementeze aceste metode abstracte, astfel incat sa creeze un corp al metodei. Daca o clasa abstracta contine numai

metode, nu si variabile, este mai bine sa folositi o interfata ( despre care vom discuta in sectiunea Interfete ). Iata un exemplu de declaratie a unei clase abstracte:
abstract class Aclass { int globalVariable; abstract void isBlack } }

(boolean)

Aceasta clasa abstracta declara o variabila globala , numita si globalVariable , si defineste sablonul unei metode numite isBlack( ) .Remarcati ca exista un corp pentru metoda isBlack ( ).Acesta trebuie sa fie implementat de subclasele clasei AClass. In caz contrar, compilatorul afiseaza un mesaj de eroare.

Variabile folosite de clase


In capitolul 6, am discutat despre variabile , privite ca elemente independente.In caeasta sectiune , veti vedea cum sunt folosite variabilele in clase. Variabilele sunt folosite in clase pentru stocarea unor valori care vor fi utilizate mai tarziu. In cadrul unui program, se recomanda ca ele sa fie declarate imediat dupa instructiunea de declarare a clasei , ca in exemplul urmator:
class ShowVarables { int Int1, Int2; int Int3=37; char OneChar; float FloatArray [ ]; // declara doua variabile intregi //declara si initializeaza o variabila // declara o variabila de tip caracter //declara o matrice unidimensionala de numere in //virgula mobila boolean AmITrue; //declara o variabila de tip boolean //aici urmeaza codul care va executa ceva

Instructiunile de declarare a variabilelor din acest exemplu stabilesc variabilele care vor fi folosite in clasa.In acest moment, nu exista expresii sau metode care sa efectueze o actiune. Toate clasele pot avea variabile asociate.Variabilele pot fi impartite in doua categorii: cele specifice unei instante, numite variabile de instanta, si cele globale, pentru toate instantele unei clase, numite variabile de clasa.Tipul fiecarei variabile este determinat de utilizarea acesteia.

Variabile de instanta
Variabilele de instanta exista numai pentru o anumita instanta a unui obiect.Aceasta inseamna ca diferite instante ale unei clase pot avea variabile cu acelasi nume, Java stocand valorile acestora la adrese de memorie diferite.Fiecare dintre variabilele de instanta este manipulata individual.La disparitia unei instwnte, dispar toate variabilele acesteia.Aveti acces la variabilele de instanta si din alte instante, dar variabilele exista numai in instanta respectiva. Ati intalnit variabile de instanta in exmplele din acest capitol.Ele sunt declarate imediat dupa declarare clasei, dar inainte de declararea metodelorToate instantele clasei contin o copie a variabilelor respective.Iata un exemplu de declarare a unor variabile de instanta:

class cat { String [ ] name; Strig [ ] color;

int

weight;

Fiecare instanta a clasei ACat are variabile pentru nume, culoare si greutate, care stocheaza informatii despre o anumita pisica ( in limba engleza cat ).Daca aveti doua pisici despre care vreti sa scrieti intr-o pagina Web, veti specifica numele , culoarea si greutatea fiecarei pisici intr-o instanta separata a clasei, fara sa va faceti griji in privinta suprascrierii informatiilor.

Variabile statice
Declaratiile variabilelor si metodelor pot fi modificate cu modificatorul static.Variabilele statice sunt pastrate intr-un singur loc din memoria calculatorului si sunt accesibile global tuturor instantekor unei clase.O variabila nu poate fi modificata de subclasele unei clase, daca a fost declarata statica si finala.Variabilele statice au deci aceeasi valoare in toate instantele unei clase. Acesta este un instrument foarte util in situatiile in care o variabila este partajata de mai multe instante ale unei clase si/sau ale subclaselor unei clase.Toate instantele contin aceeasi valoare pentru variabila respectiva.De asemenea, toate clasele care au acces la acea variabila adreseaza acelasi loc din memorie.Variabila ramane acolo pana cand ultima instanta care are acces la ea este stearsa din memorie. O variabila statica este declarata in acelasi fel ca si o variabila de instanta, dar este precedata de cuvantul cheie static.In secventa de cod care urmeaza, variabila animalType este declarata statica, avand aceeasi valoare pentru toate instantele clasei ACat:
class ACat } { static String animalType [ ] = cat;

In acest mod , pentru toate instantele valoarea acestei variabile este aceeasi.Variabila animalType este accesibila si pentru clasele externe.Valoarea sa trauie specificata o singura data si stocata intrun anumit loc, deoarece este aceeasi pentru toate instantele clasei ACat.

Instante predefinite
In Java exista trei instante predefinite:null, this si super.Acestea sunt folosite ca scurtaturi pentru multe operatii uzuale.

null
Ce se intampla in cazul in care clasa creata este o superclasa? Poate fi creata o variabila care sa tina locul subclaselor pentru completarea valorilor. In aceasta situatie, variabila poate fi declarata nula, ceea ce inseamna ca nu are atribuita nici o valoare, ca in exmplul urmator:
int PlaceHolder=null; //PlaceHolder este un obiect fara continut

Iata un fragment de cod care foloseste valoarea null:


class ACat { static String name=null; public void main (String args [ ] ) { ACat cat=new ACat ( ); if (cat.name==null) { PromtForName (Introduceti un nume:); } }

In acest exemplu , variabila name este initializata cu valoarea null.Metoda main ( ) testeaza daca variabila name are valoarea null.In caz afirmativ, utilizatorului i se cere sa introduca un nume.Valoarea null nu poate fi folosita cu tipurile de date primitive.

this
Pentru referirea la obiectul curent , se foloseste cuvantul cheie this, care permite desemnarea explicita a instantei curente a unei variabile.Acest mod de referire este util atunci cand instanta curenta a unei variabile trebuie sa fie transmisa unei alte clase care foloseste aceeasi variabila:
void promtForName(Sring promt) { StringBuffer name; char ch=\0; name= new StringBuffer( ); System.out.print(promt); System.out.flush( ); while (ch !=\n) { try{ch=(char) System.in.read ( );} catch(IOException e) { }; name.append (ch); } this.name = name.toString ( );

Compilatorul intelege implicit ca instanta curenta a unei variabile de clasa este this.Nu faceti o referire explicita, daca nu este absolut necesar.

super
super este o referinta la superclasa.Ea este deseori folosita ca o scurtatura sau ca o modalitate explicita de referire la un membru din superclasa clasei curente.In secventa urmatoare de cod, o subclasa numita APersianCat foloseste cuvantul cheie super pentru referirea la metoda promtForName ( ) din superclasa ACat :
class ApersianCat extends ACat { void getCatInfo { super.promtForName ( ) ; } }

Daca nu ar fi fost folosit cuvantul cheie super, ApersianCat ar fi cautat metoda numita promtForName ( ) in clasa curenta, ceea ce ar fi generat o eroare de compilare.

Metode folosite de clase


De-a lungul acestui capitol, am folosit metode, dar a venit momentul sa le definim mai exact.Metodele sunt similare functiilor din C si C++.Ele furnizeaza o modalitate de grupare a unui set de instructiuni , care vor putae fi desemnate cu un nume.Puteti sa refolositi blocul de cod respectiv prin simpla referire la numele metodei.In plus, codul metodei nu este inclus in alte secvente de cod. Metodele nu sunt declarate cu un cuvant cheie explicit.Ca si clasele, metodele au un nume , dar , spre deosebire de acestea, au argumente si tipuri de valori returnate.

Argumentele sunt parametrii transmisi la apelarea metodei, astfel incat aceasta sa poata efectua diferita sarcini.Codul intern al metodei stie cum sa manipuleze parametrii de intrare. De asemenea, metodele au un tip de valoare returnata.Aceasta este o valoare care poate fi returnata codului care a apelat metoda.Valorile returnate pot avea orice tip acceptat de limbajul Java, inclusiv siruri de caractere si valori numerice. Metodele pot fi apelate nu numai de din clasa curenta, ci si din subclasele si superclasa acesteia, si chiar din alte clase.Este o caracteristica a structurii limbajului Java, care ii confera flexibilitate si eficienta. Iata un exemplu de metoda:
public static void main ( String . . . corpul metodei . . . } args [ ] ) {

Metoda de mai sus a fost folosita de mai multe ori in aceasta carte.Este metoda main ( ), prima apelata la lansarea in executie a unei aplicatii Java independente.In acest exemplu , public si static sunt modificatorii metodei, void este tipul returnat de metoda, main este numele metodei, iar ( String args [ ] ) este lista sa de argumente.Aceasta este urmata de o acolada deschisa , care marcheaza inceputul corpului metodei.Corpul metodei poate contine orice bloc valid de cod Java.De asemenea, poate include apelari la alte metode si chiar la ea insasi.In fine, corpul metodei este urmata de o acolada inchisa.

Tipul valorilor returnate


Metodele pot returna orice tip de valori acceptat de Java : valori de tip boolean , matrice, obiect reprezentand un intreg cartier de blocuri etc.Tipul returnat trebuie precizat imediat inaintea numelui metodei.Secventa de cod care urmeaza declara o metoda numita isBlack ( ) , care returneaza o valoare de tip boolean:
boolean if isBlack (Color color ) ( color == black ) return (true); (false); {

else return }

In corpul metodei, se verifica daca culoarea transmisa ca parametru este negru (black).Daca raspunsul este afirmativ, metoda foloseste cuvantul cheie return pentru a returna metodei apelante valoarea true.In caz contrar, metoda foloseste cuvantul cheie return pentru a returna metodei apelante valoarea false. void este un tip special de retyrnare in Java, care semnifica faptul ca metoda nu returneaza nici un fel de valoare.Acest cuvant cheie este folosit pentru metodele care nu trebuie sa returneze nimic programului apelant sau care doar modifica argumentele metodei sau variabilele globale. Un exemplu de metoda care nu trebuie sa returneze vreo valoare programului apelant este cea care nu face altceva decat sa afiseze rezultatele pe ecran.In acest caz, nu este nevoie de valori returnate, deoarece nu mai urmeaza alte prelucrari.Daca metoda este declarata void, nu este nevoie sa folositi cuvantul cheie return.

Modificatorii metodelor

Conceptul de modificator, prezentat pentru clade, este valabil si pentru metode. Modificatorii controleaza accesul la metode.De asemenea, ei sunt folositi pentru a declara tipul unei metode.Metodele au la dispozitie mai multi modificatori decat clasele.

Declararea securitatii si accesibilitatii metodelor


Instructiunile de declarare a metodelor furnizeaza compilatorului informatii referitoare la acces.In termenii limbajului Java, accesibilitate inseamna securitate. Exista cinci niveluri de acces : Nivel public private protected private protected <default> Accesul este permis pentru Toate celelalte clase Nici o alta clasa Subclase si clase din acelasi pachet Numai subclase Clasele din acelasi pachet

private
Modificatorul private precizeza ca nici o alta clasa sau subclasa nu poate apela metoda.Acest modificator poate fi folosit pentru a ascunde complet o metoda pentru celelalte clase.Daca nici o alta clasa nu are acces la metoda, aceasta poate fi modificata oricand, fara sa genereze probleme.Iata un exemplu de metoda declarata ca privata :
private void . . . } isBlack (Color color ) {

protected
Modificatorul protected precizeaza ca metoda poate fi apelata numai de clasele aflate in acelasi pachet cu clasa in cadrul careia a fost definita si de subclasele acesteia.In acest fel, este permis accesul obiectelor care fac parte din aceeasi aplicatie, dar nu si al obiectelor din alte aplicatii.Iata un exemplu de metoda partajata :
protected void . . . } isBlack ( Color color ) {

private protected
Modificatorul private protected este o combinatie speciala a modificatorilor de acces private si protected.Acest modificator precizeaza ca metoda poate fi apelata numai de clasa in care este definita si de subclasele acesteia.Spre deosebire de modificatorul protected , nu permite apelarea metodei de catre clasele din acelasi pachet ; in schimb, permite apelarea metodei de catre subclase, ceea ce nu se intampla in cazul modificatorului private. Iata un exemplu:
private protected void isBlack (Color color) . . . } {

Accesul prestabilit
In mod prestabilit, accesul la metode este permis clasei in care este definita metoda, subclaselor acesteia si claselor din acelasi pachet. In acest caz, nu se foloseste nici un modificator de acces explicit in declaratia clasei. Iata un exemplu:
void isBlack (Color color) { . . . }

static
Modificatorul static este asociat numai metodelor si variabilelor, nu si claselor. El este folosit pentru a preciza ca o metoda poate fi declarata o singura data. Nici o subclasa nu poate implementa o metoda cu acelasi nume.Acest modificator este folosit in cazul metodelor care constituie puncte de intrare intr-un program , precum metoda main ( ). Sistemul de operare nu ar sti ce metoda sa apeleze mai intai, daca ar exista doua metode main( ) .Metodele statice sunt folosite pentru a specifica metodele care nu trebuie redefinite in subclase.Iata un exemplu:
static void isBlack (Color color) . . . } {

final
Modificatorul final indica faptul ca un obiect este stabilit si nu poate fi modificat.Atunci cand folositi acest modificator pentru un obiect de nivelul clasei, inseamna ca acea clasa nu poate avea subclase .Daca aplicati modificatorul unei metode, inseamna ca metoda respectiva nu poate fi redefinita.Daca aplicati modificatorul unei variabile, variabila respectiva ramane constanta.In cazul in care incercati sa modificati o metoda sau o clasa finala, compilatorul va genera o eroare.Acelasi lucru se intampla daca incercati sa modificati valoarea unei variabile finale. Iata cum puteti folosi modificatorul final:
class neverChanging { // o variabila finala final int unchangingValue = 21; // o metoda finala final int unchangingingMethod } } (int a, int b) {

abstract
Modificator abstract este folosit pentru crearea metodelor sablon, care sunt foarte asemanatoare cu functiile prototip din C si C++.Metodele abstracte definesc tipul returnat, numele metodei si argumentele, dar nu contin corpul metodei.Subclasele trebuie sa impleteze metodele abstracte si sa furnizeze corpul acestora.Iata un exemplu de clasa abstracta:
abstract void isBlack (Color color) } {

Aceasta defineste un sablon pentru metoda isBlack ( ) .Remaecati ca nu este specificat corpul metodei isblack ( ) ; acesta urmeaza sa fie implementat de subclasele apartinand clasei in a fost definita metoda abstracta.In cazul in care subclasele nu implementeaza corpul metodei isBlack, va fi semnalata o eroare de compilare.

Supraincarcarea metodelor
Conceptul de supraincarcare (overloading) a metodelor pare,la prima vedere, fara sens. Dar, dupa ce va familiarizati cu termenul, veti vedea ca supraincarcarea creste forta limbajului Java.De ce ar dori cineva sa denumeasca la fel metode cu functionalitati diferite? Este exact ceea ce se realizeaza prin supraincarcarea metodelor.Puteti sa definiti de mai multe ori o metoda cu acelasi nume. Java selecteaza una dintre metodele cu acelasi nume, in functie de parametrii folositi la apelarea metodei.Fiecare metoda trebuie sa aiba o lista unica de parametrii. In Java , puteti supraincarca orice metoda curenta sau din superclase, cu exceptia cazului cand metoda este declarata statica. De exemplu, in secventa de cod care urmeaza, metoda isBlack ( ) este supraincarcata de trei ori:
class CheckForBlack { public boolean isBlack (Color color) { if (color == black) return(true); else return (false); } public boolean isBlack (String desc) { return (desc.compareTo(black); } public boolean isBlack (Paint paint) { if (paint.reflectedLight < 0.05) return (true); else return (false); } }

Toate metodele au acelasi nume si returneaza valori de acelasi tip, dar fiecare are o alta lista de argumente. Prima metoda verifica daca culoarea transmisa ca parametru metodei este negru (black).A doua metoda verifica daca sirul de caractere transmis ca parametru este egal cu sirul de caractere black.Ultima metoda determina daca obiectul paint transmis ca parametru metodei reflecta mai putin de 5% din lumina primita.Daca raspunsul este afirmativ, obiectul este considerat a fi negru. In toate cele trei cazuri, numele metodei si tipul valorii returnate sunt aceleasi, dar argumentele sunt diferite.Compilatorul Java foloseste automat metoda care accepta parametii transmisi la apelare.Daca nici una dintre metodele declarate nu accepta acesti parametri, compilatorul semnaleaza o eroare. Supraincarcarea metodelor permite o mai mare flexibilitate in apelare lor. In exemplul de mai sus, daca aveti nevoie de alt tip de test , puteti sa-l adaugati la clasa CheckForBlack.Programul Java va putea apela metoda isBlack folosind noul obiect. In acest fel, puteti sa efectuati mai multe teste, folosind un singur nume de metoda. Programatorul nu trebuie sa foloseasca un alt nume pentru o metoda care face acelasi lucru, dar intr-un mod

diferit.El se poate concentra asupra lizibilitatii programului, fara sa isi faca probleme in privinta numelor de metode.Iar in cazul proiectelor mari , un programator poate folosi metode care au acelasi nume cu cele folosite deja de un alt programator (cu conditia ca lista de argumente sa fie diferita).

Folosirea obiectelor
Folosirea obiectelor reprezinta una dintre diferentele majore intre un limbajprocedural, precum C, si un limbaj orientat pe obiecte, precum C++ sau Java.In limbajele , datele sunt considerate a fi distincte fata de cod.In programarea orientata pe obiecte, codul si datele formeaza o singura entitate.

Crearea si distrugerea obiectelor


In limbajele procedurale, spatiul pentru date este, de obicei, pre-alocat.Compilatorul cunoaste dimensiunea, tipul si numarul variabilelor si aloca spatiul necesar pentru acestea.Spatiul alocat datelor este fix in memorie si continua sa fie alocat pana la terminarea aplicatiei. In Java, spatiul necesar datelor nu este pre-alocat, ci este creat pe masura ce este necesar.Spatiul respectiv este alocat pe durata folosirii datelor, apoi este dezalocat automat.Aceasta procedura este asemanatoare cu apelurile de sistem malloc si free din C. Cea mai mare diferenta dintre Java si C consta in faptul ca eliberarea memoriei care nu mai este folosita de program nu trebuie facuta in mod explicit.In Java exista un sistem automat de colectare a gunoiului, care gaseste zonele de memorie nefolosite si le elibereaza automat.Acesta este un mare avantaj pentru programatori, deoarece scurgerile de memorie constituie o sursa de probleme serioase in limbajele standard (si unul din motivele pentru care in sistemele Unix reinitializarile sistemului sunt evenimente planificate). Exista unele diferente si intre limbajele C++ si Java.In C++, constructorii si destructorii sunt executati de fiecare data cand un obiect este creat sau distrus.In Java, exista un echivalent al constructorului C++, numit tot constructor, dar nu exista nici un echivalent al destructorului C+ +.Toate obiectele Java sunt eliminate cu ajutorul sistemului de colectare automata a gunoiului.Destructorii nu pot fi apelati explicit.Exista totusi o metoda, numita finalize, care poate fi folosita ca un destructor C++ in operatiile finale de curatenie pentru un obiect, inainte de a interveni sistemul de colectare a gunoiului, dar metoda are restrictii severe.

Crearea unei instante


Java aloca memoria in mod similar functiei malloc din C, cu ajutorul cuvantului cheie new.Acesta creeaza un obiect de orice tip, cu exceptia tipurilor de date primitive.Apoi, este atribuita o variabila care adreseaza obiectul respectiv.Iata un exemplu in acest sens:
String desc; desc = new String(10);

Aceste instructiuni aloca suficient spatiu in memorie pentru stocarea unui sir de 10 caractere si asociaza spatiul alocat cu variabila desc.Variabila desc este considerata un obiect de tip String si contine toate metodele asociate clasei String.Aceasta clasa include metode pentru determinarea lungimii sirului de caractere, pentru compararea cu un alt sir de caractere, pentru obtinerea unui subsir si multe altele. Apelarea metodelor in Java difera de apelarea functiilor in C.In limbajele procedurale, precum C, variabila desc este transmisa, in mod normal, ca parametru al unei functii.In Java, obiectul asociat

variabilei desc contine deja toate metodele necesare.Acesta este rezultatul folosirii metodelor asociate clasei String.In momentul crearii obiectului desc cu operatorul new, metodele devin parte a obiectului, ca in exemplul urmator:
sizeOfString = desc.length; //obtine lungimea sirului de caractere desc if (desc.compareTo(black); //verifica daca sirul de caractere desc este egal cu //black locOfSubString = desc.indexOf(black); //returneaza indexul subsirului

Aceste exemple sunt centrate pe obiect, nu pe functii, de unde si numele de programare orientata pe obiecte.

Distrugerea unei instante


Metoda destroy( ) este apelata de fiecare data cand executia unei miniaplicatii s-a terminat sau a fost intrerupta.In acel moment, sunt executate toate operatiile de curatenie.Metoda destroy( ) nu poate avea alt nume, are intotdeauna tipul de returnare void, este declarata publica si nu are argumente.Iata o exemplificare a metodei destroy( ) :
public void destroy( ) { counter = 0; }

Metoda destroy( ) din exemplul de mai sus nu face decat sa atribuie variabilei counter valoarea 0.Ea poate executa insa si sarcini mai complexe , cum ar fi intreruperea corecta a unei conexiuni la retea, inregistrarea unor informatii de jurnal in fisiere si alte operatii finale. Declararea metodei destroy( ) nu este necesara.Daca este declarata, metoda redefineste metoda destroy( ) din clasa java.applet.Applet; acesta este motivul pentru care numele, tipul returnat, argumentele si celelalte informatii sunt fixe.

Metoda constructor
Am aratat mai sus ca Java nu aloca memoria pentru obiectele dintr-o aplicatie in momentul lansarii acesteia, ci atunci cand sunt create instantele cu ajutorul cuvantului cheie new.La apelarea operatorului new, se intampla mai multe lucruri.In primul rand , Java aloca suficienta memorie pentru stocarea obiectului.In al doilea rand, Java initializeaza toate variabilele de instanta cu valori prestabilite. In al treilea rand, Java apeleaza toti constructorii clasei respective.Constructorii sunt metode speciale, folosite pentru initializarea unui obiect.Ei pot efectua aceleasi operatii ca si metodele, dar , in general, sunt folositi numai pentru initializarea variabilelor din cadrul unui obiect cu valorile de inceput. Constructorii nu au un cuvant cheie care sa ii marcheze ca atare.In schimb, constructorul are acelasi nume ca si clasa in care este dclarat.In exemplul urmator, apare o metoda cu numele ACat ( ):
class ACat { void ACat (Strinf breed[ ] ) this.breed=breed; } } {

Constructorii nu returneaza valori (sunt de tip void) si nu intotdeauna acelasi nume cu clasa in care au fost definiti. Atunci cand se foloseste operatorul new pentru crearea unui obiect, este apelat constructorul din exemplul precedent.De exemplu, in secventa de cod care urmeaza, apelarea operatorului new transmite constructorului ca parametru sirul de caractere Siamese, ceea ce determina initializarea variabilei de instanta breed cu aceasta valoare:
ACat cat; cat = new ACat(Siamese) ;

Constructorii se aseamana cu metodele obisnuite declarate explicit, in sensul ca pot fi supraincarcati prin declarari repetate, cu liste diferite de argumente.Constructorii multiplisunt creati prin declararea mai multor metode cu numele clasei.Ca si in cazul metodelor supraincarcate, Java determina constructorul care trbuie folosit pe baza argumentelor transmise operatorului new, ca in exemplul urmator:
class ACat { void ACat (String breed [ ] ) { this.breed = breed: } void ACat (Color color, int weight) this.color = colr; this.weight = weight; } }

In acest exemplu, este declarat un constructor suplimentar, care primeste ca argumenteculoarea (color) si greutatea (weight), pe langa primul constructor, care primeste ca argument rasa pisicii (btreed).Cel de-al doilea constructor este apelat astfel:
ACat cat ; cat = new ACat (black, 15) ;

Posibilitatea de declarare a constructorilor multipli ofera o mare flexibilitate in modul de construire a noilor obiecte.Constructorii sunt creati in functie de nevoile aplicatiei. Constructorii pot apela alti constructori din aceeasi clasa sau din superclasa.Java extinde conventiile de denumire a constructorilor,n folosind cuvintele cheie this si super pentru referirea constructorilor din clasa curenta sau din superclasa acesteia, ca in exemplul urmator:
class Amammal { anAnimal (String mammalType[ ] ) { } class ACat extends Amammal { void ACat (String breed[ ]) { this.breed = breed; } void ACat (Color color, int weight) } this.color = color; this.weight = weight; } void ACat (Color color, int weight, String breed[ ]) this(breed); this(color, weight); super(cat); } {

Cel de-al treilea constructor accepta toate argumentele folosite de ceilalti doi constructori.Dar, in loc sa copieze codul de initializare din ceilalti constructori, ii apeleaza direct cu ajutorul sintaxei this( ).In acest exemplu, exista si o superclasa numita Amammal, cu un constructor care defineste tipulmamiferului (mammaal).Cel de-al treilea constructor al clasei Acat foloseste acest tip, prin intermediul sintaxei super ( ) .

Metoda finalize( )
Atunci cand un obiect nu mai este referit de alte obiecte, Java recupereaza spatiul folosit de acesta, cu ajutorul sistemului de colectare automata a gunoiului.Inainte de colectarea gunoiului, Java apeleaza un un destructor.Spre deosebire de de metoda constructor,destructorul are un nume specific : finalize.Iata un exemplu:
void finalize ( ) { . . . corpul metodei finalize }

Metodele finalize ( ) nu returneaza nici o valoare(sunt de tip void) si redefinesc destructorul prestabilit din clasa java.object.Object. Un program poate apela metoda finalize ( ) ca pe orice alta metoda.Apelarea metodei finalize ( ) nu declanseaza insa operatia de colectare a gunoiului.Daca este apelata direct, finalize ( ) este tratata ca orice alta metoda.Atunci cand Java realizeaza colectarea gunoiului (eliberarea memoriei nefolosite) , metoda finalize ( ) este apelata din nou, chiar daca a fost deja apelata direct de program. Metoda finalize ( ) se aseamana cu celelalte metode, in sensul ca poate fi supraincarcata.Retineti ca Java apeleaza automat metoda finalize ( ), fara ai transmite vreun argument.Chiar daca in timpul operatiei de colectare a gunoiului gaseste o metoda finalize ( ) cu argumente, Java va continua sa caute o metoda finalize ( ) fara argumente.Daca o astfel de metoda nu este gasita, Java va folosi metoda finalize ( ) prestabilita. Una dintre deosebirile existente intre metoda finalize ( ) si destructorii din C++ este faptul ca sistemul apeleaza metoda finalize ( ) numai atunci cand este pregatit sa recupereze memoria asociata obiectului.Acest apel nu se face imediat ce obiectul respectiv nu mai este referit.Operatiile de curatenie sunt organizate de sistem in functie de necesitati.Poate aparea o intarziere semnificativa intre terminarea aplicatiei si apelarea metodei finalize ( ).Aceasta se intampla chiar daca sistemul este ocupat , in cazul in care nu exista o nevoie imperioasa de memorie.Din aceste motive, uneori este mai bine sa apelati direct metoda finalize ( ) la terminarea unui program, in loc sa asteptati ca aceasta sa fie apelata automat de sistemul de colectare a gunoiului;totul depinde de aplicatie.

Pachete
Cum se integreaza pachetele in aceasta ierarhie?Sa ne intoarcem la exemplul cu apartamentul.In orasul dumneavoastra, exista mai multe cartiere de blocuri care apartin aceleiasi companii.Aceasta companie mai detine spatii rezidentiale, zone comerciale si depozite, adica proprietati imobiliare.Ganditi-va la compania care le detine ca la cea mai mare unitate de referinta pentru aceste proprietati.Compania cunoaste fiecare dintre apartamente si le poate folosi in functie de necesitati.

In Java, echivalentul companiei din exemplul de mai sus este pachetul.Pachetele grupeaza biblioteci de clase, cum ar fi bibliotecile care contin informatii despre diferite proprietati comerciale sau despre terenurile din suburbii.Pachetul este cea mai mare unitate logica de obiecte din Java.Pachetele Java grupeaza o varietate de clase si/sau interfete.Unele contin clase unice.De asemenea, pachetele furnizeaza o modalitate de control al securitatii, precum si posibilitatea de ascundere a unor clase, impiedicand accesul altor pachete sau programe la clasele interne ale unei aplicatii.

Declararea unui pachet


Pachetele sunt declarate cu ajutorul cuvantului cheie package, urmat de numele pachetului.Aceasta declaratie trebuie sa fie prima instructiune dintr-un fisier sursa Java, exceptand comentariile si spatiile libere.Iata un exemplu:
package mammals ; class AMammal { . . . corpul clasei AMammal }

In acest exmplu, numele pachetului este mammals.Clasa AMammal este acum considerata parte componenta a acestui pachet.Includerea altor clase in pachetul mammals este o operatie simpla : nu trebuie decat sa plasati la inceputul fisierului sursa o linie identica celei din exemplul de mai sus.Deoarece, in general, fiecare clasa este plasata in propriul fisier sursa, toate fisierele sursa care contin clase dintr-un anumit pachet trebuie sa includa aceasta linie.Un fisier sursa nu poate contine decat o singura instructiune pentru declararea pachetului. Retineti faptul ca numai clasele declarate publice trebuie sa fie stocate in fisiere sursa separate.Celelalte clase pot fi stocate in acelasi fisier.Desi scrierea fiecarei clase intr-un fisier separat constituie un bun exercitiu de programare, instructiunea package de la inceputul fisierului se aplica tuturor claselor declarate in fisierul recpectiv. Java accepta si conceptul de ierarhie de pachete.Aceasta este similara ierarhiei de directoare folosita in multe sisteme de operare.Ierarhia este stabilita prin specificarea in instructiunea package a mai multor nume, delimitate prin caracterul punct.In exemplul urmator, clasa AMammal apartine pachetului mammal din ierarhia de pachete animal :
package animal.mammal ; class Amammal { . . . corpul clasei AMammal }

In felul acesta, este posibila gruparea claselor inrudite intr-un pachet si apoi gruparea pachetelor inrudite intr-un pachet mai mare.Pentru referirea la un membru al unui alt pachet, numele clasei este precedat de numele pachetului.Exemplul urmator ilustreaza modul in care poate fi apelata metoda promtForName din clasa ACat a subpachetului mammal din pachetul animal
Animal.mammal.Acat.promtForName ( ) ;

Analogia cu ierarhia de directoare este evidentiata si de interpretorul Java.Atunci cand urmareste sa obtina accesul la un membru al unui subpachet, interpretorul Java cere ca fisierul de clasa sa fie stocat intr-un subdirector avand acelasi nume cu subpachetul respectiv.Daca exemplul de mai sus ar fi folosit pe un sistem UNIX, clasa in care se afla metoda promtForName ( ) ar fi localizata astfel:

animal/mammal/ACat.class

Desigur, conventiile de denumire a directoarelor difera de la un sistem de operare la altul.Compilatorul Java va stoca fisierul de clasa in acelasi director cu fisierul sursa.In cazul in care fisierele sursa nu sunt in acelasi director cu fisierele de clasa, se impune mutarea fisierelor de clasa rezultate in directoarele corespunzatoare. Fisierele de clasa pot fi stocate intr-un anumit director prin folosirea optiunii d (director) in linia de comanda a compilatorului javac.Pentru a continua exemplul de mai sus, comanda care urmeaza va plasa fisierele rezultate in subdirectorul animal/mammal/ACat din directorul curent:
>javac d animal/mammal/ACat ACat.java

Toate clasele apartin unui pachet, chiar daca acesta nu a fost declarat explicit.In majoritatea exemplelor din aceasta carte nu a fost declarat nici un nume de pachet:totusi, ele nu pot fi compilate si rulate fara probleme.Asa cum ne-am obisnuit deja, in Java, tot ceea ce nu este declarat explicit primeste in mod automat valorile prestabilite.In cazul nostru exista un pachet prestabilit fara nume caruia ii apartin toate pachetele.Pachetul nu are un nume explicit, iar alte pachete nu pot referi un pachet fara nume.Ca urmare, nici un alt pachet nu poate face referiri la exemplele din aceasta carte, asa cum se prezinta ele in momentul de fata.Este bine sa plasati in pachete toate clasele care prezinta un interes oarecare.

Accesul la alte pachete


Va amintiti, probabil, ca puteti face referiri la clasele din alte pachete, precedand numele clasei cu numele complet al pachetului.Instructiunea import reprezinta o scurtatura ce poate fi folosita atunci cand faceti referiri multiple la un anumit pachet sau cand numele pachetului este lung si greoi. Instructiunea import este folosita pentru includerea unei liste de pachete in care urmeaza sa fie cautata o anumita clasa.Iata care este sintaxa acestei instructiuni:
import nume_pachet ;

import este un cuvant cheie , iar nume_pachet este numele pachetului ce urmeaza sa fie importat.Instructiunea se termina cu caracterul punct si virgula.Instructiunea import trebuie sa apara inaintea oricarei declaratii de clasa din fisierul sursa.In cadrul unui fisier sursa pot exista mai multe instructiuni import.Iata un exmplu de instructiune import :
import mammal.animal.Cat :

In acest exemplu, toti membrii clasei Cat (cum ar fi variabilele si metodele) sunt accesibili prin simpla specificare a numelui lor, fara a fi necesara precedarea acestora cu numele complet al pachetului. Folosirea acestei scurtaturi prezinta un avantaj si un dezavantaj.Avantajul consta in eliberarea codului de nume lungi, ceea ce simplifica introdicerea lui de la tastatura.Dezavantajul consta in dificultatea determinarii pachetului caruia ii apartine o anumita clasa, mai ales atunci cand se importa un numar mare de pachete. Instructiunile import pot include si caracterul de inlocuire *.Asteriscul specifica faptul ca se importa toate clasele dintr-o ierarhie , nu numai dintr-o singura clasa.De exemplu, instructiunea de mai sus importa toate clasele din subpachetul mammal.animal :
import mammal.animal.* ;

Aceasta este o modalitate simpla de a importa toate clasele dintr-un anumit pachet. Instructiunea import este folosita destul de des in exemplele din carte.In general, ea apare atunci cand se doreste importul unor parti din interfata Java API.In mod prestabilit, aste importat setul de clase java.lang.*.Celelalte biblioteci de clase Java trebuie importate explicit.De exemplu, secventa de cod care urmeaza importa toate clasele pentru imagini si grafica din setul de instrumente pentru gestionarea ferestrelor (a se vedea partea a IV-a) :
import java.awt.Graphics ; import java.awt.Image ;

Conventii de denumire a pachetelor


Pachetele pot primi orice nume care respecta standardele Java.Prin conventie, numele pachetelor incep cu litera mica, pentru a putea fi deosebite de numele claselor.Din acest motiv, numele claselor incep cu litera mare.Cunoscand aceste conventii, este usor sa ne dam seama ca, in exemplul urmator, mammal si animal reprezinta pachete, iar Cat este numele clasei :
mammal.animal.Cat.promtForName ( ) ;

Java respecta aceste conventii pentru clasele interne si pentru interfata API.Metoda System.cut.println ( ) pe care am folosit-o pana acum respecta conventia de denumire.Numele pachetului nu este declarat explicit, deoarece pachetul java.lang.* este importat implicit.System este o clasa din pachetul java.lang.* si, prin urmare, incepe cu litera mare.Numele complet al metodei este :
java.lang.System.out.println ( ) ;

Pentru o utilizare eficienta a pachetelor, numele acestora trebuie sa fie unice.Conflictele de nume vor determina aparitia unor erori de excutie. Unicitatea numelor nu constituie o problema, daca programul este conceput de o singura persoana sau de un grup restrans.Pentru proiectele la care lucreaza grupuri mari de programatori, trebuie stabilite conventii stricte de denumire a pachetelor inca de la inceput, pentru a se evita haosul. Nu exista vreo organizatie care sa detina controlul asupra sistemului World Wide Web, iar multe aplicatii Java vor fi implementate chiar in Web.Retineti si faptul ca pe acelasi server Web pot fi incluse miniaplicatii Java din mai multe surse.Evitarea conflictelor de nume pare imposibila. Firma Sun a detectat aceasta problema intr-un stadiu avansat al dezvoltarii limbajului Java, dar inainte de lansarea oficila a acestuia.In consecinta, a pus la punct o conventia care asigura unicitatea numelor de pachete:acestea sunt precedate de numele inversat al domeniului.Pentru domeniul mycompany.com, se va adauga com.mycompany inainte de numele pachetelor.Pentru un institut educational, city.state.edu, se va adauga edu.state.city inainte de numele pachetelor.In acest mod, problema conflictelor de nume este rezolvata si se creeaza o structura arborescenta pentru toate bibliotecile de clase Java.

Variabila de mediu CLASSPATH


Interpretorul Java trebuie sa gaseasca toate bibliotecile de clase apelate la rularea unei aplicatii Java.In mod prestabilit, Java cauta bibliotecile de clase in arborele de directoare de instalare.Este bine ca atunci cand dezvoltati o aplicatie, sa plasati bibliotecile de clase proprii in alte directoare.Pentru localizarea acestor biblioteci, Java poate folosi variabila de mediu CLASSPATH.Aceasta contine lista directoarelor in care face cautarea bibliotecilor de clase.Sintaxa difera in functie de sistemul de operare.In sistemele UNIX, numele directoarelor din

lista sunt separate prin caracterul doua puncte.In Windows, se foloseste caracterul punct si virgula.Iata un exemplu de declarare a variabilei CLASSPATH intr-un sistem UNIX :
CLASSPATH = /grps/IT/Java/classes:/opt/apps/Java

Declaratia de mai sus ii transmite compilatorului sa caute bibliotecile de clase Java in directoarele /grps/IT/Java/classes si /opt/apps/Java.

Pe scurt, despre pachete


Pachetele sunt folosite pentru gruparea claselor inrudite.Ele permit accesul la clasele inrudite si protejarea componentelor unui pachet pentru programele externe. Pachetele sunt declarate cu ajutorul cuvantului cheie package, care trebuie plasat la inceputul tuturor fisierelor sursa din cadrul unui pachet.Accesul la membrii unui pachet se realizeaza precedand numele membrului respectiv cu numele complet al pachetului si caracterul punct.Continutul unui pachet poate fi utilizat si prin importul pachetului intr-o clasa, cu ajutorul cuvantului cheie import.In acest fel, puteti sa specificati direct numele unui membru, fara sa mai scrieti numele complet al pachetului. Prin conventie, numele pachetelor incep cu litera mica, ceea ce le diferentiaza de numele de clase, care incep cu litera mare.Firma Sun incurajeaza programatorii sa foloseasca numele inversat al domeniului Internet inaintea numelui pachetului, pentru a pastra unicitatea numelor de pachete la scara globala. Pachetele pot contine subpachete.Java solicita ca fisierele de clasa rezultatele in urma compilarii sa fie stocate intr-o structura de directoare care sa respecte ierarhia de nume a pachetelor.In mod prestabilit, interpretorul cauta pachetele in directoarele in care au fost instalate programele Java.Puteti sa folositi variabila CLASSPATH pentru a specifica si alte directoare in care vreti sa se realizeze cautarea.

Mostenirea
Unul din cele mai interesante concepte ale limbajelor orientate pe obiecte este cel de mostenire, reprezentand metodologia prin care codul dezvoltat intr-un anumit scop poate fi folosit si pentru alte scopuri, fara a mai fi necesara copierea lui. In Java , mostenirea se realizeaza prin crearea unor noi clase, ca extensii ale claselor existente.Clasele nou create se numesc subclase, iar cele originale poarta numele de superclase.O subclasa are toate atributele superclasei si, in plus, unele atribute specifice.O clasa poate avea o singura superclasa.Aceasta relatie se numeste mostenire simpla.O superclasa poate avea mai multe subclase.Pentru clarificarea acestor notiuni, sa ne intoarcem la exemplul cu apartamentul. Blocul de locuinte se compune din mai multe apartamente individuale si face parte dintr-un cartier, format din mai multe tipuri de cladiri, cum ar fi scoli, magazine si case.Pentru a implementa acest exemplu in Java , sa incepem cu conceptul de cladire.Toate cladirile au anumite caracteristici, cum ar fi dimensiunile exterioare (inaltime, lungime, latime), dimensiunea terenului si tipul de incalzire.Puteti crea o clasa pentru stocarea si manipularea acestor caracteristici. Un bloc de locuinte este o varianta (specializata) de cladire.El se compune din mai multe apartamente individuale, fiecare din acestea putand fi, la un moment dat, locuit sau liber.Aceste caracteristici pot fi incorporate clasei care reprezinta cladirile, dar nu pot fi aplicate unei scoli, de exemplu.Este de preferat crearea unei noi clase, care sa mosteneasca toate caracteristicile clasei pentru cladiri, dar sa aiba si caracteristici proprii.In acest fel, se creeaza o versiune particulara a

clasei pentru cladiri, care va fi folosita pentru reprezentarea unui bloc de locuinte.Pot fi create versiuni particulare ale clasei pentru cladiri si in cazul scolilor, magazinelor sau claselor.

Declararea mostenirii
Declararea mostenirii unei clase reprezinta o extensie a regulilor de declarare a claselor, discutate in sectiunile anterioare.De data aceasta, se foloseste cuvantul cheie extends:
class nume_clasa extends alta_clasa . . . corpul clasei } {

Cuvantul cheie extends trebuie plasat imediat dupa numele clasei.El este urmat de numele superclasei de la care sunt mostenite caracteristicile.Dupa cuvantul cheie extends poate urma un singur nume de clasa. In exemplele prezentate in sectiunea Clase pentru miniaplicatii, miniaplicatiile erau declarate ca subclase ale clasei java.applet.Applet.O astfel de declaratie furnizeaza miniaplicatiei toate caracteristicile clasei parinte.Nu exista nici un motiv pentru a scrie din nou codul care implementeaza aceste caracteristici, deoarece ele sunt mostenite de la superclasa. Sa folosim din nou analogia cu blocul de locuinte, pentru ilustrarea conceptului de mostenire, pornind de la clasa pentru cladiri:
public class Bldg { int height, width, depht, lotsize; String heatType; public String getHeatType ( ) { return (heatType); } }

Aceasta este o versiune simplificata a clasei pentru cladiri, continand variabile pentru dimensiunile exterioare ale cladirii (lungime, latime, inaltime) si dimensiunea terenului, precum si o metoda care returneaza tipul de incalzire.Sunt caracteristici comune tuturor cladirilor. Urmatorul pas este crearea unei clase pentru blocurile de locuinte, care sa extinda clasa pentru cladiri, declarata anterior:
public class AptBldg extends Bldg { int numApts; Apt apt[ ]; public int findVacantApt ( ) { int I; for (I=0;I<numApts; i++) { if (apt[I].isVacant == true) return(i) ; } } return (-1) } } public class Apt { boolean vacant; int aptNumber; public boolean isVacant ( ) { return(vacant); }

In acest exemplu, sunt declarate doua clase: una pentru blocurile de locuinte (AptBldg) si alta pentru apartemente (Apt).Clasa pentru blocuri este declarata prin extinderea clasei Bldg, ceea ce inseamna ca AptBldg este o subclasa a clasei Bldg.In acset fel, clasa AptBldg mosteneste toate variabilele si metidele declarate in clasa Bldg.AptBldg extinde clasa Bldg prin declararea unei variabile pentru numarul de apartamente si a unei matrice pentru obiectele care reprezinta apartamente. Clasa Apt este nou introdusa si nu extinde nici o alta clasa.In cadrul ei sunt declarate doua variabile, vacant si aptNumber, si o metoda, asVacant ( ) , care poate fi folosita pentru a afla daca un apartament este liber.Urmatorul pas consta in folosirea claselor declarate anterior.

Folosirea mostenirii
Este timpul sa cream un program pentru administratorii de bloc.Programul trebuie sa sa efectueze operatii precum gasirea unui apartament lober.Pentru aceasta, vom folosi in program clasele declarate anterior:
public class AptManager { public findEmptyApt (AptBkdg aptBldg) { int AptNum; String heatType; AptNum = aptBldg.findCavantApt ( ); if (AptNum > 0) { heatType = aptBldg.getHeatType( ) ; System.out.println (Apartamentul + AptNum + este disponibil pentru inchiriere) ; System.out.println (Tipul de incalzire este + heatType) ; } } }

In acest exemplu a fost creata o metoda pentru gasirea unui apartament liber.Aceaste primeste ca parametru un obiect ce reprezinta un bloc de locuinte.Apoi apeleaza metoda findVacantApt ( ) din obiectul aptBldg pentru localizarea primului apartament liber.In cazul in care este gasit un astfel de apartament, va fi apelata metoda getHeatType ( ) pentru a determina tipul de incalzire al cladirii.In continuare, sunt afisate ambele informatii obtinute. Remarcati faptul ca doar metoda findVacantApt ( ) este declarata explicit in clasa AptBldg, nu si metoda getHeatType, care este declarata in clasa Bldg.Deoarece clasa AptBldg este declarata ca subclasa a clasei Bldg, ea mosteneste automat toate metodele clasei Bldg, inclusiv metoda getHeatType.Prin folosirea mostenirii, nu a fost necesar sa rescriem codul pentru determinarea tipului de incalzire.Daca ar fi fost declarate si alte subclase ale clasei Bldg, cum ar fi cele pentru scoli sau case, si acestea ar fi mostenit aceeasi metoda.In programele complexe, puteti ecunomisi o mare cantitate de effort pentru scrierea codului. O alta caracteristica importanta a limbajului Java este evitarea problemei superclaselor fragile din C++, adica necesitatea recompilariituturor subclaselor de fiecare data cand se modifica o clasa de pe un nivel superior.Datorita faptului ca Java este un limbaj interpretat, nu compilar, recompilarea claselor nu mai este necesara.toate caracteristicile superclasei sunt transmise prin mostenire claselor de nivel inferior.Aceasta reprezinta o imbunatatire importanta fata de C++.

Pe scurt, despre mostenire


Mostenirea este o metoda de refolosire a codului, permitand adaptarea acestuia.atunci cand lucrati cu un grup de obiecte care su unele caracteristici comune , mostenirea se poate dovedi utila. Mostenirea este folosita in declaratiile de clase, fiind specificata cu ajutorul cuvantului cheie extends.O clasa care extinde o alta clasa este cunoscuta sub numele de subclasa, iar clasa pe care o extinde se numeste superclasa.O clasa poate avea oricate subclase, dar numai o superclasa.Aceasta relatie se numeste mostenire simpla. Prin mostenire, o subclasa are acces la toate variabilele si metodele declarate in superclasa, ceea ce permite ca toate elementele comune unui grup de clase sa fie plasate in acelasi loc.In fiecare subclasa, pot fi declarate noi metode si variabile, care sporesc functionalitatea si cantitatea de informatii. Mostenirea furnizeaza un puternic mecanism de refolosire a codului existent, ceea ce reprezinta un ajutor important in cadrul proiectelor mari.Ea permite adaugarea unor noi clase in orice moment.

Interfete
Interfetele reprezinta modalitatea folosita de limbajul Java pentru reducerea complexitatii unui proiect.Mostenirea simpla reduce dificultatea determinarii originilor metodelor sau claselor.Totusi, exista anumite limitari.C++introduce mostenirea multipla,ceea ce poate conduce la complicarea inutila a codului, dar permite o mai mare flexibilitate.Limbajul Java este mai putin flexibil, dar si mai putin complex.El foloseste mostenirea simpla, dar permite includerea functionalitatii altor clase, prin intermediul interfetelor. Inainte de a trece mai departe, sa revenim putin la metode, despre care am mai discutat.Metodele sunt echivalente cu functiile din alte limbaje de programare.O metoda este o unitate de cod care poate fi apelata si care returneaza o valoare.Ea opereaza asupra unor variabile si contine cod executabil.Metodele apartin unei clase si sunt asociate unui obiect. Conceptul de interfata constituie una din principalele diferente intre proiectarea programelor in limbajul C clasic si dezvoltarea aplicatiilor in Java.Ciclul de dezvoltare a aplicatiilor in limbajele procedurale, precum C, incepe de obicei prin definirea functiilor aplicatiei si a argumentelor lor, sub firma unor cutii negre. Cu alte cuvinte, programatoril care scrie codul pentru apelarea unei functii stie care sunt parametrii necesari, dar nu cunoaste modul de implementare a acestora in cadrul functiei.Astfel poate dezvolta codul, fara sa implementeze de la inceput toate functiile.In C, poate fi definit un prototip de functie, pe baza caruia, in masura in care timpul si resursele o permit, se implementeaza toate finctiile din cadrul aplicatiei.Cum se realizeaza acest lucru in Java? Cu ajutorul interfetelor. O interfata stabileste numele, tipul returnat si argumentele unei metode.Ea nu include cod executabil si nu adreseaza o anumita metoda.Interfata poate reprezenta un model de structura, nu de utilizare. Interfetele sunt folosite pentru definirea structurii unui set de metode care vor fi implementate de clasele ce urmeaza sa fie proiectate.Cu alte cuvinte, argumentele si valorile returnate trebuie sa corespunda definitiilor din interfata.Compilatorul verifica aceasta conformitate.Codul intern al unei metode definite de interfata poate conduce la rezultatele asteptate intr-un mod total diferit fata de aceeasi metoda, implementata de o alta clasa. Interfetele reprezinta o varianta a mostenirii, folosita pe scara larga in Java.Principalul avantaj este faptul ca aceeasi interfata poate fi implementata de mai multe clase, ceea ce garanteaza ca acestea

vor implementa cateva metode comune.In plus, aceste metode vor avea acelasi tip de valoare returnata, acelasi nume si aceleasi argumente. Vom concretiza aceste lucruri.Sa presupunem ca interfata defineste o metoda ca fiind de tip boolean.Singurul argument este un sir de caractere de intrare.Din sectiunea de comentarii, aflam ca metoda testeaza daca un obiect este negru si, in functie de rezultatul obtinut, returneaza valoarea true sau false.Metodele care folosesc aceasta interfata pot aplica acest test pentru pisici, danturi, pavaje, culori de pe ecran sau orice altceva.Singurul element comun al acestor metode este faptul ca au aceeasi definitie.Orice programator care vede numele metodei stie care este obiectivul ei si ce argumente accepta. Desigur, Java nu cere tuturor claselor care implementeaza metode cu acelasi nume sa foloseasca interfata pentru verificarea argumentelor.Nici un limbaj nu poate suplini proasta gestionare a proiectelor.In schimb, furnuzeaza o structura utilizabila.

Declararea unei interfete


O interfata este declarata intr-un mod asemanator cu o clasa, dar in locul cuvantului cheie class, se foloseste cuvantul cheie interface:
interface nume { . . . corpul interfetei }

Corpul interfetei este declarat intre acolade.El include declaratii de metode si de variabile.

Modificatori
Declaratiile de interfete accepta aceiasi modificatori ca si declaratiile de clase: public si default.In mod prestabilit, interfetele nu sunt publice, ceea ce inseamna ca sunt accesibile oricarui membru dintr-un anumit pachet.Dar majoritatea interfetelor sunt publice, deoarece ele constituie unica modalitate de partajare a definitiilor de metode si de variabile intre diferite pachete. Iata un exemplu de declarare a unei interfete publice:
public interface AnInterface . . . corpul interfetei } {

Variabilele si metodele declarate in cadrul interfetei pot avea , la randul lor, modificaturi, dar acestia sunt limitati la anumite combinatii. Modificatorii pentru variabile se limiteaza la un anumit set: public static final.Prin urmare, variabilele declarate in interfete pot avea numai valori constante.Modificatorii public static final sunt prestabiliti.Declararea lor explicita nu este necesara, dar usureaza intelegerea codului.Folosirea altor modificatori pentru variabile, cum ar fi protected, va genera o eroare de compilare.Iata cateva exemple de declaratii de variabile:
public static final int smtpSocket=25; public static final float pie=3.14159; public static final String=The quick brown fox;

Si modificatorii pentru metode se limiteaza la un anumit set: public abstract, ceea ce inseamna ca metodele declarate in interfete pot fi numai metode abstracte.Modificatorii public abstract sunt prestabiliti.Declararea lor explicita nu este necesara, dar usureaza intelegerea codului.

Folosirea altor modificatori pentru metode, cum ar fi protected, va genera o eroare de compilare.Iata cateva exemple de declaratii de metode:
public abstract boolean isBlack(Color); public abstract boolean isBlack(String); public abstract StringBuffer promtForName(String);

Asa cum se observa in acest exemplu, metodele pot fi supraincarcate in interfete, la fel ca si in clase.Iata cum arata o interfata creata pe baza exemplelor de mai sus:
public interface MyInterface { public static final int smtSocket=25; public static final float pie=3.14159; public static final String=The quick brown fox; public abstract boolean isBlack(Color); public abstract boolean isBlack(String); public abstract StringBuffer promtForName(String); }

Asa cum clasele pot extinde alte clase, si interfetele pot extinde alte interfete cu ajutorul cuvantului cheie extends.In secventa de cod urmatoare, interfata AnInterface declara o variabila cu numele theAnswer:
public interface anInterface { public static final int theanswer=42; } public interface MyInterface extends AnInterface { public static final float int smtpsocket=25; public static final float pie=3.14159; public static final String=The quick brown fox; public abstract boolean isBlack(Color); public abstract boolean isBlack(String); public abstract StringBuffer promtForName(String); }

Interfata MyInterface specifica faptul ca extinde interfata AnInterface.Aceasta inseamna ca toate clasele care folosesc interfata MyInterface vor avea acces si la variabilele si metodele declarate in interfata AnInterface. Spre deosebire de mostenirea claselor, cuvantul cheie extends va permite sa specificati mai multe interfete, eventual disparate, care pot fi combinate intr-o unitate logica mai mare, ca in exemplul urmator:
public interface YourInterface extends HerInterface, HisInterface . . . corpul interfetei } {

Folosirea unei interfete


Putem continua exemplul cu blocul de locuinte pentru ilustrarea unor detalii referitoare la interfete.Amintiti-va ca am definit mai devreme clasa AptBldg pentru blocuri de locuinte.Aceasta contine toate informatiile necesare pentru definirea unui bloc. O alta informatie care poate fi adaugata clasei pentru blocuri este adresa.Aceasta poate fi manipulata prin adaugarea unor metode specifice la clasa existenta.In felul acesta, informatiile

despre adresa sunt limitate la o singura clasa.Daca metodele pentru manipularea adresei ar fi plasate intr-o interfata , ele ar fi accesibile pentru toate clasele.Iata un exemplu:
public interface Address { public abstract void printaddress (anAddress); public abstract void setStreet (anAddress); public abstract String getState (anAddress); }

Aceasta interfata este un sablon pentru manipularea informatiilor despre adresa prin intermediul metodelor.Prima metoda afiseaza intreaga adresa, a doua introduce numele strazii si a treia returneaza numele statului.Dar de ce sa plasam metodele intr-o interfata daca este atat de simplu sa le adaugam la o clasa existenta?Deoarece refolosirea este punctul forte al limbajului Java! Dupa ce este definita o interfata, ea poate fi folosita de catre clase prin intermediul cuvantului cheie implements.Iata sintaxa unei astfel de declaratii:
class nume [extends nume_clasa] implements nume_interfata { . . . corpul clasei } [,nume_interfata]

Cuvantul cheie implements apare dupa numele clasei (sau dupa declaratia extends) si inainte de unul sau mai multe nume de interfete, separate prin virgule.Posibilitatea specificarii unei liste de interfete permite accesul claselor la mai multe interfete predefinite.In exemplul cu blocul de locuinte, clasa este declarata astfel:
public class AptBuilding implements Address . . . corpul clasei } {

Alte clase pot folosi aceste metode prin implementarea aceleiasi onterfete, dupa declararea ei. Sa presupunem ca vreti sa implementati alte clase, cum ar fi cele pentru scoli, magazine sau cladiri administrative.Fiecare dintre ele poate folosi declaratiile de metode pentru manipularea adreselor din clasa aptBldg.In acest fel, nu numai ca sariti etapele de programare prin folosirea unui sablon existent, dar puteti crea mai multe clase care sa foloseasca aceleasi metode pentru manipularea adreselor. Apelul pentru obtinerea adresei unei scoli este identic cu cel pentru adresa unui magazin.Aceasta inseamna ca se poate folosi o metoda cu acelasi nume.Nu este absolut necesara utilizarea unui nume distinct pentru fiecare adresa dintr-o clasa, ceea ce prezinta mari avantaje pentru proiectele mari. Metodologia prezentata acopera asemanarile dintre clase.Ce se intampla insa cu diferentele?S-ar putea ca pentru o alta aplicatie sa fie necesare si numerele de telefon, nu numai adresa.Solutia este simpla.Java nu impune folosirea exclusiva a metodelor din interfata.Orice clasa poate adauga metodele care ii sunt necesare. Adaptarea se aplica la o singura clasa.Nu trebuie sa fiti ingrijorat ca vor fi afectate si celelalte clase care folosesc interfata.

Rezumat
In acest capitol, am discutat conceptele de clase, pachete, mostenire si interfete.O buna intelegere a relatiilor dintre aceste parti ale limbajului Java este esntiala in crearea aplicatiilor si a miniaplicatiilor.

Clasele sunt folosite in Java pentru definirea unui obiect.Obiectele sunt formate din informatii si metode pentru manipularea acestora.O instanta este o anumita implementare a unui obiect. Pachetele sunt grupuri de boblioteci de clase, care contin clase inrudite.Ele pot fi folosite pentru controlul accesului si simplifica importul unui intreg set de clase. Mostenirea permite refolosirea codului existent si furnizeaza mijloacele necesare pentru adaptarea noului cod.Java accepta mostenirea simpla de la clase la subclase.Subclasele mostenesc toate caracteristicile superclasei.Este unul dintre conceptele de baza in programarea orientata pe obiecte. Interfetele sunt sabloane de metode, folosite pentru standardizarea definitiilor acestora.Ele sunt necesare, datorita faptului ca Java nu accepta mostenirea multipla.Interfetele permit unor clase diferite sa partajeze metode inrudite.