3. Zßklady OOP III
  1. V tΘto kapitole se zaΦneme zab²vat d∞diΦnostφ. Zam∞°φme se na mechanismus d∞d∞nφ a jak jej zabudovat do programu. ZaΦneme jednoduchou t°φdou, kterou budeme pou╛φvat b∞hem seznamovßnφ s d∞diΦnostφ. Nejprve uvedeme deklaraci tΘto t°φdy a implementaci tΘto t°φdy (zapφ╣eme ji do na╣eho programu p°ed funkci main).

  2. class vozidlo {
      int kola;
      float vaha;
    public:
      void inicializace(int nova_kola, float nova_vaha);
      int ziskej_kola(void);
      float ziskej_vahu(void);
      float vaha_na_kolo(void);
    };
    void vozidlo::inicializace(int nova_kola, float nova_vaha){
      kola = nova_kola;
      vaha = nova_vaha;
    }
    int vozidlo:: ziskej_kola(){
      return kola;
    }
    float vozidlo::ziskej_vahu(){
      return vaha;
    }
    float vozidlo::vaha_na_kolo(){
      return vaha/kola;
    }
    T°φda je jednoduchß a nepot°ebuje ╛ßdnΘ vysv∞tlenφ. Tato t°φda je pou╛ita v nßsledujφcφm programu (je zde uveden pouze obsah funkce main). Zjist∞te, jak tento program pracuje.
    vozidlo automobil, motocykl, nakladni, sedan;
    automobil.inicializace(4, 1300.0);
    motocykl.inicializace(2, 400.0);
    nakladni.inicializace(10, 22000.0);
    sedan.inicializace(4, 1500.0);
    cout << "Automobil mß " << automobil.ziskej_kola() << " kola.\n";
    cout <<"Nßkladnφ mß zßt∞╛ "<<nakladni.vaha_na_kolo()<<" kg na kolo.\n";
    cout << "Motocykl mß vßhu " << motocykl.ziskej_vahu() << " kg.\n";
    cout << "Sedan vß╛φ " << sedan.ziskej_vahu() << " kg a mß " <<
       sedan.ziskej_kola() << " kola.\n";
  3. V toto p°φkladu se poprvΘ seznßmφme s d∞diΦnostφ. T°φda automobil je odvozena od t°φdy vozidlo (prost°ednictvφm zßpisu ": public vozidlo" na prvnφm °ßdku definice t°φdy automobil). T°φda automobil obsahuje v╣e, co obsahuje t°φda vozidlo a v╣echny svΘ vlastnφ p°idanΘ informace. V programu budeme moci nadßle pou╛φvat ob∞ tyto t°φdy. Pro oznaΦenφ t°φdy, od kterΘ odvozujeme, budeme pou╛φvat nßzev p°edek a odvozenou t°φdu budeme naz²vat potomek. P°edek je obecn∞j╣φ t°φda, m∙╛e popisovat v╣echny mo╛nΘ typy vozidel, p°esn∞ji °eΦeno to, co v╣echny typy vozidel majφ spoleΦnΘ. Potomek je specializovanß t°φda, popisuje ji╛ konkrΘtnφ typ vozidla. V na╣em p°φpad∞ p°edek vozidlo m∙╛e b²t pou╛it k deklarovßnφ objekt∙ reprezentujφcφch nßkladnφ auta, motocykly, kola a mnoho jin²ch typ∙ vozidel, zatφm co t°φda automobil pouze pro objekty osobnφch automobil∙. T°φda automobil je vφce specifikovanß ne╛ t°φda vozidlo. V p°φpad∞ pot°eby bychom od t°φdy automobil mohli odvodit dal╣φ specifiΦt∞j╣φ t°φdu, nap°. t°φdu popisujφ sportovnφ automobily.

  4. Nßsleduje deklarace a implementace t°φdy automobil.  T°φda automobil obsahuje dv∞ datovΘ slo╛ky zd∞d∞nΘ od t°φdy vozidlo a jednu novou. Pokud se t²Φe metod, od vozidlo byly zd∞d∞ny Φty°i metody a zde byly p°idßny dv∞ novΘ metody. Metoda inicializace ze t°φdy vozidlo nenφ zde ale pou╛itelnß, nebo╗ ve t°φd∞ automobil je skryta lokßlnφ verzφ tΘto metody (ob∞ metody majφ stejnΘ jmΘno). Tuto deklaraci a implementaci zapφ╣eme za deklaraci a implementaci t°φdy vozidlo.
    class automobil : public vozidlo {
      int osob;
    public:
      void inicializace(int nova_kola, float nova_vaha, int lidi = 4);
      int pasazeru(void);
    };
    void automobil::inicializace(int nova_kola, float nova_vaha, int lidi){
      osob = lidi;
      vozidlo::inicializace(nova_kola, nova_vaha);
    }
    int automobil::pasazeru(void){
      return osob;
    }
    Pov╣imn∞te si, ╛e v implementaci t°φdy ji╛ nenφ ╛ßdnß informace o tom, ╛e tato t°φda byla odvozena od n∞jakΘ jinΘ t°φdy. Na Φerven∞ oznaΦenΘm °ßdku je pou╛ita novß konstrukce. P°i inicializaci musφme provΘst takΘ inicializaci slo╛ek obsa╛en²ch ji╛ ve t°φd∞ p°edka, tzn. zaslat zprßvu t°φd∞ p°edka. Metoda inicializace provßdφ inicializaci novΘ slo╛ky (osob) a vyvolßvß zd∞d∞nou metodu inicializace k inicializovßnφ p∙vodnφch polo╛ek. Prostudujte si tuto novou t°φdu.
  5. Od t°φdy vozidlo m∙╛eme odvodit dal╣φ t°φdy. Vytvo°φme je╣t∞ t°φdu nakladni. T°φda nakladni je op∞t odvozena od t°φdy vozidlo a jsou zde p°idßny dv∞ slo╛ky a t°i metody. V╣e co n∞jak spojuje t°φdy automobil a nakladni je to, co je obsa╛eno v jejich spoleΦnΘm p°edkovi. Ob∞ tyto t°φdy majφ sice metody pasazeru, ale to nep∙sobφ ╛ßdnΘ problΘmy.

  6. class nakladni : public vozidlo {
      int osob;
      float naklad;
    public:
      void inic_nakl(int kolik = 2, float max_naklad = 12000.0);
      float vykonost(void);
      int pasazeru(void);
    };
    void nakladni::inic_nakl(int kolik, float max_naklad){
      osob = kolik;
      naklad = max_naklad;
    }
    float nakladni::vykonost(void){
      return naklad / (naklad + ziskej_vahu());
    }
    int nakladni::pasazeru(void) {
      return osob;
    }
    Zjist∞te, co tato t°φda provßdφ.
  7. Nßsledujφcφ program ukazuje jak lze pou╛φt v╣echny t°i t°φdy v jednom programu (je to nov² obsah funkce main).

  8. vozidlo unicykl;
    unicykl.inicializace(1, 7.5);
    cout << "Unicykl mß " << unicykl.ziskej_kola() << " kol.\n";
    cout << "Zßt∞╛ na kolo unicyklu je " << unicykl.vaha_na_kolo() << endl;
    cout << "Vßha unicyklu je " << unicykl.ziskej_vahu() << " kg.\n";
    automobil sedan;
    sedan.inicializace(4, 1500.0, 5);
    cout << "Sedan mß " << sedan.pasazeru() << " osob.\n";
    cout << "Sedan mß zßt∞╛ " << sedan.vaha_na_kolo() << " kg na kolo.\n";
    cout << "Sedan vß╛φ " << sedan.ziskej_vahu() << " kg.\n";
    nakladni tatra;
    tatra.inicializace(2, 7500.0);
    tatra.inic_nakl(1, 7000.0);
    cout << "Vßha tatry je " << tatra.ziskej_vahu() << " kg.\n";
    cout << "V²konnost tatry je "<<100.0 * tatra.vykonost()<<" procent.\n";
    Prostudujte si tento program a zjist∞te co provßdφ. Do programu p°idejte dal╣φ objekt t°φdy vozidlo a prove∩te s nφm stejnΘ operace jako s unicyklem.
  9. Do t°φdy nakladni p°idejte novou metodu vracejφcφ celkovou vßhu (vΦetn∞ nßkladu) a do programu p°idejte p°φkaz vypisujφcφ tuto hodnotu na monitor.
  10. Mimo t°φd typu class mohou v d∞dickΘ hierarchii vystupovat i t°φdy typu struct. Pokuste se zm∞nit vozidlo na deklaraci t°φdy typu struct (pozor na implicitnφ p°φstupovß prßva k polo╛kßm) a p°edchozφ program s touto zm∞nou vyzkou╣ejte. Svazy nesm∞jφ v d∞dickΘ hierarchii vystupovat, tj. nesm∞jφ b²t p°edkem ani potomkem. Vyzkou╣ejte.
  11. P°esto╛e metoda inicializace definovanß ve t°φd∞ automobil skr²vß metodu stejnΘho jmΘna ve t°φd∞ svΘho p°edka, m∙╛e se stßt, ╛e n∞kdy pot°ebujeme pou╛φt tuto skrytou metodu. Lze to provΘst takto:

  12. sedan.vozidlo::inicializace(4, 1500.0);
    Vyzkou╣ejte v na╣em programu. Zm∞nφ se po pou╛itφ tohoto p°φkazu hodnota slo╛ky osob?
  13. Pov╣imn∞te si dßle, ╛e inicializaci objektu nakladni je nutno provΘst pomocφ zaslßnφ dvou zprßv tomuto objektu. KterΘ p°φkazy to jsou? Zm∞≥te metodu inic_nakl, aby provßd∞la inicializaci najednou (p°edßvejte ji v╣echny Φty°i parametry a u poslednφch dvou nap°. uve∩te implicitnφ hodnoty). Pot°ebnou zm∞nu prove∩te i v hlavnφm programu. Program vyzkou╣ejte.
  14. P°edchozφ program zm∞≥te takto: v prvnφm °ßdku definice obou odvozen²ch t°φd vynechejte klφΦovΘ slovo public. Pou╛itφ tohoto klφΦovΘho slova zaji╣╗uje, ╛e v╣echny slo╛ky definovanΘ ve t°φd∞ p°edka jsou pou╛itelnΘ (dostupnΘ) v odvozenΘ t°φd∞ a to stejn∞ jako by zde byly definovßny. V p°edchozφm programu jsme tedy mohli volat metody definovanΘ v t°φd∞ vozidlo z hlavnφho programu i kdy╛ jsme pracovali s n∞kter²m objektem n∞kterΘ odvozenΘ t°φdy. Nap°. mohli jsme zaslat zprßvu objektu sedan, aby zjistil svou vßhu. Vynechejte tato klφΦovß slova a zjist∞te jakΘ chyby bude p°ekladaΦ signalizovat. ChybnΘ °ßdky oznaΦte jako komentß° a program vyzkou╣ejte.

  15. Kdy╛ nynφ deklarujeme objekt typu automobil, obsahuje t°i datovΘ slo╛ky. Jedna je nov∞ definovanß a ostatnφ dv∞ jsou zd∞d∞ny od svΘho p°edka. Pro p°φmΘ pou╛itφ ve sv²ch metodßch je dostupnß pouze nov∞ definovanß a ostatnφ dv∞ (zd∞d∞nΘ) jsou skryty. Neexistuje tedy v tomto programu ╛ßdn² zp∙sob jak pou╛φt polo╛ky kola a vaha.

Zßkladnφ pravidla pro datovΘ slo╛ky:

3. Zßklady OOP III