PHP OOP - Clase si obiecte (2)
- Invatati sa redefiniti metodele inadecvate
- Invatati sa folositi metode care au fost anulate
- Invatati sa lucrati cu tablouri de obiecte
In acest tutorial sunt prezentate metode mai avansate de lucru cu OOP (Object Oriented Programming - Programarea orientata spre obiecte) in PHP.
1. Redefinirea metodelor
Uneori, o clasa parinte include o metoda (functie) care nu este adecvata pentru o clasa copil. In loc de a re-crea noua clasa fara referire la o clasa de baza, puteti anula metoda inadecvata adaugand o metoda cu acelasi nume in clasa copil (derivata). Astfel la instantiere va fi folosita metoda, cu acelasi nume, din clasa derivata.
De exemplu, sa consideram urmatoarea clasa:
<?php
class ContBanca2 {
var $cont_id;
var $nume_posesor;
var $sold = 1;
function ContBanca2($id, $nume, $suma) {
$this->cont_id = $id;
$this->nume_posesor = $nume;
$this->sold = $suma;
}
function inchide_cont() {
$suma = $this->sold;
$this->sold = 1;
return $this->sold;
}
}
?>
Sa presupunem ca dorim sa derivam din aceasta o clasa copil care reprezinta un nou tip de cont bancar, cu dobânda. La închiderea contului, programul trebuie sa calculeze dobânda pe care sa o adauge la soldul curent si sa returneze suma acumulata.
Iata cum putem proceda, definim clasa derivata astfe:
<?php
class ContEco extends ContBanca2 {
function inchide_cont($zile, $rata) {
$suma = $this->sold * $rata * ($zile / 365);
$suma = $suma + $this->sold;
$this->sold = 1;
return $suma;
}
}
?>
- In cadrul clasei derivate (copil) este definita o metoda numita "inchide_cont()". O metoda cu acelasi nume exista si în clasa de baza (clasa parinte), dar are o alta definitie. Astfel, in clasa copil nu va mai fi mostenita metoda cu acelasi nume, ci o va folosi pe cea proprie.
In continuare creem un obiect "ContEco" si apelam metoda "inchide_cont()" astfel:
<?php
// Aici sunt adaugate datele pentru definirea clasei de baza, ContBanca2
// Aici sunt adaugate datele pentru definirea clasei derivate, ContEco
$cont = new ContEco(8, "Didi", 100);
echo "<br /> Didi primeste ". $cont->inchide_cont(22, 0.8);
// Va fi afisat sirul: "Didi primeste 104.82191780822"
?>
- Este invocata metoda "inchide_cont" definita de clasa copil, nu cea definita în clasa parinte. Astfel, metoda definita în clasa parinte a fost anulata (redefinita) de catre metoda, cu acelasi nume, definita în clasa copil.
2. Invocarea unei metode redefinite
Daca încercati sa invocati o metoda anulata (redefinita), probabil ca veti obtine o eroare.
Daca in exemplul anterior, am fi scris instructiunea: "echo "<br /> Didi primeste ". $cont->inchide_cont();", fara cele doua argumente (22, 0.8), incercand astfel sa facem referire la metoda anulata "inchide_cont()", am primi mesaje de eroare:
- Warning: Missing argument 1 for ContEco::inchide_cont(),
- Warning: Missing argument 2 for ContEco::inchide_cont(),
Cu toate acestea, este posibila invocarea metodei redefinite. Prin specificarea in clasa copil a numelui clasei parinte, urmat de o pereche de caractere doua puncte (
::) si metoda redefinita. Astfel se poate indica programului PHP sa foloseasca metoda, cu acelasi nume, definita în clasa parinte, nu metoda definita în clasa copil.
Invocarea unei metode redefinite este un procedeu mai complicat, pentru incepatori este mai bine a fi evitat deoarece poate complica intelegerea scriptului.
Iata cum ar arata clasa derivata utilizand acest procedeu:
<?php
class ContEco extends ContBanca2 {
function inchide_cont($zile, $rata) {
$suma = ContBanca2::inchide_cont();
$suma = $suma + $suma * $rata * ($zile / 365);
return $suma;
}
}
?>
3. Tablouri cu obiecte
Tablourile (numite si matrice) reprezinta o modalitate convenabila pentru lucrul cu mai multe valori. Valorile stocate în tablouri pot face referire la obiecte exact asa cum procedeaza în cazul numerelor sau al sirurilor.
Un tablou care face referire la obiecte se numeste "tablou cu obiecte".
Pentru a intelege modul de utilizare a unui tablou cu obiecte, sa examinam urmatoarea clasa "ContBanca" si doua clase copil ale acesteia:
<?php
// Clasa parinte
class ContBanca {
var $cont_id;
var $nume_posesor;
var $sold;
var $tip_cont;
function ContBanca($id, $nume, $suma, $tip) {
$this->cont_id = $id;
$this->nume_posesor = $nume;
$this->sold = $suma;
$this->tip_cont = $tip;
}
function dump() {
return "Cont = ". $this->cont_id.
" posesor = ". $this->nume_posesor.
" sold = ". $this->sold.
" tip = ". $this->tip_cont;
}
}
// Incepe codul pt. prima clasa copil
class ContCurent extends ContBanca {
function ContCurent ($id, $nume, $suma) {
ContBanca::ContBanca($id, $nume, $suma, "curent");
}
}
// Incepe codul pt. a doua clasa copil
class ContEco extends ContBanca {
function ContEco ($id, $nume, $suma) {
ContBanca::ContBanca($id, $nume, $suma, "economii");
}
}
?>
- Remarcati faptul ca metodele constructor ale celor doua clase copil fac referire la constructorul clasei parinte (
folosind perechea "::"), reutilizând în mod eficient caracteristica furnizata de clasa parinte, reducand astfel codul programului.
Acum, creem instante ale claselor copil si stocam referintele la aceste instante într-un tablou:
<?php
$cont[0] = new ContCurent(11, "Plo Mar", 100);
$cont[1] = new ContEco(12, "Didi", 140);
?>
Dupa ce referintele au fost stocate în tablou, pot fi accesate în mai multe moduri, (
vedeti lectiile despre lucrul cu tablouri:
Lectia 9 si
Lectia 10 ).
De exemplu, dupa ce am definit clasele si am stocat instantele in tabloul "$cont[]" de mai sus, adaugam urmatorul cod:
<?php
// Aici adaugam datele pt. definirea claselor
// Aici adaugam codul pentru stocarea instantelor in tablou
foreach ($cont as $contul) {
echo "<br /> ". $contul->dump();
}
?>
- Apelam metoda "dump()" deoarece aceasta este inclusa in clasa parinte, deci mostenita de clasele copil, si are ca rol returnarea datelor.
- Tabloul este simplu de parcurs, prin invocarea metodei "dump()", care doar afiseaza membrii claselor unui obiect "ContBancar" sau ale unui obiect din una din clasele sale copil.
Exemplul va afisa urmatorul rezultat:
Cont = 11 posesor = Plo Mar sold = 100 tip = curent
Cont = 12 posesor = Didi sold = 140 tip = economii
- Primul rand reprezinta datele returnate din "$cont[0]" care face referire la obiectul clasei copil "ContCurent"
- Al doilea rand reprezinta datele returnate din "$cont[1]" care face referire la obiectul clasei copil "ContEco"
Studiati cu atentie aceste exemple si exersatile (adaugand si alte valori) pana le intelegeti.- Lectia 30
OOP - Utilizare clase ... <<-- Anterior ----------- Urmator -->> Expediere date la o ...
Curs realizat de MarPlo