Učíme se PHP online a nekupujem knihy :o)

>> Pro všechny, kdo mají rádi tento jazyk nebo pro ty, kteří se v něm chějí zdokonalit.



Lekce 12: Třídy I




- Touto lekcí začíná lehce pokročilé programování v PHP.
- Jako první lekci si představíme třídy, které patří do objektově orientovaného programování - OOP.
- Objekt je něco, co dokáže udržovat svůj stav a interagovat s okolím zasíláním a přijímáním zpráv.
- OOP vzniklo jako reakce na stále se zvyšující složitost programů s cílem usnadnit jejich psaní.
- V dnešní době je OOP běžná záležitost a je to nutné znát - aspoň základy. Hlavně u větších programů je to nezbytné.


Tvorba tříd


- Název třídy je opakem názvu všeho ostatního, protože název třídy začíná vždy velkým písmenem.
- Deklarace třídy je dělá pomocí klíčového slova class.

class Auto
{
  // nejaky obsah tridy
}
- Název je většinou jedno slovo. Pokud slov je více, tak se spojí jako u funkcí.. například MaleAuto, MojeSuperTrida apod.

Pozor: Za názem třídy nikdy nejsou kulaté závorky jako u funkcí, takže neplést!

- Jakmile máme vytvořenou třídu Auto, tak do ní můžeme vkládat funkce a proměnné.
- Než ale začnem, tak je důležité zmínit modifikátory přístupu, které je nutné znát a používat.

public - veřejný člen... je přístupný uvnitř i mimo třídu (vychozí)

protected - chráněný člen... je přístupný pouze uvnitř třídy a třídách odvozených z této třídy

private - soukromý člen... je přístupný pouze uvnitř třídy


- Tyto modifikátory si dobře zapamatujte, protože používat třídu bez nich je jako nepoužívat třídu vůbec.
- No a jakmile známe modifikátory, tak si můžeme ukázat daklaraci proměnných do třídy.
class Auto
{
  // deklarace 2 privatnich promennych, ktere je mozne pouzit pouze ve tride
  private $rychlost;
  private $hmotnost;
}
- Deklarace proměnných nemusí mít nutně hodnotu, výchozí hodnota je null.
- Pokud máme takovýto tvar, kde jsou 2 a více proměnných bez hodnoty se stejným modifikátorem, tak to lze zapsat i jako:
class Auto
{
  private $rychlost, $hmotnost;
}
- Tento způsob se ale moc nedoporučuje, hlavně z pohledu přehlednosti. My budeme používat ten první - co proměnná, to nový řádek.
- Jako další věc bych vám představil gettry a settry. Ty slouží k tomu, aby jsme mohli přistupovat k privátním proměnným mimo třídu (přes objekt) a jak už název říká, tak gettry slouží pro získání hodnoty a settry pro její nastavení.
- Ale nebojte, není to nic jiného, než obyčejná funkce. Jediný rozdíl bude v jejím jménu. Pro getry se přidá do názvu get a pro setry set a hlavně funkce musí být public.
class Auto
{
  private $rychlost, $hmotnost;
  
  // gettry - ziska pouze hodnotu promennych
  public function getRychlost() { return $this->rychlost; }
  public function getHmotnost() { return $this->hmotnost; }
  
  // settry - nastavuje hodnotu promennych
  public function setRychlost($rychlost) { $this->rychlost = $rychlost; }
  public function setHmotnost($hmotnost) { $this->hmotnost = $hmotnost; }
}
- Určitě jste si všimli, že v každé funkci používám místo normálního názvu proměnné, tvar $this->promenna.
- Toto slovíčko $this slouží k tomu, aby jsme mohli přistupovat k proměnným, které jsou ve třídě (bez vyjjímky modifikátoru). Zároveň nám odlišuje proměnné uvnitř tříd a lokální ve funkcích.
- Teď vás asi bude zajímat, jak vůbec můžu třídu použít, když jí mám takto vytvořenou.
- Jak jsem předtím řekl, tak třída je objekt, takže máme nový datový typ a to object. A objekty tvoříme pomocí slovíčka new.
$prom = new Auto(); // vytvorime objekt Auto na promenne $prom
$prom = new Auto; // v tomto pripade lze zapsat i takto

$prom->setRychlost(120);  // nastavime rychlost auta
$prom->setHmotnost(1650); // nastavime hmotnost auta

// vypisem: "Auto jede rychlostí 120 km/h a váží 1650 kg."
echo "Auto jede rychlostí ".$prom->getRychlost()." km/h a váží ".$prom->getHmotnost()." kg.";
- Jednoduše řečeno... proměnná, na které se vytvoří třída bude typu objekt a pomocí šipky -> se volají funkce nebo proměnné, které jsou ve třídě public.
- V dalším příkladu uvedu funkci, která je pouze ve třídě a trochu si zkusíme modifikátory.
class Funkce // jmeno tridy
{
  // pokud nezadam modifikator "public", tak funkce bude stale "public"
  // doporucuji vsak modifikator vzdy uvadet, at je to jasne videt
  public function vypis1($text) { echo $text; }
  
  protected function vypis2($text) { echo $text; } // protected
  private function vypis3($text) { echo $text; } // private
  
  function vypis4($text) { echo $text; } // bez modifikatoru
}

$fce = new Funkce();
$fce->vypis1("Bagr"); // funguje
$fce->vypis2("Bagr"); // fatal error
$fce->vypis3("Bagr"); // fatal error
$fce->vypis4("Bagr"); // funguje
- Nyní bych chtěl ještě zmínit nový příkaz instanceof, který porovnává objekty a vrací true nebo false.
- Je proto užitečný v porovnání tříd, jestli daný objekt náleží té třídě nebo ne.
class A { } // nejaka trida A
class B { } // nejaka trida B

$a = new A(); // vytvorime objekt trida A

if ($a instanceof A) // porovname, jestli $a patri k A
{
  echo "Proměnná náleží třídě A"; // vypise toto
}
else echo "Proměnná NEnáleží třídě B";
- Jako příklad použití může být případ, kde budeme mít nějaké pole objektů dvou nebo více tříd a díky instanceof můžeme rozlišit, k jaké třídě objekt patří.
- Nastala by kritická chyba, kdyby jsme volali třeba funkci třídy A, která v ní neexistuje, ale je ve třídě B.
class A
{
  // trida A ma funkci pro vypsani cisla
  public function vypisCislo() { return 10; }
}

class B
{
  // trida B ma funkci pro vypsani jmena
  public function vypisJmeno() { return "Pavel"; }
}

// do pole si ulozime 2 objekty (tridu A i B)
$pole = array(new A(), new B());

foreach ($pole as $p) // projdeme pole
{
  // SPATNY zpusob !!
  echo $p->vypisJmeno(); // fatal error
  echo $p->vypisCislo(); // fatal error
  
  // SPRAVNY zpusob
  // musime zjistit, k jakemu objektu dana funkce patri
  if ($p instanceof A)
  {
	echo $p->vypisCislo();
  }
  else echo $p->vypisJmeno();
}


Konstruktory a destruktory


- Konstruktor je výborná věc. Je to vlastně funkce, která má specifický název a volá se automaticky po vytvoření objektu třídy.
- Jméno funkce pro konstruktor je __construct() a nemá žádný návratový typ a musí být vždy public.
- Uvedem si příklad, jak pomocí konstruktoru vypíši text.

class Text
{
  public function __construct($text)
  {
	echo $text;
  }
}
- Volání a použití třídy bude tedy:
$text = new Text("bagr"); // vypise "bagr"

new Text("bagr"); // to same
- Konstruktor může volat cokoliv, i vaše funkce uvnitř třídy. Může sloužit jako nastavení prvotních hodnot.
class Text
{
  private $text;
  
  public function __construct()
  {
	$this->text = "Zde zatím žádný text není!";
  }
  
  public function nastavText($text) { $this->text = $text; }
  public function vypisText() { echo $this->text; }
}

$texty = new Text();
$texty->vypisText(); // vypise "Zde zatím žádný text není!"
$texty->nastavText("bagr");
$texty->vypisText(); // vypise "bagr"
- Ještě bych chtěl dodat, že konstruktory by se měli uvádět jako první funkce ve třídě.
- Destruktor je opakem konstruktoru a deklaruje se jako poslední funkce ve třídě a nese název __destruct().
- Destruktor stejně jako konstruktor nemá žádný návratový typ a volá se automaticky, až jako poslední.
class Trida
{
  public function __destruct() { echo "bagr"; }
}
new Trida(); // vypise "bagr"
- Je ve všem stejný jako konstruktor, až na jednu věc... destruktor nemá žádné parametry.
- Můžeme konstruktor i destruktor použít na automatické vygenerování html hlaviček a patiček. Možnosti jsou široké.
class Web
{
  // konstruktor, pro vytvoreni hlavicky
  public function __construct()
  {
	echo '<head> ... </head><body>';
  }
  
  // text, ktery se napise do tela webu
  public function text($vstup) { echo $vstup; }

  // destruktor, pro vytvoreni paticky
  public function __destruct()
  {
	echo '<div id="footer"> ... </div></body>';
  }
}

$web = new Web(); // vytvori objekt a vypise konstruktor (hlavicku webu)
$web->text("bagr"); // do tela vypise text a hned za to se prida destruktor (paticka)

// vypise: <head> ... </head><body>bagr<div id="footer"> ... </div></body>  


Třída a konstanty


- V příkazech jsem se naučili příkaz const, tak ho nyní můžeme využít.
- Jen pro připomenutí.. konstanta je hodnota, která slouží pouze pro čtení a píše se velkými písmeny.
- Určitě víte, jak se volají konstanty normálně. Ve třídách je to trochu jiné.
- Konstanta je vždy public a volat jí můžeme hned několika způsoby.
- Ukážeme si, jak se konstanta volá ve třídě.

class Dynamit
{
  const POCET = 10;
  
  public function vypis()
  {
	echo "Máme ".POCET." kusů dynamitu.";          // chyba
	echo "Máme ".self::POCET." kusů dynamitu.";    // spravne (bezny zpusob)
	echo "Máme ".Dynamit::POCET." kusů dynamitu."; // spravne
	echo "Máme ".static::POCET." kusů dynamitu.";  // spravne (moc se nepouziva)
  }
}
- Doporučuji používat volání konstanty přes self, to znamená, že volá současnou třídu, ve které se konstanta nachází a pomocí :: (znáte možná z C/C++) se přidělí její název.
- Třetí možnost volá přes název třídy, také to není chyba. Je to naprosto to samé, jako předchozí self.
- Poslední možnost přes static je spíše určeno pro statické deklarace, ale konstanta je též statická - proto to lze použít. Jinak static si ukážeme trochu níže.

- Volání konstanty mimo třídu je jednoduché, k tomu použijeme třetí způsob - více způsobů ani neni.
- Výhodou je, že nemusíme tvořit objekt... můžeme hned volat.
echo Dynamit::POCET; // vypise 10
- Pokud dáme konstantu mimo funkci, tak se chová stejně tak, jak ji známe.
const NOVY_POCET = 50; // konstanta mimo tridu

class Dynamit
{
  public function vypis()
  {
	echo "Máme ".NOVY_POCET." kusů dynamitu."; // spravne
  }
}
- Trochu jiné to bude pro zjištění existence konstanty.
- K tomu použijeme funkci defined(), kterou již známe, ale tvar bude trochu odlišný.
class Hodnoty
{
  const VAL = 50;

  public function __construct()
  {
	// toto by jsme logicky mohli pouzit, ale je to CHYBA!
	if (defined(self::VAL)) echo "Existuje";
	
	// spravny zpusob pro tridu
	if (defined(__CLASS__.'::'.VAL)) echo "Existuje";
  }
}
- U zjištění existence konstanty ve třídě je nutné uvést název třídy a ::, takže lze to zapsat i jako Hodnoty::VAL.
- My jsme použili příkaz __CLASS__, protože vrací název třídy (je to více dynamické). Pokud by jsme změnili název třídy, tak se nemusíme starat o změny v kódu a to jen, kvůli názvu třídy.

- Teď si představíme typ static, který je tak trochu zvláštní, protože aby jsme se dostali ke statickým členům, tak nemusíme tvořit objekt, ale lze k nim přistupovat přímo pomocí ::.
- Volání statického členu mimo funkci je stejné jako u konstanty, ale lze to pouze u modifikátoru public.
- Pokud statický člen voláme uvnitř třídy, tak je to stejné jako u konstanty - self nebo zde i static.
- Stručně řečeno... statický člen je proměnná, u které lze měnit hodnoty a přidávat modifikátory, ale ve všem ostatním se chová jako konstanta.
class Dynamit
{
  public static $cislo = 10; // verejna
  private static $moje = 50; // privatni - pouze pro tuto tridu

  public function vypis()
  {
	echo "Máme ".self::$cislo." kusů dynamitu.";
  }
}

echo Dynamit::$cislo; // vypise 10
echo Dynamit::$moje; // fatal error - privatni clen
- Samozřejmě statická nemusí být pouze proměnná, ale můžeme udělat i statickou funkci... zde ale platí určitá pravidla.
class Bagr
{
  private $cislo = 10; // bezna promenna vazana s objektem tridy
  private static $CISLO = 20; // staticka promenna
  
  // v poradku, ne-staticka funkce muze pouzivat jak objekty, tak staticke cleny
  public function vypis()
  {
	echo $this->cislo;
	echo self::$CISLO;
  }
  
  // chyba, staticka funkce obsahuje volani ne-staticke promenne (pres $this)
  public static function napis()
  {
	echo $this->cislo; // chyba - potrebuje objekt
	echo self::$CISLO;
  }
  
  // v poradku, staticka funkce vola staticke promenne
  public static function zapis()
  {
	echo self::$CISLO;
  }
}
$obj = new Bagr();
$obj->vypis(); // v poradku
$obj->napis(); // fatal error - nelze volat statickou funkci pres objekt
Bagr::napis(); // fatal error - funkce obsahuje volani ne-staticke promenne
Bagr::zapis(); // v poradku
- Pokud vás napadne, že slovíčko static nacpete do konstruktoru nebo destruktoru, tak to vás musím sklamat. Konstruktory i destruktory jsou vázaný na objekty, zatím co statické členy ne.
- Můžeme si ještě ke konci ukázat plně statickou třídu.
class Bagr
{
  private static $num; // staticka promenna
  
  public static function init() // bude nahrazovat konstruktor
  {
	self::$num = 5; // nastavi hodnotu
  }
  
  public static function nastav($num) { self::$num = $num; } // nastavi hodnotu
  public static function vypis() { echo self::$num; } // vypise hodnotu
}

Bagr::vypis();    // zde nevypise nic, hodnota ma NULL
Bagr::init();     // nastavi hodnotu na 5
Bagr::vypis();    // vypise 5
Bagr::nastav(10); // nastavime 10
Bagr::vypis();    // vypiseme 10


Dědění


- Dědičnost je celkem silná zbraň OOP, protože dokáže rozšiřovat objekty, takže se objekt neváže pouze na jednu třídu, ale na několik.
- Je to stejné jako ve skutečném světě - děti dědí z rodiče a ty zase z prarodiče. Je to taková struktůra stromu.
- Vytvořme si příklad, kde budeme mít hlavní třídu Zvire, kde budou nějaké vlastnosti zvířat, které mají všichni stejné. Dále budeme mít dvě další třídy Pes a Kocka. Tyto dvě třídy budou dědit z hlavní třídy Zvire a nejenom, že dědí všechny vlastnosti předchozí třídy, ale přidají se nové, které mají pouze ta 2 zvířata.
- Pojďme si tedy ukázat příklad v praxi.

// hlavni abstraktni trida Zvire
abstract class Zvire
{
  // prvky tridy
  private $vek;
  private $hmotnost;
  
  // konstruktor pro nastaveni veku a hmotnosti
  public function __construct($vek, $hmotnost)
  {
	$this->vek = $vek;
	$this->hmotnost = $hmotnost;
  }
  
  // gettry pro prvky tridy
  public function getVek() { return $this->vek; }
  public function getHmotnost() { return $this->hmotnost; }
}

// finalni trida Pes, ktera dedi ze Zvire
final class Pes extends Zvire
{
  private $umiStekat; // privatni promenna pro pocet zivotu
  
  // konstruktor tridy Kocka, do ktereho se vkladaji prvky ze trid, od kterych dedi a
  // zaroven prvky teto tridy
  public function __construct($vek, $hmotnost, $umiStekat)
  {
	parent::__construct($vek, $hmotnost); // dedeny konstruktor
	$this->umiStekat = $umiStekat;
  }
  
  // getter pro ziskani jestli pes umi stekat
  public function getUmiStekat() { return $this->umiStekat; }
}

// finalni trida Kocka, ktera dedi ze Zvire
final class Kocka extends Zvire
{
  private $pocetZivotu; // privatni promenna pro pocet zivotu
  
  // konstruktor tridy Kocka, do ktereho se vkladaji prvky ze trid, od kterych dedi a
  // zaroven prvky teto tridy
  public function __construct($vek, $hmotnost, $pocetZivotu)
  {
	parent::__construct($vek, $hmotnost); // dedeny konstruktor
	$this->pocetZivotu = $pocetZivotu;
  }
  
  // getter pro ziskani poctu zivotu
  public function getPocetZivotu() { return $this->pocetZivotu; }
}

$pes1 = new Pes(5, 10, true);  // pes1 = 5 let, 10kg a umi stekat
$pes2 = new Pes(8, 12, false); // pes2 = 8 let, 12kg a neumi stekat

$kocka1 = new Kocka(2, 3, 7);  // kocka1 = 2 roky, 3kg a ma stale 7 zivotu
$kocka2 = new Kocka(4, 5, 4);  // kocka2 = 4 roky, 5kg a ma jen 4 zivoty
- Je to celkem přehledně okomentovaný, takže bych se zaměřil na věci, které zatím neznáme a proč to tak je.
- Začnu asi příkazem extends, tento příkaz ukazuje na třídu, ze které se má dědit.
- První co je nové, jsou modifikátory abstract a final, které se používají pro třídu.
- Abstract vlastně znamená, že třídu nemůžeme použít jako objekt (nelze z ní vytvořit objekt pomocí new). Je to vlastně takové zabezpečení, aby k ní mohl být přístup pouze ze tříd, které jí dědí.
- Tady se dostáváme k pravidlu, že třída, která dědí z nejvíce tříd, je nejschopnější - může toho nejvíc.
- Druhým modifikátorem je final. Jak už název říká, tak se bude jednat o finální třídu, to znamená, že jí už nelze dále dědit.
- Další, co je zde nové, je příkaz parent. Tento příkaz volá konstruktor předka a přes současnou třídu se nastaví i třída děděná (právě přes ten konstruktor).
- Pomocí veřejných funkcí (gettrů), které jsou jak v hlavní třídě, tak děděných... můžeme volat hodnoty proměnných, protože se dědí také.

Pozor: Dědit pomocí extends můžeme pouze z jedné třídy!

- Zkusíme to u menších příkladů. První příklad jsem možná trochu přehnal.
class Hlavni // hlavni trida
{
  // objektove promenne
  private $A = 10;
  protected $B = 20;
  public $C = 30;
  
  // staticke promenne
  private static $D = 40;
  protected static $E = 50;
  public static $F = 60;
}

class Vedlejsi extends hlavni // vedlejsi trida co dedi z Hlavni
{
  public function __construct()
  {
	echo $A;         // chyba - jedna se o lokalni promennou
	echo parent::$A; // fatal error - promenna ve tride Hlavni je private
	echo parent::$B; // fatal error - pristup je mozny, ale promenna neni static
	echo parent::$C; // fatal error - to sami jako u $B
	echo parent::$D; // fatal error - pristup je mozny, promenna je private
	echo parent::$E; // v poradku, vypise 50
	echo parent::$F; // v poradku, vypise 60
	
	echo parent::$this->A; // notice - promenna neexistuje (je private)
	echo parent::$this->B; // v poradku, vypise 20
	echo parent::$this->C; // v poradku, vypise 30
	echo parent::$this->D; // notice - promenna neexistuje (je private)
	echo parent::$this->E; // strict - promenna je staticka
	echo parent::$this->F; // notice - to same jako u $E
	
	echo $this->A; // notice - nedefinovana promenna
	echo $this->B; // v poradku, vypise 20
	echo $this->C; // v poradku, vypise 30
	echo $this->D; // notice - nedefinovana promenna
	echo $this->E; // strict - nelze takto pristupovat ke staticke promenne
	echo $this->F; // notice - to same jako u $E
  }
}

new Vedlejsi(); // vytvoreni objektu vedlejsi tridy (pro volani konstruktoru)
- Zde vidíte jak lze přistupovat k proměnným, které se dědí a jak nelze.
- Slovíčko parent, které jsem sice vysvětlil, ale jen připomenu... ukazuje na rodiče - třídu děděnou.
// mame tyto tridy
class Hlavni { } // Hlavni trida
class Vedlejsi extends hlavni { }  // Vedlejsi trida, ktera dedi z Hlavni
class Dalsi extends Vedlejsi { } // Dalsi trida, ktera dedi z Vedlejsi

// vytvareni objektu trid
new Hlavni();   // objekt hlavni tridy bude obsahovat jen sam sebe
new Vedlejsi(); // bude obsahovat tridu Hlavni a sam sebe
new Dalsi();    // bude obsahovat tridy Hlavni, Vedlejsi a sam sebe
- Zde je opět vidět, jak poslední třída Dalsi obsahuje nejvíce informací a možností než předchozí 2 třídy.
- Teď si ukážem modifikátory abstract a final.
// mame tyto tridy
abstract class Hlavni { } // Hlavni abstraktni trida
class Vedlejsi extends hlavni { }  // Vedlejsi trida, ktera dedi z Hlavni
final class Dalsi extends hlavni { }  // Dalsi trida, ktera dedi z Hlavni

new Hlavni();   // fatal error - nelze vytvorit objekt abstraktni tridy
new Vedlejsi(); // v poradku
new Dalsi();    // v poradku
// opet mame tyto tridy
final class Hlavni { } // Hlavni finalni trida
class Vedlejsi extends hlavni { }  // Vedlejsi trida, ktera dedi z Hlavni
final class Dalsi extends hlavni { }  // Dalsi trida, ktera dedi z Hlavni

new Hlavni();   // v poradku
new Vedlejsi(); // fatal error - nelze dedit z finalni tridy
new Dalsi();    // fatal error - nelze dedit z finalni tridy
- Ovšem modifikátor final se nemusí týkat pouze tříd, ale je možné ho aplikovat i na funkce.
- U funkcí má trochu jiný význam a to, že zamezuje překrývání funkcí.
- Uvedem si tedy příklad, jak vypadá překrývání funkce a poté jak to vypadá po aplikování modifikátoru final.
class A
{
  // pokud by jsme zde vytvorili objekt na tridu A a zavolali funkci vypis(),
  // tak se vypise slovo "ahoj"
  public function vypis() { echo "ahoj"; }
}

class B extends A
{
  // v tomhle pripade, pokud vytvorime objekt na tridu B, ktera dedi od A a zavolali
  // funkci vypis(), tak se prekryje puvodni funkce ve tride A a vypise "svete"
  public function vypis() { echo "svete"; }
}
- Z této ukázky je to celkem jasné - novější funkce vždy přepisují starší, my však můžeme zařídit, aby to nešlo a to pomocí modifikátoru final.
class A
{
  // opet stejny vysledek jako predtim
  final public function vypis() { echo "ahoj"; }
}

class B extends A
{
  // zde jiz nastava fatal error, protoze finalni funkce se neda prekryt / prepsat
  public function vypis() { echo "svete"; }
}


Dobrovolný domácí úkol


1) Vytvořte třídu Matice, kde budou funkce vytvor(velikost_matice, minCislo, maxCislo), vynulujDiagonaly() a vypis(). Kde do vytvor(...) se zadá velikost matice třeba 6 = 6x6 a min a max čísla (od 1 do 9), která se budou do matice náhodně generovat v tom rozmezí. Funkce vynulujDiagonaly() je jasná, po vygenerování matice se zavolá tato funkce a nastaví na hlavní i vedlejší diagonále samé 0. A poslední funkce vypis() matici vypíše - musí mít tvar matice.

- Výstup by měl vypadat nějak takto pro matici 6x6 - čísla jsou náhodná.

0 5 4 3 4 0
2 0 6 6 0 7
4 7 0 0 6 2
1 9 0 0 5 5
9 0 3 5 0 4
0 6 5 8 9 0 
class Matice
{
  private $pole;		// uchovava matici - pouze pro tridu
  private $velikost;	// uchovava velikost matice - opet pouze pro tridu
  
  // vytvori matici
  public function vytvorPole($velikost, $min, $max)
  {
	$this->velikost = $velikost; // nastavime velikost do promenne tridy
	
	for ($i = 0; $i < $velikost; $i++)
	{
	  for ($j = 0; $j < $velikost; $j++)
	  {
		$this->pole[$i][$j] = rand($min, $max); // generuje cisla do matice
	  }
	}
  }
  
  // funkce pro vynulovani hlavni a vedlejsi diagonaly
  public function vynulujDiagonaly()
  {
	for ($i = 0; $i < $this->velikost; $i++)
	{
	  $this->pole[$i][$i] = 0; // hlavni
	  $this->pole[$this->velikost - $i - 1][$i] = 0; // vedlejsi
	}
  }
  
  // vypisuje matici
  public function vypis()
  {
	for ($i = 0; $i < $this->velikost; $i++)
	{
	  for ($j = 0; $j < $this->velikost; $j++)
	  {
		echo $this->pole[$i][$j]."\t"; // odsadi tabulatorem
	  }
	  echo '
'; // novy radek } } } $mat = new Matice(); // novy objekt matice // vytvori matici s velikosti 6x6 s nahodnymi cisly od 1 do 9 $mat->vytvorPole(6, 1, 9); $mat->vynulujDiagonaly(); // vynuluje diagonaly $mat->vypis(); // vypise matici
2) Vytvořte třídu Auto, která bude obsahovat informace o automobilu - znacku, max. rychlost, hmotnost a cenu. Přes konstruktor zadáme všechny informace - tím vytvoříme nové auto. Nyní si mimo třídu vytvoříme pole, do kterého vložíme 3 objekty aut. Poté přes cyklus je vypíšem - informace o každém automobilu.

- Výpis z pole by měl vypadat třeba takto.
Značka: Škoda
Maximální rychlost: 200 km/h
Hmotnost: 1650 kg
Cena: 350000 kč

Značka: Ford
Maximální rychlost: 240 km/h
Hmotnost: 1422 kg
Cena: 498000 kč

Značka: Fiat
Maximální rychlost: 180 km/h
Hmotnost: 1210 kg
Cena: 280000 kč
class Auto
{
  // uchovava informace o aute
  private $znacka;
  private $maxrychlost;
  private $hmotnost;
  private $cena;
  
  // pres konstruktor vytvori auto
  public function __construct($znacka, $maxrychlost, $hmotnost, $cena)
  {
	$this->znacka = $znacka;
	$this->maxrychlost = $maxrychlost;
	$this->hmotnost = $hmotnost;
	$this->cena = $cena;
  }
  
  // pouze gettry pro ziskani informaci z privatnich promennych
  public function getZnacka() { return $this->znacka; }
  public function getMaxRychlost() { return $this->maxrychlost; }
  public function getHmotnost() { return $this->hmotnost; }
  public function getCena() { return $this->cena; }
}

// nase pole aut (objektu)
$poleAut = array(
  new Auto("Škoda", 200, 1650, 350000),
  new Auto("Ford", 240, 1422, 498000),
  new Auto("Fiat", 180, 1210, 280000)
);

// cyklus pro vypsani informaci o kazdem aute
foreach ($poleAut as $row)
{
  echo "Značka: ".$row->getZnacka()."
"; echo "Maximální rychlost: ".$row->getMaxRychlost()." km/h
"; echo "Hmotnost: ".$row->getHmotnost()." kg
"; echo "Cena: ".$row->getCena()." kč

"; } //PS: promenna $row ukazuje na objekt tridy Auto, proto je mozne takto pristupovat
3) Vytvořte třídu Stroje, která bude obsahovat prázdné pole a dvě funkce pridejProstredek(objekt), přes který se budou přidávat prostředky do pole (celé třídy). Druhá funkce bude vypisProstredky(), která vypíše celé pole se všemi vlastnostmi, které ten objekt má. Poté si vytvořte třídu DopravniProstredky a ta bude obsahovat 4 základní vlastnosti, který každý prostředek bude mít a to typ, hmotnost, rychlost a barva. Na konec vytvoříme třídu Auto s vlastností rodinnyVuz a třídu Autobus s vlastností pocetMist. Nyní do pole přidáme 2 objekty Auta a Autobusu a vypíšem. Ještě bych chtěl doplnit, že rodinnyVuz je typ bool a až ve výpisu se mění na string (ano/ne). Dále nezapomeňte uvést, jestli daný objekt je Auto nebo Autobus a na konec počet objektů v poli.

- Takto by měl vypadat výpis.
Stroj: Auto
Typ: Ford
Hmotnost: 1866 kg
Rychlost: 260 km/h
Barva: Černá
Rodinné auto: ano

Stroj: Auto
Typ: Mazda
Hmotnost: 1610 kg
Rychlost: 280 km/h
Barva: Červená
Rodinné auto: ne

Stroj: Autobus
Typ: Ikarus
Hmotnost: 2680 kg
Rychlost: 180 km/h
Barva: Bílá
Počet míst: 46

Stroj: Autobus
Typ: Scania
Hmotnost: 2976 kg
Rychlost: 220 km/h
Barva: Modrá
Počet míst: 58

Počet strojů: 4
final class Stroje // finalni trida stroje
{
  private $pole; // zde bude prazdne pole
  
  // pridava objekty do pole (dopravni prostredky)
  public function pridejProstredek($obj)
  {
	$this->pole[] = $obj;
  }
  
  // vypisuje cele pole
  public function vypisProstredky()
  {
	$out = null;
	
	foreach ($this->pole as $row)
	{
	  // pomoci instanceof zjistuje, zda se jedna o Auto nebo Autobus
	  $out.= "Stroj: ".(($row instanceof Auto) ? "Auto" : "Autobus")."
"; $out.= "Typ: ".$row->getTyp()."
"; $out.= "Hmotnost: ".$row->getHmotnost()." kg
"; $out.= "Rychlost: ".$row->getRychlost()." km/h
"; $out.= "Barva: ".$row->getBarva()."
"; // kontroluje typ objektu, aby nesahl po funkci, ktera v objektu neexistuje if ($row instanceof Auto) { $rod = ($row->getRodinnyVuz()) ? "ano" : "ne"; $out.= "Rodinné auto: ".$rod."
"; } else $out.= "Počet míst: ".$row->getPocetMist()."
"; $out.= "
"; } echo $out; echo "Počet strojů: ".count($this->pole); // velikost pole } } abstract class DopravniProstredky // abstraktni trida pro dopravni prostredky { // sdilene vlastnosti private $typ; private $hmotnost; private $rychlost; private $barva; // pres konstruktor se nastavi vlastnosti objektu public function __construct($typ, $hmotnost, $rychlost, $barva) { $this->typ = $typ; $this->hmotnost = $hmotnost; $this->rychlost = $rychlost; $this->barva = $barva; } // gettry pro ziskani hodnoty z privatni promenne public function getTyp() { return $this->typ; } public function getHmotnost() { return $this->hmotnost; } public function getRychlost() { return $this->rychlost; } public function getBarva() { return $this->barva; } } // finalni trida Auto, co dedi prostredky final class Auto extends DopravniProstredky { private $rodinnyVuz; // vlastnost auta // pres konstruktor se nastavi vlastnost automobilu public function __construct($typ, $hmotnost, $rychlost, $barva, $rodinnyVuz) { // pristupuje k dedene tride a nastavuje jeji vlastnosti pres tuto tridu parent::__construct($typ, $hmotnost, $rychlost, $barva); $this->rodinnyVuz = $rodinnyVuz; } // getter pro ziskani hodnoty z privatni promenny public function getRodinnyVuz() { return $this->rodinnyVuz; } } // finalni trida Autobus, ktera dedi z prostredku final class Autobus extends DopravniProstredky { private $pocetMist; // vlastnost autobusu // pres konstruktor se nastavi vlastnost autobusu public function __construct($typ, $hmotnost, $rychlost, $barva, $pocetMist) { // pristupuje k dedene tride a nastavuje jeji vlastnosti pres tuto tridu parent::__construct($typ, $hmotnost, $rychlost, $barva); $this->pocetMist = $pocetMist; } // getter pro ziskani hodnoty z privatni promenny public function getPocetMist() { return $this->pocetMist; } } $stroj = new Stroje(); // vytvorime objekt tridy Stroje // pridame tyto objekty do pole $stroj->pridejProstredek(new Auto("Ford", 1866, 260, "Černá", true)); $stroj->pridejProstredek(new Auto("Mazda", 1610, 280, "Červená", false)); $stroj->pridejProstredek(new Autobus("Ikarus", 2680, 180, "Bílá", 46)); $stroj->pridejProstredek(new Autobus("Scania", 2976, 220, "Modrá", 58)); $stroj->vypisProstredky(); // vypisem pole


This page was loaded in 0.379883 seconds. © 2011-2025 by mimic | mimic.php5.cz
ICQ contact is 204-517-399