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
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.
|