Hlavní navigace

PHP v objetí objektů (1)

Michal Burda

V tomto seriálu bych rád objasnil základní principy objektově orientovaného programování, jeho realizace a použití v PHP. Nechci se omezit jen na výklad konstrukce tříd a vytváření objektů, ale rád bych celou tématiku popsal tak, aby neznalý čtenář byl po přečtení schopen objektovou část PHP *skutečně* používat.

K napsání tohoto článku mě přiměla mezera v originální dokumentaci k PHP, kde je práce s objekty popsána jen okrajově a mnoho důležitých faktů v ní není zmíněno vůbec. Také další odborná literatura o PHP, která v České republice vyšla, objektově orientované programování v PHP popisuje jenom povrchně. V tomto seriálu se vám pokusím předat ucelený materiál, abyste celou problematiku bez problémů zvládli a mohli OOP v PHP skutečně uplatnit – nebo přečíst a zavrhnout.

Telegraficky o tom, co nás v tomto a příštích pokračováních čeká:

  1. Co je to OOP
  2. Definice tříd, jejich atributů a metod
  3. Pojednání o konstruktorech
  4. Dědičnost, volání předefinovaných metod
  5. Statická volání metod
  6. Polymorfizmus
  7. Problémy s operátorem přiřazení
  8. …a něco navíc

Chvíli jsem uvažoval, jestli by název tohoto článku neměl raději znít „V PHP obětí objektů“, protože pokusy o objektové programování v PHP vám místy přinesou nejednu pernou chvilku. Jako třeba… Začněme ale pěkně od začátku.

Stručně o objektově orientovaném programování (OOP)

OOP je metoda tvorby programů, která víceméně věrně napodobuje způsob, jakým zacházíme s předměty reálného světa. Tento způsob programování je přehlednější, více strukturovaný, modulárnější a abstraktnější, než klasické procedurální programování.

Objekt je jednoznačně identifikovatelná entita, která má určité vlastnosti (atributy) a chování. Vezměme si třeba obyčejný budík. Jeho vlastnostmi jsou například barva, tvar a druh zvonění. Funkční budík měří čas a ve zvolený okamžik začne zvonit – takové je jeho chování. Každý z nás umí s budíkem zacházet a nikoho už nezajímá, jak uvnitř funguje. Víme, jak z budíku odečíst přesný čas a jak jej nastavit, a to nám stačí k tomu, abychom jej mohli úspěšně používat. OOP ztělesňuje nástroj, kterým lze kód chování „ukrýt“ uvnitř objektu. Až se naučíme definovat třídy objektů, poznáme, že objekty jsou programátorskou konstrukcí sdružující dohromady proměnné (vlastnosti, atributy) a funkce, které s těmito proměnnými pracují (akce, chování). Uživateli objektů stačí znát jenom určité funkce objektu (rozhraní) a o vnitřní implementaci se nemusí starat. Tento koncept je známý pod pojmem zapouzdření: vnitřní implementace mechanismu je oddělena od jeho rozhraní.

Podívejme se na budíky trochu s nadhledem. Všechny plní tutéž úlohu, a přitom se každé jejich provedení tak liší: existují budíky mechanické, elektronické nebo s rádiem, digitální nebo s ručičkama a podobně. Přitom je zřejmé, že jsou si všechny velice podobné. Bavíme se tady o budících, ale každý z nás si představí nějaký jiný. Cítíme, že základní vlastnosti všech budíků světa lze shrnout do abstraktního pojmu „budík“. Každý konkrétní druh je z tohoto abstraktního budíku odvozen – v řeči OOP jaksi dědí všechny vlastnosti abstraktního budíku a staví na nich svá vylepšení.

Přesuňme se teď k programování. Všechny nastíněné principy lze v OOP uplatnit. Objektem je datová struktura se sadou atributů (proměnných) a množstvím funkcí, které s daty pracují. Funkce přiřazené k objektům se v OOP nazývají metody. Data i obslužné metody jsou v objektu zapouzdřeny a navenek ukazují jen svá rozhraní.

Definici objektu je možno zdědit a vytvořit tak nový typ objektu, který může ke stávajícím atributům přidávat nějaké nové vlastnosti, stejně tak jako dodefinovávat (nebo předefinovávat!) zděděné metody. V programech vytváříme rozsáhlou hierarchii příbuzných modulů – objektů. Na vrcholu stromu stojí nejabstraktnější objekt se základními atributy a funkcemi společnými pro všechny. Jeho vlastnosti každý objekt dědí, přidává své atributy a chování – specializuje se až ke konkrétním nástrojům. Výhodami jsou opakovaná použitelnost a přehlednost kódu.

Třídy

Třída je šablonou objektu. Lze si ji představovat jako formičku, do které se „nalejou“ data a vznikne instance (výskyt) objektu.

Abychom mohli vytvářet nějaké objekty, musíme si nejprve připravit patřičné „formy“, tj. třídy. Třída se definuje pomocí příkazu class. V našem příkladu se pokusíme implementovat jednoduché menu. Každá třída musí mít nějaký název, který se píše za klíčové slovo class. Naši třídu nazveme prozaicky „ Menu“:

class Menu {
  # tady budou definice atributů a metod...
} 

Začněme nyní definovat nějaké atributy. Před deklarací vlastnosti se píše klíčové slovo var. Za ním následuje seznam atributů, oddělených čárkou. Proměnným může být rovnou přiřazena hodnota – v takovém případě bude mít každý nový objekt příslušné atributy automaticky inicializovány.

class Menu {
  var $polozky;             # pole položek menu
  var $podklad = '#FFFF00'; # barva pozadí
} 

Zda píšete var před každý název atributu, nebo vlastnosti městnáte za jeden var a identifikátory oddělujete čárkou, je úplně jedno. Vyberte si jeden způsob a ten používejte. Jejich kombinace působí rušivě a přispívá k nepřehlednosti.

Poznámka: Třídy můžete používat také jako obyčejný datový typ záznam (struct v C, record v Pascalu), nadefinujete-li jim jenom atributy, ale žádné metody. Kdo by se ale takto okrádal o sílu OOP?

Pro přístup k atributům objektu se používá operátor ->. Máme-li vytvořen objekt s názvem $moje_menu (jak se ze tříd vyrábějí objekty, se dozvíme příště), který obsahuje atribut $podklad, manipulujeme s ním takto:

Uvedený příklad nejprve do atributu podklad objektu $moje_menu uloží hodnotu #33FF33, a později ji vytiskne na stránku.

Všimněte si, že znak dolaru ( $) se vkládá před název atributu při jeho definici ve třídě (za klíčové slovo var), ale ne při odkazování pomocí operátoru ->.

Poznámka: Samozřejme vám nic nebrání v používání konstrukcí typu:

$promenna = 'pozdrav';
$muj_objekt->$promenna = 'ahoj'; 

Výsledkem bude, že se řetězec „ahoj“ uloží do atributu, jehož název je uchován v proměnné $promenna, tedy do atributu $pozdrav.

Poznámka: Poctivě řečeno, PHP nijak netrvá na deklarování atributů třídy pomocí var. Nové atributy můžete do objektu klidně přidávat „za chodu“. Např. následující kód je úplně v pořádku:

class MojeTrida {
  var $nazev;
}

/*
... tady se vytvoří objekt moje_trida
podle třídy MojeTrida (jak na to, viz dále)
*/

$moje_trida->nazev = '1.B';
$moje_trida->pocet_zaku = 15;
...
print 'Třída ' . $moje_trida->nazev
    . 'má ' . $moje_trida->pocet_zaku . ' žáků.'; 

Bez jakýchkoliv rozpaků jsem použil nový atribut pocet_zaku a PHP to ochotně zbaští. Chtěl bych vás ale před takovou nedbalostí varovat. Velice to zvyšuje nepřehlednost kódu.

Pokračování příště…

Našli jste v článku chybu?

18. 7. 2001 15:37

c3a (neregistrovaný)

Pokud se ptate obecne jak ma clovek poznat ze $neco je objekt, tak na to je fce isObject() (Vraci true {kupovivu} ci false). Pokud nevite jak to poznat v clanku, tak s trochou znalosti OOP by vam mohli dojit ze pokud se trida jmenuje Moje_trida, tak instance teto tridy (tedy objekt) se (v ramci nazornosti) muze jemnovat $moje_trida. (Povsimete si zmeny velikosti poc. pismen v nazvu.) :-}

18. 7. 2001 13:10

Míra Kaas (neregistrovaný)

Jó taky se moc těším na další díly ...

DigiZone.cz: R2B2 a Hybrid uzavřely partnerství

R2B2 a Hybrid uzavřely partnerství

120na80.cz: Rovnátka, která nejsou vidět

Rovnátka, která nejsou vidět

Root.cz: Nová třída SD karet A1 s vysokým výkonem

Nová třída SD karet A1 s vysokým výkonem

120na80.cz: Boreliózu nelze žádným testem prokázat

Boreliózu nelze žádným testem prokázat

Vitalia.cz: To nejhorší při horečce u dětí: Febrilní křeče

To nejhorší při horečce u dětí: Febrilní křeče

Vitalia.cz: Test na HIV je zdarma i za pět set

Test na HIV je zdarma i za pět set

DigiZone.cz: Česká televize mění schéma ČT :D

Česká televize mění schéma ČT :D

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

DigiZone.cz: V Plzni odstartovalo Radio 1

V Plzni odstartovalo Radio 1

Lupa.cz: Levný tarif pro Brno nebude, je to kartel

Levný tarif pro Brno nebude, je to kartel

Měšec.cz: Exekuční poradna: ptejte se online

Exekuční poradna: ptejte se online

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte

Root.cz: Certifikáty zadarmo jsou horší než za peníze?

Certifikáty zadarmo jsou horší než za peníze?

120na80.cz: Co všechno ovlivňuje ženskou plodnost?

Co všechno ovlivňuje ženskou plodnost?

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

Vitalia.cz: Proč vás každý zubař posílá na dentální hygienu

Proč vás každý zubař posílá na dentální hygienu

Vitalia.cz: Pamlsková vyhláška bude platit jen na základkách

Pamlsková vyhláška bude platit jen na základkách

Podnikatel.cz: K EET. Štamgast už peníze na stole nenechá

K EET. Štamgast už peníze na stole nenechá

Vitalia.cz: Jak vybrat ořechy do cukroví a kde mají levné

Jak vybrat ořechy do cukroví a kde mají levné