Issuu on Google+

curs programare web

Clase şi obiecte POO (programare orientată pe obiecte) Dacă lucraţi de ceva timp în PHP, probabil că aţi mai auzit că termenul de POO înseamna Programare Orientată pe Obiecte. În POO, scriptul PHP lucrează cu entităţi denumite obiecte pentru a construi funcţionalitatea necesară programului tău. Spre deosebire de PHP 4, PHP 5 oferă suport extins pentru POO, aducând obiectele PHP la standardele impuse de către principiile POO şi oferind programatorilor noi facilităţi. Pe parcursul acestui tutorial, veţi putea citi despre capacităţile PHP în legătura cu implementarea obiectelor (atât în PHP 4 cât şi în PHP 5) şi veţi putea urmări diverse exemple şi explicaţii ce ilustrează utilizarea lor. Vom acoperi principiile de bază clasa, obiecte, atribute şi metode însoţite de câteva concepte mai avansate : constructori, destructori, specificatori de acces, proprietăţi şi clase moştenite. Chiar dacă programarea orientată pe obiecte este un subiect nou pentru dvs, nu aveţi de ce să vă faceţi griji : obiectele în PHP sunt uşor de folosit şi de înţeles şi vă vor ajuta să vă organizaţi cât mai bine munca.

Clase în PHP Înainte de a trece mai departe, trebuie să aveţi o idee clară despre conceptele pe care POO le presupune. În PHP, o clasă reprezintă un set de instrucţiuni care îndeplinesc o anumită sarcină. Implementarea unei clase conţine atât variabile, cât şi funcţii, ea reprezentând un şablon (template) cu ajutorul căruia pot fi create instanţe specifice. Aceste instanţe specifice ale unei clase poartă numele de obiecte. Fiecare obiect are o serie de caracteristici, sau proprietăţi, şi anumite funcţii predefinite metode. Aceste proprietăţi şi metode ale unui obiect corespund variabilelor şi funcţiilor din definiţia clasei. Odată ce aţi creat o clasă, puteţi defini oricâte instanţe ale acesteia. Fiecare dintre aceste instanţe reprezintă un obiect independent, ce poate fi manipulat fără ca celelalte obiecte să fie afectate în vreun fel. Această indepedenţă a obiectelor devine foarte utilă atunci când trebuie să lucraţi cu două instanţe în acelaşi timp, de exemplu, două conexiuni simultane la o bază de date, sau două interogări (query), sau două cărucioare de cumpărături ale unui magazin online. Clasele vă ajută şi în ceea ce priveşte modularitatea codului. Puteţi defini o clasă într-un fişier separat, incluzându-l apoi în scripturile care folosesc această clasă. Această modalitate de implementare simplifică modificările ulterioare pentru ca, în cazul în care veţi dori sa adăugaţi noi funcţionalităţi obiectelor , veţi avea de modificat un singur fişier. Ca să înţelegeţi mai bine cele de mai sus, să luăm ca exemplu un copilaş şi să încercăm să îl reprezentăm ca un obiect. Orice copilaş are anumite caracteristici : vârstă, greutate, sex care sunt echivalente cu proprietăţile unui obiect. În plus, fiecare copilaş are anumite activităţi : mănâncă, doarme, merge, aleargă şi se joacă , acestea reprezentand metodele unui obiect. Deoarece toţi copiii au în comun anumite caracteristici, putem crea un template Copil(), care defineşte caracteristicile de bază si abilitatile fiecarui copil. Această clasă Copil() poate fi utilizată pentru a crea un obiect $copil, proprietăţile individuale ale unui copil putând fi manipulate independent faţă de cele ale altor obiecte de acelasi tip. În PHP 5, clasa Copil ar arăta în felul următor: <?php // PHP 5 // definitia clasei class Copil { // definitia proprietatilor public $nume; public $greutate; public $varsta; public $sex;

1


curs programare web public $culoare_ochi; // definitia metodelor public function mananca() { echo $this->nume." mananca laptic etc "; } public function alearga() { echo $this->nume." alearga "; } public function joaca() { echo $this->nume." se joaca cu mingiuta etc "; } public function doarme() { echo $this->nume." doarme la orele cutare "; } } ?> Având această clasă, putem crea oricâţi copilaşi vrem: <?php // primul $Ionut = new Copil; // sa-i dam un nume $Ionut->nume = "Ionut"; // cati ani are $Ionut->varsta = 2; // ce este $Ionut->sex = "baietel"; // culoarea ochilor $Ionut->culoare_ochi = "verzi cacanii"; // cat cantareste $Ionut->greutate = 12; // cel de-al doilea $Danut = new Copil; $Danut->nume = "Danut"; $Danut->varsta = 1; $Danut->sex = "baietel"; $Danut->culoare_ochi = "caprui"; $Danut->greutate = 10; // cel de-al treilea $sanz = new Copil; $sanz->nume = "Sanziana"; $sanz->varsta = 2; $sanz->sex = "fetita"; $sanz->culoare_ochi = "caprui"; $sanz->greutate = 11; // Ionut se joaca $Ionut->joaca(); // Danut mananca $Danut->mananca(); // la fel si Sanziana $sanz->mananca();

2


curs programare web // Danut doarme $Danut->doarme(); // la fel si Ionut $Ionut-> doarme (); // Sanziana mananca in continuare $sanz->mananca(); ?> După cum se poate observa din exemplul de mai sus, atunci când sunt definite noi obiecte, metodele şi proprietăţile lor pot fi accesate în mod independent pentru fiecare obiect.

Definiţia unei clase După ce am explicat conceptele de baza ale POO, să vedem în continuare cum anume se defineşte o clasă: <?php // PHP 5 // definitia clasei class Copil { // defineste proprietatile public public $nume; public $varsta; // alte proprietati // defineste o metoda public public function mananca() { echo $this->nume." mananca... "; // mai mult cod } // alte metode } ?> Orice definiţie a unei clase începe prin cuvântul cheie class, urmat de numele clasei. Acesta poate fi orice şir de caractere, în afara unui cuvant rezervat PHP, fiind urmat de o pereche de acolade ce include variabilele şi funcţiile clasei. PHP5 introduce un nou concept care nu este disponibil în PHP4: specificatorii de acces. Aceştia controlează gradul în care proprietăţile obiectelor şi metodele lor pot fi manipulate din exteriorul clasei, având un rol important în ceea ce priveşte securitatea claselor. Există trei specificatori de acces, de la cel mai permisiv la cel mai restrictiv: public, private şi protected. În definiţia unei clase poţi marca gradul de vizibilitate al unei proprietăţi sau metode precedând-o cu unul dintre cele trei cuvinte cheie. In mod implicit, proprietăţile şi metodele unei clase sunt public. Aceasta înseamnp ca ele pot fi accesate direct şi manipulate de către un script care nu se află în interiorul clasei. Dacă nu doriţi acest lucru, îl puteţi împiedica utilizând specificatorii de acces private sau protected, în funcţie de gradul de control pe care vrei să îl deţină un script exterior asupra obiectelor. Deoarece în PHP4 nu există specificatori de acces, definiţia clasei de mai sus nu va funcţiona în PHP4. În schimb, ea poate fi inlocuită cu următorul cod: <?php // PHP 4 // definitia clasei class Copil { // definitia proprietatilor var $nume; var $greutate; var $varsta; var $sex;

3


curs programare web var $culoare_ochi; // definitia metodelor function mananca() { echo $this->nume." mananca... "; } function alearga() { echo $this->nume." alearga... "; } function joaca() { echo $this->nume." vaneaza... "; } function doarme() { echo $this->nume." doarme... "; }

} ?>

Având în faţă exemplul de mai sus, puteţi deduce uşor faptul că în PHP4 toate proprietăţile şi metodele unui obiect sunt public. Pentru a crea o nouă instanţă a clasei de mai sus, se foloseşte cuvântul cheie new: <?php $Ionut = new Copil; ?> Codul din exemplul anterior s-ar putea citi ca : “creează un nou obiect de tipul Copil şi salvează-l în variabila $Ionut”. Acum puteţi accesa toate proprietăţile şi funcţiile clasei Copil folosind această variabilă. De exemplu, codul: <?php $Ionut->nume = "Ionut"; ?> s-ar traduce ca “atribuie valoarea Ionut variabilei $nume a instanţei $Ionut a clasei Copil”, în timp ce declaraţia: <?php $Ionut->doarme(); ?> înseamnă “execută funcţia doarme() pentru instanţa $Ionut a clasei Copil”. Puteţi observa că simbolul “->” este folosit pentru a apela diferitele proprietăţi şi metode ale obiectelor, caracterul “$” fiind omis atunci când accesăm variabilele unui obiect.

Cuvantul cheie “this” Dacă vreţi sa accesaţi funcţiile şi variabilele unei clase chiar în cadrul acesteia, atât PHP4, cât şi PHP5, vă pun la dispoziţie cuvântul cheie $this, care este folosit ca o referinţă la instanţă curentă. Pentru a vedea cum funcţionează acesta, să modificăm funcţia mananca() pentru a primi ca parametru un număr de unităţi de mâncare care sunt adunate la greutatea unui copil: <?php // PHP 5 // definitia clasei class Copil { // definitia proprietatilor public $nume;

4


curs programare web public $greutate; // definitia metodelor public function mananca($unitati) { echo $this->nume." mananca ".$unitati." unitati de mancare... "; $this->greutate += $unitati; }

} ?>

În acest caz, prefixul $this indică faptul că variabila ce urmează a fi modificată a fost definită ca proprietate a clasei. Acest lucru poate fi exprimat ca: “pentru acest obiect, adună argumentul funcţiei mananca() la variabila $greutate”. În concluzie, cuvântul cheie $this vă oferă o metodă facilă de a accesa variabilele şi funcţiile “locale” ale clasei. Iată un exemplu care ilustrează funcţionarea sa: <?php // creeaza instanta $copilas = new Copil; $copilas->nume = "Ionut"; $copilas->greutate = 12; // creeaza o alta instanta // cu valori independente pentru fiecare proprietate $nasic = new Copil; $nasic->nume = "Danut"; $nasic->greutate = 10; // afiseaza proprietatile echo $copilas->nume." cantareste ".$copilas->greutate." kg "; echo “<br>”; echo $nasic->nume." cantareste ".$nasic->greutate." kg "; // apeleaza functia mananca() $copilas->mananca(0.1); $copilas->mananca(0.05); $nasic->mananca(0.210); // afiseaza noile valori echo $copilas->nume." cantareste acum ".$copilas->greutate." kg "; echo $nasic->nume." cantareste acum ".$nasic->greutate." kg "; ?> Codul de mai sus va afişa: Ionut cantareste 12 kg Danut cantareste 10 kg Ionut mananca 0.1 kg de mancare... Ionut mananca 0.05 kg de mancare... Danut mananca 0.210 kg de mancare... Ionut cantareste acum 12.150 kg Danut cantareste acum 10.210 kg

Constructori În PHP aveţi posibilitatea de a executa o metodă a unei clase atunci când este creată o noua instanţă a acesteia. Această metodă poartă denumirea de constructor. Pentru a o utiliza, definiţia clasei în PHP5 trebuie să conţină o funcţie specială, _construct(). De exemplu, daca vreţi ca toţi nou-nascuţii să cântărească 3 kg, puteţi folosi codul:

5


curs programare web <?php // PHP 5 // definitia clasei class Copil { // definitia proprietatilor public $nume; public $greutate; public $varsta; public $culoare_ochi; // constructor public function __construct() { $this->varsta = 0; $this->greutate = 3; $this->culoare_ochi = "albastri"; } // definitia metodelor } ?> În PHP4, constructorul trebuie sa aibă acelaşi nume ca şi clasa. Iată codul echivalent pentru PHP4: <?php // PHP 4 // definitia clasei class Copil { // definitia proprietatilor var $nume; var $greutate; var $varsta; var $culoare_ochi; // constructor function Copil() { $this->varsta = 0; $this->greutate = 3; $this->culoare = "albastri"; } // definitia metodelor } ?> Să creăm o nouă instanţă a clasei: <?php // creeaza instanta $bebelus = new Copil; $bebelus->nume = "Maria"; echo $bebelus->nume." are culoarea ochilor ".$bebelus->culoare_ochi." si cantareste ".$bebelus->greutate." kg la nastere"; ?> Constructorul va iniţializa în mod automat proprietăţile culoare şi greutate pentru fiecare obiect de tipul Copil care este creat. În consecinţă, scriptul de mai sus la afişa: Maria are culoarea ochilor albastri si cantareste 3 kg la nastere.

6


curs programare web Restrictionarea accesului După cum am precizat mai sus, PHP5 permite marcarea proprietăţilor şi metodelor unei clase ca private, ceea ce înseamnă că ele nu pot fi modificate sau afişate în afara definiţiei clasei respective. Acest lucru este util a împiedica manipularea proprietăţilor unei clase de către o instanţă a acesteia. Să considerăm următorul exemplu, care ilustrează acest lucru prin adăugarea unei noi variabile private $_ultimeleUnitatiConsumate în clasa Copil(): <?php // PHP 5 // definitia clasei class Copil { // definitia proprietatilor public $nume; public $greutate; public $varsta; private $_ultimeleUnitatiConsumate; // constructor public function __construct() { $this->varsta = 0; $this->greutate = 3; $this->_ultimeleUnitatiConsumate = 0; } // definitia metodelor public function mananca($unitati) { echo $this->nume." mananca ".$unitati." unitati de mancare... "; $this->greutate += $unitati; $this->_ultimeleUnitatiConsumate = $unitati; } public function afiseazaUltimaMasa() { echo "Unitatile consumate la ultima masa au fost ".$this->_ultimeleUnitatiConsumate." "; } } ?> Deoarece variabila $_ultimeleUnitatiConsumate este declarată ca private, orice tentativă de a o modifica va genera o eroare. Iată un exemplu: <?php $bebelus = new Copil; $bebelus->nume = "Mimo"; $bebelus->mananca(0.05); $bob->mananca(0.02); echo $bebelus-> afiseazaUltimaMasa(); // urmatoarea linie va genera o eroare $bebelus->_ultimeleUnitatiConsumate = 0.1; ?> În mod similar şi metodele unei clase pot fi declarate ca private, ceea ce înseamnă că ele nu pot fi apelate decât din interiorul clasei respective.

7


curs programare web Moştenirea unei clase Două dintre principalele avantaje ale POO, fie PHP4, fie PHP5, sunt extensibilitatea şi moştenirea. Aceasta înseamnă că puteţi crea o clasă nouă dintr-o clasă deja existentă, adăugând noi proprietăţi şi metode, şi apoi poţi defini noi instanţe ale acestei clase. Aceste obiecte vor avea toate facilităţile moştenite de la clasa părinte, împreună cu noile proprietăţi şi metode ale clasei copil. Pentru a ilustra acest concept, să considerăm clasa Copil_sclifosit() care mosteneste clasa Copil() şi defineşte o nouă metodă: <?php // PHP 5 // definitia clasei class Copil{ // definitia proprietatilor public $nume; public $greutate; public $varsta; public $sex; public $culoare_ochi; // constructor public function __construct() { $this->varsta = 0; $this->greutate = 3; } // definitia metodelor public function mananca($unitati) { echo $this->nume." mananca ".$unitati." unitati de mancare... "; $this->greutate += $unitati; } public function alearga() { echo $this->nume." alearga... "; } public function joaca() { echo $this->nume." vaneaza... "; } public function doarme() { echo $this->nume." doarme... "; } } // extindem definitia clasei Copil class Copil_sclifosit extends Copil { // constructor public function __construct() { parent::__construct(); $this->culoare_ochi = "verzi cacanii"; $this->greutate = 12; } // definitia metodelor public function nu_papa() { echo $this->nume." nu papa carne, supite, ardei etc "; } } ?>

8


curs programare web Cuvântul cheie extends este utilizat pentru a crea o clasă copil dintr-o clasă părinte. În acest mod, toate funcţiile şi variabilele din clasa părinte sunt disponibile în clasa copil, după cum se poate observa în exemplul de mai jos: <?php // creeaza o noua instanta a clasei Copil() $tudor = new Copil; $tudor->nume = "Tudor"; // creeaza o noua instanta a clasei Copil_sclifosit() $Ionut = new Copil_sclifosit; $Ionut->nume = "Ionut"; /* $Ionut poate apela toate metodele claselor Copil() si Copil_sclifosit() */ $Ionut->alearga(); $Ionut->joaca(); $Ionut->nu_papa(); // $tudor poate apela doar metodele clasei Copil() $tudor->alearga(); $tudor->joaca(); $tudor->nu_papa(); ?> În acest caz, apelul final $tudor->nu_papa() va genera o eroare deoarece clasa Copil() nu conţine nicio metodă nu_papa(). În acelaşi timp, instrucţiunile $Ionut->alearga() şi $Ionut->joaca() vor fi executate cu succes deoarece clasa Copil_sclifosit() moşteneste toate metodele şi proprietăţile clasei Copil(). În exemplul anterior, puteţi observa cum a fost apelat constructorul clasei părinte din constructorul clasei Copil_sclifosit(). În general, acest lucru este util pentru a ne asigura că toate iniţializările din clasa părinte au fost efectuate înaintea altor iniţializări în constructorul clasei copil. Dacă o clasă moştenită nu are constructor, va fi apelat în mod implicit constructorul clasei pe care o moşteneşte. Iată definiţia clasei Copil_sclifosit in PHP4: <?php // PHP 4 class Copil_sclifosit extends Copil { // constructor function Copil_sclifosit() { parent::Copil(); $this->culoare_ochi = "albastri"; $this->greutate = 3; } // definitia metodelor function nu_papa() { echo $this->nume." nu papa carne. "; } } ?> Pentru a impiedica moştenirea unei clase sau a unor metode ale sale, folosiţi cuvântul cheie final înaintea numelui clasei sau al metodei (aceasta este o facilitate a PHP5 care nu este disponibilă în versiunile PHP mai vechi). Iată un exemplu care modifică definiţia clasei Copil() astfel încât aceasta să nu mai poată fi moştenită: <?php // PHP 5 // definitia clasei final class Copil { // definitia proprietatilor

9


curs programare web // definitia metodelor } /* extinderea definitiei clasei va genera o eroare deoarece clasa Copil nu poate fi mostenita */ class Copil_sclifosit extends Copil { // definitia metodelor } // crearea unei instante a clasei Copil_sclifosit() // apelul va esua deoarece clasa Copil nu poate fi mostenita $Ionut = new Copil_sclifosit; $Ionut->nume = "Ionut"; echo $Ionut->greutate; ?>

TEMĂ

1. Să se creeze clasa “hotel” având proprietăţile nume, adresă, locaţie şi metodă afişare şi subclasa hotel_stele având proprietăţile nr_stele, tarif, vedere_la_mare şi metodă calcul_tarif. 2. Să se creeze un formular pentru înscrierea într-o excursie şi datele preluate din formular să se introducă într-un obiect aparţinând clasei excursie.

10


Curs de web design PHP - http://videotutoriale35.blogspot.ro/