21. Seznßmenφ s OOP I

Co je objekt?
Kdy╛ se rozhlΘdneme okolo sebe vidφme mnoho p°φklad∙ objekt∙ skuteΦnΘho sv∞ta. Je to nap°. pes, st∙l, televizor nebo jφzdnφ kolo. Tyto objekty skuteΦnΘho sv∞ta sdφlejφ dv∞ charakteristiky: v╣echny majφ stav a v╣echny majφ chovßnφ. Nap°. pes mß stav (jmΘno, barvu, rasu) a pes mß chovßnφ (╣t∞kot, slintßnφ apod.). Jφzdnφ kolo mß stav (dv∞ kola, poΦet p°evod∙, rychlost ╣lapßnφ) a chovßnφ (brzd∞nφ, akcelerace, zm∞na p°evodu).
Objekty skuteΦnΘho sv∞ta m∙╛eme reprezentovat pomocφ programov²ch objekt∙. M∙╛eme chtφt znßzornit psa ze skuteΦnΘho sv∞ta jako programov² objekt v animaΦnφm programu nebo jφzdnφ kolo skuteΦnΘho sv∞ta jako programov² objekt v elektronickΘm trena╛Θru jφzdnφho kola. ProgramovΘ objekty ale takΘ m∙╛eme pou╛φt k modelovßnφ abstraktnφch p°edstav. Nap°. udßlost je obecn² objekt pou╛φvan² v systΘmu GUI k reprezentaci akce stisknutφ tlaΦφtka my╣i nebo klßvesy na klßvesnici.
Nßsledujφcφ obrßzek je Φastß vizußlnφ reprezentace programovΘho objektu.

To ╛e programov² objekt mß stav a m∙╛e n∞co d∞lat (mß chovßnφ) je zaji╣t∞no prom∞nn²mi (datov²mi slo╛kami) a metodami v tomto objektu. Programov² objekt modelujφcφ na╣e jφzdnφ kolo tedy musφ mφt prom∞nnΘ, kterΘ indikujφ souΦasn² stav kola, tj. jeho souΦasnou rychlost, jeho prßv∞ za°azen² p°evodov² stupe≥ atd. Nßsledujφcφ obrßzek ukazuje model jφzdnφho kola jako programov² objekt.

ProgramovΘ jφzdnφ kolo mß takΘ metody k brzd∞nφ, zm∞n∞ p°evodu, zm∞n∞ rychlosti ╣lapßnφ, atd. Jφzdnφ kolo nemß metodu pro zm∞nu rychlosti, nebo╗ rychlost kola zßvisφ na rychlosti ╣lapßnφ a za°azenΘm p°evodu. N∞co objekt jφzdnφho kola ale nemß a n∞co nem∙╛e provßd∞t. Nap°. na╣e jφzdnφ kolo (pravd∞podobn∞) nemß jmΘno a nem∙╛e ╣t∞kat. Tedy ve t°φd∞ jφzdnφho kola nejsou prom∞nnΘ nebo metody pro tento stav a chovßnφ.
Jak m∙╛eme vid∞t na p°edchozφm obrßzku, prom∞nnΘ objektu jsou umφst∞ny uprost°ed (v jßdru) objektu. Metody obklopujφ a skr²vajφ jßdro objektu p°ed ostatnφmi objekty v programu. Zabalenφ prom∞nn²ch objektu v jßdru chrßn∞nΘm sv²mi metodami se naz²vß zapouzd°enφ. Zapouzd°enφ je obvykle pou╛ito k ukrytφ implementaΦnφch detail∙ p°ed jin²mi objekty. Kdy╛ chceme zm∞nit ?p°evodov² stupe≥, nepot°ebujeme znßt jak p°evodov² mechanismus pracuje, staΦφ pouze p°esunout pßΦku. Podobn∞ v programu, nepot°ebujeme znßt jak t°φda je implementovßna, pot°ebujeme pouze v∞d∞t, kterou metodu vyvolat. ImplementaΦnφ detaily je tedy mo╛no m∞nit bez ovlivn∞nφ ostatnφch Φßstφ ?,
Tento koncepΦnφ obrßzek objektu, s jßdrem prom∞nn²ch zabalen²ch v ochrannΘ slupce metod, je ideßlnφ reprezentacφ objektu a je ideßlem, kter² se nßvrhß°i objektov∞ orientovan²ch systΘm∙ sna╛φ dosßhnout. NicmΘn∞ to nelze v╛dy.
Objekty mohou chtφt zve°ejnit svΘ prom∞nnΘ pro dal╣φ objekty a tφm umo╛nit jin²m objekt∙m prohlφ╛et nebo modifikovat tyto prom∞nnΘ. Objekt takΘ m∙╛e chtφt skr²t metody p°ed jin²mi objekty a zabrßnit tak t∞mto objekt∙m vyvolßvat metody. Objekt mß kompletnφ °φzenφ nad tφm, zda jinΘ objekty mohou p°istupovat k prom∞nn²m a metodßm objektu.



Co jsou zprßvy?
Samotn² objekt obecn∞ nenφ moc u╛iteΦn² a obvykle je pou╛it jako Φßst v∞t╣φ aplikace, kterß obsahuje mnoho objekt∙. Teprve vzßjemn²m p∙sobenφm t∞chto objekt∙, program zφskß svoji funkΦnost a slo╛itΘ chovßnφ. Na╣e jφzdnφ kolo stojφcφ v garß╛i a kterΘ je nepou╛φvanΘ, nenφ moc u╛iteΦnΘ. Jφzdnφ kolo je u╛iteΦnΘ pouze tehdy, kdy╛ jin² objekt (nap°. jß) na n∞j zaΦne p∙sobit (nap°. zaΦnu ╣lapat).
ProgramovΘ objekty vzßjemn∞ p∙sobφ na jinΘ objekty a komunikujφ s nimi pomocφ zasφlßnφ zprßv. Kdy╛ objekt A chce, aby objekt B provedl jednu ze sv²ch metod, pak objekt A zasφlß zprßvu objektu B.


N∞kdy p°ijφmajφcφ objekt vy╛aduje n∞jakΘ informace, kterΘ urΦφ co d∞lat. Nap°. kdy╛ chceme zm∞nit p°evod na╣eho jφzdnφho kola, musφme indikovat, kter² p°evod chceme pou╛φt. Tato informace je p°edßvßna jako parametr zprßvy.

Zprßva se sklßdß ze t°φ prvk∙:

Tyto t°i prvky jsou informace pro p°ijφmajφcφ objekt k provedenφ urΦenΘ metody. Dal╣φ informace nejsou vy╛adovßny.
Chovßnφ objektu je ovl∙iv≥ovßno pomocφ jeho metod a tedy (mimo p°φmΘho p°φstupu k prom∞nn²m) zprßvy provßd∞jφ v╣echno pot°ebnΘ vzßjemnΘ p∙sobenφ mezi objekty. Komunikujφcφ objekty nemusφ b²t ve stejnΘm procesu ani na stejnΘm poΦφtaΦi.


Co jsou t°φdy?
Ve skuteΦnΘm sv∞t∞, Φasto mßme mnoho objekt∙ stejnΘho typu. Nap°. na╣e jφzdnφ kolo je prßv∞ jedno z mnoha jφzdnφch kol na sv∞t∞. Pomocφ objektov∞ orientovanΘ terminologie, m∙╛eme °φci, ╛e objekt na╣eho jφzdnφho kola je instance t°φdy objekt∙ znßm²ch jako jφzdnφ kola. Jφzdnφ kola majφ n∞jak² spoleΦn² stav (poΦet p°evod∙ nebo poΦet kol) a spoleΦnΘ chovßnφ (zm∞na p°evodu, brzd∞nφ). Ale stav ka╛dΘho jφzdnφho kola je nezßvisl² a m∙╛e se li╣it od stavu jin²ch jφzdnφch kol.
Kdy╛ vyrßbφme jφzdnφ kola, pak °adu jφzdnφch kol vytvß°φme podle stejnΘho plßnu (vyrobenß jφzdnφ kola majφ n∞kterΘ stejnΘ charakteristiky). Bylo by znaΦn∞ neefektivnφ vytvß°et nov² plßn pro ka╛dΘ vyrobenΘ jφzdnφ kolo. V objektov∞ orientovanΘm programu je takΘ mo╛no mφt mnoho objekt∙ stejnΘho typu, kterΘ sdφlφ n∞jakΘ charakteristiky. Stejn∞ jako u skuteΦn²ch jφzdnφch kol, m∙╛eme p°ijmout skuteΦnost, ╛e programovΘ objekty stejnΘho typu jsou si podobnΘ a jsou vytvo°eny podle programovΘho plßnu t∞chto objekt∙. Programov² plßn pro objekty se naz²vß t°φda.
Nap°. m∙╛eme vytvo°it t°φdu jφzdnφ kolo, kterß se sklßdß z n∞kolika instancφ prom∞nn²ch k ulo╛enφ aktußlnφ rychlosti, aktußlnφho p°evodu, atd. T°φda takΘ deklaruje a poskytuje implementace pro metody instance, kterΘ umo╛≥ujφ zm∞nu p°evodu, brzd∞nφ apod. T°φdu m∙╛eme znßzornit stejn²m obrßzkem jako objekt.
Hodnoty pro prom∞nnΘ objektu jsou poskytnuty pro ka╛dou instanci t°φdy. Po vytvo°enφ t°φdy jφzdnφ kolo, musφme p°ed pou╛itφm instancφ t°φdy tyto instance vytvo°it. Kdy╛ vytvß°φme instanci t°φdy, vytvß°φme objekt tohoto typu a systΘm alokuje pam∞╗ pro prom∞nnΘ deklarovanΘ ve t°φd∞. Pak ji╛ m∙╛eme vyvolßvat metody objektu a provßd∞t s objektem r∙znΘ Φinnosti. Instance stejnΘ t°φdy sdφlφ implementace metod (jsou umφst∞ny v samotnΘ t°φd∞).


Co je d∞diΦnost?
Objektov∞ orientovanΘ systΘmy umo╛≥ujφ aby t°φdy byly definovßny pomocφ jin²ch t°φd. Nap°. horskß kola, zßvodnφ kola a tandemy jsou r∙znΘ typy jφzdnφch kol. V objektov∞ orientovanΘ terminologii, horskß kola, zßvodnφ kola a tandemy jsou v╣echno podt°φdy (potomci) t°φdy jφzdnφ kolo. Obdobn∞ t°φda jφzdnφ kolo je nadt°φda (p°edek) t°φd horskΘ kolo, zßvodnφ kolo a tandem.

Ka╛dß podt°φda d∞dφ stav (ve form∞ instancφ prom∞nn²ch) od nadt°φdy. Horskß kola, zßvodnφ kola a tandemy sdφlejφ n∞jak² stav (nap°. rychlost). Ka╛dß podt°φda takΘ d∞dφ metody od nadt°φdy. Horskß kola, zßvodnφ kola a tandemy sdφlejφ n∞jakΘ chovßnφ (nap°. brzd∞nφ).
Podt°φda ale nenφ omezena stavem a chovßnφm poskytnut²m ji jejφ nadt°φdou. Podt°φda m∙╛e k zd∞d∞n²m prom∞nn²m a metodßm p°idat svΘ vlastnφ prom∞nnΘ a metody. Tandemy majφ dv∞ sedla a dvojici °idφtek; n∞kterß horskß kola majφ specißlnφ p°evod s mal²m p°evodov²m pom∞rem.
Podt°φdy takΘ mohou p°episovat zd∞d∞nΘ metody a poskytujφ specializovanou implementaci t∞chto metod. Nap°. jestli╛e mßme horskΘ kolo se specißlnφm p°evodem, musφme zm∞nit metodu Zm∞na p°evodu, tak aby jezdec mohl pou╛φt tento nov² p°evod.
Nejsme omezeni jen na jednu vrstvu d∞d∞nφ. Strom d∞diΦnosti nebo hierarchie t°φd m∙╛e mφt libovoln² poΦet ·rovnφ. Metody a prom∞nnΘ se d∞dφ p°es tyto ·rovn∞. Obecn∞, Φφm hloub∞ji v hierarchii t°φd se t°φda vyskytuje, tφm vφce specializovanΘ je jejφ chovßnφ.
Podt°φdy poskytujφ specializovanΘ chovßnφ na zßklad∞ spoleΦn²ch prvk∙ poskytnut²ch nadt°φdou. Pomocφ pou╛itφ d∞diΦnosti, programßto°i mohou mnohokrßt op∞tovn∞ pou╛φvat k≤d v nadt°φd∞. Programßto°i mohou implementovat nadt°φdy naz²vanΘ abstraktnφ t°φdy, kterΘ definujφ v╣eobecnΘ chovßnφ. Abstraktnφ nadt°φdy definujφ a majφ ΦßsteΦnou implementaci chovßnφ, ale v∞t╣ina t°φdy je nedefinovanß a neimplementovanß. Tyto detaily jsou dopln∞ny ve specializovan²ch podt°φdßch.


  1. S OOP se nejprve budeme seznamovat na konzolov²ch aplikacφch. UrΦete co provßdφ nßsledujφcφ program (nejednß se o program OOP).

  2. struct jeden_udaj {
      int hodnota;
    };
    int main(int argc, char **argv)
    {
      jeden_udaj pes1, pes2;
      int prase;
      pes1.hodnota = 12;
      pes2.hodnota = 17;
      prase = 123;
      cout << "Hodnota pes1 je " << pes1.hodnota << endl;
      cout << "Hodnota pes2 je " << pes2.hodnota << endl;
      cout << "Hodnota prasete je " << prase << endl;
      return 0;
    }
  3. P°edchozφ "nesmysln²" program se pokusφme p°evΘst do objektov∞ orientovanΘho programovßnφ. Po tomto p°evodu dostaneme:

  4. class jeden_udaj {
      int hodnota;
    public:
      void nastav(int int_hodnota);
      int ziskej(void);
    };
    void jeden_udaj::nastav(int int_hodnota){
      hodnota = int_hodnota;
    }
    int jeden_udaj::ziskej(void){
      return hodnota;
    }
    int main(int argc, char **argv)
    {
      jeden_udaj pes1, pes2;
      int prase;
      pes1.nastav(12);
      pes2.nastav(17);
      prase = 123;
      cout << "Hodnota pes1 je " << pes1.ziskej() << endl;
      cout << "Hodnota pes2 je " << pes2.ziskej() << endl;
      cout << "Hodnota prasete je " << prase << endl;
      return 0;
    }
    Tento program dßvß stejnΘ v²sledky, jako p°edchozφ program. Je zde ale n∞kolik zm∞n. Namφsto struktury je pou╛ita t°φda. Jeden z rozdφl∙ mezi strukturou a t°φdou je ten, ╛e t°φda zaΦφnß soukromou Φßstφ, zatφmco struktura zaΦφnß ve°ejnou Φßstφ. Soukromß Φßst t°φdy je Φßst datov²ch slo╛ek, kterß nenφ p°φstupnß z vn∞j╣ku t°φdy (je ukryta jakΘmukoli vn∞j╣φmu p°φstupu). Prom∞nnß hodnota, kterß je Φßstφ objektu pes1, nenφ dostupnß z hlavnφho programu. Zdß se to trochu podivnΘ deklarovat prom∞nnou, kterou nem∙╛eme pou╛φt, ale p°esn∞ to jsme ud∞lali. Na╣e t°φda je slo╛ena z jednoduchΘ prom∞nnΘ nazvanΘ hodnota a dvou funkcφ, z nich╛ jedna se jmenuje nastav a druhß ziskej.
    NovΘ klφΦovΘ slovo public zahajuje ve°ejnou Φßst (tj. ve°ejnΘ rozhranφ). Tato Φßst je p°φstupnß z hlavnφho programu. Ob∞ funkce v na╣φ t°φd∞ le╛φ ve ve°ejnΘ Φßsti a jsou tedy p°φstupnΘ pro pou╛itφ z hlavnφho programu. Prom∞nnß hodnota je p°φstupnß pouze ve funkcφch definujφcφch ve°ejnΘ rozhranφ t°φdy. Funkce t°φdy se naz²vajφ metody (nebo ΦlenskΘ funkce), nebo╗ jsou Φßstφ t°φdy.
    Jeliko╛ jsme deklarovali dv∞ funkce, musφme je takΘ definovat, tj. urΦit co budou d∞lat. To provßdφme obvykl²m zp∙sobem, s tφm rozdφlem, ╛e jmΘno funkce p°edchßzφ jmΘno t°φdy a je odd∞leno dv∞ma dvojteΦkami. Tyto definice se naz²vajφ implementace metod. JmΘno t°φdy je po╛adovßno, proto╛e m∙╛eme v n∞kolika t°φdßch pou╛φt stejnΘ jmΘno funkce a p°ekladaΦ musφ v∞d∞t, se kterou t°φdou mß spojit kterou implementaci. PodstatnΘ je, ╛e soukromß data t°φdy jsou dostupnß v metodßch t°φdy pro modifikovßnφ nebo Φtenφ, ale soukromß data z jin²ch t°φd zde dostupnß nejsou.
    S pou╛itφm terminologie OPP m∙╛eme °φci, ╛e na╣e t°φda obsahuje jednu prom∞nnou (datovou slo╛ku) a dv∞ metody. Metody operujφ na prom∞nn²ch t°φdy. V deklaraci typu t°φdy jsou uvedeny prototypy metod.
    V programu (po skonΦenφ definicφ) deklarujeme dva objekty t°φdy jeden_udaj a nazveme je pes1 a pes2. Ka╛d² objekt obsahuje jednu datovou slo╛ku, kterou m∙╛eme nastavovat pomocφ jednΘ metody a Φφst pomocφ druhΘ. Nejprve zasφlßme zprßvu objektu pes1 s instrukcφ aby nastavil vnit°nφ hodnotu na 12. Objekt pes1 mß metodu nastav(), kterß nastavuje jeho vnit°nφ hodnotu na aktußlnφ parametr obsa╛en² ve zprßv∞. Pou╛it² zßpis se podobß p°φstupu k prvku struktury (jmΘno objektu, teΦka a jmΘno metody). Dßle obdobn∞ za╣leme zprßvu druhΘmu objektu. Druhß metoda je takΘ definovßna pro v╣echny objekty a v p°φkazech cout je pou╛ita. Objektu je zaslßna zprßva a vrßcenß hodnota je vypsßna.
    V programu je takΘ pou╛ita prom∞nnß prase. Je to normßlnφ prom∞nnß a pou╛φvßme ji b∞╛n²m zp∙sobem.
  5. Do p°edchozφho programu p°idejte metodu vracejφcφ druhou mocninu ulo╛enΘ hodnoty. Do programu vlo╛te dßle n∞kolik °ßdk∙ k≤du pro zji╣t∞nφ a zobrazenφ druhΘ mocniny ulo╛enΘ hodnoty.
  6. Zjist∞te co provßdφ nßsledujφcφ konzolovß aplikace:

  7. int plocha(int obd_vyska, int obd_sirka);
    struct obdelnik {
      int vyska;
      int sirka;
    };
    struct pole {
      int delka;
      int sirka;
    };
    int plocha(int obd_vyska, int obd_sirka) {                  // plocha obdΘlnφka
      return obd_vyska * obd_sirka;
    }
    int main(int argc, char **argv)
    {
      obdelnik okno, ctverec;
      pole moje_pole;
      okno.vyska = 12;
      okno.sirka = 10;
      ctverec.vyska = ctverec.sirka = 8;
      moje_pole.delka = 50;
      moje_pole.sirka = 6;
      cout << "Plocha okna je " << plocha(okno.vyska, okno.sirka) << endl;
      cout <<"Plocha ctverce je "<<plocha(ctverec.vyska,ctverec.sirka)<<endl;
      cout <<"Nesmyslnß plocha je "<<plocha(ctverec.vyska, okno.sirka)<<endl;
      cout<<"⌐patnß plocha je "<<plocha(ctverec.vyska,moje_pole.sirka)<<endl;
      return 0;
    }
    V tomto programu jsou poslednφ dva v²sledky v reßlnΘm sv∞t∞ nesmyslnΘ.
  8. P°edchozφ program p°evedeme do OOP a dostaneme:

  9. class obdelnik {                            // jednoduchß t°φda
      int vyska;
      int sirka;
    public:
      int plocha(void);                           // s dv∞mi metodami
      void inicializace(int, int);
    };
    int obdelnik::plocha(void){              // plocha obdΘlnφku
      return vyska * sirka;
    }
    void obdelnik::inicializace(int nova_vyska, int nova_sirka){
      vyska = nova_vyska;
      sirka = nova_sirka;
    }
    struct pole {
      int delka;
      int sirka;
    };
    int main(int argc, char **argv)
    {
      obdelnik okno, ctverec;
      pole moje_pole;
      okno.inicializace(12,10);
      ctverec.inicializace(8,8);
      moje_pole.delka = 50;
      moje_pole.sirka = 6;
      cout << "Plocha okna je " << okno.plocha() << endl;
      cout << "Plocha ctverce je " << ctverec.plocha() << endl;
      //cout << "Nesmyslnß plocha je " <<plocha(ctverec.vyska, okno.sirka)<<endl;
      //cout << "⌐patnß plocha je "<<plocha(ctverec.vyska,moje_pole.sirka)<<endl;
      return 0;
    }
    V tomto programu obdelnik je zm∞n∞n na t°φdu se dv∞mi slo╛kami, kterΘ jsou nynφ soukromΘ a dv∞mi metodami. Jedna z metod je pou╛ita k inicializaci hodnot vytvo°enΘho objektu a druhß metoda vracφ plochu objektu. Pole je ponechßno jako struktura. V programu jsou deklarovßny dva objekty (okno a ctverec), ale ji╛ nelze p°i°adit hodnoty p°φmo jejφm polo╛kßm. Jejich inicializace nynφ probφhß zaslßnφm zprßv objekt∙m. Nelze ji╛ provßd∞t nesmyslnΘ v²poΦty tak, jako v p°edchßzejφcφm programu.
    S daty mohou b²t provßd∞ny pouze ty operace, kterΘ jsou definovßny metodami (data jsou tedy chrßn∞na p°ed nesmysln²mi operacemi). Zapouzd°enφ a skr²vßnφ dat spojuje data a funkce pevn∞ dohromady a omezuje obor platnosti a viditelnost soukrom²ch prvk∙ t°φdy. 

NovΘ pojmy:

21. Seznßmenφ s OOP I