Zarábaj až 6 000 € mesačne! Akreditované rekvalifikačné kurzy od 0 €. Viac informácií.

14. diel - Interface (rozhranie v PHP)

V predchádzajúcom cvičení, Riešené úlohy k 12.-13. lekciu OOP v PHP, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.

V minulej lekcii, Riešené úlohy k 12.-13. lekciu OOP v PHP , sme si vyskúšali praktické znalosti OOP na príklade s počítadlom návštev. Dnes v PHP tutoriálu zas načnete novú teóriu, ktorú bude rozhranie. Budeme pokračovať v našom príklade s ľuďmi.

Interface (rozhranie)

Rozhraním sa v programovaní myslí verejnej metódy, ktoré nám trieda vystavuje zvonku. Pomocou tohto rozhrania s inštanciou triedy potom komunikujeme.

Rozhranie je však možné definovať samostatne, mimo triedu. Takéto rozhranie neobsahuje implementáciu, ale iba hlavičky metód. Je to skrátka len rozhranie :) Keď si také rozhrania vytvoríme, môžeme ho nechať implementovať v nejakej triede. Skúsme si to.

Rozhranie si vytvoríme v priečinku tridy, aj keď triedou vlastne nie je. Pôjde o rozhranie programátora. Založte si nový súbor s názvom Programator.php. Do neho vložte nasledujúci obsah:

interface Programator
{
    public function programuj();
}

Rozhranie Programator obsahuje jednu metódu programujte (). Mohlo by ich samozrejme obsahovať viac a metódy by mohli mať aj parametre. Pre naše účely to však bohato stačí.

Presuňme sa do našej triedy Javista.php. Pre úplnosť zopakujem ako jej kód vyzerá:

class Javista extends Clovek
{

    public $ide;

    public function __construct($jmeno, $prijmeni, $vek, $heslo, $ide)
    {
        $this->ide = $ide;
        parent::__construct($jmeno, $prijmeni, $vek, $heslo);
    }

    public function pozdrav()
    {
        echo('Hello world! Jsem ' . $this->jmeno);
    }

    public function programuj()
    {
        echo("Programuji v {$this->ide}...");
    }

}

Trieda dedí z triedy Clovek, volá rodičovský konštruktor, prepisuje metódu pozdrav () a pridáva novú metódu programujte ().

My už vieme, že v PHP môžeme dediť iba z jednej triedy. Môžeme však zároveň implementovať aj ľubovoľný počet rozhraní. V deklarácii triedy pomocou kľúčového slova Implements určíme, že implementuje rozhranie Programator.

class Javista extends Clovek implements Programator

Čo sa týka názvoslovie, triedy sa dedí, rozhranie sa implementujú. Je to logické, pretože dedenie triedu obohatia i novú implementácií, interface triede iba prikáže, že má obsahovať nejaké metódy. Rozhranie môžeme v triede implementovať koľko chceme, oddeľujú sa čiarkou.

V index.php si vytvoríme nejakého Javistu:

$javista = new Javista('Tomáš', 'Marný', 28, 'mamradsvyheslo', 'NetBeans');
echo("Vše OK");
class Clovek
{

    public $jmeno;
    public $prijmeni;
    public $vek;
    private $unava = 0;
    public $id;
    private static $pocetLidi = 0;
    private $heslo;

    public function __construct($jmeno, $prijmeni, $vek, $heslo)
    {
        $this->jmeno = $jmeno;
        $this->prijmeni = $prijmeni;
        $this->vek = $vek;
        self::$pocetLidi++;
        $this->id = self::$pocetLidi;
        $this->heslo = $heslo;
    }

    public function spi($doba)
    {
        $this->unava -= $doba * 10;
        if ($this->unava < 0)
            $this->unava = 0;
    }

    public function behej($vzdalenost)
    {
        if ($this->unava + $vzdalenost <= 20)
            $this->unava += $vzdalenost;
        else
            echo('Jsem příliš unavený.');
    }

    public function pozdrav()
    {
        echo('Ahoj, já jsem ' . $this->jmeno);
    }

    protected function celeJmeno()
    {
        return $this->jmeno . ' ' . $this->prijmeni;
    }

    public function __toString()
    {
        return $this->jmeno . ' - ' . $this->id;
    }

    public static function validniHeslo($heslo)
    {
        return (mb_strlen($heslo) >= 5);
    }

}
interface Programator
{
    public function programuj();
}
class Javista extends Clovek implements Programator
{

    public $ide;

    public function __construct($jmeno, $prijmeni, $vek, $heslo, $ide)
    {
        $this->ide = $ide;
        parent::__construct($jmeno, $prijmeni, $vek, $heslo);
    }

    public function pozdrav()
    {
        echo('Hello world! Jsem ' . $this->jmeno);
    }

    public function programuj()
    {
        echo("Programuji v {$this->ide}...");
    }

}

Keď aplikáciu skúsime spustiť, všetko funguje rovnako dobre, ako predtým. Teraz sa presuňte do triedy Javista a metódu programujte () zakomentujte. Keď znovu prejdeme na index, zobrazí sa nám nasledujúce chybová hláška:

Tvoja stránka
localhost

Hláška nám oznamuje, že trieda Javista implementuje rozhranie a pritom v implementácii nemá všetky metódy, ktoré toto rozhranie obsahuje. Metódu opäť odkomentujeme.

Význam rozhrania

Rozhranie má v programovaní hneď niekoľko významov.

Predpis metód

Ako sme si teraz vyskúšali, umožňuje predpísať triede aké metódy musí obsahovať. Podobne ako napr. Modifikátory viditeľnosti (private) je to ďalší z nástrojov, ktorý nám umožňuje strážiť správnu funkčnosť kódu.

Zistenie prítomnosti rozhrania

Vráťme si do index.php naše poľa ľudí s niekoľkými inštanciami Javistů a ľudí. V cykle tieto inštancie prejdeme a necháme ich pozdraviť. Ak je daná inštancia programátor, necháme ho programovať. Všimnite si, že hovorím programátor, nie Javista. Môžeme sa totiž spýtať či inštancia implementuje určité rozhranie:

$lide = array();
$lide[] = new Clovek('Karel', 'Novák', 30, 'felix15');
$lide[] = new Javista('Jan', 'Nový', 24, 'mamradsvykolo', 'Eclipse');
$lide[] = new Clovek('Josef', 'Nový', 50, 'password');
$lide[] = new Javista('Tomáš', 'Marný', 28, 'mamradsvyheslo', 'NetBeans');
$lide[] = new Clovek('Marie', 'Nová', 32, 'tohlen3uhodn3s');

foreach ($lide as $clovek)
{
    echo($clovek . '<br />');
    if ($clovek instanceof Programator)
    {
        $clovek->programuj();
        echo('<br />');
    }
}
class Clovek
{

    public $jmeno;
    public $prijmeni;
    public $vek;
    private $unava = 0;
    public $id;
    private static $pocetLidi = 0;
    private $heslo;

    public function __construct($jmeno, $prijmeni, $vek, $heslo)
    {
        $this->jmeno = $jmeno;
        $this->prijmeni = $prijmeni;
        $this->vek = $vek;
        self::$pocetLidi++;
        $this->id = self::$pocetLidi;
        $this->heslo = $heslo;
    }

    public function spi($doba)
    {
        $this->unava -= $doba * 10;
        if ($this->unava < 0)
            $this->unava = 0;
    }

    public function behej($vzdalenost)
    {
        if ($this->unava + $vzdalenost <= 20)
            $this->unava += $vzdalenost;
        else
            echo('Jsem příliš unavený.');
    }

    public function pozdrav()
    {
        echo('Ahoj, já jsem ' . $this->jmeno);
    }

    protected function celeJmeno()
    {
        return $this->jmeno . ' ' . $this->prijmeni;
    }

    public function __toString()
    {
        return $this->jmeno . ' - ' . $this->id;
    }

    public static function validniHeslo($heslo)
    {
        return (mb_strlen($heslo) >= 5);
    }

}
interface Programator
{
    public function programuj();
}
class Javista extends Clovek implements Programator
{

    public $ide;

    public function __construct($jmeno, $prijmeni, $vek, $heslo, $ide)
    {
        $this->ide = $ide;
        parent::__construct($jmeno, $prijmeni, $vek, $heslo);
    }

    public function pozdrav()
    {
        echo('Hello world! Jsem ' . $this->jmeno);
    }

    public function programuj()
    {
        echo("Programuji v {$this->ide}...");
    }

}

Aplikáciu spustíme:

Tvoja stránka
localhost

Vo výsledku vidíme, že sme všetkých ľudí vypísali a ak s človekom môžeme pracovať ako s programátorom, tak ho necháme aj programovať. Na zistenie prítomnosti rozhrania sme použili operátor instanceof.

Táto technika je veľmi zaujímavá a umožňuje nám pýtať sa len či objekt v premennej obsahuje len nejakú časť, ktorú práve potrebujeme. Je nám celkom jedno, či je v premennej Javista alebo programátor v PHP, diernych štítkoch a podobne. Zaujíma nás skrátka či objekt vystavuje rozhranie programátor.

Zistenia typu premennej

S instanceof vlastne zisťujeme typ inštancie v premennej. Môžeme sa jednoducho pýtať na typ inštancie v premennej len s využitím OOP. Bez instanceof by sme si museli na javistovi napr. Definovať nejakú konštantu TYP_CLOVEKA s hodnotou "programator". A keby sme chceli, aby bol zároveň programátor a šachista, opäť by sme mali problém. Takto len implementujeme ďalšie rozhrania.

Keď sa pýtame na prítomnosť rozhrania, nemusíme uviesť len interface, ale pokojne triedu. Kód by fungoval podobne aj s touto podmienkou, avšak volal by iba inštancie triedy Javista:

if ($clovek instanceof Javista)

Samotná trieda sa teda chová aj ako rozhranie. Instanceof funguje aj pri dedenie. Ak niekoľkokrát podědíme a opýtame sa pomocou instanceof na nejakého z predkov, bude podmienka platiť.

V silne typovaných jazykoch (napr. V Jave) má rozhranie ešte oveľa väčší význam, v PHP sa bez neho v podstate zaobídete a sám sa priznám, že ho príliš nepoužívam. Občas je však vhodné ho použiť, najmä ak pracujeme s nejakou zložitejšie hierarchiou tried.

Pomenovanie rozhranie

Na záver si krátko povedzme aj niečo o tom, ako sa rozhranie pomenúvajú. Ak sa budeme držať konvencií Javy, platí pre pomenovanie rozhranie PascalCase, rovnako ako u tried. Existuje konvencie, ktorá predpisuje, že by všetky rozhrania v PHP mala končiť na "Interface". Mali by sme teda napr. Rozhranie ProgramatorIn­terface.

V angličtine sa rozhraní často pomenúvajú s koncovkou -able, napr. Drawable (niečo, čo ide vykresliť, predpisuje napr. Metódu paint ()), sortable a podobne. Slovensky by to bolo asi Vykreslitelny, čo tiež neznie zle. Programátor je zrovna prípad, kde sa názov rozhrania vymýšľa zle, možno by sa mohlo volať aj programujúce.

V budúcej lekcii, Kvíz - Statika a práca s databázou v PHP OOP , budeme s rozhraním pokračovať a uvedieme si tzv. Abstraktné triedu. Zdrojové kódy nájdete ako vždy k stiahnutiu pod článkom.

V nasledujúcom kvíze, Kvíz - Statika a práca s databázou v PHP OOP, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 613x (4.97 kB)
Aplikácia je vrátane zdrojových kódov v jazyku PHP

 

Predchádzajúci článok
Riešené úlohy k 12.-13. lekciu OOP v PHP
Všetky články v sekcii
Objektovo orientované programovanie (OOP) v PHP
Preskočiť článok
(neodporúčame)
Kvíz - Statika a práca s databázou v PHP OOP
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity