PHP a riadenie prístupu do tried v objektovo-orientovanom kóde

Published:

Add / read comments

V minulom článku som sa zaoberal dedením pri triedach a na konci som spomenul, že ak programátor neuvedie inak, tak sú všetky premenné a metódy nastavené na typ "public". Toto však môže byť pri určitých situáciách problém a preto je potrebné niektoré premenné alebo metódy pred prístupom zvonku chrániť.

Tak som začal študovať a skúmať riadenie prístupu k premenným a metódam tried. Materskú triedu som oproti pôvodnému stavu zmenil takto:

class Chemikalie {
 
  // privatne parametre (vlastnosti) triedy
  private $systematicky_nazov;
  private $trivialny_nazov;
  private $vzorec;
  protected $vyrobca;	 
 
  // konstruktor objektu
  public function __construct( $systematicky_nazov, $trivialny_nazov, $vzorec,	$vyrobca ) {
 
    // inicializaciou triedy, vytvorim objekt triedy (jej instanciu), ktory ma taketo vlastnosti
    $this->systematicky_nazov = $systematicky_nazov;
    $this->trivialny_nazov = $trivialny_nazov;
    $this->vzorec = $vzorec;
    $this->vyrobca = $vyrobca;				
 
  }
 
  // verejna metoda v materskej triede
  public function vytvorPlneInfo() {	  
    // vygeneruje kompletne info zlucenine (nazov+vzorec)
    return $this->systematicky_nazov." (".$this->trivialny_nazov.") [".$this->vzorec."]";	
  }
 
  // verejna metoda tzv. "setter" nastavi parameter chranenej premennej objektu
  public function setVyrobca( $vyr ) {
    $this->vyrobca = $vyr;	
  }
 
  public function setTrivialnyNazov( $naz ) {
    $this->trivialny_nazov = $naz;	
  }
 
  // verejna metoda tzv. "getter" vrati hodnotu chranenej premennej objektu
  public function getVyrobca() {
    return $this->vyrobca;
  } 
 
  public function getVzorec() {
    return $this->vzorec;
  } 
 
  public function getTrivialnyNazov() {
    return $this->trivialny_nazov;
  } 
 
  public function getSystematickyNazov() {
    return $this->systematicky_nazov;
  } 	
}

Jednotlivé parametre triedy sú teraz nastavené na hodnotu "private" a jedna z nich má hodnotu "protected". Private znamená, že z vonku k hodnote nemôžeme pristúpiť jednoduchým zápisom:

//Fatal error: Cannot access private property Chemikalie::$vzorec
echo $product->vzorec;

a musíme použiť tzv. "getter" metódu:

//verejna "getter" metoda na ziskanie hodnoty
$product->getVzorec();

Private takisto znamená, že hodnotu nededia detské triedy automaticky, ale je potrebné v detskej triede rozšíriť metódu materskej triedy s použitím kľúčového slova "parent". Tým sa detská trieda dostane k hodnote z materskej triedy:

public function getVzorec(){
  return parent::getVzorec();
}

Protected tiež znamená, že nie je možné pristúpiť k hodnote triedy priamo, ale iba prostredníctvom "getter" sprostredkovávateľa:

//vypise chybu Fatal error: Cannot access protected property Chemikalie::$vyrobca
echo $produkt->vyrobca;
//toto je v poriadnu, vrati hodnotu
echo $produkt->getVyrobca();

Protected na rozdiel od typu private znamená, že hodnotu dedia detské triedy automaticky:

// getter "getVyrobca" moze pristupit k hodnote materskej triedy,
// lebo je nastavena na typ "protected" => dieta dedi jej hodnotu
public function getVyrobca() {
  return $this->vyrobca;
}

Existujú aj tzv. "settery", ktoré nastavujú hodnoty chránených premenných. To znamená, že nemôžem zvonku priamo nastaviť hodnotu chránenej premennej a preto nasledujúci pokus zlyhá.

//Fatal error: Cannot access private property Chemikalie::$trivialny_nazov
$produkt->trivialny_nazov = 'test';

treba použiť "setter":

// verejna metoda tzv. "setter" nastavi parameter chranenej premennej objektu
public function setTrivialnyNazov( $naz ) {
  $this->trivialny_nazov = $naz;	
}

a to nasledovne:

$produkt->setTrivialnyNazov('naftalín');

a prostredníctvom gettera:

public function getTrivialnyNazov() {
  return $this->trivialny_nazov;
}

sa dostanem k hodnote:

echo $produkt->getTrivialnyNazov();

Na záver už len uvediem kód detských tried:

class TechnickeInfo extends Chemikalie {
 
  private $skupenstvo;
 
  //detske konstruktory rozsiruju materske o vlastne parametre (vlastnosti)
  public function __construct( $systematicky_nazov, $trivialny_nazov,	$vzorec, $vyrobca, $skupenstvo ) {		
    parent::__construct( $systematicky_nazov, $trivialny_nazov,	$vzorec, $vyrobca );		
    $this->skupenstvo = $skupenstvo;
  }
 
  // "getter" skupenstva kedze je to chranena premenna
  public function ziskatSkupenstvo() {
    return $this->skupenstvo;
  }
 
  // getter "getVyrobca" moze pristupit k hodnote materskej triedy,
  // lebo je nastavena na typ "protected" => dieta dedi jej hodnotu
  public function getVyrobca() {
    return $this->vyrobca;
  } 
 
  //rozsirime matersku metodu
  public function vytvorPlneInfo() {
    $prem = parent::vytvorPlneInfo();
    $prem .= "Skupenský stav = $this->skupenstvo";
    return $prem;
  }
 
  public function getVzorec(){
    return parent::getVzorec();
  }
}
 
class UctovneInfo extends Chemikalie {
 
  private $cena;
  private $mena;
  private $jednotka;
 
  public function __construct( $systematicky_nazov, $trivialny_nazov,	$vzorec, $vyrobca, $cena, $mena, $jednotka ) {
    //vyuzijeme matersky konstruktor 
    parent::__construct( $systematicky_nazov, $trivialny_nazov, $vzorec, $vyrobca );
    //doplnim detsku triedu o vlastne parametre
    $this->cena = $cena;
    $this->mena = $mena;
    $this->jednotka = $jednotka;	
  }
 
  // "getter" vrati hodnotu chranenej premennej objektu
  public function ziskatCenu() {
    return $this->cena;
  }
 
  public function ziskatMenu() {
    return $this->mena;
  }
 
  public function ziskatJednotku() {
    return $this->jednotka;
  }
 
  //rozsirime matersku metodu
  public function vytvorPlneInfo() {
    $prem = parent::vytvorPlneInfo();
    $prem .= "Cena = $this->cena [$this->mena/$this->jednotka]";
    return $prem;
  }		
}

Published:

Add / read comments

FIND ME

Share, follow or connect with me.