Prieš pradėdami skaityti straipsnį įsitikinkite, kad turite geras PHP 4 Objektinio Programavimo žinias.
Straipsnyje bus naudojami tokie ženklai:
- <> - tarp šių skliaustelių rašoma, kas turėtų būti toje vietoje;
- <…> - ir taip toliau…
- [] - tokie skliausteliai žymi, kad raktažodžiai nurodyti tarp šių skliaustelių nėra būtini;
- | - nurodo, kad gali būti vienas ar kitas variantas.
Taip pat įsidėmėkite, kad metodai - tai klasių funkcijos.
Klasės, Klasės, Klasės….
Klasė tai kolekcija kintamųjų bei metodų, kuri sėkmingai gali dirbti su klasės kintamaisiais ir kitais metodais.
Pavyzdinė klasė parašyta PHP 4 kalboje:
class Seima { // Keletas klasės kintamųjų var $Vaikai; var $Mama; var $Tetis; // Konstruktorius function Seima($Mama, $Tetis, $Vaikai) { // Priskiriame klasės kintamiesiems konstruktoriaus kintamųjų/argumentų reikšmes $this->Vaikai = $Vaikai; $this->Mama = $Mama; $this->Tetis = $Tetis; } // Funkcija function ShowFamily() { echo "<PRE >"; echo "Vaikai: "; // Spausdiname kintamąjį, kuris yra klasėje print_r($this->Vaikai); echo "\n"; echo "Mama: {$this->Mama}\n"; echo "Tetis: {$this->Tetis}\n"; echo "</PRE >"; } }
Aukščiau pateiktos klasės objektą galime sukurti ir naudoti taip:
// Sukuriame klasę, jos objektą priskiriame kintamajam $Seima $Seima =& new Seima( "Mama1", "Tetis1", Array("Vaikas1", "Vaikas2", "Vaikas3") ); // Atvaizduojame šeimą $Seima->ShowFamily();
Dabar susipažinkime su PHP 5 Objektiniu Programavimu.
Visų pirma norėčiau paminėti, jog PHP 5 kalboje norint perduoti objekto adresą nebereikia dėti adreso ženklo `&`.
Objekto Adresas PHP 5 kalboje yra nusiunčiamas automatiškai.
Access modiferiai…. Kas tai?
Access modiferiai - tai klasėje esančio metodo ar kintamojo pasiekimo leidimas.
Access modiferiai PHP 5 kalboje yra 3:
- private - pasiekiamas TIK iš tos klasės, kur aprašytas;
- protected - pasiekiamas iš tos klasės, kur aprašytas ir iš jos vaikų;
- public - pasiekiamas iš visur.
Senąjį raktažodį var pakeičia naujasis PHP 5 raktažodis public.
Jei PHP 5 klasės metodui nenurodytas pasiekiamumas, jis automatiškai tampa public.
Todėl PHP 5 gali tvarkytis su PHP 4 klasėmis.
Metodų ir kintamųjų su access modiferiais aprašymo sintaksė:
[[final]|[abstract]] class <klasės pavadinimas> { [<access modiferis> $<kintamojo pavadinimas> [= <reikšmė>];] [<...>] [const <KONSTANTOS PAVADINIMAS> [= <reikšmė>];] [[<access modiferis>] [static] [[abstract]|[final]] function <funkcijos pavadinimas>(<argumentai>){<...>}|;] [<...>] }
Klasės aprašymo ir panaudojimo pavyzdys:
class Foo { // kintamieji su įvairiais modiferiais public $Name; private $MyName; protected $Bar; // Konstruktorius. public function Foo($Vardas, $ManoVardas, $Baras) { // nustatome klasės kintamųjų reikšmes $this->Name = $Vardas; $this->MyName = $ManoVardas; $this->Bar = $Baras; } public function Reset() { // iškviečiame klasėje esančius metodus (klasės funkcijas) $this->SetBar("Hello"); $this->SetMyName("Hi"); $this->SetName("Bevardis"); } public function Show() { return "{$this->Name}\n{$this->MyName}\n{$this->Bar}\n"; } protected function SetBar($Reiksme) { // nustatome klasės kintamojo Bar reikšmę $this->Bar = $Reiksme; } private function SetMyName($Reiskme) { // nustatome klasės kintamojo MyName reikšmę $this->MyName = $Reiskme; } public function SetName($Reiskme) { // nustatome klasės kintamojo Name reikšmę $this->Name = $Reiksme; } } // Panaudojimo pavyzdys: $FooClass = new Foo("Jonas", "Paulius", "Blynas"); echo $FooClass->Atvaizduoti(); // visi aukščiau nurodyti vardai bus sėkmingai atvaizduoti echo "{$FooClass->Name}\n"; // ekrane pamatysime: "Jonas" echo "{$FooClass->MyName}\n"; // Klaida! Negalima pasiekti "privataus" kintamojo. echo "{$FooCloss->Bar}\n"; // Klaida! Negalima pasiekti "uždrausto" kintamojo $FooClass->SetBar(10); // Klaida! Negalima pasiekti "uždrausto" metodo $FooClass->Reset(); echo $FooClass->Show(); // sėkmingai išspausdins naujas reikšmes. // Praplečiame klasę Foo (Sukuriame "vaiką") class FooBar extends Foo { public function Show() { echo "Kita"; } public function Debug() { $this->Reset(); // metodą įvykdys iš šios klasės (atspausdins "Kita") parent::Reset(); // metodą įvykdys iš paveldėtos klasės (Foo) $this->Show(); // metodą įvykdys iš parento. $this->SetBar("FooBar nustatytas."); // metodą įvykdys iš paveldėtos klasės sėkmingai $this->SetMyName("Dfsdasfasf"); // Klaida! Privatus metodas nepasiekiamas. } } // panaudojimo pvz.: $FBObject = new FooBar(); $FBObject->Reset(); $FBObject->Show(); $FBObject->Debug();
Taigi kaip matome klasė FooBar taip pat įgijo paveldėtos klasės metodus ir kintamuosius.
Kitaip tariant praplėtė klasę Foo.
Naujas konstruktorius, ir DESTRUKTORIUS.
Konstruktorių galite vartoti kaip ir anksčiau (T.y. function <klasės pavadinimas>(<argumentai>) { <…> }).
Bet kam gi naudoti senąjį jei yra naujasis?
Naujojo konstruktoriaus pavadinimas - __constructor(…);
Konstruktorių aprašyti galime lygiai taip pat kaip ir anksčiau (PHP 4 kalboje) tik kitokiu pavadinimu.
Konstruktoriaus aprašymo sintaksė:
class <klasės pavadinimas> { public function __constructor([<Argumentai>][<...>]) { <...> } }
Susipažinkime su destruktoriumi.
Destruktoriaus funkcija įvykdoma objekto sesijos pabaigoje (kai objektas yra nebenaudojamas).
Destruktoriaus aprašymo sintaksė:
class <klasės pavadinimas> { [public] function __destructor() { <...> } }
Panagrinėkime konstruktoriaus ir destruktoriaus aprašymo ir naudojimo pavyzdį:
class Klase { public function __constructor($Argmentas, $Argumentas_2, $Argumentas_3 /* ..... */) { echo "Pradėta: {$Argumentas}, {$Argumentas_2}, {$Argumentas_3}....\n"; } public function __destructor() { echo "Pabaigta\n"; } public function DoSomething() { echo "Darau kažką...\n"; } } // Panaudojimo pvz.: $KlasesObj = new Klase("Vienas", "du", "trys"); $KlasesObj->DoSomething(); // ... //
Ekrane pamatysime:
Pradėta: Vienas, du, trys....
Darau kažką...
Pabaigta.
Turbūt kyla klausimas - kur aš galėčiau panaudoti tą “konstruktorių” ir “destruktorių”?
Atsakymas paprastas - tarkime duomenų bazės valdymui, kai reikia prisijungti prie duomenų bazės ir visų užklausų vykdymo pabaigoje reikia atsijungti nuo duomenų bazės.
Pavyzdžiui:
class DB_MySQL { protected $Database; public function __construct($Host, $Database, $Username, $Password) { $this->Database = mysql_connect($Host, $Username, $Password); mysql_select_db($Database); } public function __destruct() { mysql_close($this->Database); } public function SendQuery($Query) { return mysql_query($Query); } } $Localhost = new DB_MySQL("localhost", "mydatabase", "root", "sa"); $Result = $Localhost->SendQuery("SELECT * FROM Seeds");
Manau, jau supratote kaip veikia konstruktorius ir destruktorius.
Susipažinkime su Interfeisais (Angl. Interface)
Interfeisai - tai abstrakčių/deklaruotų metodų ir konstantų rinkinys.
Klasė, kuri paveldės interfeisą privalės aprašyti tuos metodus, kurie yra deklaruoti interfeise.
Interfeisai kaip ir klasės yra paveldimi panašiai tik naudojant raktažodį `implements`:
class <klasės Pavadinimas> implements <interfeisas>[,<...>] { }
Interfeisai yra aprašomi taip:
interface <interfeiso pavadinimas> { [const <KONSTANTOS PAVADINIMAS> [= <reikšmė>];] [<...>] [[<access modiferis>] [static] [[abstract]|[final]] function <funkcijos pavadinimas>(<argumentai>);] [<...>] }
Kad interfeisų pavadinimai nesimaišytų su klasių pavadinimais, prie interfeiso pavadinimo rekomenduojama naudoti didžiąją `I` raidę:
interface I<interfeiso pavadinimas> {}
Interfeiso panaudojimo pavyzdys:
interface IFamily { const SEX_MALE = 0x00; const SEX_FEMALE = 0x01; public function __construct($Father, $Mother); public function AddChild($Sex, $Name); } class Family implements IFamily { private $Father; private $Mother; private $Childrens = Array(); public function __construct($Father, $Mother) { $this->Father = $Father; $this->Mother = $Mother; } public function AddChild($Sex, $Name) { if($Sex == IFamily::SEX_MALE) // jei $Sex yra 0x00 $this->Childrens['Male'][] = $Name; elseif($Sex == IFamily::SEX_FEMALE) // jei $Sex yra 0x01 $this->Childrens['Female'][] = $Name; else // jeigu nebuvo nei 0x00 nei 0x01 $this->Childrens['Unknown'][] = $Name; } public function Show() { echo "{$this->Father}'s & {$this->Mother}'s Family:\n"; echo " Father: {$this->Father}\n"; echo " Mother: {$this->Mother}\n"; echo " Childrens:\n"; foreach($this->Childrens as $Sex => $Children) foreach($Children as $Name) echo " {$Name} ({$Sex})\n"; } } $Families = Array(); // Įkelia į masyvą objektą, kuris paveldi IFamily interfeisą function AddFamily(IFamily $Family) { global $Families; $Families[] = $Family; } function ShowAll() { global $Families; echo "<PRE >"; foreach($Families as $Family) { $Family->Show(); echo "\n"; } echo "</PRE >"; } $TedFamily = new Family("Ted", "Lisa"); $TedFamily->AddChild(IFamily::SEX_MALE, "John"); $TedFamily->AddChild(IFamily::SEX_FEMALE, "Groove"); $TedFamily->AddChild(IFamily::SEX_FEMALE, "Rihana"); AddFamily($TedFamily); $JohnFamily = new Family("John", "Britney"); $JohnFamily->AddChild(IFamily::SEX_MALE, "Gabriel"); $JohnFamily->AddChild(IFamily::SEX_FEMALE, "Garazi"); $JohnFamily->AddChild(IFamily::SEX_MALE, "Vandy"); AddFamily($JohnFamily); ShowAll();
Ekrane pamatysime:
Ted's & Lisa's Family: Father: Ted Mother: Lisa Childrens: John (Male) Groove (Female) Rihana (Female) John's & Britney's Family: Father: John Mother: Britney Childrens: Gabriel (Male) Vandy (Male) Garazi (Female)
PHP 5 kalboje yra galimybė deklaruoti abstraktų metodą ne tik interfeisuose bet ir klasėse - tai veikia lygiai taip pat.
Deklaruoti abstraktų metodą galime taip:
abstract <klasės pavadinimas> { [[<access modiferis>] [static] abstract function <funkcijos pavadinimas>(<argumentai>);] }
Pavyzdžiui:
abstract class MyClass { public function DoSomething() { echo "I'm doing something...\n"; } public abstract function DoWhatever(); } $MyObject = new MyClass; $MyObject->DoSomething(); // Metodą iškvies sėkmingai $MyObject->DoWhatever(); // Klaida! Metodas DoWhatever yra abstraktus (neaprašytas) class ExtendMyClass extends MyClass { public function DoWhatever() { echo "Hello!\n"; } } $ExtendMyObject = new ExtendMyClass; $ExtendMyObject->DoSomething(); // Metodą iškvies sėkmingai $ExtendMyObject->DoWhatever(); // Metodą iškvies sėkmingai
Objektų klonavimas - kas tai?
Objektų klonavimas - tai objekto kopijavimas, o ne adreso gavimas.
Kaip minėjau PHP 5 kalboje adresas objektams yra siunčiamas automatiškai,
todėl visada keisdami vieno kintamojo reikšmę (kuri yra objektas) pakeičiame ir kito kintamojo reikšmę.
Norėdami nepakeisti kito kintamojo reikšmės (objekto), o tiesiog sukurti naują objekto kopiją turime naudoti raktažodį `clone`.
Panagrinėkime vieną pavyzdį:
class Mano { public $Name; public function __construct($Name) { $this->Name = $Name; } // "Magiškasis metodas", kai objektas verčiamas į String tipą public function __toString() { return $this->Name; } } $Object = Array(); $Object[0] = new Mano("Jonas"); $Object[1] = new Mano("Petras"); echo "\$Object[0] = {$Object[0]}\n"; // $Object[0] = Jonas echo "\$Object[1] = {$Object[1]}\n"; // $Object[1] = Petras $Object[2] = $Object[0]; $Object[2]->Name = "Jonukas"; $Object[3] = $Object[1]; $Object[3]->Name = "Petriukas"; echo "\$Object[0] = {$Object[0]}\n"; // $Object[0] = Jonukas echo "\$Object[1] = {$Object[1]}\n"; // $Object[1] = Petriukas echo "\$Object[2] = {$Object[2]}\n"; // $Object[0] = Jonukas echo "\$Object[3] = {$Object[3]}\n"; // $Object[1] = Petriukas
Kaip pastebėjote objektai pasikeitė tolygiai.
O dabar panagrinėkime sekantį pavyzdį, kai naudojame raktažodį `clone`:
class Mano { public $Name; public function __construct($Name) { $this->Name = $Name; } // "Magiškasis metodas", kai objektas verčiamas į String tipą public function __toString() { return $this->Name; } } $Object = Array(); $Object[0] = new Mano("Jonas"); $Object[1] = new Mano("Petras"); echo "\$Object[0] = {$Object[0]}\n"; // $Object[0] = Jonas echo "\$Object[1] = {$Object[1]}\n"; // $Object[1] = Petras $Object[2] = clone $Object[0]; $Object[2]->Name = "Jonukas"; $Object[3] = clone $Object[1]; $Object[3]->Name = "Petriukas"; echo "\$Object[0] = {$Object[0]}\n"; // $Object[0] = Jonas echo "\$Object[1] = {$Object[1]}\n"; // $Object[1] = Petras echo "\$Object[2] = {$Object[2]}\n"; // $Object[0] = Jonukas echo "\$Object[3] = {$Object[3]}\n"; // $Object[1] = Petriukas
Manau, skirtumą pastebėjote iškart.
Susipažinkime su finalinėmis klasėmis ir metodais.
Finalinės klasės ir metodai (Angl. Final Classes & Methods) - tai tokios klasės, metodai, kurių praplėsti ar perrašyti (Angl. Override) negalima.
Final raktažodis tarsi užrakina metodą ar klasę.
Finalinės klasės ir metodai turi būti aprašyti taip:
final class <klasės pavadinimas> { [[<access modiferis>] [static] [final] function <funkcijos pavadinimas>(<argumentai>){<...>}] [<...>] }
Panaudojimo pavyzdys:
final class MyFinalClass { public function function Do() { echo "Hello!\n"; } public final function DoFinal() { echo "Hello Again!\n"; } } // Klaida! Negalima paveldėti/praplėsti finalinės klasės! class ExtendMyFinalClass extends MyFinalClass { // ... } class MyFinalMethod { public function function Do() { echo "Hello!\n"; } public final function DoFinal() { echo "Hello Again!\n"; } } // Gerai! Klasė nėra finalinė, todėl paveldėti/praplėsti galima class ExtendMyFinalMethod extends MyFinalMethod { // Klaida! Negalima perrašyti finalinio metodo public function DoFinal() { // ... } }
Turbūt pastebėjote, jei klasė yra finalinė, tai ir visi metodai, kintamieji bus taip pat finaliniai.
2007-08-21 | 12:48
apie objektinį programavimą daug gerų resursų yra.. o kai žinai OOP tai nesvarbu ant ko OOP naudoti. naudingos čia nebent php plonybės kurias susigūglini kai prireikia. nu bet tarkim “zajebys pavarei” :D
2007-08-22 | 14:49
[…] 3. Kas yra SimpleXML? SimpleXML - biblioteka (pateikiama kartu su PHP5), kurios pagalba galima lengvai ir patogiai dirbti su XML failais OOP būdu. […]
2007-09-11 | 21:54
[…] 3.Kuo skiriasi PHP 4 ir PHP 5 konstruktoriai (oop)? […]
2007-09-15 | 9:10
[…] Kuo skiriasi PHP 4 ir PHP 5 konstruktoriai (oop)? PHP 4 konstruktoriaus pavadinimas yra identiškas klasės pavadinimui, o PHP 5 turi […]