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∙:
-
Objektu, kterΘmu je zprßva adresovßna (Moje kolo),
-
JmΘna provßd∞nΘ metody (Zm∞n p°evod) a
-
Parametr∙ vy╛adovan²ch metodou (Nφzk² p°evod).
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.
-
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).
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;
}
-
P°edchozφ "nesmysln²" program se pokusφme p°evΘst do objektov∞ orientovanΘho
programovßnφ. Po tomto p°evodu dostaneme:
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.
-
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.
-
Zjist∞te co provßdφ nßsledujφcφ konzolovß aplikace:
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Θ.
-
P°edchozφ program p°evedeme do OOP a dostaneme:
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:
-
T°φda je deklarace typu objektu (programov² plßn pro objekty stejnΘho
typu).
-
Objekt je konkrΘtnφ instance t°φdy.
-
Ve°ejnß Φßst t°φdy je ve°ejnΘ rozhranφ t°φdy.
-
Soukromß Φßst t°φdy nenφ p°φstupnß z vn∞j╣ku t°φdy.
-
Metoda je funkce, kterß je souΦßstφ t°φdy.