Občas chceme vytvořit třídu podobnou té, kterou už máme definovánu. Bylo by naprosto zbytečné, kdybychom vše přepisovali – stačí pozměnit pouze stávající třídu. Proces, kdy vytváříme novou třídu, která přebírá libovolné metody a atributy, se právě nazývá dědičnost.

Dědičnost třídy je označována klíčovým slovem extends. Říkáme, že původně definovaná třída se nazývá rodič, zatímco nově vytvořená se nazývá potomek. Více prozradí následující příklad:

<?php 
  class Trida{ 
  public $vek; 
    public function __construct($vek=3){ 
    $this->vek = $vek; 
    } 

    public function KolikJeVamRoku(){ 
    echo $this->vek; 
    } 

  } 

  class ZdedenaTrida extends Trida{ 
  public $dalsi_vek; 
    public function __construct($dalsi_vek){ 
    parent::__construct(); 
    $this->dalsi_vek = $dalsi_vek; 
    } 

    public function KolikJeVamRoku(){ 
    echo 'Nejprve zděděná třída: '; 
    parent::KolikJeVamRoku(); 
    echo 'a nová třída: '; 
    echo $this->dalsi_vek; 
    } 

  } 

$volana_zdedena_trida = new ZdedenaTrida(8); 
$volana_zdedena_trida->KolikJeVamRoku(); 
?>

Jak funguje tento skript? Klíčové slovo extends nám říká, že budeme chtít rozšířit třídu ZdedenaTrida o metody a vlastnosti třídy Trida. Zděděné vlastnosti i metody ZdedenaTrida může, nebo nemusí využít. Může je také rozšiřovat (což je náš případ).

V PHP 5 je, na rozdíl od nižších verzí, nutné volat rodičovský konstruktor. Všechny metody rodičovské třídy jsou přístupné přes zápis parent::, za kterým následuje název rodičovské metody. Pokud nechcete použít implicitní hodnotu argumentu v rodičovském konstruktoru, pak můžete použít zápis:

<?php 
  class Trida{ 
  public $vek; 
    public function __construct($vek){ 
    $this->vek = $vek; 
    } 

    public function KolikJeVamRoku(){ 
    echo $this->vek; 
    } 

  } 

  class ZdedenaTrida extends Trida{ 
  public $dalsi_vek; 
    public function __construct($vek,$dalsi_vek){ 
    parent::__construct($vek); 
    $this->dalsi_vek = $dalsi_vek; 
    } 

    public function KolikJeVamRoku(){ 
    echo 'Nejprve zděděná třída: '; 
    parent::KolikJeVamRoku(); 
    echo 'a nová třída: '; 
    echo $this->dalsi_vek; 
    } 

  } 

$volana_zdedena_trida = new ZdedenaTrida(5,8); 
$volana_zdedena_trida->KolikJeVamRoku(); 
?>

Pozn. red.: Zdůrazňujeme, že tento text se týká PHP 5.

5 Příspěvků v diskuzi

  1. Lze rovněž provézt toto (z vyse uvedeneho to nevypliva):

    metodaRodice();
    }
    }

    $potomek = new ZdedenaTrida();
    $potomek->metodaPotomka();
    $potomek->dalsiMetodaRodice();
    ?>

  2. Znovu:
    metodaRodice();
    }
    }

    $potomek = new ZdedenaTrida();
    $potomek->metodaPotomka();
    $potomek->dalsiMetodaRodice();
    ?>

  3. class Trida {
    public function __construct(){
    }

    public function metodaRodice(){
    echo „metoda rodice“;
    }

    public function dalsiMetodaRodice(){
    echo „dalsi metoda rodice“;
    }
    }

    class ZdedenaTrida extends Trida{
    public function __constuct(){
    parent::__construct();
    }

    public function metodaPotomka(){
    $this->metodaRodice();
    }
    }

    $potomek = new ZdedenaTrida();
    $potomek->metodaPotomka();
    $potomek->dalsiMetodaRodice();

  4. Ahoj,
    proc jsou v prikladech promene $vek resp. $dalsi_vek typu public a ne private?

    Chapu to spravne, ze jako private jsou pristupne pouze pomoci nejake funkce dane tridy a pokud chceme zmenit pozdeji jejich hodnotu ve vytvorene instanci, tak potrebujeme nejprve nadefinovat funkci:

    public function ZmenVek($vek){
    $this->vek = $vek;
    }

    a pote tuto funkci pouzit u instance:

    $rodic = new Trida(10);
    $rodic->ZmenVek(11);

    zatimco pokud jsou typu public, tak k nim muzeme pristupovat primo vyrazem:

    $rodic = new Trida(10);
    $rodic->vek = 11;

    Pokud ano, tak by me zajimalo jak je to s vyuzitim v praxi, jestli se vyuziva u vnitrnich promenych typ public nebo se z duvodu bezpecnosti a vetsi prehlednosti kodu pouziva private a pristup pouze pomoci funkci dane tridy?

  5. Co sa tyka dostupnosti premennych:

    private: je dostupna len v ramci danej triedy
    protected: je dostupna v ramci danej triedy a jej potomkov

    public: je dostupna odkialkolvek

    podla mna je dobrym zvykom pouzivat premenne protected a private, public len ked je to nutne,
    ak chces pristupovat k premennym z vonka je dobry zvyk pouzivat gettery a settery cize metody get…() a set…($value) ktore vratia hodnotu premennej prip nastavia jej hodnotu

    je to dobre aj z toho podhladu ak potrebujes spravit refactoring triedy a zmenis nazov premennej, ak k nej pristupujes priamo kde kade musis to vsade zmenit, ak pouzivas gettery a settery zmenis to len v nich z hotovo

Odpovědět