Umíte pascalsky - 31.lekce ...

Umíte pascalsky?
31.lekce
Vytisknout  

Objektově orientované programování I.

Okolní svět je světem předmětů (objektů), které mají určité vlastnosti a chování. Objektivně orientované programování (OOP) je metoda tvorby programů, která napodobuje způsob, jakým zacházíme s předměty reálného světa. Je založena na pojmu objekt, jako abstrakci reálného objektu, který má určité vlastnosti (atributy) a může provádět definované akce. (Budík mé určitou barvu, tvar, druh zvonění - vlastnosti - měří čas a ve zvolený okamžik zazvoní - definované akce, chování). Vlastnosti objektu jsou reprezentovány hodnotami určitého typu a akce metodami, což jsou procedury a funkce. Při objektově orientovaném návrhu vytváříme model řešeného problému - hledáme objekty, jejich atributy a způsob jejich komunikace.

Objektově orientované programování je charakterizováno třemi základními vlastnostmi:
1. Zapouzdřenost (encapsulation) - data jsou ukryta uvnitř objektu a výlučný přístup k nim mají pouze metody objektu. Objekty komunikují mezi sebou posíláním zpráv - metody, které umí realizovat.
2. Dědičnost (inheritance) - umožňuje vytvářet složitější objektové typy z jednodušších, přičemž to co umí "předek", může využít nebo modifikovat jeho potomek.
3. Mnohotvárnost (polymorfismus) - stejná zpráva (metoda) může vyvolat u různých objektů různé reakce.

Objektově orientované programování tak zvyšuje strukturovanost, modularitu a možnost abstrakce vytvářeného programu.
Nyní si tyto vlastnosti OOP trochu více vysvětlíme.

1.Zapouzdřenost (encapsulation)

je uskutečněno novým datovým typem objekt, který vznikl kombinací typu record a typu procedura popř.funkce. Obsahuje kromě datových položek také řídící struktury - metody.
Objekt je množina informací (dat a metod = návod, jak s daty pracovat), které popisují určitý prvek.
Při deklaraci typu objekt definujeme:
- množinu hodnot, kterých může proměnná typu objekt nabývat - datové struktury
- metody, pomocí nichž můžeme realizovat určité operace - řídící struktury

Deklarace typu objekt

se skládá z popisu (deklarace dat a hlavičky metod) a implementace metod (deklarace těl procedur a funkcí):

type <název> = object {popis}
<dat.položka1> : <typ1>;

<dat.položkan> : <typn>;
{deklarace datových položek}
procedure <metoda1>;

function <metodan>: <typ>;
{hlavičky metod}
end;
procedure <název>.<metoda1>;
     begin
         <příkazy>
     end;
function <název>.<metoda2>:<typ>;
     begin
         <příkazy>
     end;
{implementace metod}



{deklarace těl procedur a funkcí}




Data jsou ukryta uvnitř objektu a přístup k nim zajišťují metody objektu.
Objekty komunikují mezi sebou posíláním zpráv - realizací metody, které umí provést.
Programátor by měl připravit dostatečný počet metod, aby nebylo potřebu pracovat přímo s daty.
Metody by měly zabezpečit inicializaci dat, styk s okolím i vnitřní operace.
Na příkladě si ukážeme deklaraci typu objekt pro objekt TKalkulacka umožňující počítání s celými čísly.

Příklad 1:

type TKalkulacka = object
cislo1, cislo2, vysledek: integer; {cislo1, cislo2 - operandy, vysledek je výsledek}
procedure Init (ZadX, ZadY: integer);
function Soucin: integer;
procedure Podil;
{zadání operandů}
{výpočet součinu}
{výpočet celočísel.podílu}
end;       
procedure TKalkulacka.Init(ZadX,ZadY:integer);
     begin
         cislo1:=ZadX;
         cislo2:=ZadY;
     end;
function TKalkulacka.Soucin: integer;
     begin
         Soucin:=cislo1*cislo2;;
     end;
procedure TKalkulacka.Podil;
     begin
         vysledek:=cislo1 div cislo2;
         writeln('Celociselnz podik cisel ',cislo1,'/',cislo2,'=',vysledek);
     end;
{popis metody Init}

{operndy budou vstupní parametry ZadX, ZadY}

{popis metody Soucin}

{vypočte součin operandů}

{popis metody Podil}

{vypočte celočís.podíl operandů}
{vytiskne výsledk}


Po deklaraci typu objekt (říká se mu také třída) můžeme deklarovat proměnné typu objekt (instance třídy).


Deklarace proměnné typu objekt vypadá:

var < název proměnné > : < typ objektu >;

Například:
var kalkulacka : TKalkulacka;


Přístup ke složkám proměnné

typu objekt se provádí pomocí tečkové notace (jako u záznamu) nebo pomocí příkazu with.

Například:
Potřebujeme-li prvnímu operandu proměnné kalkulacka přiřadit hodnotu 5, můžeme použít příkazu:
   kalkulacka.cislo1 := 5    nebo    with kalkulacka do cislo1 := 5;
V těle popisu metody nemusíme název objektu uvádět, jak je vidět v příkladu . Lze psát tedy přímo cislo1 := 5;
Podobně je to s metodami. Chceme-li volat proceduru na podíl, můžeme psát:
   kalkulacka.Podil;    nebo    with kalkulacka do Podil;

Nyní už bychom si mohli ukázat první příklad celého programu pracujícího s objekty.

Příklad 2:
Sestavte program Pocitej, který s využitím objektové proměnné typu TKalkulacka umožňuje podle volby uživatele zadat dvě čísla, vypočítat jejich součin a celočíselný podíl.
Zde pouze dáme dohromady již ukázané příklady a doplníme hlavním programem
Program Pocitej může vypadat takto:

program Pocitej;

  uses Crt;

{připojení jednotky Crt}
  type TKalkulacka = object  
cislo1, cislo2, vysledek: integer; {cislo1, cislo2 - operandy, vysledek je výsledek}
procedure Init (ZadX, ZadY: integer);
function Soucin: integer;
procedure Podil;
{zadání operandů}

{výpočet součinu}
{výpočet celočísel.podílu}
end;           
  procedure TKalkulacka.Init(ZadX,ZadY:integer);
     begin
         cislo1:=ZadX;
         cislo2:=ZadY;
     end;
  function TKalkulacka.Soucin: integer;
     begin
         Soucin:=cislo1*cislo2;;
     end;
  procedure TKalkulacka.Podil;
     begin
         vysledek:=cislo1 div cislo2;
         writeln('Celociselnz podik cisel ',cislo1,'/',cislo2,'=',vysledek);
     end;
{popis metody Init}

{operandy budou vstupní parametry ZadX, ZadY}

{popis metody Soucin}

{vypočte součin operandů}

{popis metody Podil}

{vypočte celočís.podíl operandů}
{vytiskne výsledk}

  var   kalkulacka:TKalkulacka;
          volba,prvni_cislo,druhe_cislo:integer;

{globální objektová proměnná}
{další globální proměnné}

Begin
   clrscr;
   writeln('Program Pocitej umoznuje podle volby uzivatele:');
   repeat
     writeln;
     writeln('1 - zadat dve cela cisla');;
     writeln('2 - vypocitat jejich soucin');
     writeln('3 - vypocitat jejich celosiselnz podil');
     writeln('0 - ukoncit cinnost');writeln;
     write('Zadejte svoji volbu:');readln(volba);writeln;
     case volba of
        1:begin
          write('Zadej dve cela cisla:');
          readln(prvni_cislo,druhe_cislo);
          kalkulacka.Init(prvni_cislo,druhe_cislo);
        end;
        2:writeln('Soucin cisel ',prvni_cislo,'*', druhe_cislo ,'=', kalkulacka. Soucin);
        3:kalkulacka.Podil;
        0:;
      end;
   until volba=0


{opakuje}



{nabídka programu}


{zadáni volby}



{zadání čísel}


{součin čísel}

{celočíselný podíl čísel}


{program končí nulou}
End.


2.Dědičnost (inheritance)

umožňuje vytvářet nové objekty jako potomky již existujících objektů (předků) a přebírat od nich datové položky a metody. Položky i metody lze u potomků rozšiřovat o nové. Staré metody (metody předků) lze také modifikovat. Každý rodič může mít v TP libovolný počet potomků, potomci mají pouze jednoho rodiče.

Příklad 3:
Vytvoříme nový typ objektu TNewKalkulacka, který bude dědit datové položky cislo1, cislo2, vysledek a metody Init, Soucin objektu TKalkulacka (je potomkem rodice TKalkulacka). Navíc bude mít novou datovou položku vysl_podil pro výsledek reálného dělení. Metodu Podil bude mít modifikovanoiu tak, že bude provádět reálné dělení daných čísel. Novou metodou bude Mocnina pro výpočet reálné mocniny cislo1cislo2.

type TNewKalkulacka = object(TKalkulacka)
vysl_podil:real; {nová datová položka}
procedure Podil;
function Mocnina: real;
{modifikace metody Podil}
{nová metoda Mocnina}
end;                                     
procedure TNewKalkulacka.Podil;
     begin
         if cislo2<>0 then
           vysl_podil:=cislo1/cislo2;
           writeln('Podil cisel ',cislo1,'/',cislo2,'=',vysl_podil:5:2)
          else
           writeln('Podil neni definovan');
     end;
function TNewKalkulacka.Mocnina:real;
     begin
         Mocnina:=exp(cislo2*ln(cislo1));
     end;
{modifikace metody Podil}

{počítá podíl jako real.číslo}





{popis metody Mocnina}

{vypočte mocniu cislo1 na cislo2}


Proměnná typu TNewKalkulacka by se v programu deklarovala
  var new_kalkulacka : TNewKalkulacka;


Příklad 4:
Sestavte program Pocitej_vic, který s využitím objektové proměnné typu TKalkulacka a TNewKalkulacka umožňuje podle volby uživatele zadat dvě čísla, vypočítat jejich součin, celočíselný podíl, reálný podíl a mocninu.
Program Pocitej_vic může vypadat takto:

program Pocitej_vic;

  uses Crt;

{připojení jednotky Crt}
  type TKalkulacka = object  
cislo1, cislo2, vysledek: integer; {cislo1, cislo2 - operandy, vysledek je výsledek}
procedure Init (ZadX, ZadY: integer);
function Soucin: integer;
procedure Podil;
{zadání operandů}

{výpočet součinu}
{výpočet celočísel.podílu}
end;          
  procedure TKalkulacka.Init(ZadX,ZadY:integer);
     begin
         cislo1:=ZadX;
         cislo2:=ZadY;
     end;
  function TKalkulacka.Soucin: integer;
     begin
         Soucin:=cislo1*cislo2;;
     end;
  procedure TKalkulacka.Podil;
     begin
         vysledek:=cislo1 div cislo2;
         writeln('Celociselnz podik cisel ',cislo1,'/',cislo2,'=',vysledek);
     end;
{popis metody Init}

{operndy budou vstupní parametry ZadX, ZadY}


{popis metody Soucin}

{vypočte součin operandů}

{popis metody Podil}

{vypočte celočís.podíl operandů}
{vytiskne výsledk}


  type TNewKalkulacka = object(TKalkulacka)  
vysl_podil:real; {nová datová položka}
procedure Podil;
function Mocnina: real;
{modifikace metody Podil}
{nová metoda Mocnina}
end;                                
procedure TNewKalkulacka.Podil;
     begin
     begin
         if cislo2<>0 then
            begin
             vysl_podil:=cislo1/cislo2;
             writeln('Podil cisel ',cislo1,'/',cislo2,'=',vysl_podil:5:2);
            end
          else
             writeln('Podil neni definovan');
     end;
function TNewKalkulacka.Mocnina:real;
     begin
         Mocnina:=exp(cislo2*ln(cislo1));
     end;
{modifikace metody Podil}

{počítá podíl jako real.číslo}







{popis metody Mocnina}

{vypočte mocniu cislo1 na cislo2}



var   kalkulacka:TKalkulacka;
           new_kalkulacka:TNewKalkulacka;
           volba,prvni_cislo,druhe_cislo:integer;

{globální objektová proměnná }
{potomek proměnné}
{další globální proměnné}

Begin
   clrscr;
   writeln('Program Pocitej_vic umoznuje podle volby uzivatele:');
   repeat
     writeln;
     writeln('1 - zadat dve cela cisla');;
     writeln('2 - vypocitat jejich soucin');
     writeln('3 - vypocitat jejich celočiselný podil');
     writeln('4 - vypocitat jejich podil');
     writeln('5 - vypocitat jejich mocninu');
     writeln('0 - ukoncit cinnost');writeln;;
     write('Zadejte svoji volbu:');readln(volba);writeln;
     case volba of
        1:begin
            write('Zadej dve cela cisla:');
            readln(prvni_cislo,druhe_cislo);
            kalkulacka.Init(prvni_cislo,druhe_cislo);
            new_kalkulacka.Init(prvni_cislo,druhe_cislo);
           end;
        2:writeln('Soucin ',prvni_cislo,'*', druhe_cislo ,'=', kalkulacka. Soucin);
        3:kalkulacka.Podil;
        4:new_kalkulacka.Podil;
        5:writeln('Mocnina ',prvni_cislo,' na ',druhe_cislo,'=', new_kalkulacka.Mocnina:5:2);
        0:;
      end;
   until volba=0


{opakuje}

{nabídka programu}


{zadání volby}



{zadáni čísel}



{součin čísel}
{celočíselný podíl čísel}
{reálný podíl čísel}
{mocnina}
End.


Domácí úkol:

Sestavte program Emil, ktery pomoci objektu TRobot předvede pozdrav při setkání, rozloučení, sdělí jeho jméno. Potom vytvořt potomka TNewRobot, ketrý umí jinak rozloučení a navíc sdělí odkud je.

On-line účast na řešení úkolu

Řešit úkol Prohlídka hodnocení úkolu Dotazy,připomínky

Pomocí volby Řešit můžete (po přihlášení) odeslat vaše řešení domácího úkolu (každý úkol smíte řešit jen jednou). Volbou Hodnocení si přečtete hodnocení a komentář od vyučujícího. Dotaz nebo připomínku můžete opakovaně zasílat pomocí tlačítka Dotazy, Komunikace (na levém okraji) zobrazuje příklad možné komunikace s vyučujícím.