<?php /* No rozdiel je, a to dost podstatny. Abstraktna trieda je taka, z ktorej sa neda vytvorit instancia a ma minimalne jednu metodu abstraktnu == bez kodu. To znamena nieco taketo: */ abstract class Inzinier{ // tuto metodu musite prepisat v odvodenej triede abstract public function Name(); } class StavebnyInzinier extends Inzinier { public function Name() { return "Ja som stavebny inzinier"; } } class ChemickyInzinier extends Inzinier { public function Name() { return "Ja som chemicky inzinier"; } } //a v kode potom pouzijete nieco taketo: $SI = new StavebnyInzinier; $ChI = new ChemickyInzinier; echo $SI->Name; // vrati Ja som stavebny inzinier echo $ChI->Name; // vrati Ja som chemicky inzinier $Ing = new Inzinier; // toto spadne (v Jave, .NET, C++ a pod. sa to ani neskompiluje) echo $Ing->Name(); // toto nemozete pouzit //Problem by teraz bol, keby som chcel, aby obidvaja inzinieri mali aj vlastnost Plat, ktory by bol tiez objekt class Plat { private $_zakladny = 0; private $_odmeny = 0; private $_zrazky = 0; function __construct($zakladny, $odmeny, $zrazky) { // konstruktor $_zakladny = $zakladny; $_odmeny = $odmeny; $_zrazky = $zrazky; } public function GetCelyPlat() { $toRet = $_zakladny + $_odmeny + $_zrazky; return $toRet; } } //neda sa teraz napisat nieco taketo ( dedenie z dvoch objektov ) class StavebnyInzinier extends Inzinier, Plat // toto tu neprejde, lebo PHP5 nepodporuje viacnasobnu dedicnost objektov (chvalabohu), ale "iba" interfaces { public function Name() { return "Ja som stavebny inzinier"; } public function GetCelyPlat() { parent::GetCelyPlat(); // nevie, kto je jeho parent - Inzinier, alebo Plat? } } /*da sa ale urobit toto Abstraktnu triedu Inzinier napisem ako Interface. (Interface je v podstate abstraktna trieda, ktora me VSETKY metody abstraktne (to znamena, ze nemaju ziadne telo, su to len hlavicky funkcii) Akurat sa tam nepise klucove slovo "abstract") */ interface IInzinier { public function Name(); } interface IPlat { public function GetCelyPlat($odmeny); } class StavebnyInzinier implements IInzinier, IPlat { private $mMeno; private $mZaklPlat; function __construct($meno, $zaklplat) { // konstruktor $this->mMeno = $meno; $this->mZaklPlat = $zaklplat; } public function Name() { return $this->mMeno; } public function GetCelyPlat($odmeny) { $toRet = $this->mZaklPlat + $odmeny; return $toRet; } } class ChemickyInzinier implements IInzinier, IPlat { private $mMeno; private $mZaklPlat; function __construct($meno, $zaklplat) { // konstruktor $this->mMeno = $meno; $this->mZaklPlat = $zaklplat; } public function Name() { return $this->mMeno; } public function GetCelyPlat($odmeny) { $priplatok = 1000; $toRet = $this->mZaklPlat + $odmeny + $priplatok; return $toRet; } } //a potom v kode pouzijem toto $SI = new StavebnyInzinier("Fero Hruska",12000); echo $SI->Name().":"; // vrati "Fero Hruska" echo $SI->GetCelyPlat(3000); // vrati 15000 echo "<br>"; $ChI = new ChemickyInzinier("Jozo Hruska",12000); echo $ChI->Name().":"; // vrati "Jozo Hruska" echo $ChI->GetCelyPlat(3000); // vrati 16000 (12000 + 3000 + 1000) /* Ak teda implementacia (obsah) funkcie GetCelyPlat() v triede StavebnyInzinier a v ChemickyInzinier bude rozdielna, umozni mi to Stavebnym inzinierom davat odmeny 3000 a chemickym napr. 4000 V com je vyhoda napr. takto postavenych objektov je vidno na prvy pohlad: Pristupuje sa k nim rovnako: $ChI->Name(); $SI->Name(); A nemusim si teda pamatat taketo konstrukcie: echo stavebnyInzinier_Name(); echo chemickyInzinier_Name(); ak by som si vyrobil len knihovnu funkcii. To je pripad pristupu k databazam v PHP, ked namiesto DB->Query("SELECT...") sa pouziva mysql_query("SELECT ..."); a ked mam inu databazu zase oracle_query("SELECT..."); Pozor: Ani z interface sa neda urobit instancia-je to len popis rozhrania objektu. Nemozete teda napisat $MyObjekt = new IInzinier; !!! */ ?>
