You are on page 1of 126

Jn Hank

Objektovo orientovan programovanie v jazyku C# 3.0


Prruka pre vvojrov, programtorov a softvrovch expertov

Jn Hank

Objektovo orientovan programovanie v jazyku C# 3.0


(Prruka pre vvojrov, programtorov a softvrovch expertov)

Microsoft 2008

Obsah
vod ............................................................................................................................................... 3 Pre koho je tto kniha uren ............................................................................................. 5 Obsahov truktra knihy .................................................................................................... 6 Typografick konvencie ........................................................................................................ 6 Poakovanie............................................................................................................................... 7 1. Teoretick zklady objektovo orientovanho programovania..................... 10
1.1 Vvojov vetvy a paradigmy programovania ........................................................................ 10 1.1.1 truktrovan programovanie ............................................................................................ 10 1.1.2 Objektovo orientovan programovanie ........................................................................... 15 1.1.2.1 Hybridn a objektovo orientovan programovacie jazyky .............................. 24 1.1.3 Komponentov programovanie .......................................................................................... 24

2. Objektovo orientovan programovanie v jazyku C# 3.0 ................................. 30


2.1 Trieda ako abstraktn objektov dtov typ ......................................................................... 30 2.1.1 Deklarcia triedy ....................................................................................................................... 31 2.1.2 Vizualizcia deklarcie triedy a Nvrhr tried (Class Designer) ............................ 34 2.1.3 Intancicia triedy a pouitie zrodenej intancie ......................................................... 36 2.1.4 Kontruktory .............................................................................................................................. 40 2.1.5 Statick kontruktor a statick leny intannch tried ........................................... 42 2.1.6 Mechanizmus typovej inferencie (MTI) ........................................................................... 45 2.1.7 Skalrne intann vlastnosti triedy ................................................................................. 47 2.1.8 Automaticky implementovan skalrne intann vlastnosti triedy ................... 49 2.1.9 Indexovan intann vlastnosti triedy ........................................................................... 52 2.1.10 Finalizr ..................................................................................................................................... 56 2.1.11 Detruktory v jazyku C++ a finalizry v jazyku C# 3.0 ............................................ 57 2.2 Analza ivotnch cyklov intanci tried ................................................................................. 59 2.2.1 Finalizcia intanci tried ....................................................................................................... 62 2.2.2 Stavba riadenej haldy a riadiace algoritmy automatickho sprvcu pamte.... 62 2.3 Agregano-kompozin vzahy medzi triedami ................................................................... 68 2.4 Dedinos ............................................................................................................................................. 71 2.5 Abstraktn triedy .............................................................................................................................. 74

2.6 Zapeaten triedy ............................................................................................................................. 77 2.7 Parcilne triedy ................................................................................................................................. 80 2.8 Statick triedy .................................................................................................................................... 83 2.9 Anonymn triedy a inicializtory intanci anonymnch a pomenovanch tried ... 85 2.10 Polymorfizmus implementovan pomocou verejnej jednoduchej dedinosti ....... 89 2.11 Polymorfizmus implementovan pomocou rozhrania .................................................... 91 2.12 Delegti .............................................................................................................................................. 98 2.12.1 Spojenie intancie delegta s anonymnou cieovou metdou............................105 2.12.2 Kovariancia a kontravariancia delegtov ...................................................................106 2.13 -vrazy a -kalkul ......................................................................................................................109 2.14 -vrazy v jazyku C# 3.0............................................................................................................112 2.15 Praktick aplikcia -vrazov v jazyku C# 3.0 .................................................................115 2.16 -prkazy v jazyku C# 3.0 ..........................................................................................................116

Zver ........................................................................................................................................ 120 O autorovi .............................................................................................................................. 121 Pouit literatra ............................................................................................................... 123

vod
Poas uplynulho polstoroia sa v informatickch vedch uskutonil tak progres, ak sa v inch oblastiach udskch innost zaznamenva spravidla za niekoko storo. Z pvodne slovch potaov sa stali mikropotae s ohromnm vkonom, ktor s kedykovek a kdekovek pripraven pomha uom s rieenm ich kadodennch problmov. Vedno s prevratnm technologickm tempom drala krok aj teoretick informatika, ktor definovala metodiky, postupy a paradigmy vvoja potaovho softvru. Je to toti prve softvr, ktor doke vdchnu duu rozmanitm hardvrovm strojom a zariadeniam. Bez sofistikovanho softvru by nemohol by spene realizovan ani zlomok sasnej technologicko-informanej revolcie. Hoci z dnenho pohadu je to sn a nepredstaviten, paradigmy vvoja potaovho softvru neboli vdy tak vyspel ako v sasnosti. Zaiatky sa spjaj s priamym programovanm potaov pomocou rdzo technickch konov, ktor boli neskr nahraden tvorbou programov v strojovom kde. Explicitn programovanie slicovch potaov na nzkej rovni sa vyznaovalo nielen vemi malou mierou pracovnej produktivity, ale aj nronosou na abstraktn myslenie a technick precznos. Presun od strojovho kdu smerom k jazykom symbolickch adries priniesol vo svojej dobe signifikantn rove abstrakcie. Hoci aj dnes sa asti jadier mnohch operanch a informanch systmov programuj v jazyku symbolickch adries, v akademickej a komernej sfre sa udomcnili paradigmy vvoja potaovho softvru, ktor s typick vyou mierou abstrakcie od hardvrovej infratruktry. truktrovan programovanie umonilo naplno rozvin mylienku problmovej dekompozcie, kedy sa problm rozloil na viacero algoritmicky rieitench podproblmov, ktorch spracovanie mali na starosti viacer funkcie jednho programu. truktrovan programovanie sa stalo prvou vvojovou vetvou, ktorej sa podarilo zapoji do programovania potaov irok cieov publikum. O perspektvnosti truktrovanho programovania sved jeho stle vek praktick obbenos, a to aj napriek tomu, e od uvedenia tohto tlu vvoja softvru uplynulo u niekoko desaro. Vek posun vpred zaznamenala objektov paradigma, ktor sa stala zkladnm pilierom objektovo orientovanho programovania. Dta a manipulan opercie, ktor s s dtami uskutoovan, s zapuzdren do logickch jednotiek, ktorm vravme objekty. Virtulne objekty vznikaj v procese objektovho modelovania, priom reflektuj vlastnosti a schopnosti skutonch objektov tvoriacich relny svet. Virtulne objekty s navye inteligentn a vedia kooperova tak, aby spolone vyrieili mnoh aj z tch najnronejch problmov, s akmi sa teoretick informatika stretla. Netrvalo dlho a vvoj softvru sa z pvodne akademickch a vskumnch centier preniesol do rdzo komernej sfry. A v nej, ako je znme, sa cen najm vek pracovn
3

produktivita, ktorej cieom je krecia produktov s vysokou pridanou hodnotou. Proces vvoja softvru sa zaal podoba vrobe inch zloitch strojov a zariaden, priom sa do implementovali prvky hromadnej vroby. Komponentov programovanie predstavilo komponentov technolgiu vvoja softvru, poda ktorej s aplikcie tvoren kolekciou vhodne nakonfigurovanch potaovch siastok, teda komponentov. Komponentov programovanie vyuva vetky siln strnky objektovo orientovanho programovania, ve koniec koncov, komponenty ako tak s tvoren spravou spolupracujcich objektov. Komponentov programovanie umonilo naplno rozvin ideu rchleho vvoja potaovch aplikci. Vzvou sasnch a urite aj budcich rokov je paraleln programovanie, ktor mono realizova v sinnosti s objektovo orientovanm a komponentovm programovanm. Paraleln programovanie sa stva hitom, priom tento stav je podmienen predovetkm prchodom potaov, ktor s osaden viacjadrovmi procesormi. Prve takto stroje umouj dosiahnu skuton paralelizmus, kedy s toky programovch intrukci spracvan paralelne na jednotlivch jadrch procesora. Kee meme s istotou predpoveda, e v budcnosti sa bud objavova procesory so stle vm potom exekunch jadier, je nutn v zujme optimlneho vyuitia celkovej vpotovej kapacity systmu venova zven pozornos masvnej paralelizcii. Cieom tejto knihy je vysvetli vetky princpy objektovo orientovanho programovania v jazyku C# 3.0. V publikcii sme sa snaili vytvori robustn teoreticko-praktick zzemie, ktor pome vvojrom pripravi sa na novo prichdzajcu paradigmu tvorby potaovho softvru, ktorou je paraleln objektovo orientovan programovanie (POOP). Tak bud mc vvojri, programtori a softvrov experti eli novm apelom, ktor prinesie paraleln epocha potaovej evolcie.

Jn Hank Praha, september 2008

Pre koho je tto kniha uren


Kniha Objektovo orientovan programovanie v jazyku C# 3.0 sa sstreuje na vklad zkladnch pilierov veobecnej terie objektovo orientovanho programovania s ich praktickou aplikciou v programovacom jazyku C# 3.0, ktor je implementovan v produktoch Microsoft Visual C# 2008 a Microsoft Visual C# 2008 Express. Primrnym cieovm segmentom publikcie s mierne pokroil programtori a vvojri v jazyku C#, ktor ovldaj zklady tohto programovacieho jazyka. Kniha predpoklad, e itatelia vedia, ako funguje program v jazyku C# 3.0 a rovnako s oboznmen s elementrnymi programovmi kontrukciami, ku ktorm patria premenn, opertory, rozhodovacie prkazy a cykly. Ak ste zaiatonkom v algoritmizcii alebo v programovan vo veobecnosti, odporame vm, aby ste si pred tdiom tejto publikcie najskr pretali niektor z mnostva knh, ktor podvaj zkladn vubov kurz programovania v jazyku C# 3.0. Vklad kladie mimoriadny draz na vysok technick kvalitu, terminologick exaktnos a vedeck spracovanie problematiky, m napa koncepciu primeranho tudijnho zaaenia itateov.

Obr. A: Vhodnos knihy pre rzne segmenty pouvateov Publikcia je vhodn pre posluchov vysokch kl univerzitnho typu so zameranm na vubu informatickch a potaovch vied. Svoje uplatnenie nachdza v pecializovanch predmetoch 1., resp. 2. stupa vysokokolskho tdia.

Obsahov truktra knihy


Kniha Objektovo orientovan programovanie v jazyku C# 3.0 sa sklad z dvoch hlavnch tematickch celkov: 1. Teoretick zklady objektovo orientovanho programovania. 2. Objektovo orientovan programovanie v jazyku C# 3.0. 1. tematick celok oboznamuje itateov s tromi hlavnmi paradigmami vvoja potaovho softvru, ktor sa vyvinuli za posledn desaroia. Ide o truktrovan, objektovo orientovan a komponentov programovanie. Draz je kladen predovetkm na komplexn ozrejmenie princpov veobecnej terie objektovo orientovanho programovania. 2. tematick celok nadvzuje na teoretick zklady poloen v 1. tematickom celku. Hlavn vkladov prd tvoria kapitoly, ktor sa venuj praktickmu objektovo orientovanmu programovaniu v jazyku C# 3.0. Komplementrnou pridanou hodnotou je vklad syntakticko-smantickch inovci jazyka C# 3.0, ktor sa viau s filozofiou objektovo orientovanho programovania.

Typografick konvencie
Aby sme vm tanie tejto knihy sprjemnili v o mono najvej miere, bol prijat kdex typografickch konvenci, pomocou ktorch dolo k tandardizcii a unifikcii pouitch textovch tlov a grafickch symbolov. Verme, e prijat konvencie zvia prehadnos a pouvatesk prvetivos vkladu. Prehad pouitch typografickch konvenci uvdzame v tab. A. Tab. A: Prehad pouitch typografickch konvenci Typografick konvencia tandardn text vkladu, ktor neoznauje zdrojov kd, identifiktory, modifiktory a kov slov jazyka C# 3.0, ani nzvy inch syntaktickch elementov a entt, je formtovan tmto typom psma. Ukka pouitia typografickej konvencie Vvojovo-exekun platforma Microsoft .NET Framework 3.5 kreuje spolone s jazykom C# 3.0 jednotn technologick bzu na vytvranie modernch riadench aplikci pre Windows, web a inteligentn mobiln zariadenia.

Tab. A: Prehad pouitch typografickch konvenci (pokraovanie) Ukka pouitia Typografick konvencia typografickej konvencie V zujme zaloenia novho projektu tandardnej aplikcie pre systm Windows (Windows Forms Application) v prostred produktu Visual C# 2008 postupujeme takto: 1. Otvorme ponuku File, ukeme na poloku New a klikneme na prkaz Project. 2. V dialgovom okne New Project klikneme v stromovej truktre Project Types na poloku Visual C#. 3. Zo spravy projektovch abln (Templates) vyberieme ikonu ablny Windows Forms Application. 4. Do textovho poa Name zapeme nzov pre nov aplikciu a stlame tlaidlo OK. Fragmenty zdrojovho kdu jazyka C# 3.0, prpadne akchkovek inch programovacch jazykov, s formtovan neproporcionlnym psmom Courier New.
// Defincia premennej typu string. string sprva; // Inicializcia premennej. sprva = "Vitajte v jazyku " + "C# 3.0!"; // Zobrazenie okna so sprvou // pomocou metdy Show triedy // MessageBox. MessageBox.Show(sprva);

Nzvy ponk, poloiek ponk, ovldacch prvkov, komponentov, dialgovch okien, podpornch softvrovch nstrojov, typov projektov ako aj nzvy alch sast grafickho pouvateskho rozhrania s formtovan tunm psmom. Tunm psmom s rovnako formtovan aj identifiktory programovch entt, ktor s uvdzan priamo vo vkladovom texte.

Poakovanie
Na tomto mieste by autor knihy rd vyjadril svoje poakovanie pnovi Jimu Burianovi, ktor zastva pozciu produktovho manara vo vvojrskej divzii eskej poboky spolonosti Microsoft za vborn niekokoron spoluprcu, ktor priniesla vvojrskej komunite mnoho hodnotnch produktov. Rovnako srdene akuje autor za skvel spoluprcu, ochotu a podporu aj pnovi Miroslavovi Kubovkovi, ktor je kmeovm lenom vvojrskeho tmu slovenskej poboky spolonosti Microsoft. Bez ich podpory
7

by nemohla vznikn nielen tto kniha, ale ani mnoh alie diela, ktor permanentne zlepuj stav vvojrskeho ekosystmu. Take pni, ete raz, primn vaka!

1. tematick celok Teoretick zklady objektovo orientovanho programovania

Teoretick zklady objektovo orientovanho programovania

1. Teoretick zklady objektovo orientovanho programovania


1.1 Vvojov vetvy a paradigmy programovania
Poas uplynulch pdesiatich rokov zaznamenali prstupy k vvoju potaovho softvru nebval rozmach. Pri bliej analze meme determinova tri zkladn vetvy programovania: 1. truktrovan programovanie. 2. Objektovo orientovan programovanie. 3. Komponentov programovanie. Kad z uvedench vetiev prichdza s vlastnou paradigmou vvoja potaovho softvru.

1.1.1 truktrovan programovanie


truktrovan (procedurlne) programovanie sa sstreuje na nvrh imperatvnych programov, ktor implementuj algoritmy prostrednctvom troch zkladnch grafov riadenia, resp. riadiacich kontrukci, ktormi s: sekvencia, selekcia a itercia. Nvrh truktrovanch programov spravidla prebieha postupnm zjemovanm zloitosti, kedy sa pvodne rieen komplexn problm rozklad na menie podproblmy, ktor disponuj niou zloitosou. Naznaen problmov dekompozcia je spojen s intenzvnym vyuitm zkladnch riadiacich kontrukci, ktor je mon spoahlivo definova syntaktickmi prkazmi aplikovanho programovacieho jazyka. truktrovan programovanie vyuva truktrovan algoritmy. truktrovan algoritmus meme charakterizova induktvno-rekurzvnym spsobom: 1. Kad jednotliv krok je truktrovanm algoritmom. 2. Zkladn riadiace kontrukcie (sekvencia, selekcia a itercia) truktrovanch algoritmov predstavuj taktie truktrovan algoritmus. 3. truktrovanm algoritmom je vetko to, o zskame opakovanm pouitm prems poloench v 1. a 2. kroku tohto postupu. Z praktickho hadiska je truktrovan program tvoren mnoinou funkci, ktor medzi sebou ved prospen informan dialg. Funkcia je zkladnou stavebnou jednotkou truktrovanho programu a ako tak sa asto stotouje s podprogramom. Z uvedenho vyplva, e truktrovan program je mnoinou spriaznench funkci , o meme matematicky formalizova takto:
10

Teoretick zklady objektovo orientovanho programovania

Jedna z funkci truktrovanho programu m vsadn postavenie, priom sa klasifikuje ako hlavn funkcia programu. Hlavn funkcia predstavuje vstupn bod programu, o znamen, e exekcia programu sa zana volanm a spracovanm tejto funkcie. Hlavn funkcia je automaticky aktivovan operanm systmom vdy, ke je zaregistrovan poiadavka na spustenie truktrovanho programu. V rmci implementcie truktrovanch algoritmov je idelne, ak jedna funkcia programu riei prve jeden algoritmus. Tak je mon dosiahnu efektvnu lohov dekompozciu. lohov dekompozcia pracuje v sinnosti s technikou postupnho zjemovania zloitosti rieenho problmu. Hlavn funkcia sa preto nekoncentruje na samostatn rieenie problmu, jej lohou je optimlna dekompozcia problmu na jednotliv podproblmy, ktorch spracovanie je delegovan rznym funkcim (podprogramom). Vizulna kompozcia truktrovanho programu je znzornen na obr. 1.

Obr. 1: truktrovan program


11

Teoretick zklady objektovo orientovanho programovania

Medzi hlavnou funkciou a ostatnmi, tzv. pouvatesky definovanmi, funkciami existuj tesn dtov vzby. Pri volan pouvatesky definovanej funkcie, ktor zabezpeuje spracovanie istho parcilneho algoritmu, je mon tejto funkcii odovzda kvant vstupnch dt. Vstupn dta pecifikovan pri volan funkcie sa nazvaj argumenty. V lohe argumentov mu vystupova dtov objekty, ktor s na syntaktickej rovni reprezentovan hodnotami primitvnych dtovch typov, resp. intanciami pouvatesky deklarovanch dtovch typov. Je pochopiten, e ak s funkcii odovzdvan urit argumenty, mus funkcia disponova prostriedkom, pomocou ktorho bude schopn tieto argumenty prija a uchova. Tmto prostriedkom s v truktrovanch programoch formlne parametre, ktor z technickho hadiska predstavuj loklne premenn funkcie uren len na absorpciu argumentov. Ak funkcia truktrovanho programu definuje vo svojej signatre aspo jeden formlny parameter, charakterizujeme ju ako parametrick funkciu. Naproti tomu, funkcie s przdnou signatrou sa oznauj termnom bezparametrick funkcie. truktrovan programovacie jazyky zvyajne implementuj dva zkladn mechanizmy odovzdvania argumentov formlnym parametrom: 1. Mechanizmus odovzdvania argumentov hodnotou. 2. Mechanizmus odovzdvania argumentov odkazom. Pri aplikcii mechanizmu odovzdvania argumentov hodnotou je vdy vytvoren kpia argumentu (pvodnho dtovho objektu), ktor je nsledne poskytnut volanej funkcii. Volan funkcia zska identick duplikt argumentu, ktor me poui pri svojej prci. Dokonca me zskan duplikt aj modifikova, no tieto modifikcie nijakm spsobom neovplyvnia pvodne odovzdvan argument. Na druh stranu, pri mechanizme odovzdvania argumentov odkazom je volanej funkcii poskytnut pamov adresa, na ktorej je argument (dtov objekt) situovan. Kee volan funkcia pozn pamov adresu argumentu, m k nemu priamy prstup a je schopn ho ubovone modifikova (aj potencilne nebezpenm spsobom, ktor by mohol spsobi poruenie dtovej integrity argumentu). Ak uskutonme dkladn komparciu oboch mechanizmov odovzdvania argumentov, dospejeme k nasledujcim zverom: 1. Mechanizmus odovzdvania argumentov hodnotou je bezpenejm mechanizmom odovzdvania dtovch objektov volanm funkcim. Existuje toti garancia, e volan funkcie nie s schopn vykona potencilne nebezpen programov opercie, ktor by vystili do poruenia dtovej integrity. Kee jednotliv programovacie jazyky preferuj ochranu dtovej integrity, mechanizmus odovzdvania argumentov hodnotou je v nich realizovan spravidla implicitne. 2. Za istch okolnost sa pouitie mechanizmu odovzdvania argumentov hodnotou viae s neiaducou postrannou riou. Spomenut reijn nklady s alokovan
12

Teoretick zklady objektovo orientovanho programovania

predovetkm vtedy, ak volajca funkcia poskytuje volanej funkcii kapacitne nron dtov objekty. Kapacitne nron dtov objekty s objekty, ktor alokuj v operanej pamti potaa pomerne vek miesto, zvyajne presahujce niekoko stovk kilobajtov. Keby boli determinovan dtov objekty odovzdvan hodnotou, pre kad z volanch funkci by bolo nutn vytvori samostatn duplikt pvodnho dtovho objektu. Pochopitene, vyie poiadavky na dostupn alokan pamov priestor by sa vypuklejie prejavili najm pri frekventovanom vkone mechanizmu odovzdvania argumentov hodnotou. To sa deje naprklad pri odovzdvan dt volanm funkcim v iteratvnych prkazoch. Monosou, ako eliminova pamov zaaenie systmu, je uprednostni mechanizmus odovzdvania argumentov odkazom. Toto rieenie je ovea efektvnejie, pretoe nech u budeme pracova s ubovonm potom volanch funkci, v pamti bude alokovan vdy len jeden dtov objekt. Vetky aktivovan funkcie zskaj pamov adresu, prostrednctvom ktorej je dan objekt dosiahnuten1. Volan funkcia me po vyrieen problmu, resp. po dokonen svojej innosti, poda o jej vsledku sprvu hlavnej funkcii. Tento komunikan model je realizovan pomocou odovzdvania tzv. nvratovej hodnoty volanej funkcie. Za bench okolnost meme kategorizova vetky pouvatesky definovan funkcie v truktrovanom programe poda toho, i ist nvratov hodnotu vracaj, alebo nie. Funkcie bez nvratovej hodnoty s zo smantickho hadiska toton s procedrami, teda blokmi zdrojovho kdu, ktor s spracovan bez toho, aby podvali sprvu o vsledku uskutonench aktivt. Podobne, ako me komunikova hlavn funkcia so vetkmi pouvatesky definovanmi funkciami, mu kooperova aj jednotliv pouvatesky definovan funkcie medzi sebou. Pritom platia vetky pravidl, ktor sme rozobrali vyie. Manipulcia s argumentmi a nvratovmi hodnotami kreuje zkladn rmec pre riadenie tokov dt v truktrovanch programoch. Pre plnos dodajme, e existuj aj in mechanizmy, ktor umouj transport dt medzi viacermi funkciami navzjom. Typickm prkladom je pouitie globlnych dtovch objektov, ktor s zapuzdren v globlnych premennch. K takmto premennm maj prstup vetky funkcie, ktor sa nachdzaj v prslunej prekladovej jednotke zdrojovho kdu. Ak djde k vyvolaniu funkcie, riadenie programu je presmerovan na kd vstupnho bodu tela prslunej funkcie. Ak s funkcii odovzdvan argumenty, alokuje sa priestor pre formlne parametre, do ktorch s argumenty uloen. V alej etape je zahjen
1

V tejto svislosti je potrebn upozorni na synchronizovan prstup k dtovmu objektu, a to najm pri paralelnom programovan. Ak by truktrovan program obsahoval funkcie, ktor by mohli by vykonvan paralelne, bolo by nutn naprogramova aplikan logiku programu tak, aby nevznikali neiaduce interferencie pri prstupe k zdieanmu dtovmu objektu z viacerch programovch vlkien sasne.

13

Teoretick zklady objektovo orientovanho programovania

exekcia programovch prkazov, ktor s umiestnen v tele volanej funkcie. Z technickho hadiska nzkorovovej interpretcie funkcie s vetky programov prkazy vyjadren v strojovom (natvnom) kde triedy x86. Vo veobecnosti, tandardn prenositen sbor PE (Portable Executable) truktrovanho programu obsahuje natvny kd, ktor je po natan rozloen na mikrointrukcie priamo spracovaten intruknou spravou procesora. Po spracovan vetkch programovch prkazov uloench v tele funkcie je vrten nvratov hodnota funkcie a riadenie programu je presmerovan sp do volajcej funkcie. Pouvatesky definovan funkcie truktrovanho programu mu by okrem priamej aktivcie vyvolvan aj rekurzvne. Teoretick informatika rozliuje viacero variantov rekurzie, pre potreby tejto publikcie sa budeme sstredi len na priamu a nepriamu rekurziu. Pri priamej rekurzii je vytvoren nov intancia identickej funkcie predtm, ako sa ukon spracovanie vetkch prkazov v tele tejto funkcie. Pri priamej rekurzii volan funkcia aktivuje sam seba v uritom okamihu svojho spracovania. Hoci empiricky me rekurzvne volanie funkcie psobi najprv netradine, z technickho hadiska nie je iaden rozdiel medzi volanm nerekurzvnej a rekurzvnej funkcie. Priama rekurzia sa uskutouje opakovane, priom pri kadom opakovan je volan nov intancia funkcie s modifikovanou spravou argumentov (rekurzvne funkcie bud vdy parametrick). Kee pri priamej rekurzii jedna intancia funkcie zrod nov intanciu funkcie, meme sledova cel reazec funkci, ktor vznikaj v priebehu rekurzvne rieenho problmu. Reazec jednotlivch intanci volanej funkcie mus by vdy konen (bez ohadu na to, i pracujeme s priamou, alebo nepriamou rekurziou)2. Pri kadom zrode novej intancie funkcie sa tto funkcia mus rozhodn, i parcilna as problmu, ktor riei, predstavuje rekurzvny, alebo zkladn prpad. Ak funkcia identifikuje, e ide o rekurzvny prpad, tak v procese dekompozcie pvodne komplexnho problmu ete stle nebola dosiahnut tak rove problmu, ktor by bolo mon okamite vyriei. Podproblm na prslunej rovni je preto nutn op dekomponova na jednoduchie problmy. Rekurzvne prpady generuj rekurzvne volania funkcie, ktor znamenaj zakladanie novch a novch intanci funkcie v operanej pamti. Proces rekurzvneho volania funkcie sa mus poda prijatch predpokladov ukoni vtedy, ke ist intancia v reazci rekurzvneho volania funkci naraz na zkladn prpad. Zkladn prpad je asociovan s takou rovou analyzovanho podproblmu, ktor doke funkcia v danej intancii vyriei. Samozrejme, otzkou zostva, za ako dlho bude
2

Je zrejm, e nekonen rekurzia neme existova. Tento stav je v skutonosti vemi nebezpen, pretoe by sa v praktickch podmienkach skonil vyerpanm systmovch zdrojov, ktor operan systm dedikuje fyzickmu procesu truktrovanho programu. Modern operan systmy umoujce viaclohov a viacvlknov spracovanie truktrovanch programov vak nedovolia, aby jeden havarovan program nepriaznivo ovplyvnil in, aktulne spracvan programy.

14

Teoretick zklady objektovo orientovanho programovania

schopn rekurzvne volan funkcia dosiahnu zkladn prpad. Vetky intancie funkcie vytvoren v procese priamej rekurzie mono vizulne reprezentova ako rovne vnrania sa rekurzvne volanej funkcie. Po dosiahnut zkladnho prpadu sa rekurzvne volan funkcia vynra sp, priom kad z vytvorench intanci poskytuje svojmu nadradenmu nprotivku vsledok svojej innosti. Nepriama rekurzia je len variciou priamej rekurzie: pri nej rekurzvne volan funkcia aktivuje in pouvatesky definovan funkciu a tto zase sptne vol pvodn funkciu. Rekurzvne volan funkcie sa uplatuj pri rieen problmov, ktor maj rekurzvnu povahu. Hoci je syntakticko-smantick vyjadrenie rekurzvne volanej funkcie prirodzen a v mnohch prpadoch aj elegantn, je potrebn poukza na vyiu priestorov zloitos rekurzvne implementovanch algoritmov. Kapacitn nronos je spsoben generovanm intanci rekurzvne volanej funkcie, ktor musia by alokovan v operanej pamti potaa. Vyia za je viazan tie s vkonom komunikanho mechanizmu medzi jednotlivmi intanciami rekurzvne volanej funkcie.

1.1.2 Objektovo orientovan programovanie


Hoci zklady paradigmy objektovo orientovanho vvoja potaovho softvru boli teoreticky poloen u v 60. rokoch 20. storoia, praktick rozmach zaznamenal tento model tvorby softvru pribline o tridsa rokov neskr. Objektovo orientovan programovanie sa sna riei jeden zo zkladnch problmov truktrovanho programovania, ktorm je separcia dtovch objektov a funkci (podprogramov), ktor s tmito dtovmi objektmi manipuluj. Veobecn teria objektovo orientovanho programovania vychdza z nasledujcich axim: 1. Objekt je zkladn logick entita, ktor je charakterizovan svojm identifiktorom, vlastnosami a innosami. Identifiktor objektu je jednoznan urenie objektu v systme, resp. v objektovo orientovanom prostred. Vlastnosti objektu s dan jeho atribtmi a predstavuj znaky, ktormi objekt disponuje. innosti objektu s reprezentovan jeho metdami a tvoria behaviorlnu zloku objektu. Poda mnoiny metd meme diagnostikova tl sprvania sa objektu voi klientom, resp. voi inm objektom v jeho prostred. 2. Objekt je vsledkom objektovho modelovania, teda procesu, prostrednctvom ktorho sa vytvraj virtulne ekvivalenty fyzickch objektov, s ktormi pracujeme v relnom svete. 3. Kee fyzick objekty s spravidla vemi zloit, poas objektovho modelovania sa uplatuje princp objektovej abstrakcie, v rmci ktorej abstrahujeme od tch atribtov a innost fyzickch objektov, ktor pre ns nie s dleit (obr. 2).

15

Teoretick zklady objektovo orientovanho programovania

Objektov abstrakcia nm dovouje sstredi sa len na tie vlastnosti a innosti objektu, ktor s vznamn z hadiska vytvranho systmu, resp. aplikcie.

Obr. 2: Objektov modelovanie a objektov abstrakcia 4. Kad objekt je svojprvnou jednotkou, ktor obsahuje vlastn atribty a metdy. Atribty s reprezentovan dtovmi polokami, ktor s uren na schovu dt objektu. Metdy stelesuj innosti vykonvan objektom. Metdy mu priamo pracova s atribtmi objektu. Nahliadanie na objekt ako na monolitn kontajner, v ktorom sa nachdzaj atribty a metdy, je princpom zapuzdrenia (obr. 3).

Obr. 3: Atribty a metdy s zapuzdren do objektu 5. Objekt je z vonkajieho pohadu iernou skrinkou, pretoe in objekty nevidia jeho atribty, ani metdy. Tm, e objekt ukrva svoje atribty, zabezpeuje ochranu dt, ktor obsahuje. Nie je teda mon, aby boli tieto dta modifikovan potencilne nebezpenm spsobom inm objektom, resp. inou entitou vyskytujcou sa vo vonkajom prostred objektu. Vo veobecnej terii objektovo orientovanho programovania je uveden princp znmy ako ukrvanie dt. 6. S dtami objektu mu priamo narba len metdy objektu. Tie s naprojektovan tak, aby sa dtov as objektu nikdy nedostala do nekonzistentnho stavu. Podobne ako atribty, aj metdy s v objekte ukryt, a teda nikto (okrem objektu samotnho) nevie, ako je v skutonosti vykonvan innos, ktorej realizcia je prslunou metdou garantovan. Tento princp sa
16

Teoretick zklady objektovo orientovanho programovania

nazva ukrvanie implementcie a umouje pouvateovi vyuva sluby objektu aj bez znalosti toho, ako s tieto sluby implementovan. 7. Atribty objektu formuj jeho vntorn pam. Objekt teda vie o svojej existencii, priom jeho aktulny stav vdy reflektuj hodnoty jeho atribtov. Stav objektu me by kedykovek diagnostikovan prostrednctvom metd na to urench. 8. Komunikcia vo vzahoch pouvate objekt a objekt in objekt sa uskutouje pomocou mechanizmu sprv. Kad objekt je schopn prija a spracova ist mnoinu sprv. Kolekcia sprv, na ktor doke objekt reagova, je zaznamen v protokole sprv. Protokol sprv determinuje vzjomn relcie medzi jednotlivmi sprvami a metdami objektu. Pomocou protokolu sprv je mon vdy jednoznane uri, ktor metda bude aktivovan ako reakcia na prjem istej sprvy. Medzi sprvami a metdami uvedenmi v protokole sprv existuje relcia typu 1:1. Kad sprva je teda mapovan na prve jednu metdu. Ak prde sprva od pouvatea, resp. inho objektu, objekt ju zachyt a spracuje. Spracovanie sprvy znamen vyhadanie sprvy v zozname sprv, ktor je uveden v protokole sprv (obr. 4). Proces alej pokrauje aktivovanm metdy, ktor je s prijatou sprvou asociovan. Objekt vykon poadovan innos a s jej vsledkom oboznmi pouvatea.

Obr. 4: Komunikcia s objektom pomocou protokolu sprv 9. Sprvy, ktor s objektu zasielan meme rozdeli na bezparametrick a parametrick. Bezparametrick sprvy so sebou nenes iadne dta a ako tak s uren len na zistenie aktulneho stavu objektu. Naopak, parametrick sprvy integruj dta, ktor modifikuj aktulny stav objektu. Km parametrick sprvy menia vntorn pam objektu, bezparametrick sprvy sa iadnej priamej modifikcie nedopaj. Medzi sprvami a metdami objektu existuje priama

17

Teoretick zklady objektovo orientovanho programovania

korelcia: bezparametrick sprvy aktivuj bezparametrick a parametrick sprvy spaj parametrick metdy.

metdy

10. Z hadiska asovej latencie pri akan na vsledok zaslania sprvy meme sprvy klasifikova na synchrnne a asynchrnne. Aby sme mohli lepie vysvetli rozdiely medzi synchrnnymi a asynchrnnymi sprvami, budeme uvaova abstraktn komunikan modely s viacermi objektmi. Prv objekt ozname identifiktorom A, druhmu objektu priradme identifiktor B a tret objekt pomenujeme identifiktorom C. Zameriame sa na skmanie dvoch situci: 1. Analza synchrnneho komunikanho modelu. 2. Analza asynchrnneho komunikanho modelu. V synchrnnom komunikanom modeli pracujeme s dvomi objektmi: A a B. Komunikcia medzi spomenutmi objektmi sa zana tm, e objekt A zale synchrnnu sprvu objektu B. Objekt B sprvu pomocou protokolu sprv spracuje a synchrnne spust metdu, ktor je s danou sprvou prepojen. Objekt B teda zane vykonva opercie, ktor s naprogramovan v tele metdy, ktor si objekt A elal spusti. Dleit je poukza na skutonos, e objekt A neme realizova iadne alie aktivity (napr. rozposiela in sprvy), pokia metda objektu B nedokon svoju innos. Povedan inak, objekt A mus aka na nvrat synchrnne aktivovanej metdy objektu B. Je zrejm, e synchrnny komunikan model vytvra pevn vzbu medzi komunikujcimi objektmi. asov latencia, ktor vznik po doruen sprvy, je signifikantn. Vizulne zobrazenie synchrnneho komunikanho modelu medzi objektmi meme vidie na obr. 5.

18

Teoretick zklady objektovo orientovanho programovania

Obr. 5: Synchrnny komunikan model medzi objektmi Komentr k synchrnnemu komunikanmu modelu (obr. 5): V ase t1 zasiela objekt A synchrnnu sprvu (SS) objektu B. Objekt B zabezpeuje spracovanie synchrnnej sprvy (SSS) protokolom sprv. Po diagnostike sprvy objekt B zahajuje synchrnnu aktivciu asociovanej metdy (SAM). Volan metda je spracvan synchrnne (SSM), o znamen, e objekt A je znehybnen do okamihu, kedy tto metda ukon svoju innos. Po vrten nvratovej hodnoty (VNH) a jej spracovan (SNH) v ase tn sa riadenie vracia sp objektu A. Priama asov zvislos (PZ), vyjadrujca inoperabilitu objektu A, je dan intervalom <t1, tn>. Objekt A neme zasla aliu sprvu objektu B (alebo inmu objektu) skr, ne v ase tn+1. Asynchrnny komunikan model eliminuje citen asov latenciu, ktor vznik v synchrnnom komunikanom modeli. V tomto modeli sa komunikcia medzi zastnenmi objektmi odohrva nasledujcim spsobom: Objekt A zale asynchrnnu sprvu objektu B. Riadenie sa v tejto chvli okamite vracia sp objektu A, ktor me zahji uskutonenie alch operci. Objekt B zaslan
19

Teoretick zklady objektovo orientovanho programovania

sprvu prijme, diagnostikuje ju pomocou protokolu sprv a asynchrnne spust metdu asociovan s prslunou sprvou. Ke metda objektu B skon svoju innos, bude o jej vsledku informovan objekt A. Ako meme zaregistrova, asynchrnny komunikan model je paralelizcii loh naklonen ovea viac ako synchrnny model. Kee objekt zasielajci asynchrnnu sprvu nie je znehybnen poas vkonu metdy dopytovanho objektu, smie pokraova vo svojej prci. Vizulnu interpretciu asynchrnneho komunikanho modelu medzi objektmi znzoruje obr. 6.

Obr. 6: Asynchrnny komunikan model medzi objektmi Komentr k asynchrnnemu komunikanmu modelu (obr. 6): V zujme skmania asynchrnneho komunikanho modelu musme analyzova viac ako dva objekty. V naom modeli uskutoujeme vskum na troch objektoch s identifiktormi A, B a C. V ase t1 zasiela objekt A objektu B 1. asynchrnnu sprvu (AS1). Objekt B spracuje asynchrnnu sprvu (SAS1) a asynchrnne spust metdu spojen s touto sprvou (AAM1). Kee objekt A neak na dokonenie asynchrnne aktivovanej metdy objektu B, me v ase t2 zasla aliu asynchrnnu sprvu (AS2) objektu C. Objekt C doruen asynchrnnu sprvu spracuje (SAS2) a asynchrnne spust zviazan metdu (AAM2). Obe asynchrnne
20

Teoretick zklady objektovo orientovanho programovania

aktivovan metdy objektov B a C pracuj paralelne. Ich finlny exekun as je variabiln: v naom modeli predpokladme, e asynchrnne aktivovan metda objektu B vrti svoju nvratov hodnotu v ase tn, zatia o asynchrnne aktivovan metda objektu C nm poskytne nvratov hodnotu v ase tn+s. Vimnime si, e v asynchrnnom komunikanom modeli je priama asov zvislos (PZ) ovea menej signifikantn ako v synchrnnom komunikanom modeli. Kee objekt A po zaslan sprvy objektu B neak na spracovanie prslunej metdy, me u v ase t2 (priom plat, e t2 < tn) vytvori a zasla in asynchrnnu sprvu. 11. Protokol sprv predstavuje verejne prstupn rozhranie objektu a je potrebn upozorni na skutonos, e pouvatelia objektu maj prstup len k tomuto verejne prstupnmu rozhraniu (atribty i metdy objektu s skryt). To vak postauje, pretoe rozhranie ponka kompletn apart, prostrednctvom ktorho mu pouvatelia vyuva vetky sluby objektu. 12. Objekty s funkne spriaznenmi atribtmi a metdami patria do rovnakej triedy objektov. Triedu objektov meme charakterizova ako mnoinu funkne ekvivalentnch objektov. Objekty s intanciami rovnakej triedy3. Kad objekt triedy m svoje vlastn atribty a metdy4. 13. Objekty mu dedi vlastnosti a innosti od inch objektov. To sa deje v procese dedinosti, kedy potomkovia preberaj charakteristick rty svojich rodiov. Triedy objektov mu vytvra rzne varianty dedinosti. Ak potomok ded svoje schopnosti len od jednho rodia, ide o jednoduch dedinos. Naopak, ke potomok zdedil svoje schopnosti od viacerch rodiov sasne, vravme o viacnsobnej dedinosti. Potomkovia vak nie s odkzan len na tie schopnosti, ktor zdedili po svojich rodioch. K u nadobudnutm (zdedenm) vlastnostiam a innostiam mu pridva nov vlastnosti a innosti. Z hierarchie objektov, ktor vznikn na bze dedinosti, je zrejm, e potomkovia s vdy prinajmenom tak funkne vyspel ako ich rodiia. Spravidla s vak potomkovia vyspelej ne ich predkovia, pretoe maj monos rozri apart svojich schopnost. To ns privdza k zaujmavej a vskutku jedinenej vlastnosti objektovo orientovanho programovania, z ktorej vyplva, e potomok sa me vyskytn vade tam, kde je oakvan jeho rodi. Je teda mon uskutoni substitciu rodia potomkom bez vzniku kolznych stavov. Podotknime, e
3

Aj ke veobecn teria objektovo orientovanho programovania nepecifikuje triedu ako zkladn predpis na vytvranie objektov, hybridn programovacie jazyky s najvou penetrciou na trhu takto pecifikciu uplatuj. V ich prostred je nutn najskr deklarova triedu, ktor determinuje fyzick reprezentciu a monosti pouitia budcich objektov (intanci danej triedy). 4 V konkrtnej implementcii objektovo orientovanho programovania v hybridnom programovacom jazyku je situcia odlin. Hoci kad objekt disponuje svojou vlastnou spravou atribtov, metdy objektov totonej triedy s v operanej pamti uloen prve jedenkrt. Samotn innos metdy potom prebieha tak, e metda si po svojej aktivcii vyhad objekt, v svislosti s ktorm bude spracovan.

21

Teoretick zklady objektovo orientovanho programovania

naopak tento proces nefunguje. Toti tam, kde je oakvan potomok, neme by dosaden rodi tak, aby nedolo k vzniku chybovch stavov. Je to preto, e rodi nie je schopn v plnej miere zastpi svojho potomka, pretoe ten me by funkne vyspelej ako on. 14. Vzahy medzi objektmi nemusia by generovan len na zklade dedinosti. Odhliadnuc od dedinosti, je mon modelova vzby medzi objektmi aj pomocou asociatvnych relci. K tmto relcim patr agregcia a kompozcia. Ich podstata spova v tom, e objekt me vznikn zloenm z inch objektov. V tomto kontexte rozliujeme hlavn (nadraden) objekt a mnoinu podobjektov, ktor nadraden objekt obsahuje. Agregano-kompozin vzahy sa vyuvaj predovetkm pri kontrukcii zloitch objektov, ktor vykonvaj irok paletu innost. Nadraden objekt potom me delegova prvomoci na vykonvanie istch innost na rzny poet vnorench objektov. Poda sily vzby, ak panuje medzi nadradenm objektom a podobjektmi, s ich vzahy definovan pomocou agregcie alebo kompozcie. Vo veobecnosti, kompozcia reprezentuje silnejiu asociatvnu vzbu, priom vrav, e nadraden objekt neme poskytova svojim pouvateom vetky sluby v zodpovedajcej kvalite, ak je aspo jeden vnoren objekt nefunkn, resp. absentujci. Km pri kompozcii nemu podobjekty pracova samostatne bez nadradenho objektu, agregcia tento spsob pouitia podobjektov umouje. Analogicky, ako pri u zmienench komunikanch modeloch, aj nadraden objekt komunikuje s vnorenmi objektmi pomocou mechanizmu sprv. Vetky vnoren objekty disponuj svojimi protokolmi sprv, ktor formuj ich verejne prstupn rozhrania.

Obr. 7: Agregano-kompozin vzahy medzi objektmi 15. Ak dva objekty reaguj na zaslanie totonej sprvy odlinm spsobom, hovorme, e sa sprvaj polymorfne. Polymorfizmus je aspekt objektovo orientovanho programovania, ktor zko svis s dedinosou a umouje vzjomn substitciu objektov (potomkovia s schopn zastpi svojich predkov).

22

Teoretick zklady objektovo orientovanho programovania

Obr. 8: Polymorfn sprvanie intanci tried Vizualizciu programu, ktor bol vytvoren v rdzo objektovo orientovanom programovacom jazyku, uvdza obr. 9.

Obr. 9: Rdzo objektovo orientovan program

23

Teoretick zklady objektovo orientovanho programovania

1.1.2.1 Hybridn a objektovo orientovan programovacie jazyky Vina v praxi rozrench programovacch jazykov patr do kategrie hybridnch programovacch jazykov, pretoe v sebe kombinuje monosti pre vvoj truktrovanho a objektovo orientovanho potaovho softvru. Pri niektorch jazykoch je ich zaradenie do tejto kategrie dan poiadavkou na zachovanie sptnej kompatibility. K hybridnm programovacm jazykom patria C#, C++, Visual Basic, Delphi a Java. Popri hybridnch programovacch jazykoch existuj aj rdzo objektovo orientovan jazyky, ku ktorm patria najm dynamick jazyky rieiace lohy pre potreby umelej inteligencie, simulcie, potaovej grafiky at. Mnoinu rdzo objektovo orientovanch programovacch jazykov tvor Smalltalk, CLOS, Eiffel, ESP a Object-Prolog. Program vytvoren v rdzo objektovo orientovanch jazykoch nie je zvisl od hlavnej funkcie, resp. metdy, ktor zahajuje spracovanie programov vytvorench v hybridnch programovacch jazykoch. V rdzo objektovch programoch sa exekcia zana zaslanm sprvy z rozhrania programu objektom, ktor na tto sprvu prslunm spsobom reaguj.

1.1.3 Komponentov programovanie


Komponentov programovanie je modulrnou nadstavbou objektovo orientovanho programovania. Komponentov programovanie vyuva cel apart objektovo orientovanho programovania, priom pomocou objektov vytvra komponenty, ktor charakterizujeme ako softvrov jednotky vyieho kvalitatvneho stupa. Zkladn princp komponentovho programovania spova vo vytvran komponentov, ktor s natoko inteligentn, aby dokzali na seba prebra zodpovednos za realizciu mnoiny prbuznch innost aplikcie, resp. potaovho systmu. Komponentov programovanie vychdza z premisy, e softvr by mal by vytvran presne tak, ako produkty priemyselnej vroby, ktor sa vyrbaj hromadne v psovej vrobe. Vemi obben je analgia najm s automobilovm priemyslom, kde sa aut vyrbaj na vrobnej linke. Vrobn proces je znane komplikovan, no je dobre truktrovan do jednotlivch vrobnch tdi. V kadom tdiu sa podoba finlneho vrobku men v zvislosti od komponentov, ktor s do neho intalovan. Ak je mon vyrobi auto ako umne navrhnut a implementovan kombinciu niekokch tiscov rznych technickch komponentov, preo by podobnm tlom nemohol by produkovan aj potaov softvr? Komponentov programovanie vrav, e aj v softvrovom svete mono zhotovi samostatn programov siastky, z ktorch sa potom skontruuje finlny program. Aby bolo mon naplni tto ideu, musia by prijat nasledujce postulty:

24

Teoretick zklady objektovo orientovanho programovania

1. Aplikcia (A) je konenou neprzdnou mnoinou komponentov (K), ktor meme matematicky definova takto:

2. Jeden z komponentov aplikcie zaujma stanovisko primrneho komponentu. Primrny komponent je bzov komponent, ktor zabezpeuje jadrov funkcionalitu komponentovej aplikcie. Ak by aplikcia nedisponovala primrnym komponentom, nemohla by fungova. 3. Okrem primrneho komponentu me by aplikcia tvoren ubovonou prpustnou mnoinou alch (komplementrnych) komponentov. Kad z komplementrnych komponentov je zodpovedn za vykonvanie uritej mnoiny innost aplikcie. Ak odhliadneme od nutnej prtomnosti primrneho komponentu, tak meme kontatova, e finlna podoba aplikcie smie by znane variabiln, a teda konfigurovaten. Kee komponenty s projektovan na modulrnej bze, meme vytvori rozmanit kolekciu komplementrnych komponentov. Modularita komponentov je vhodn nielen z pohadu vvojrov, ale aj cieovch pouvateov. V zvislosti od svojich potrieb mu pouvatelia priamo ovplyvni konen komponentov skladbu aplikcie. Softvrov firmy asto produkuj rzne verzie komponentovch aplikci, ktor sa odliuj mnostvom intalovanch komponentov. Uvaujme trebrs aplikciu na spracovanie grafickch obrazov, ktor v zkladnej verzii obsahuje dva komponenty: primrny komponent vykonvajci natavanie a zobrazovanie bitovch mp rznych grafickch formtov a jeden komplementrny komponent realizujci grafick transformcie, akmi s inverzia bitovej mapy, prevod bitovej mapy do sivotnu a prahovanie bitovej mapy. Tvorca komponentovej aplikcie vak me dodva aj in komplementrne komponenty, ktor si pouvate me zakpi (napr. komponent umoujci vytvra z kolekci bitovch mp videosbory). Pouvate sa me rozhodn, ktor komponenty zakpi a ktor nie. Softvrov firma me zasa kategorizova komponentov aplikcie poda potu implementovanch komponentov (napr. zkladn, pokroil i luxusn verzia komponentovej aplikcie). Vizulnu podobu komponentovej aplikcie meme vidie na obr. 10.

25

Teoretick zklady objektovo orientovanho programovania

Obr. 10: Komponentov aplikcia 4. Kad komponent je charakterizovan tmito vlastnosami: Identifikcia. Komponent mus by jednoznane identifikovaten (a to tak v aplikcii, ako aj v informanom a operanom systme). Vaka jednoznanej identifikcii mu existova dva rovnak komponenty, ktor sa lia len svojimi identifikanmi slami. Podotknime, e v praktickch podmienkach je identifikan slo komponentu asto zhodn s slom verzie komponentu. Zapuzdrenie. Komponent zapuzdruje vetku poadovan funkcionalitu v sebe. Hoci z vonkajieho pohadu to nie je zrejm, vo svojom vntri obsahuje komponent spravu objektov s delegovanmi prvomocami pre vykonanie pecifikovanch innost (obr. 11). S objektmi komunikuje komponent pomocou mechanizmu zasielania a prijmania sprv.

Obr. 11: Intern kompozcia primrneho komponentu


26

Teoretick zklady objektovo orientovanho programovania

Rozhranie. Podobne ako objekty, aj komponenty maj svoje verejne prstupn rozhrania, pomocou ktorch vyuvaj pouvatelia ich sluby. Pri funkne spriaznench komponentoch je rozhranie tandardizovan, unifikovan a typizovan. Komponent rovnako ukrva dta a implementciu innost, ktor vykonva. Vetky tieto aspekty s pred vonkajm svetom vhodne ukryt. Pripravenos na pouitie. Komponent psob za kadch okolnost ako hotov softvrov siastka, ktor poskytuje komplexn automatizciu vybranch innost. Za predpokladu, e klient m ku komponentu prstup, me okamite zaa vyuva jeho sluby prostrednctvom verejne prstupnho rozhrania. Optovn pouitenos. Ak je komponent vyvinut, odladen, otestovan a optimalizovan, meme ho poui tokokrt, kokokrt potrebujeme. Komponentov programovanie v tomto smere alej rozvja mylienku objektovho programovania, ktorej zmyslom je znan nrast pracovnej produktivity vvojrov pomocou optovnej pouitenosti raz vytvorenej softvrovej entity. Anonymita pouvateov. Funkcionalita komponentu je plne oddelen od jeho aplikcie. Komponent mus poskytova sluby v zodpovedajcom ase a kvalite akmukovek pouvateovi, ktor m zujem komponent poui. Kee neexistuje iadna fixcia na pouvateov, bza praktickho vyuitia komponentu je vemi irok. Interoperabilita. Komponenty musia by schopn medzi sebou spolupracova aj vtedy, ke boli vytvoren v rznych integrovanch vvojovch prostrediach a programovacch jazykoch. V zujme uplatnenia bezproblmovej komunikcie medzi komponentmi mus by interoperabilita zabezpeen na nzkej, spravidla binrnej rovni. 5. Vybran komponenty sm vytvra celky, ktor sa sami osebe mu sta komponentmi. Proces skladania komponentov pracuje na podobnch princpoch ako agregcia, resp. kompozcia objektov v objektovo orientovanom programovan. Identifikujeme teda nadraden komponent a spravu podkomponentov (obr. 12).

27

Teoretick zklady objektovo orientovanho programovania

Obr. 12: Skladanie komponentov

28

2. tematick celok Objektovo orientovan programovanie v jazyku C# 3.0

Objektovo orientovan programovanie v jazyku C# 3.0

2. Objektovo orientovan programovanie v jazyku C# 3.0


Programovac jazyk C# bol vytvoren spolonosou Microsoft, ktor jeho prv verziu uviedla na softvrov trh v roku 2002. C# je hybridnm programovacm jazykom, pretoe implementuje syntakticko-smantick kontrukcie truktrovanho i objektovo orientovanho programovania. Jazyk C# bol vytvoren pecilne pre potreby vvojovoexekunej platformy Microsoft .NET Framework, ktor ponka vvojrom metodiky, nstroje a technolgie pre vytvranie rozmanitch typov potaovch aplikci urench pre operan systmy Windows a web. Prv verzia programovacieho jazyka C# bola implementovan v produkte Microsoft Visual Studio .NET. Po nej nasledovali alie verzie s selnm oznaenm C# 1.1 (Visual Studio .NET 2003), C# 2.0 (Visual Studio 2005) a zatia najaktulnejia verzia C# 3.0 (Visual Studio 2008). Programovac jazyk C# bol tandardizovan organizciami ISO a ECMA5, podobne ako aj zkladn komponenty vvojovo-exekunej platformy Microsoft .NET Framework. Genzu programovacieho jazyka C# zobrazuje obr. 13.

Obr. 13: Vvoj programovacieho jazyka C#

2.1 Trieda ako abstraktn objektov dtov typ


Vetky hybridn programovacie jazyky vytvraj objekty z tried, ktor s v tchto prostrediach povaovan za abstraktn objektov dtov typy. Z hadiska klasifikcie dtovch typov v jazyku C# 3.0 (a rovnako aj v spolonom typovom systme vvojovoexekunej platformy Microsoft .NET Framework 3.5), s triedy zaraovan k odkazovm objektovm dtovm typom. Trieda predstavuje abstraktn dtov typ,
5

tandard ISO: ISO/IEC 23270:2006 Information Technology - Programming Languages -- C# tandard ECMA: ECMA - 334 C# - Language Specification

30

Objektovo orientovan programovanie v jazyku C# 3.0

ktorho deklarcia pecifikuje vlastnosti a innosti objektov, ktor z tejto triedy vznikn. Triedy s rovnako pouvatesky deklarovanmi dtovmi typmi, o znamen, e vvojri musia najskr zavies deklarcie tried a a potom ich mu intanciova. V tomto smere sa triedy odliuj od primitvnych dtovch typov, ktor s priamo vstavan do jazykovej pecifikcie C# 3.0. Primitvne dtov typy s pre kompiltor znme a okamite pouiten.

2.1.1 Deklarcia triedy


Trieda ako abstraktn, objektov a odkazov pouvatesky deklarovan dtov typ sa v jazyku C# 3.0 deklaruje poda tohto generickho syntaktickho modelu:
class T { ... }

kde: T je identifiktor triedy6. Deklarcia triedy je zloen z hlaviky triedy a jej tela. V hlavike sa mus nachdza kov slovo class, poda ktorho dvame kompiltoru na znmos, e sa chystme deklarova triedu ako nov pouvatesky deklarovan odkazov dtov typ. Za kovm slovom class je umiestnen identifiktor triedy, ktor predstavuje jednoznan pomenovanie triedy v danej oblasti platnosti. Aby sme predili potencilnym mennm konfliktom, meme deklarciu triedy vloi do vopred pripravenho mennho priestoru. Pokia nie je uren inak, deklarovan trieda m intern prstupn prva. V jazyku C# 3.0 je triede implicitne priraden prstupov modifiktor internal, ktor vymedzuje viditenos a oblas platnosti triedy. Pri aplikovanom modifiktore internal je trieda prstupn pre vetky ostatn dtov typy (i u hodnotov, alebo odkazov), ktor s situovan v danom zostaven aplikcie .NET. Aj ke sme sa v naom generickom syntaktickom modeli spoahli na implicitne intern viditenos deklarovanej triedy, je potrebn doda, e prstupov modifiktor me by zadan aj explicitne. Okrem modifiktora internal mu vvojri deklarova aj verejne prstupn triedy (modifiktor public). Verejne prstupn trieda je viditen pre akkovek extern, a teda klientsky zdrojov kd.

Identifiktor triedy, podobne ako aj identifiktory inch programovch entt, musia spa zkladn nomenklatrne pravidl pre pomenovanie. Identifiktor sa nesmie zana slicou, neme obsahova medzery a taktie sa neme zhodova s niektorm z kovch slov jazyka C# 3.0.

31

Objektovo orientovan programovanie v jazyku C# 3.0

Telo triedy je ohranien zloenmi ztvorkami ({}), v ktorch sa nachdzaj defincie lenov triedy. Jazyk C# 3.0 podporuje mnoho programovch entt, ktor mu vystupova ako lenovia triedy. K zkladnm lenom triedy patria atribty (dtov poloky) a metdy. Okrem nich vak sm lenmi triedy by tie vlastnosti i delegti. Poda predstavenho generickho syntaktickho modelu meme v jazyku C# 3.0 navrhn nasledujcu deklarciu triedy:
// Deklarcia triedy. class Zamestnanec { // Defincie atribtov (dtovch poloiek). private string meno; private string priezvisko; private int mzda; private int odpracovanRoky; // Defincia kontruktora. public Zamestnanec(string meno, string priezvisko, int mzda, int roky) { this.meno = meno; this.priezvisko = priezvisko; this.mzda = mzda; odpracovanRoky = roky; } // Defincie prstupovch metd. public string PretaMeno() { return meno; } public void NastaviMeno(string meno) { this.meno = meno; } public string PretaPriezvisko() { return priezvisko; } public void NastaviPriezvisko(string priezvisko) { this.priezvisko = priezvisko; } public int ZskaMzdu() { return mzda; } public void NastaviMzdu(int mzda) { this.mzda = mzda; } public int ZskaRoky() { return odpracovanRoky; } public void NastaviRoky(int roky) { odpracovanRoky = roky; } }

32

Objektovo orientovan programovanie v jazyku C# 3.0

Trieda deklaruje abstraktn typ Zamestnanec, ktor je charakterizovan svojimi atribtmi a metdami. Atribty s implementovan definciami skromnch dtovch poloiek. Dtov poloky musia by skromn, pretoe musme dodra jeden zo zkladnch princpov objektovo orientovanho programovania, ktorm je ukrvanie dt. Pre nae potreby sledujeme u zamestnanca nasledujce atribty: meno, priezvisko, mzdu a poet odpracovanch rokov. Vetky uveden atribty s v relcii typu 1:1 namapovan na prslun dtov poloky. Z defininch prkazov je zrejm, e meno a priezvisko zamestnanca budeme uchovva v podobe textovch reazcov, ktor bud uskladnen v intancich systmovej triedy System.String. Na uloenie mzdy a potu odpracovanch rokov nm poslia dtov poloky primitvneho integrlneho hodnotovho typu int. Po defincii dtovch poloiek, ktor tvoria dtov sekciu triedy, prichdza na rad kontruktor. Kontruktor je pecilna metda triedy, ktor je zodpovedn za korektn inicializciu jej zakladanch intanci. Zo syntaktickho hadiska je kontruktor verejne prstupnou metdou a v naom prpade aj parametrickou metdou. Identifiktor kontruktora sa zhoduje s identifiktorom triedy, v tele ktorej je kontruktor definovan. Kontruktor nevracia iadnu nvratov hodnotu (v hlavike kontruktora nesmie by pouit ani kov slovo void, nvratov hodnotu jednoducho vbec nepecifikujeme). Podotknime, e analyzovan kontruktor je intann. Adjektvum intann znamen, e lohou kontruktora je uvies do vchodiskovho (a teda okamite pouitenho) stavu dtov poloky kadej jednej zrodenej intancie triedy. Povaujeme za vhodn poukza na intann povahu vyie definovanho kontruktora, pretoe jazyk C# 3.0 nm dovouje okrem intannho kontruktora definova aj statick kontruktor7. Ak by v tele triedy nebol explicitne definovan iaden intann kontruktor, kompiltor jazyka C# 3.0 by vygeneroval implicitn intann kontruktor. Implicitn intann kontruktor je verejne prstupn a bezparametrick. Kompiltor jazyka C# 3.0 garantuje, e implicitn intann kontruktor zabezpe implicitn inicializciu vetkch dtovch poloiek intancie triedy. Pokia do tela triedy ist intann kontruktor explicitne zavedieme, kompiltor sa nebude zaobera zostavovanm jeho implicitnej verzie. Za tchto okolnost sme my zodpovedn za sprvnu inicializciu prslunch dtovch poloiek intancie triedy. V tele verejne prstupnho parametrickho intannho kontruktora dochdza k inicializcii intannch dtovch poloiek, ktor sme definovali v dtovej sekcii
7

V hlavike statickho kontruktora sa mus nachdza modifiktor static. Zatia o intann kontruktor sa sstreuje na inicializciu dtovch poloiek intanci triedy, jeho statick nprotivok sa venuje inicializcii statickch dtovch poloiek triedy. Statick dtov poloky nie s asociovan s jednotlivmi intanciami triedy, ale s triedou samotnou. Medzi intannm a statickm kontruktorom existuj aj alie rozdiely. Naprklad, hoci intann kontruktor sa me sta predmetom preaenia, pri statickom kontruktore to nie je mon. V skutonosti mus by statick kontruktor vdy bezparametrick a nesmie uvdza iaden prstupov modifiktor.

33

Objektovo orientovan programovanie v jazyku C# 3.0

triedy. Ktorkovek z dtovch poloiek je priamo dosiahnuten prostrednctvom svojho identifiktora. Na dtov poloku sa meme odvola rovnako pouitm kovho slova this, za ktorm nasleduje opertor priameho prstupu (.) a identifiktor poadovanej dtovej poloky. Tmto spsobom vieme vdy jednoznane uri, ktor entita predstavuje dtov poloku a ktor formlny parameter s inicializanou hodnotou. Technicky povedan, kov slovo this je identifiktorom pecilnej odkazovej premennej, v ktorej je uloen objektov referencia determinujca aktulnu intanciu triedy. Aktulna intancia triedy je za kadch okolnost prve jedna intancia triedy, v svislosti s ktorou je vykonvan ist innos (napr. inicializcia jej dtovch poloiek, volanie metdy a pod.). Ako si meme vimn, v tele kontruktora s inicializovan vetky dtov poloky. Kee objekt je logick jednotka zachovvajca konzistenciu a integritu svojich dt, neme umoni externmu zdrojovmu kdu svojvon prstup k dtam objektu. Pritom vak chceme navrhn spsob, akm by pouvate mohol zska o objekte poadovan informcie. Tmto variantom s verejn prstupov metdy, ktor umouj vopred naprogramovan, overen a najm bezpen prstup k dtam objektu. Ku kadej intannej dtovej poloke preto navrhujeme spravu dvoch prstupovch metd. Zatia o jedna z prstupovch metd sa sstreuje na zskanie hodnoty dtovej poloky, druh sa venuje jej modifikcii.

2.1.2 Vizualizcia deklarcie triedy a Nvrhr tried (Class Designer)


Integrovan vvojov prostredie (Integrated Development Environment, IDE) Microsoft Visual Studio 2008 umouje vizualizova akkovek sprvne deklarovan triedu. Pre automatick vygenerovanie sboru s grafickm modelom triedy musme urobi toto: 1. V podokne Solution Explorer klikneme pravm tlaidlom myi na zdrojov sbor jazyka C# 3.0 s deklarciou triedy (*.cs), ktorej vizulny model chceme zostavi. 2. Z kontextovej ponuky vyberieme prkaz View Class Diagram. 3. Prostredie IDE vytvor nov sbor s extenziou *.cd a vlo do grafick model, ktor vizulne charakterizuje deklarovan triedu a vetky jej leny.8 Grafick podoba predstavuje tzv. diagram triedy (Class Diagram). Diagramy tried zostavuje pecilny nstroj integrovanho vvojovho prostredia Visual Studio 2008, ktor sa vol Nvrhr tried (Class Designer).
8

V automaticky zostavenom diagrame tried bud prtomn modely vetkch hodnotovch a odkazovch dtovch typov, ktor sa v prslunom zdrojovom sbore jazyka C# 3.0 nachdzaj.

34

Objektovo orientovan programovanie v jazyku C# 3.0

Diagram triedy Zamestnanec je uveden na obr. 14.

Obr. 14: Diagram triedy reprezentuje vizulny model deklarovanej triedy Diagram triedy Zamestnanec je na obr. 14 zobrazen v tzv. rozrenom reime, kedy vidme kompletn zloenie lenov deklarovanej triedy. Na druh stranu, diagram tried smie by zobrazen aj v kompaktnom reime (podotknime, e diagram primrnej triedy Program je zobrazen v kompaktnom reime). Medzi oboma zobrazeniami sa meme
35

Objektovo orientovan programovanie v jazyku C# 3.0

prepna pomocou tlaidla s ikonou dvojitej pky (spomnan tlaidlo sa nachdza v pravom hornom rohu diagramu tried). Z grafickho hadiska sa diagram tried vemi pona na diagram tried unifikovanho modelovacieho jazyka UML. Podobne ako v jazyku UML, aj v prostred produktu Visual Studio 2008 je diagram tried zloen z troch zkladnch ast: 1. Identifikan as (podva informcie o nzve triedy). 2. Dtov as (podva informcie o dtovch lenoch triedy). 3. Procedurlna as (podva informcie o metdach triedy). Nvrhr tried umouje dvojcestn modelovanie. Tak, ako je mon z deklarcie triedy vytvori grafick diagram, meme postupova aj opanm smerom. Najskr navrhneme pomocou jednoduchch grafickch nstrojov a pridruench konfiguranch prostriedkov diagram triedy, a potom nechme Nvrhra tried, aby vygeneroval syntakticko-smanticky korektn deklarciu triedy poda navrhnutho grafickho modelu. Samozrejme, je na vvojrovi, aby do tela triedy doplnil zdrojov kd, ktor bude zavdza poadovan aplikan logiku. Okrem deklarci tried smieme vizualizova aj vzahy medzi triedami, ktor s zaloen na agregcii, kompozcii a dedinosti.

2.1.3 Intancicia triedy a pouitie zrodenej intancie


Deklarovanm triedy vyjadrujeme nae poiadavky, ktor sa tkaj vlastnost a schopnost intanci, ktor z tejto triedy vznikn. Proces zrodu intancie triedy (objektu) sa vol intancicia triedy. Intancicia sa len na niekoko tdi, s ktormi sa v tejto kapitole zoznmime. Predovetkm ale musme vyhlsi, e trieda je v jazyku C# 3.0 intanciovan opertorom new. Generick syntaktick podoba intancicie triedy vyzer takto:
T obj = new T();

kde: T je identifiktor triedy. obj je identifiktor odkazovej premennej. Z akademickch sksenost plynie, e uveden intancian prkaz je lepie pochopiten, ak na nahliadame ako na definin inicializciu odkazovej premennej s identifiktorom obj. Kee ide o priraovac prkaz, meme ho vizulne rozdeli na tri asti:
36

Objektovo orientovan programovanie v jazyku C# 3.0

1. Vraz nachdzajci sa na avej strane od priraovacieho opertora (=). 2. Priraovac opertor. 3. Vraz nachdzajci sa na pravej strane od priraovacieho opertora. Zanime analzou vrazu naavo od opertora =. Vraz T obj predstavuje definciu odkazovej premennej s identifiktorom obj. Takto definovan premenn bude alokovan na zsobnku programovho vlkna. Kee typom definovanej odkazovej premennej je trieda, vieme u v tejto chvli poveda, o me by do odkazovej premennej uloen: bude to objektov referencia (alebo odkaz), ktor je nasmerovan na intanciu triedy T. Vzhadom na to, e ide o definin inicializciu odkazovej premennej obj, je tto premenn po svojej defincii okamite inicializovan. Inicializanou hodnotou odkazovej premennej je hodnota vrazu, ktor sa nachdza napravo od priraovacieho opertora. Vraz new T() znamen pouitie opertora new v svislosti s identifiktorom deklarovanej triedy T. Opertor new realizuje intanciciu pecifikovanej triedy, priom vykon tieto innosti: 1. Na riadenej halde vyhad a alokuje dostaton pamov priestor pre novo zakladan intanciu triedy T.9 2. Vytvor intanciu triedy, umiestni ju do vopred pripravenho alokanho priestoru a inicializuje ju. Inicializciu realizuje verejne prstupn intann kontruktor, ktor je opertorom new automaticky aktivovan. Je zrejm, e v generickom syntaktickom intancianom prkaze je za inicializciu zaloenej intancie triedy zodpovedn verejne prstupn bezparametrick intann kontruktor. Inicializciu vak samozrejme me uskutoova aj parametrick intann kontruktor. Potom by vak vraz na pravej strane priraovacieho prkazu vyzeral takto: new T(a1, a2, ..., an), kde v ztvorkch s zoskupen argumenty, ktor bud odovzdan formlnym parametrom parametrickho intannho kontruktora10. Po spracovan kontruktora sa intancia triedy nachdza v aktvnom, a teda priamo pouitenom stave. 3. Vrti typovo siln objektov referenciu na vytvoren intanciu triedy. V tejto svislosti je nutn poukza na skutonos, e zaloen intancia triedy nachdzajca sa na riadenej halde je anonymn (nedisponuje iadnym symbolickm pomenovanm). Jedinm spsobom, ako s intanciou triedy
9

Riaden halda je vyhraden dynamick pamov priestor fyzickho procesu aplikcie .NET, ktor je uren na alokciu intanci pouvatesky deklarovanch odkazovch dtovch typov. Riaden halda je interne lenen na tri objektov genercie (0, 1 a 2), v ktorch sa nachdzaj objekty v zvislosti od dky svojich ivotnch cyklov. Objekty umiestnen na riadenej halde s pod kontrolou automatickho sprvcu pamte. 10 Zapsan intancian vraz predpoklad existenciu relcie typu 1:1 medzi argumentom a formlnym parametrom. Povedan inak, parametrick intann kontruktor prevezme prve toko argumentov, koko formlnych parametrov definuje.

37

Objektovo orientovan programovanie v jazyku C# 3.0

pracova, je poui objektov referenciu, ktor nm poskytne opertor new. Objektov referencia jednoznane identifikuje pozciu intancie triedy na riadenej halde. Objektov referencia, ktor je nvratovou hodnotou opertora new, je teda hodnotou celho vrazu new T(), resp. new T(a1, a2, ..., an). Je samozrejme vemi dleit, aby sme poskytnut objektov referenciu uchovali, pretoe len prostrednctvom nej meme vyuva sluby vytvorenej intancie triedy. To sa koniec koncov aj deje: navrten objektov referenciu ukladme do definovanej odkazovej premennej obj. Vravme, e tto odkazov premenn je inicializovan objektovou referenciou identifikujcou intanciu triedy na riadenej halde.

Obr. 15: Vizualizcia intancicie triedy Vdy, ke budeme chcie pracova s vytvorenm objektom, musme poui odkazov premenn, v ktorej je umiestnen objektov referencia ukazujca na dan objekt. K verejne prstupnm intannm metdam objektu pristupujeme pomocou bodkovho opertora (.). Nasledujci fragment zdrojovho kdu jazyka C# 3.0 demontruje intanciciu deklarovanej triedy Zamestnanec a jej praktick pouitie:
static void Main(string[] args) { // Intancicia triedy Zamestnanec. Zamestnanec zam1 = new Zamestnanec("Emil", "Mal", 30000, 10); // Vyuitie sluieb zaloenej intancie. Console.WriteLine("daje o zamestnancovi: \n" + "Meno: " + zam1.PretaMeno() + "\n" + "Priezvisko: " + zam1.PretaPriezvisko() + "\n" + "Mzda: " + zam1.ZskaMzdu() + "\n" + "Odpracovan roky: " + zam1.ZskaRoky() ); Console.ReadLine(); }

38

Objektovo orientovan programovanie v jazyku C# 3.0

Na rozdiel od jazyka C++, vvojri v jazyku C# 3.0 nie s povinn dynamicky zaloen objekty z riadenej haldy explicitne uvoova. Odstraovanie nepotrebnch objektov m na starosti automatick sprvca pamte (Garbage Collector, GC), ktor doke rozpozna tie objekty, ktor sa u nepouvaj. Ak automatick sprvca pamte zist, e objekt je nedosiahnuten z programovho kdu, uskuton jeho uvonenie11. Generick syntaktick intancian prkaz sa d rozdeli do dvoch samostatnch prkazov, samozrejme so zachovanm pvodnej funkcionality:
T obj; obj = new T();

Prv prkaz vytvra nov odkazov premenn s identifiktorom obj. Ako sme u uviedli, do takto definovanej odkazovej premennej meme uloi objektov referenciu na intanciu triedy T. Kee v tomto prpade nejde o definin inicializciu odkazovej premennej, je namieste otzka, i bude tto premenn implicitne inicializovan. Aby sme mohli na zmienen otzku kvalifikovane odpoveda, musme zisti viac informci o oblasti platnosti a charaktere odkazovej premennej. Pokia by tto premenn vystupovala ako loklna premenn (definovan naprklad v tele hlavnej metdy Main), tak potom by nebola implicitne inicializovan. V tomto smere sa jazyk C# 3.0 sprva podobne ako C++, jeho ISO tandard vrav, e hodnota definovanch loklnych premennch nie je determinovan. Keby sa ale definin prkaz vytvrajci odkazov premenn nachdzal v tele triedy, implicitn intann kontruktor by zabezpeil jej implicitn inicializciu. Implicitnou inicializanou hodnotou takejto odkazovej premennej by potom bola nulov referencia, reprezentovan kovm slovom null jazyka C# 3.0. Odkazov premenn nemus by inicializovan okamite poas svojej defincie. Pochopitene, k inicializcii premennej mus djs niekde v oblasti platnosti, v ktorej je definovan odkazov premenn viditen. Ak by premenn nebola vbec inicializovan, kompiltor jazyka C# 3.0 by ns na tto skutonos upozornil. V kadom prpade je neprpustn pouva neinicializovan premenn. Kompiltor jazyka C# 3.0 je vak vemi citliv a doke sprvne diagnostikova vetky neinicializovan premenn. Inicializcia definovanej odkazovej premennej sa odohrva v druhom prkaze, ktor je spojen s intanciciou deklarovanej triedy T. Samotn intancicia je realizovan presne tak, ako sme ju opsali.

11

Proces uvoovania objektov z riadenej haldy je znmy ako finalizcia objektov. V zvislosti od internej kompozcie objektu me by jeho finalizcia bu implicitn, alebo explicitn.

39

Objektovo orientovan programovanie v jazyku C# 3.0

2.1.4 Kontruktory
Kontruktory, s ktormi sa meme v telch tried programovacieho jazyka C# 3.0 stretn, smieme rozdeli do viacerch skupn: 1. Intann kontruktor. Implicitn intann kontruktor. Explicitn intann kontruktor. o Bezparametrick explicitn intann kontruktor. o Parametrick explicitn intann kontruktor. 2. Statick kontruktor. Ako u bolo spomenut, ak do tela intannej (nestatickej) triedy nevlome iaden kontruktor, kompiltor automaticky vygeneruje implicitn intann kontruktor. Implicitn intann kontruktor je verejne prstupn a bezparametrick. Jeho lohou je uloi do vetkch intannch dtovch poloiek vchodiskov inicializan hodnoty. Trieda s implicitnm intannm kontruktorom:
class A { // Telo triedy je przdne. Kompiltor do neho automaticky // vlo implicitn bezparametrick intann kontruktor. }

Ke programtor umiestni definciu intannho kontruktora do tela triedy, hovorme o takomto kontruktore ako o explicitnom. Explicitn intann kontruktor me by bu bezparametrick (s przdnou signatrou), alebo parametrick (signatra je naplnen mnoinou formlnych parametrov). Trieda s explicitnm bezparametrickm intannm kontruktorom:
class B { public B() { // Telo bezparametrickho kontruktora. } }

40

Objektovo orientovan programovanie v jazyku C# 3.0

Trieda s explicitnm parametrickm intannm kontruktorom:


class C { public C(int x) { // Telo parametrickho kontruktora. } }

V prpade dodania len parametrickho explicitnho intannho kontruktora nie je kompiltorom samoinne vytvran iaden bezparametrick intann kontruktor. Ak takto kontruktor potrebujeme, musme ho zostroji sami. V jazyku MSIL je intann kontruktor (i u implicitn, alebo explicitn) predstavovan metdou s identifiktorom .ctor. Je povolen, aby sa v triede nachdzalo viacero definci explicitnho intannho kontruktora. Pritom plat, e bezparametrick verzia explicitnho intannho kontruktora sa v triede smie objavi prve jedenkrt. Naopak, parametrick verzia explicitnho intannho kontruktora sa me vyskytova vo viacerch verzich, avak len vtedy, ak sa tieto verzie odliuj zoznamami svojich formlnych parametrov. To konkrtne znamen, e rzne defincie explicitnho parametrickho intannho kontruktora sa mu li potom formlnych parametrov, dtovmi typmi formlnych parametrov alebo poradm formlnych parametrov. Ak v tele triedy pozorujeme jednu definciu explicitnho bezparametrickho intannho kontruktora a viacero definci explicitnho parametrickho intannho kontruktora, tak vravme, e intann kontruktor triedy je preaen. Klient triedy si teda me vybra z viacerch exemplrov kontruktora a inicializova tak zakladan intancie triedy rznymi spsobmi. O tom, ktor z rznych definci intannho kontruktora bude v procese intancicie triedy zavolan, rozhoduje poetnos a postupnos argumentov (atomickch kvnt vstupnch dt). Ak je trieda navrhnut korektne, kompiltor doke vdy uri cieov intann kontruktor, ktor bude zavolan v zujme inicializcie intancie triedy12.

12

Kompiltor jazyka C# 3.0 je schopn detegova nejednoznanosti v signatrach jednotlivch definci preaenho intannho kontruktora. Ak bud takto nejednoznanosti zisten, kompiltor preru preklad generovanm chybovho hlsenia.

41

Objektovo orientovan programovanie v jazyku C# 3.0


class D { public { // } public { // } public { // } }

D() Telo bezparametrickho kontruktora. D(int x) Telo 1. verzie preaenho parametrickho kontruktora. D(int x, E y) Telo 2. verzie preaenho parametrickho kontruktora.

V tele triedy D vidme jednu definciu explicitnho bezparametrickho intannho kontruktora a dve verzie explicitne definovanho parametrickho intannho kontruktora. Explicitn intann kontruktor triedy D je teda preaen. Prv parametrick verzia kontruktora pracuje len s jednm formlnym parametrom, ktor oakva 32-bitov celoseln argument. Druh parametrick verzia kontruktora m zloitejiu signatru: okrem celoselnho formlneho parametra sa v nej nachdza aj druh formlny parameter s typom, ktorho identifiktor je E. Samozrejme, z deklarcie triedy D nevieme vyta, o typ E predstavuje. Me s o nzov truktry, enumeranho typu, triedy, delegta, alebo rozhrania. Ak E reprezentuje truktru, tak formlny parameter bude inicializovan intanciou tejto truktry. Pokia je E identifiktorom enumeranho typu, tak formlny parameter bude inicializovan enumertorom. Ak bude E trieda, tak formlny parameter zska odkaz na intanciu tejto triedy. Ke bude identifiktor E predstavova delegta, formlny parameter bude schopn akceptova odkaz na intanciu tohto delegta (intancia delegta pritom obsahuje odkaz na cieov metdu, ktor bude pomocou delegta nepriamo aktivovan). V prpade, ak bude E rozhranm, tak formlny parameter bude mc prija odkaz na intanciu akejkovek triedy, ktor rozhranie E implementuje.

2.1.5 Statick kontruktor a statick leny intannch tried


Vznam statickho kontruktora spova v inicializcii statickch dtovch lenov triedy. Statick dtov leny triedy (tie statick dtov poloky triedy) s definovan pomocou modifiktora static. Statick dtov poloky a statick kontruktor sa sm vyskytova v intannch a statickch triedach. V tejto kapitole budeme skma psobnos statickch dtovch poloiek a statickho kontruktora v intannch triedach. Rozpravu o statickch triedach budeme vies v kapitole 2.8 Statick triedy.
42

Objektovo orientovan programovanie v jazyku C# 3.0

Ke s dtov poloky triedy statick, existuj vdy v prve jednom vyhotoven, a to bez ohadu na to, koko intanci (intannej) triedy existuje13. Naopak, vetky intancie triedy mu vyuva statick dtov poloky triedy. Vravme, e statick dtov poloky triedy s intanciami triedy zdiean. Aj pri statickch dtovch polokch triedy sa zachovva princp ukrvania dt, a preto s (implicitne) definovan ako skromn. Popri dtovch polokch sa mu v telch intannch tried vyskytova aj in statick leny, naprklad metdy alebo vlastnosti. Veobecn defincia statickho kontruktora v tele intannej (a aj statickej) triedy je nasledujca:
static T() { // Telo statickho kontruktora. }

kde: T je nzov intannej, resp. statickej triedy, v ktorej deklarcii je statick kontruktor uloen. Pri prci so statickm kontruktorom musme vedie toto: 1. Statick kontruktor je implicitne skromn (explicitne nesmie obsahova iadne prstupov modifiktory). 2. Statick kontruktor je vdy bezparametrick. 3. Statick kontruktor neme by preaen. Okrem bezparametrickej verzie, nie s v tele triedy prpustn iadne in verzie statickho kontruktora. 4. Statick kontruktor nie je nikdy explicitne aktivovan. Je to preto, e statick kontruktor je automaticky volan virtulnym exekunm systmom, a to v tchto prpadoch: Pred vytvorenm prvej intancie triedy (plat len pre intann triedy so statickm kontruktorom). Pred prvm pokusom o prstup k statickmu lenu triedy.

13

Naopak, kad intancia (intannej) triedy obsahuje svoje vlastn intann dtov poloky. Ak teda vytvorme 100 intanci triedy, kad z nich bude zapuzdrova vlastn kolekciu dtovch poloiek. Dtov poloky ubovonch dvoch rznych intanci zo 100-lennej spravy s plne samostatn a na sebe absoltne nezvisl.

43

Objektovo orientovan programovanie v jazyku C# 3.0

5. V jazyku MSIL je statick kontruktor reprezentovan metdou s identifiktorom .cctor. 6. Statick kontruktor sa me vyskytova iba v telch tried, nie truktr. Nasleduje deklarcia intannej triedy, v ktorej tele sa stretvame so statickou dtovou polokou, statickm kontruktorom a statickou metdou. Trieda doke pomocou statickej dtovej poloky sledova, kokokrt bola aktivovan jej intann metda.
class K { // Defincia statickej dtovej poloky. static int poetVolan; // Defincia statickho kontruktora. static K() { poetVolan = 0; } // Defincia intannej metdy. public void M() { poetVolan++; } // Defincia statickej metdy. public static int ZistiPoetVolan() { return poetVolan; } }

Vetky statick leny triedy disponuj modifiktorom static. Statick kontruktor inicializuje statick dtov poloku. Z charakteru ukky vyplva, e zmyslupln inicializan hodnota je nula, pretoe v ase inicializcie statickej dtovej poloky ete nebola intann metda ani raz zavolan (a ani nemohla by, kee na jej aktivciu potrebujeme zostroji aspo jednu intanciu triedy). Vdy, ke bude spomnan metda zavolan, inkrementuje sa hodnota statickej dtovej poloky triedy. Na zistenie aktulneho potu spusten metdy vyuijeme statick metdu, ktor nm na poiadanie poskytne aktulnu hodnotu statickej dtovej poloky. Deklarovan triedu pouijeme v alom fragmente zdrojovho kdu programovacieho jazyka C# 3.0:
static void Main(string[] args) { K obj = new K(); for (int i = 0; i < 20; i++) { obj.M(); } Console.WriteLine("Metda bola zavolan " + K.ZistiPoetVolan() + "krt."); }

44

Objektovo orientovan programovanie v jazyku C# 3.0

Zaujmav je interakcia medzi intannmi dtovmi polokami, intannmi metdami, statickmi dtovmi polokami a statickmi metdami. Vizualizciu tejto interakcie ponka obr. 16.

Obr. 16: Interakcia medzi rozlinmi lenmi tried Intann metdy triedy sm pristupova k intannm a statickm dtovm polokm triedy. To je evidentn, pretoe sme povedali, e statick dtov poloky zdieaj vetky intancie triedy. Na druh stranu, statick metdy mu pristupova k statickm, no u nie k intannm dtovm polokm triedy. Dvod, preo nie je povolen, aby statick metdy pristupovali k intannm dtovm polokm, je logick. Vzhadom na to, e statick metda me by zavolan bez nutnosti intancicie triedy, pokus o prstup k intannm dtovm polokm by sa skoil abnormlnym ukonenm programu. V ase aktivcie statickej metdy toti neexistuje iadna intancia, ktorej dtov poloky by mohli by predmetom programovch operci.

2.1.6 Mechanizmus typovej inferencie (MTI)


Kompiltor jazyka C# 3.0 doke automaticky uri dtov typ loklnej hodnotovej alebo odkazovej premennej poda jej inicializanho vrazu. Implicitn stanovenie dtovho typu loklnej premennej uskutouje mechanizmus typovej inferencie (MTI). Veobecn zpis intancianho prkazu triedy, ktor pracuje s MTI, je nasledujci:
var obj = new T();

45

Objektovo orientovan programovanie v jazyku C# 3.0

alebo
var obj = new T(a1, a2, ..., an);

kde: var je kov slovo indikujce, e typ loklnej premennej bude implicitne inferovan. obj je identifiktor loklnej premennej. T je nzov triedy, ktorej intancia je vytvran. a1, a2, ..., an s argumenty, ktor s poskytovan formlnym parametrom parametrickho intannho kontruktora triedy T. Syntaktickou modifikciou je pouitie kovho slova var namiesto pecifikcie dtovho typu loklnej premennej. Len o MTI vyhodnot vraz na pravej strane od priraovacieho opertora, determinuje typ loklnej premennej. V tejto svislosti je dleit uvies, e dtov typ loklnej premennej je pomocou MTI uren vdy v ase prekladu zdrojovho kdu. Pouitie MTI teda nemono chpa ako dynamick identifikciu dtovho typu loklnej premennej, resp. ako vytvorenie dynamickej vzby medzi loklnou premennou a jej dtovm typom. MTI smie by aplikovan aj pri vytvran loklnych pol intanci tried. Generick zpis zdrojovho kdu sa potom zmen takto:
var poleIntanci = new [] { new T(), new T() };

alebo
var poleIntanci = new [] { new T(a1, a2, ..., an), new T(a1, a2, ..., an) };

V 1. prpade zhotovujeme pole dvoch intanci triedy T, ktor s inicializovan bezparametrickm intannm kontruktorom. Hodnotou vrazu na pravej strane od priraovacieho opertora je odkaz na jednorozmern pole, ktor je alokovan na riadenej halde. V 2. prpade kontruujeme pole dvoch intanci triedy T, priom obe inicializujeme parametrickmi intannmi kontruktormi. Hodnota vrazu napravo od opertora = je rovnak ako v predchdzajcom prpade.

46

Objektovo orientovan programovanie v jazyku C# 3.0


// Deklarcia triedy. class T { // Defincia statickej dtovej poloky triedy. static int t; public T() { Console.WriteLine("Intancia . {0}", ++t); } } class Program { static void Main(string[] args) { // Implicitn urenie dtovho typu // loklnej odkazovej premennej pomocou MTI. var poleIntanci = new [] { new T(), new T() }; Console.Read(); } }

Hoci pri intancicii pomenovanch tried je pouitie MTI iba volitenou pomckou, zsadne in je situcia pri intancicii anonymnch tried. Vzhadom na to, e identifiktor anonymnej triedy nm nie je znmy, nevieme explicitne uri dtov typ loklnej odkazovej premennej, do ktorej bude uloen odkaz na zroden intanciu anonymnej triedy. Za tchto okolnost sa musme v plnej miere spoahn na MTI, ktor zabezpe priradenie prslunho dtovho typu loklnej premennej v ase prekladu zdrojovho kdu. O anonymnch triedach budeme hovori bliie v kapitole 2.9 Anonymn triedy a inicializtory intanci anonymnch a pomenovanch tried.

2.1.7 Skalrne intann vlastnosti triedy


Hoci v jazyku C++ boli prstupov metdy typu get/set jedinm mechanizmom na prcu s dtami objektu, jazyk C# 3.0 poskytuje elegantnejie rieenie, ktor je implementovan pomocou skalrnych intannch vlastnost. Skalrna intann vlastnos je programovou kontrukciou, ktor zapuzdruje dve prstupov metdy get a set, ktorch lohou je zskanie, resp. prava hodnoty poadovanej intannej dtovej poloky. Pozrime sa, ako by vyzerala deklarcia triedy Zamestnanec, ak aby sme mnoinu prstupovch metd nahradili skalrnymi intannmi vlastnosami:
class Zamestnanec { private string meno; private string priezvisko; private int mzda; private int odpracovanRoky; public Zamestnanec(string meno, string priezvisko, int mzda, int roky)

47

Objektovo orientovan programovanie v jazyku C# 3.0


{ this.meno = meno; this.priezvisko = priezvisko; this.mzda = mzda; odpracovanRoky = roky; } // Defincie skalrnych intannch vlastnost. public string Meno { get { return meno; } set { meno = value; } } public string Priezvisko { get { return priezvisko; } set { priezvisko = value; } } public int Mzda { get { return mzda; } set { mzda = value; } } public int OdpracovanRoky { get { return odpracovanRoky; } set { odpracovanRoky = value; } } }

V tele triedy sa nachdzaj defincie tyroch skalrnych intannch vlastnost: Meno, Priezvisko, Mzda a OdpracovanRoky. Vetky skalrne intann vlastnosti s verejne prstupn a zdieaj podobn syntaktick formu. Kad z tchto skalrnych intannch vlastnost je previazan s jednou dtovou polokou. Za elom bliej inpekcie si vyberieme prv skalrnu intann vlastnos Meno, na ktorej vysvetlme jej syntaktick reprezentciu. Ostatn vlastnosti bud pracova poda vysvetlenho modelu.
public string Meno { get { return meno; } set { meno = value; } }

Skalrna intann vlastnos m svoj dtov typ, ktor je zhodn s dtovm typom dtovej poloky, s ktorou je tto vlastnos prepojen. V prpade skalrnej intannej vlastnosti Meno je to primitvny odkazov dtov typ string. U vieme, e skalrne intann vlastnosti mu zskava, resp. modifikova hodnoty asociovanch dtovch poloiek. Ak je vlastnos schopn nielen zskava, ale aj upravova hodnoty dtovch poloiek, oznauje sa ako vlastnos uren na tanie a zpis. Skalrna intann vlastnos Meno je vlastnosou urenou na tanie aj zpis, pretoe vo svojom tele obsahuje dve prstupov metdy get a set (presne tak ist zloenie maj aj vetky ostatn skalrne intann vlastnosti analyzovanej triedy). Zatia o prstupov metda get obsahuje zdrojov kd, ktor poskytne hodnotu dtovej poloky pouvateovi, prstupov metda set sa k slovu dostva pri potrebe zmeni hodnotu dtovej poloky.
48

Objektovo orientovan programovanie v jazyku C# 3.0

V tele prstupovej metdy set je zapsan priraovac prkaz, ktor inicializuje dtov poloku. Samotn inicializan hodnota je uloen v premennej value. Tto premenn je pecilnou premennou jazyka C# 3.0, take vvojr ju nikdy nevytvra. Typ premennej value je implicitne inferovan tak, aby bol toton s typom skalrnej intannej vlastnosti. Dodajme, e definciu prstupovej metdy get, resp. prstupovej metdy set, meme v tele skalrnej intannej vlastnosti vynecha (nie vak obe sasne). Ak sa bude v tele vlastnosti nachdza len prstupov metda get, vytvorme vlastnos, ktor bude uren len na tanie hodnoty cieovej dtovej poloky. Analogicky, ak v tele vlastnosti bude definovan len prstupov metda set, pjde o vlastnos uren len za zpis hodnoty do cieovej dtovej poloky. V praktickom nasaden sa asto stretvame so skalrnymi intannmi vlastnosami, ktor nm umouj len zska, no u nie modifikova dta objektu uloen v istej dtovej poloke. S ovea menou frekvenciou sa vyskytuj skalrne intann vlastnosti uren len na zpis dt do dtovch poloiek. Fragment zdrojovho kdu jazyka C# 3.0, ktor intanciuje triedu Zamestnanec a vyuva mnoinu skalrnych intannch vlastnost, vyzer takto:
static void Main(string[] args) { Zamestnanec zam1 = new Zamestnanec("Emil", "Mal", 30000, 10); Console.WriteLine("daje o zamestnancovi: \n" + "Meno: " + zam1.Meno + "\n" + "Priezvisko: " + zam1.Priezvisko + "\n" + "Mzda: " + zam1.Mzda + "\n" + "Odpracovan roky: " + zam1.OdpracovanRoky ); Console.ReadLine(); }

Nepochybne, prca s intanciou triedy pomocou skalrnych intannch vlastnost je elegantnejia a prirodzenejia. Z pohadu pouvatea sa vlastnos jav ako inteligentn dtov poloka, aj ke v skutonosti ide o programov kontrukciu, ktor zapuzdruje dvojicu prstupovch metd.

2.1.8 Automaticky implementovan skalrne intann vlastnosti triedy


tandardn sprvanie prstupovch metd get a set skalrnych intannch vlastnost triedy meme charakterizova takto: 1. Prstupov metda get zskava hodnotu skromnej dtovej poloky intancie triedy.

49

Objektovo orientovan programovanie v jazyku C# 3.0

2. Prstupov metda set modifikuje hodnotu skromnej dtovej poloky intancie triedy. Ak nemme zujem o pokroil konfigurciu prstupovch metd get a set (napr. za elom zapracovania pokroilej aplikanej logiky), meme prenecha kompletn zostavenie tiel prstupovch metd vlastnost a vytvorenie definci spriaznench dtovch poloiek kompiltoru. Tak vytvorme automaticky implementovan skalrne intann vlastnosti triedy. alej uvdzame praktick ukku triedy, ktorej vlastnosti s automaticky implementovan.
// Deklarcia triedy, ktor vyuva automaticky implementovan // skalrne intann vlastnosti. class MP3Prehrva { public string Znaka { get; set; } public byte KapacitaPamteVGB { get; set; } public ushort PoetPiesn { get; set; } }

Intancie tejto triedy bud reprezentova obben MP3 prehrvae. Pri kadom prehrvai budeme sledova tri atribty: znaku, kapacitu vstavanej (flash) pamte v GB a maximlny poet piesn, ktor doke prehrva uchova. V tele triedy s definovan tri skalrne intann vlastnosti, ktor bud kompiltorom automaticky implementovan. Ak chceme da najavo nau intenciu o zalenenie automaticky implementovanch skalrnych intannch vlastnost do tela triedy, do tiel prslunch vlastnost umiestnime len deklarcie (nie defincie) prstupovch metd get a set. Pri doruen poiadavky na vytvorenie automaticky implementovanch vlastnost uskuton kompiltor nasledujce opercie: Telo triedy rozri o definciu mnoiny skromnch dtovch poloiek. Vzah medzi dtovmi polokami a vlastnosami ostva nezmenen a opisuje ho relcia typu 1:1. Vytvor defincie pvodne iba deklarovanch prstupovch metd get a set. Vygenerovan defincie bud fungova poda tandardnho modelu: metda get bude zskava hodnotu dtovej poloky, zatia o metda set bude tto hodnotu meni. Okrem spomenutho vytvra kompiltor v naej ukke samozrejme aj verejne prstupn implicitn intann kontruktor. O tom, e kompiltor vykonal kontatovan opercie, sa meme presvedi pri pohade na MSIL kd predmetnej triedy (obr. 17).

50

Objektovo orientovan programovanie v jazyku C# 3.0

Obr. 17: MSIL obraz triedy s automaticky implementovanmi vlastnosami Deklarcia triedy s automaticky implementovanmi ekvivalentn kompletnej deklarcii rovnomennej triedy:
class MP3Prehrva { private string znaka; private byte kapacitaPamteVGB; private ushort poetPiesn; public string Znaka { get { return znaka; } set { znaka = value; } } public byte KapacitaPamteVGB { get { return kapacitaPamteVGB; } set { kapacitaPamteVGB = value; } } public ushort PoetPiesn { get { return poetPiesn; } set {poetPiesn = value; } } }

vlastnosami

je

funkne

Kompletn deklarcia triedy sa odliuje explicitnm definovanm skromnch dtovch poloiek, ktor s pre leny triedy vdy prstupn. Dtov poloky, ktor kompiltor
51

Objektovo orientovan programovanie v jazyku C# 3.0

samoinne generuje pri automatickej implementcii skalrnych intannch vlastnost vak nie s nijakm spsobom dosiahnuten. Programtor teda nem monos s nimi priamo narba. Pouitie intancie je potom u jednoduch:
static void Main(string[] args) { MP3Prehrva zen = new MP3Prehrva(); zen.Znaka = "Creative ZEN"; zen.KapacitaPamteVGB = 4; zen.PoetPiesn = 2000; Console.WriteLine("Produktov informcie o " + "MP3 prehrvai:\n" + "Znaka: " + zen.Znaka + "\n" + "Kapacita pamte (GB): " + zen.KapacitaPamteVGB + "\n" + "Poet piesn: " + zen.PoetPiesn); Console.Read(); }

2.1.9 Indexovan intann vlastnosti triedy


Okrem skalrnych intannch vlastnost smieme v jazyku C# 3.0 rozri telo triedy tie o defincie indexovanch intannch vlastnost. Indexovan vlastnos14 nm umouje inicializova intanciu triedy podobne, ako keby bola tto intancia poom. Indexovan intann vlastnos sa definuje nasledujcim spsobom:
public T1 this[T2 i] { get { /* Zdrojov kd prstupovej metdy get. */ } set { /* Zdrojov kd prstupovej metdy set. */ } }

kde: T1 je dtov typ indexovanej vlastnosti a sasne aj dtov typ mnoiny dtovch poloiek, s ktormi je indexovan vlastnos asociovan. this je identifiktor indexovanej vlastnosti. T2 je dtov typ formlneho parametra indexovanej vlastnosti. i je identifiktor formlneho parametra indexovanej vlastnosti. Tento formlny parameter uchovva index, ktor determinuje poadovan dtov poloku intancie triedy.

14

Indexovan vlastnos sa niekedy nazva aj indexer. Kee v tejto publikcii dbme na terminologick istotu vkladu, budeme uprednostova vstinej termn indexovan vlastnos.

52

Objektovo orientovan programovanie v jazyku C# 3.0

Pre indexovan intann vlastnosti platia tieto pravidl: 1. Defincie indexovanch vlastnost sa mu nachdza v deklarcich tried a truktr. 2. Indexovan vlastnosti mu by preaen. Je teda mon vytvori mnoinu definci rovnomennej indexovanej vlastnosti. Pochopitene, jednotliv verzie preaenej indexovanej vlastnosti sa musia odliova svojou signatrou (zoznamom formlnych parametrov). Trieda Vektor, ktorej deklarciu pribliuje nasledujci fragment zdrojovho kdu jazyka C# 3.0, disponuje jednou indexovanou intannou vlastnosou.
class Vektor { private int x, y, z; // Defincia indexovanej intannej vlastnosti. public int this[int i] { get { switch (i) { case 0: return x; case 1: return y; case 2: return z; default: throw new System.ArgumentOutOfRangeException(); } } set { switch (i) { case 0: x = value; break; case 1: y = value; break; case 2: z = value; break; default: throw new System.ArgumentOutOfRangeException(); } } } }

Komentr k triede: Intancia triedy stelesuje trojrozmern (3D) vektor. Vzhadom na to, e dtovm obsahom intancie je trojica vektorovch zloiek, ako rozumn rieenie
53

Objektovo orientovan programovanie v jazyku C# 3.0

sa jav zapracova indexovan vlastnos, ktor nm dovol inicializova intanciu triedy (vektor) ako jednorozmern pole. Indexovan vlastnos je verejne prstupn a parametrick, pretoe v jej signatre je umiestnen defincia jednho formlneho parametra. Poda hodnoty tohto formlneho parametra bude indexovan vlastnos bu zskava hodnoty vektorovch zloiek, alebo ich upravova. V tele indexovanej vlastnosti meme pozorova defincie dvoch prstupovch metd get a set. Venujme sa najskr prstupovej metde get. Programov kd metdy get indexovanej vlastnosti bude vykonan vtedy, ke bude doruen poiadavka na zskanie hodnoty istej vektorovej zloky. Kee 3D vektor obsahuje 3 zloky, meme ich indexova hodnotami z intervalu <0, 2>. Pre prstup prostrednctvom indexovanej vlastnosti je dleit hodnota indexu, pretoe len na zklade nej vieme uri, s ktorou zlokou vektora budeme pracova. Toto viaccestn rozhodovanie je rieen prkazom switch, ktor operuje s hodnotou formlneho parametra i. Ak i == 0, tak prstupov metda get vrti hodnotu dtovej poloky x (teda hodnotu 1. zloky vektora). V prpade zvyujcej sa hodnoty indexu bude metda get vraca vdy zloku vektora s vym poradovm slom. Na tomto mieste si dovolme pripoji poznmku k syntaktickej implementcii: Ako meme postrehn, po vrten hodnoty dtovej poloky prkazom return u nezadvame v prslunej vetve case ukonovac prkaz break. Tento prkaz nie je v tomto kontexte potrebn, pretoe u samotn vrtenie hodnoty prkazom return znamen ukonenie rozhodovania v prkaze switch. Ak sa nedopatrenm stane, e hodnota formlneho parametra i bude mimo hranc intervalu <0, 2>, bude spusten kd vo vetve default. Za tchto okolnost iniciujeme generovanie chybovej vnimky, pretoe nevieme mapova index na dtov poloku. elom existencie prstupovej metdy set je nastavenie hodnoty dtovej poloky, ktor bude uren svojm selnm indexom. Viaccestn rozhodovanie prebieha poda znmeho algoritmu. Rozdiel spova v tom, e vybrat dtov poloku inicializujeme v rmci priraovacieho prkazu. Kee priraovac prkaz neukonuje spracovanie prkazov vo vetve case, musme za prida samostatn terminan prkaz break. Nasledujci program ukazuje, ak praktick implikcie so sebou prina pouitie indexovanch intannch vlastnost triedy.
static void Main(string[] args) { Vektor vektor = new Vektor(); // Inicializcia intancie triedy pomocou indexovanej vlastnosti. vektor[0] = 1; vektor[1] = 1; vektor[2] = 1; Console.WriteLine("Vektor [{0}, {1}, {2}]", vektor[0], vektor[1], vektor[2]); }

54

Objektovo orientovan programovanie v jazyku C# 3.0

Vimnime si, ako je inicializovan zaloen intancia triedy Vektor. Za identifiktorom odkazovej premennej zapisujeme hranat ztvorky a pecifikujeme index dtovej poloky (zloky vektora), s ktorou si prajeme manipulova. Syntakticky pouitie indexovanej vlastnosti naozaj vyzer, ako keby sme s intanciou triedy Vektor pracovali ako s jednorozmernm poom. V zvislosti od toho, kde sa vraz vektor[i] nachdza, bude spracovan bu prstupov metda get, alebo prstupov metda set indexovanej vlastnosti. Indexovan vlastnosti preukazuj svoje siln strnky aj pri prci s poami vektorov:
static void Main(string[] args) { Vektor[] poleVektorov = new Vektor[10]; Random genertor = new Random(); for (int i = 0; i < 10; i++) { poleVektorov[i] = new Vektor(); Console.Write("Vektor . {0} m sradnice ", i + 1); for (int m = 0; m < 3; m++) { poleVektorov[i][m] = genertor.Next(1, 101); Console.Write("\t{0}\t", poleVektorov[i][m]); } Console.Write("\n"); } Console.Read(); }

Tento zdrojov kd vytvra pole desiatich intanci triedy Vektor. Nam zmerom je vetky zostrojen vektory inicializova pomocou ich indexovanch vlastnost. Inicializanmi hodnotami bud pseudonhodn cel sla z intervalu <1, 100>. V alom texte sa budeme venova len kritickm miestam programu: 1. Prv prkaz vytvra jednorozmern pole, ktorho prvky bud mc by inicializovan odkazmi na intancie triedy Vektor. Je dleit si uvedomi, e po spracovan tohto prkazu existuje pole, no nie je naplnen iadnymi objektmi (vektormi). 2. Vektory s zhotovovan a v tele nadradenho cyklu for. Vo vnorenom cykle for pouvame indexovan vlastnosti vektorov na ich inicializciu pseudonhodnmi celmi slami. Vraz poleVektorov[i][m] znamen spustenie indexovanej vlastnosti i-tej intancie triedy Vektor15.

15

Vraz poleVektorov[i][m] me, najm pre vvojrov prichdzajcich z jazykov C a C++, indikova, e pracujeme s dvojrozmernm poom. To je vak chyba, ktor vznik aplikciou pravidiel jazykov C/C++ pri prci s dvojrozmernmi poami v prostred C# 3.0. Ak by sme v jazyku C# 3.0 pracovali s dvojrozmernm poom, tak indexcia by vyzerala inak: poleVektorov[i, m] a nie poleVektorov[i][m]. V tomto prpade ide o aktivciu indexovanej vlastnosti poadovanej intancie triedy Vektor.

55

Objektovo orientovan programovanie v jazyku C# 3.0

2.1.10 Finalizr
Finalizr je pecilna metda triedy, ktorej lohou je vykona finalizan prce predtm, ako bude intancia triedy uvonen z riadenej haldy16. Veobecn syntaktick podoba finalizra je nasledujca:
~T() { // Telo finalizra. }

kde: T je identifiktor triedy, v ktorej tele sa finalizr nachdza. Pre finalizr platia tieto zsady: Finalizr sa me vyskytova iba v telch tried (odkazovch dtovch typov), nikdy nie v telch truktr (hodnotovch dtovch typov). Finalizr nem iadnu nvratov hodnotu (podobne ako pri kontruktore nemono poui ani kov slovo void). Finalizr mus by vdy bezparametrick. Neme teda definova iadne formlne parametre. Finalizr sa nesmie sta predmetom preaenia, o znamen, e jedna trieda me definova prve jeden finalizr. Ak bzov trieda explicitne definuje svoj finalizr, tento nie je deden odvodenou triedou. Finalizr nesmie by volan priamo klientskym zdrojovm kdom. Je to preto, e finalizr je v prpade potreby implicitne aktivovan automatickm sprvcom pamte virtulneho exekunho systmu. Ak do tela triedy umiestnime definciu finalizra, kompiltor automaticky vlo do jeho tela kd, ktor bude vola finalizr primrnej systmovej bzovej triedy System.Object.
16

V predchdzajcich verzich jazyka C# 3.0 bol finalizr asto oznaovan ako detruktor, o vak nie je poda nho nzoru sprvne. Vyplva to z odlinch pracovnch modelov detruktorov v jazyku C++ a finalizanch metd (finalizrov) v jazyku C# 3.0. Preto sme uprednostnili pojem finalizr, ktor nahrdza skr uplatovan termn detruktor.

56

Objektovo orientovan programovanie v jazyku C# 3.0

Ak je finalizovan intancia odvodenej triedy, najskr je volan jej finalizr. Po spracovan zdrojovho kdu, ktor je uloen v tele finalizra odvodenej triedy dochdza k aktivcii finalizra bzovej triedy a exekcii v om uloench programovch prkazov. Kee finalizcia intanci tried na riadenej halde je nedeterministick, nemono presne predikova okamih, kedy bude finalizr spusten. Na rozdiel od kontruktora, finalizr nesmie by statick. Poda toho, i intancia vznikla z triedy, ktor explicitne definuje svoj finalizr alebo nie, rozliujeme dva zkladn modely finalizcie intanci tried: implicitn a explicitn finalizcia. Implicitn finalizcia sa tka len tch intanci, ktor vznikli z tried, ktor explicitne nedefinuj svoje finalizry. Ak sa takto intancia triedy stane nepotrebnou, automatick sprvca pamte uskuton jej okamit dealokciu. Na druh stranu, ak intancia vzila z triedy s explicitne definovanm finalizrom, bude vyadova explicitn finalizciu. Proces explicitnej finalizcie je bliie ozrejmen v kapitole 2.2 Analza ivotnch cyklov intanci tried.

2.1.11 Detruktory v jazyku C++ a finalizry v jazyku C# 3.0


Napriek tomu, e syntaktick obraz finalizra jazyka C# 3.0 je tak ist ako vzhad detruktora v jazyku C++, medzi oboma entitami existuj vznamn smantick rozdiely. Vbec najdleitejm rozdielom je skutonos, e km v jazyku C++ je finalizcia intanci tried deterministick, v prostred jazyka C# 3.0 pracujeme s nedeterministickou finalizciou. Ak v jazyku C++ zalome dynamicky intanciu triedy (pomocou opertora new), meme na u kedykovek aplikova opertor delete17. Pouitie opertora delete implikuje okamit aktivciu detruktora, ktor je zodpovedn za realizciu mnoiny finalizanch operci predtm, ako bude intancia triedy dealokovan. Je teda zrejm, e programtor v jazyku C++ je schopn explicitne vyvola detruktor na poiadanie kedykovek, ke to uzn za vhodn. V jazyku C# 3.0 nememe finalizr aktivova priamo, pretoe tto kompetenciu za vvojrov preber virtulny exekun systm. Aj z tohto dvodu sa v jazykovej pecifikcii C# 3.0 nenachdza iaden opertor delete, alebo in, funkne prbuzn opertor. V jazyku C++ meme vytvori intanciu triedy aj automaticky, a to prkazom
X x;

alebo
17

Presnejie povedan, opertor delete je aplikovan na smernkov premenn, v ktorej je uloen smernk identifikujci pozciu intancie triedy v dynamickej pamti.

57

Objektovo orientovan programovanie v jazyku C# 3.0


X x(a1, a2, ..., an);

Oba uveden prkazy zakladaj automaticky intanciu triedy X. V prvom prkaze je vytvoren intancia inicializovan bezparametrickm kontruktorom (i u implicitnm, alebo explicitnm). V druhom prkaze je intancia po svojej alokcii inicializovan explicitnm parametrickm kontruktorom s vhodne zvolenou spravou vstupnch argumentov. Bez ohadu na syntaktick reprezentciu automatickej intancicie triedy X je nutn spomen, e zostrojen intancia bude situovan na zsobnku programovho vlkna a nie v halde (dynamickej pamovej oblasti). Za predpokladu, e sa prkaz uskutoujci automatick intanciciu triedy X nachdza v tele funkcie (metdy), vieme presne predpoveda okamih zniku automatickej intancie. Tento okamih je ohranien poslednm programovm prkazom, ktor sa v tele funkcie nachdza. Vzpt dochdza k odstrneniu vetkch dtovch objektov zo zsobnka. Pri tejto prleitosti bude zlikvidovan aj automaticky skontruovan intancia triedy X. Ete predtm vak djde k implicitnej aktivcii detruktora intancie, ktor dostane prleitos vykona poadovan finalizan aktivity (svisiace najm s uvonenm dynamicky pridelenho pamovho priestoru, uzatvorenm vstupnovstupnch dtovch prdov at.). V jazyku C# 3.0 neexistuje spsob, ktor by viedol k automatickej intancicii triedy a k alokcii automatickej intancie na zsobnku programovho vlkna. Intancie tried bud v tomto prostred vdy alokovan v riadenej halde (dynamickej pamovej oblasti). Programy napsan v jazyku C++ nemu na rozdiel od aplikci jazyka C# 3.0 ai z prtomnosti automatickho sprvcu pamte18. Sprvca pamte eliminuje mnoinu chb, ktor vznikali najm z dvodu nekorektnej dealokcie intanci tried. V prostred jazyka C++ sa vemi asto stvalo, e vvojr zabudol dynamicky alokovan intanciu triedy v prhodnej chvli uvoni, alebo sa poksil dealokova u raz uvonen intanciu. Ete zvanejie chyby vznikali pri tzv. kruhovch referencich, kedy existovala hierarchia navzjom prepojench intanci, no absentovala algoritmicky presn distribcia zodpovednosti za ich dealokciu. V aplikcich .NET naprogramovanch v jazyku C# 3.0 s intancie tried pod stlou kontrolou automatickho sprvcu pamte, ktor analyzuje objekty a ak diagnostikuje ich nedosiahnutenos, tak zabezpe ich automatick dealokciu.

18

Hoci na softvrovom trhu existuj automatick sprvcovia pamte pre jazyk C++, vo vetkch prpadoch ide o produkty softvrovch firiem tretch strn. ISO tandard jazyka C++ nepecifikuje iaden vstavan stroj, ktor by automaticky uvooval nepotrebn intancie tried.

58

Objektovo orientovan programovanie v jazyku C# 3.0

2.2 Analza ivotnch cyklov intanci tried


V tejto kapitole podme exaktn vysvetlenie analzy ivotnch cyklov intanci tried ako pouvatesky deklarovanch odkazovch dtovch typov. ivotn cyklus intancie triedy sa sklad z tchto tdi: 1. Vytvorenie intancie triedy. 2. Vyuvanie sluieb intancie triedy. 3. Ukonenie ivota intancie triedy. Intancia triedy je vsledkom intancianho procesu, ktor bol podrobne rozobrat v asti 2.1.3 Intancicia triedy a pouitie zrodenej intancie. V 1. tdiu ivotnho cyklu s z pohadu alieho ivota intancie triedy dleit predovetkm dve opercie: alokcia intancie a inicializcia intancie. Len o je intancia triedy alokovan v riadenej halde a nleite inicializovan, me zaa poskytova sluby svojim klientom. Ponc tmto okamihom vstupuje intancia triedy do 2. tdia svojho ivotnho cyklu, ktor je z pohadu celkovej analzy najvznamnejie. Intancia triedy vystupuje ako server, ktor na poiadanie pln poiadavky konenej a neprzdnej mnoiny klientov. tl sprvania sa intancie triedy je plne determinovan komunikanm modelom klient server. 3. etapa ivotnho cyklu intancie triedy je charakterizovan vykonanm finalizanch prc19 a dealokciou intancie z riadenej haldy. Dealokcia pamovho priestoru je spojen s likvidciou intancie, m sa kon jej ivotn cyklus. 2. etapu ivotnho cyklu intancie triedy mono charakterizova funkciou ( ), ktor analyzuje poet operci ( ) realizovanch intanciou v priebehu uritho asovho intervalu ( ):

Poet operci vykonvanch intanciou triedy je priamo zvisl od potu sprv, ktor intancia triedy prijma od klientov. Vizulnu interpretciu priebehu 2. etp vybranch intanci tried uvdzaj obr. 18 20.

19

Spektrum finalizanch prc realizovanch pred detrukciou intancie triedy zvis od finalizanho modelu. Pri implicitnej finalizcii nie je ria automatickho sprvcu pamte nijako citen, no pri explicitnej finalizcii mus automatick sprvca pamte spusti finalizr intancie a vykona vetky programov prkazy, ktor finalizr obsahuje. Poet akci, ktor mus finalizr spracova, priamo ovplyvuj asov nronos explicitnej finalizcie intancie triedy.

59

Objektovo orientovan programovanie v jazyku C# 3.0

Obr. 18: Vizualizcia 2. tdia ivotnho cyklu intancie triedy (1. ukka)

Obr. 19: Vizualizcia 2. tdia ivotnho cyklu intancie triedy (2. ukka)

60

Objektovo orientovan programovanie v jazyku C# 3.0

Obr. 20: Vizualizcia 2. tdia ivotnho cyklu intancie triedy (3. ukka) Napriek tomu, e krivka grafu monitorujca innos intancie triedy me ma variabiln priebeh, vdy dokeme spoahlivo identifikova tri zkladn body: 1. Bod A so sradnicami [t1, P1]. V tomto bode intancia vstupuje do 2. etapy svojho ivotnho cyklu. Meme teda poveda, e intancia spene prekonala 1. tdium, v ktorom dolo k jej alokcii a inicializcii. Poda charakteru intancianho procesu me existova medzi 1. a 2. tdiom ivotnho cyklu intancie rzne dlh asov interval. V niektorch prpadoch je vzniknut asov latencia minimlna tento jav zaznamenvame najm pri intancich, ktor nevyaduj nron inicializciu. Naopak, ak intancia vytvra v inicializanej fze nov dtov objekty, alebo alokuje pam pre dynamick dtov truktry, do 2. etapy svojho ivotnho cyklu vstupuje s citenejm oneskorenm. 2. Bod B so sradnicami [t2, P2]. Toto je bod maximlneho pracovnho vyaenia intancie triedy. Bod maximlnej aktivity dosahuje intancia triedy v momente, ke poskytuje svoje sluby maximlnemu potu klientov. Na rozdiel od bodu A je mon, aby intancia triedy dosiahla bod maximlneho pracovnho vyaenia aj viackrt poas 2. etapy svojho ivotnho cyklu. Podotknime, e intancia triedy me by naprogramovan tak, aby bola schopn sama flexibilne modifikova mnostvo maximlneho pracovnho vyaenia, resp. maximlny poet obsluhujcich klientov. 3. Bod C so sradnicami [tn, Pn]. Tento bod predstavuje hranin bod, v ktorom sa kon 2. etapa ivotnho cyklu intancie triedy a zana sa 3. etapa finalizcia.

61

Objektovo orientovan programovanie v jazyku C# 3.0

2.2.1 Finalizcia intanci tried


3. tdiom ivotnho cyklu intancie triedy je finalizcia. Ako sme uviedli, v prostred jazyka C# 3.0 rozliujeme medzi implicitnou a explicitnou finalizciou. Ak intancia triedy neplnuje v 3. tdiu svojho ivotnho cyklu vykona rozsiahle finalizan prce, jej finalizcia bude implicitn. S implicitnou finalizciou sa stretvame pri vetkch intancich, ktor vznikli z tried, v telch ktorch sa nenachdzali defincie finalizrov. Implicitn finalizcia je vkonnostne priaznivejia, pretoe vyaduje realizciu len niekokch pracovnch cyklov automatickho sprvcu pamte. Pri implicitnej finalizcii je intancia triedy uvonen z riadenej haldy bez nutnosti spustenia jej finalizra. Ak bola na vytvorenie intancie pouit trieda, ktor definuje svoj finalizr, tak takto intancia bude vyadova explicitn finalizciu. To znamen, e skr ako bude mc by intancia triedy dealokovan z riadenej haldy, bude musie by spusten jej finalizr a rovnako bud musie by spracovan vetky programov prkazy, ktor sa v tele finalizra nachdzaj. Skr, ako budeme mc presnejie objasni proces explicitnej finalizcie intanci tried v jazyku C# 3.0, musme sa zoznmi so stavbou riadenej haldy a riadiacimi algoritmami automatickho sprvcu pamte.

2.2.2 Stavba riadenej haldy a riadiace algoritmy automatickho sprvcu pamte


Vo fyzickom procese aplikcie .NET je oblas dynamickej pamte (riaden halda) kontrolovan automatickm sprvcom pamte. Riaden halda je segmentovan do troch objektovch generci, ktor s identifikovaten poda svojho poradovho sla. Ide o nasledujce objektov genercie: 1. Objektov genercia . 0 (1. objektov genercia). 2. Objektov genercia . 1 (2. objektov genercia). 3. Objektov genercia . 2 (3. objektov genercia). Kad objektov genercia disponuje alokanou kapacitou, urujcou poet objektov, ktor je mon v prslunej objektovej genercii uskladni.20 Objekty s z hadiska asu, poas ktorho pracuj poda modelu klient server, klasifikovan do troch generci: 1. Najmladie objekty (objekty len nedvno vytvoren). 2. Objekty so stredne dlhm ivotnm cyklom.
20

Alokan kapacita jednotlivch objektovch generci je rzna: pohybuje sa od stoviek kilobajtov a po niekoko megabajtov. Virtulny exekun systm je schopn dynamicky meni alokan kapacity objektovch generci poda aktulneho aplikanho kontextu. Ak naprklad aplikcia generuje vea objektov s krtkodobou ivotnosou, virtulny exekun systm zvi alokan kapacitu 1. objektovej genercie. Naopak, ak sa aplikcia spolieha najm na objekty s dlhou ivotnosou, najviu alokan kapacitu bude ma 3. objektov genercia.

62

Objektovo orientovan programovanie v jazyku C# 3.0

3. Najstarie objekty (objekty s dlhou dobou ivotnosti). Riaden halda s objektovmi generciami je znzornen na obr. 21.

Obr. 21: Generan zloenie riadenej haldy Ako si meme vimn, objekty v objektovch genercich s umiestnen v sekvennej postupnosti, m vypaj svisl pamov blok. Takto usporiadanie je efektvne, pretoe umouje vemi rchlo vyhada objekt, s ktorm chceme pracova21. Riadiace algoritmy automatickho sprvcu pamte garantuj, e medzi objektmi nebud vznika iadne przdne miesta, ktorch prtomnos by zniovala efektivitu pri prci s objektmi. Automatick sprvca pamte vdy uchovva smernk identifikujci pamov pozciu, na ktorej bude mc by alokovan nov objekt (obr. 22).

Obr. 22: Smernk determinujci pozciu novo alokovanho objektu v 1. objektovej genercii
21

V jazyku C++ s objekty na halde uchovvan inak. V tomto prostred je halda dynamickou dtovou truktrou, ktor pracuje ako zreazen zoznam. Kad bunka zoznamu obsahuje objekt a rovnako aj smernk, ktor odkazuje na al dosiahnuten objekt. Prechdzanie zreazenho zoznamu za elom prstupu k poadovanmu objektu je tak asovo nronejie. Sprva objektov v jazyku C# 3.0 sa skr podob na sprvu intanci hodnotovch dtovch typov na zsobnku.

63

Objektovo orientovan programovanie v jazyku C# 3.0

Vetky objekty, ktor vznikn, sa z pohadu pamovho manamentu najskr ocitaj v 1. objektovej genercii. 1. objektov genercia je kapacitne projektovan tak, aby dokzala absorbova novo vznikajce objekty. Ke sa kapacita 1. objektovej genercie zapln a napriek tomu prde od aplikcie poiadavka na zostrojenie novho objektu, automatick sprvca pamte uskuton tzv. kolekciu 1. objektovej genercie. V procese kolekcie dochdza k preskenovaniu 1. objektovej genercie, priom cieom tejto akcie je urenie mnoiny nedosiahnutench objektov. Nedosiahnuten objekty s nepouvan objekty, na ktor nie s nasmerovan iadne odkazy. Takto objekty mu by podroben finalizcii. Ke automatick sprvca pamte zahji kolekciu 1. objektovej genercie, predpoklad, e vetky prtomn objekty s nedosiahnuten. innos sprvcu pamte pokrauje prechdzanm stromu koreov a generovanm grafu vetkch dosiahnutench objektov. Strom koreov je dtov truktra, ktor obsahuje odkazy (objektov referencie). Tieto odkazy mu by uloen na rznych miestach, no najastejie s uskladnen v premennch odkazovch dtovch typov. Graf dosiahnutench objektov zoskupuje odkazy na objekty, ktor s iv ide teda o objekty, ktor aplikcia .NET stle vyuva. Naopak, vetky ostatn objekty, na ktor sa odkazy v grafe nenachdzaj, me automatick sprvca pamte povaova za nedosiahnuten objekty. Predpokladajme, e automatick sprvca pamte zist, e v 1. objektovej genercii sa nachdzaj 3 nedosiahnuten objekty. Kee tieto objekty u nie s viac potrebn, mu by finalizovan. Rozvime nae vahy alej a povedzme, e 2 zo spomenutej trojice objektov sm by implicitne finalizovan. Ak je to tak, tieto objekty bud podroben detrukcii a ich alokan kapacita bude prstupn na budce pouitie. Zostva nm vak jeden objekt, ktor vyaduje explicitn finalizciu. Ak zaloen objekt vziiel z triedy, ktor explicitne definuje svoj finalizr, tak ete pred inicializciou tohto objektu (pred aktivciou kontruktora objektu) bol smernk na pridan do zoznamu objektov vyadujcich explicitn finalizciu (ZOVEF). Ke automatick sprvca pamte diagnostikuje nedosiahnuten objekt ako objekt, ktor vyaduje explicitn finalizciu, vie, e je nutn aktivova jeho finalizr. Preto sprvca pamte presunie smernk na objekt zo zoznamu objektov vyadujcich explicitn finalizciu do zoznamu dosiahnutench objektov (ZDO). Po tejto opercii dochdza k obnoveniu stavu objektu, pretoe z pvodne nedosiahnutenho objektu spravil automatick sprvca pamte dosiahnuten objekt. V tejto svislosti je vemi dleit upozorni na jednu zsadn skutonos: sprvca pamte vykonva obnovenie stavu objektu len za elom jeho explicitnej finalizcie. Zmyslom obnovenia stavu objektu je oivenie pvodne nedosiahnutenho objektu. Tak zskavame iv objekt, na ktorom me by spusten finalizr. (Z uvedenho jasne vyplva, e aktivcia finalizra neme by uskutonen v spojen s nedosiahnutenm objektom.)

64

Objektovo orientovan programovanie v jazyku C# 3.0

Finalizcia objektu, resp. objektov, na ktor sa odkazuje ZDO, je realizovan asynchrnne na samostatnom, tzv. finalizanom programovom vlkne. Hoci poradie volan finalizrov jednotlivch objektov nie je determinovan, automatick sprvca pamte garantuje, e bud spracovan finalizry vetkch objektov, ktor poaduj svoju explicitn finalizciu. Po vykonan vetkch prkazov finalizra bude objekt op oznaen ako nedosiahnuten, avak tento raz bude opatren prznakom, ktor vrav, e objekt u bol explicitne finalizovan. Pri nasledujcej kolekcii bude nedosiahnuten a u explicitne finalizovan objekt jednoducho zlikvidovan, a to bez akchkovek dodatonch akci. Pri druhej kolekcii je teda analyzovan objekt okamite uvonen, podobne ako implicitne finalizovan objekty. Samozrejme, me sa sta, e automatick sprvca pamte objav v 1. objektovej genercii mnostvo dosiahnutench objektov, ktor nemono finalizova (proste z toho dvodu, e stle existuj klienti, ktor vyuvaj sluby tchto objektov). Vzhadom na to, e cieom automatickho sprvcu pamte je uvoni pamov kapacitu na alokciu novch objektov, bud objekty, ktor preij kolekciu, transportovan do objektovej genercie s vym poradovm slom. Dosiahnuten objekty z 1. objektovej genercie sa dostan do 2. objektovej genercie. Presun objektov medzi objektovmi generciami m vznamn praktick implikcie: 1. V objektovej genercii s nim poradovm slom vznikne po premiestnen objektu przdne miesto. Toto przdne miesto predstavuje pamov medzeru, priom je ohranien pamovm priestorom, ktor pred svojm premiestnenm do objektovej genercie s vym poradovm slom okupovala intancia triedy. Je evidentn, e m viac objektov bude z niej objektovej genercie propagovanch do vyej objektovej genercie, s tm vou pravdepodobnosou bud vznika pamov medzery. Intenzvna krecia pamovch medzier zapriuje fragmentciu objektovej genercie riadenej haldy. V zujme optimalizovanho prstupu k objektom je nutn pamov medzery odstrni a zabezpei sekvenn usporiadanie objektov. Elimincia pamovch medzier sa uskutouje v procese defragmentcie pamte objektovej genercie. Po defragmentcii bud objekty v objektovej genercii usporiadan sekvenne a prstup k nim bude rovnako efektvny ako predtm. 2. Pri presune objektov z 1. do 2. objektovej genercie sa pvodn odkazy na tieto objekty (smerujce do 1. objektovej genercie) stvaj neplatnmi. Kee objekty sa po transporte ocitn v 2. objektovej genercii, je potrebn aktualizova pvodn odkazy na ne. Aktualizciu odkazov na objekty vykonva automatick sprvca pamte vo svojej vlastnej rii. Len o s odkazy aktualizovan, objekty s aj naalej priamo dosiahnuten, a to aj napriek tomu, e sa zmenila ich fyzick pozcia na riadenej halde.
65

Objektovo orientovan programovanie v jazyku C# 3.0

Kolekcia 1. objektovej genercie riadenej haldy je najastejie uskutonen pri zaplnen tejto objektovej genercie. Ak sa automatickmu sprvcovi pamte podar zska dostatok pamovho priestoru na alokciu novch objektov, bude 1. objektov genercia jedinou, v ktorej sa kolekcia vykon. Hoci za bench okolnost mono zska dostatok pamovho priestoru kolekciou 1. objektovej genercie, existuj situcie, kedy nie je automatick sprvca pamte schopn uvoni dostaton alokan priestor. V tchto prpadoch mus sprvca pamte realizova kolekciu aj v genercii s vym poradovm slom, teda v 2. objektovej genercii. Poas kolekcie dochdza k nasledujcim akcim: Diagnostikuje sa kolekcia nedosiahnutench objektov 2. objektovej genercie. Nedosiahnuten objekty s finalizovan. Ak objekt nevyaduje explicitn finalizciu, bude okamite uvonen. Objekty vyadujce explicitn finalizciu bud explicitne finalizovan tak, ako sme u vysvetlili. Dosiahnuten objekty, ktor preij kolekciu, patria k objektom s dlhou dobou ivotnosti, a preto bud prenesen do objektovej genercie s vym poradovm slom, teda do 3. objektovej genercie. Objekty z 1. objektovej genercie, ktor preili kolekciu, bud presunut do 2. objektovej genercie. Vo vnimonch prpadoch sa me sta, e vyhovujci pamov priestor nebude njden ani v 1. objektovej genercii a ani v 2. objektovej genercii. Vtedy automatick sprvca pamte vykon kolekcie vetkch troch objektovch generci a uvon nedosiahnuten objekty. Dosiahnuten objekty 3. objektovej genercie v tejto genercii aj naalej zostvaj, pretoe u iadna alia objektov genercia neexistuje. Ak by sa ani po 3-fzovej kolekcii nepodarilo automatickmu sprvcovi pamte dealokova potrebn mnostvo pamovho priestoru, virtulny exekun systm ohlsi chybu pri pokuse o alokciu a exekcia aplikcie .NET bude ukonen. Riadiace algoritmy automatickho sprvcu pamte pri kolekcii 1. objektovej genercie, implicitnej finalizcii nedosiahnutench objektov a alokcii novo vytvorench objektov predstavuj obr. 23 25.

66

Objektovo orientovan programovanie v jazyku C# 3.0

Obr. 23: Vsledkom kolekcie 1. objektovej genercie s 3 nedosiahnuten objekty

Obr. 24: Implicitn finalizcia nedosiahnutench objektov

Obr. 25: Umiestnenie novch objektov do 1. objektovej genercie


67

Objektovo orientovan programovanie v jazyku C# 3.0

Segmentcia riadenej haldy do troch objektovch generci prina tieto pozitva: 1. Klasifikuje objekty poda asu ich ivotnosti. 2. Umouje spravova objekty samostatne poda ich prslunosti k uritej objektovej genercii. 3. Napomha produktvnejej sprve riadenej haldy. Je toti vdy jednoduchie vykona kolekciu jednej, alebo dvoch objektovch generci, ako uskutoova kolekciu celej riadenej haldy. 4. Hoci transporty objektov medzi rznymi objektovmi generciami s nron na prcu procesora, automatick sprvca pamte eliminuje pamov fragmentciu a vdy pozicuje objekty v sekvennej postupnosti, o produkuje minimlne asov latencie pri prci s nimi. Objekty, ktorch alokan kapacita je via ako 85 000 bajtov, s z pohadu automatickho sprvcu pamte povaovan za tzv. kapacitne nron objekty. Objekty tohto typu s alokovan a manaovan na samostatnej riadenej halde. Ide o riaden haldu pre kapacitne nron objekty. V tejto riadenej halde s objekty uskladnen v svislch pamovch segmentoch. Na rozdiel od 3-generanej riadenej haldy, riaden halda pre kapacitne nron objekty nie je lenen na objektov genercie. Namiesto toho vystupuje ako monolitick celok, ktor je poskladan z viacerch pamovch segmentov. Aj ivotn cykly kapacitne nronch objektov s riaden automaticky, no s tm rozdielom, e sa neuskutouj iadne presuny objektov. Vzhadom na to, e objekty s kapacitne nron, ich transporty by zniovali vkon a v konenom dsledku by psobili kontraproduktvne.

2.3 Agregano-kompozin vzahy medzi triedami


V programovacom jazyku C# 3.0 existuje niekoko monost, ako na syntaktickej rovni vybudova medzi viacermi triedami agregan, resp. kompozin vzahy. Jednm rieenm je aplikova techniku vnrania tried, kedy vlome deklarciu jednej triedy do tela inej triedy. V tele nadradenej triedy potom definujeme dtov poloku, ktorej typom bude vnoren trieda. V nasledujcej praktickej ukke vytvorme model potaa, ktor bude obsahova procesor uritho typu. Prklad demontruje vytvorenie kompozinej vzby medzi triedou Pota a vnorenou triedou Procesor. Ide teda o silnej typ agregcie (kompozciu), o je vak pochopiten, pretoe pota bez procesora neme fungova. Najskr uvedieme deklarciu triedy Procesor:
68

Objektovo orientovan programovanie v jazyku C# 3.0


// Deklarcia triedy Procesor. class Procesor { // Defincie dtovch poloiek triedy. string nzov; string viacJadier; float celkovFrekvencia; string technolgiaHT; // Defincia verejne prstupnho parametrickho intannho // kontruktora triedy. public Procesor(string nzov, string viacJadier, float celkovFrekvencia, string technolgiaHT) { this.nzov = nzov; this.viacJadier = viacJadier; this.celkovFrekvencia = celkovFrekvencia; this.technolgiaHT = technolgiaHT; } // Defincie verejne prstupnch intannch skalrnych // vlastnost triedy. public string Nzov { get { return this.nzov; } set { this.nzov = value; } } public string ViacJadier { get { return this.viacJadier; } set { this.viacJadier = value; } } public float CelkovFrekvencia { get { return this.celkovFrekvencia; } set { this.celkovFrekvencia = value; } } public string TechnolgiaHT { get { return this.technolgiaHT; } set { this.technolgiaHT = value; } } }

Pokraujeme zostrojenm triedy Pota, do tela ktorej vnorme prve deklarovan triedu Procesor:
class Pota { // Tu sa nachdza deklarcia vnorenej triedy Procesor. class Procesor { ... } // Defincia dtovej poloky, do ktorej budeme mc uloi odkaz // na intanciu triedy Procesor. Procesor procesor; // Defincia verejne prstupnho bezparametrickho intannho // kontruktora triedy. public Pota() {

69

Objektovo orientovan programovanie v jazyku C# 3.0


procesor = new Procesor("AMD Turion 64 X2", "no", 4.0f, "Nie"); } // Defincia verejne prstupnej intannej metdy triedy. public void InformcieOProcesorePotaa() { Console.WriteLine("Informcie o procesore potaa:"); Console.WriteLine("Nzov: {0}\nViac jadier: {1}\n" + "Celkov frekvencia: {2} GHz\nTechnolgia HT: {3}", this.procesor.Nzov, this.procesor.ViacJadier, this.procesor.CelkovFrekvencia, this.procesor.TechnolgiaHT); } }

Vzhadom na to, e v tele triedy Pota je umiestnen deklarcia vnorenej triedy Procesor, meme v dtovej sekcii triedy Pota definova skromn odkazov premenn s identifiktorom procesor, ktorej dtovm typom je vnoren trieda. V tele kontruktora triedy Pota dochdza k zaloeniu intancie vnorenej triedy. Tmto spsobom zabezpeme, e kad korektne vytvoren intancia triedy Pota bude disponova svojm procesorom. Pravdae, z hadiska lepej pouvateskej prvetivosti by sme mohli kontruktor triedy Pota preai a ponknu tak irie monosti pre konfigurciu procesora vytvranho potaa. Kee oblas platnosti odkazovej premennej procesor je vymedzen telom nadradenej triedy, je zrejm, e ivotnos objektu triedy Procesor sa bude kry so ivotnm cyklom objektu triedy Pota. Verejne prstupn intann metda InformcieOProcesorePotaa poskytuje klientom objektu triedy Pota zkladn daje o technickej charakteristike procesora, ktorm je pota osaden. Vizulny model reprezentujci diagram triedy Pota je znzornen na obr. 26. Intancicia triedy Pota prebieha poda tandardnho postupu:
class Program { static void Main(string[] args) { // Intancicia triedy Pota. Pota mojePC = new Pota(); mojePC.InformcieOProcesorePotaa(); Console.Read(); } }

V procese intancicie bude najskr kontruovan objekt triedy Pota. Aktivcia opertora new spsob dynamick zaloenie objektu na riadenej halde. Opertor new implicitne vyvol kontruktor alokovanej intancie triedy Pota, ktor zabezpe
70

Objektovo orientovan programovanie v jazyku C# 3.0

vytvorenie vnorenho objektu triedy Procesor. Podotknime, e vnoren objekt nie je pre klientsky programov kd priamo prstupn, o je v poriadku, pretoe nam cieom je dodra zkladn princpy objektovo orientovanho programovania.

Obr. 26: Vizulne stvrnenie kompozinho vzahu medzi triedami Pota a Procesor

2.4 Dedinos
Programovac jazyk C# 3.0 podporuje verejn jednoduch dedinos. Na rozdiel od jazyka C++ teda absentuje implementcia viacnsobnej dedinosti, avak na druh stranu, tto skutonos nememe poklada za slab strnku jazyka C# 3.0. Skr naopak, najm ke uvime, e s implementciou viacnsobnej dedinosti sa v jazyku C++ viazali nemal problmy, ktor bolo asto nutn riei virtulnym dedenm. Abstrahovanie od viacnsobnej dedinosti vak nie je vlastn len programovaciemu jazyku C# 3.0, ale tie Jave, aliemu vemi populrnemu programovaciemu jazyku sasnosti.

71

Objektovo orientovan programovanie v jazyku C# 3.0

Jednoduch dedinos, s ktorou sa v jazyku C# 3.0 stretvame, je implicitne verejn (nie s vyadovan a nakoniec ani potrebn in varianty jednoduchej dedinosti, ako je skromn alebo chrnen dedinos). V procese jednoduchej dedinosti vytvrame z bzovej triedy odvoden triedu (podtriedu). Odvoden trieda ded od svojej bzovej triedy vetky atribty a metdy. Hoci zdeden bud vetky leny bzovej triedy, nie vetky musia by z tela odvodenej triedy priamo viditen. O tom, ktor zdeden leny bud viditen, rozhoduj ich prstupov modifiktory, ktor s uveden v bzovej triede. Vzahy vybudovan na zklade verejnej jednoduchej dedinosti maj vdy generalizano-pecializan charakter. Bzov trieda je veobecnou ablnou, zatia o odvoden trieda je jej pecifickejou implementciou. Ak sa vyskytuje v reazci verejnej jednoduchej dedinosti viacero tried, plat pravidlo, poda ktorho je kad nasledujca podtrieda vdy konkrtnejm prpadom svojej nadradenej triedy. Okrem optovnej pouitenosti schopnost bzovej triedy me odvoden trieda doda nov, doplnkov funkcionalitu. To sa deje definovanm novch lenov, ktor sa vyskytuj len v odvodenej triede. Podtrieda sa me taktie rozhodn predefinova sprvanie zdedench lenov bzovej triedy. V tomto kontexte je mon prekry zdeden implementciu lena bzovej triedy v triede odvodenej, o je podstatou polymorfizmu implementovanho pomocou verejnej jednoduchej dedinosti. Na druh stranu, odvoden trieda je schopn ukry zdeden implementciu lena bzovej triedy tak, e ho nahrad novou implementciou. Tto technika je znma ako ukrvanie zdedench lenov bzovej triedy v podtriede. Generick syntaktick prkaz pre deklarovanie odvodenej triedy B, ktor vznikla v procese verejnej jednoduchej dedinosti z bzovej triedy A, m nasledujcu podobu:
class B : A { ... }

Zapsan deklarcia odvodenej triedy predpoklad, e existuje trieda s identifiktorom A, ktor nie je ani zapeaten, ani statick. Ke vytvorme intanciu odvodenej triedy, tto bude obsahova zdeden podobjekt bzovej triedy. Generick syntaktick prkaz zakladajci intanciu odvodenej triedy vyzer takto:
B obj = new B();

Kee intancia odvodenej triedy v sebe zapuzdruje zdeden podobjekt bzovej triedy, je nutn korektne skontruova najskr ten, a a potom me by riadne skontruovan intancia odvodenej triedy. Tomuto princpu zodpoved aj reazec volan intannch kontruktorov: najskr je aktivovan intann kontruktor odvodenej triedy, ktor
72

Objektovo orientovan programovanie v jazyku C# 3.0

vak vzpt (ete pred vstupom do svojho tela) vol intann kontruktor bzovej triedy. Ke je zdeden podobjekt bzovej triedy skontruovan a korektne inicializovan, dokon sa kontrukcia objektu odvodenej triedy (spracuj sa programov prkazy v tele intannho kontruktora odvodenej triedy). Uvaujme deklarciu bzovej triedy GrafickObjekt:
class GrafickObjekt { public void Vykresli() { // Zdrojov kd pre vykreslenie grafickho objektu. } }

V alom kroku odvodme od triedy GrafickObjekt nov podtriedu Polygn:


class Polygn : GrafickObjekt { // Telo odvodenej triedy. }

Hoci sme do tela odvodenej triedy nevloili iadne leny, ktor by zavdzali ist funkcionalitu, meme odvoden triedu ihne intanciova a zavola zdeden verejne prstupn intann metdu Vykresli:
static void Main(string[] args) { Polygn esuholnk = new Polygn(); esuholnk.Vykresli(); Console.ReadLine(); }

Vizualizcia vzahu medzi dvomi triedami, ktor bol vybudovan na bze verejnej jednoduchej dedinosti, je zobrazen na obr. 27.

Obr. 27: Vizualizcia vzahu verejnej jednoduchej dedinosti medzi triedami


73

Objektovo orientovan programovanie v jazyku C# 3.0

Odvoden trieda sa nemus uspokoji len so zdedenou funkcionalitou, ale smie alej vylepova svoje schopnosti:
class Polygn : GrafickObjekt { public void Posun(Vektor v) { // Zdrojov kd uskutoujci translciu polygnu. } }

Deklarciu odvodenej triedy sme rozrili o definciu verejne prstupnej intannej parametrickej metdy Posun, ktor doke uskutoni translciu polygnu22. Pouitie modifikovanej triedy Polygn pribliuje nasledujci fragment zdrojovho kdu:
static void Main(string[] args) { Polygn esuholnk = new Polygn(); esuholnk.Posun(new Vektor(10, 2, 3)); Console.ReadLine(); }

2.5 Abstraktn triedy


Abstraktn trieda je v programovacom jazyku C# 3.0 trieda, ktor nie je mon poui v procese intancicie. Nie je teda mon zaklada intancie abstraktnej triedy. Abstraktn trieda vystupuje v pozcii bzovej triedy, od ktorej mu by v procese verejnej jednoduchej dedinosti odvodzovan nov podtriedy. Zskan podtriedy mu by bu znova abstraktn, alebo intann. Ak je podtrieda bzovej abstraktnej triedy intannho charakteru, doke produkova svoje intancie. V deklarcii abstraktnej triedy sa vyskytuje modifiktor abstract:
[M] abstract class X { // Telo abstraktnej triedy. }

kde: [M] je prstupov modifiktor abstraktnej triedy. X je identifiktor abstraktnej triedy.

22

Formlny parameter metdy prijma intanciu hodnotovej truktry Vektor, ktor uchovva sradnice vektora, pomocou ktorho bude grafick objekt posunut.

74

Objektovo orientovan programovanie v jazyku C# 3.0

Pre abstraktn triedy platia tieto zsady: 1. leny abstraktnej triedy (metdy a vlastnosti) mu by abstraktn alebo intann. 2. Abstraktn len abstraktnej triedy je implicitne virtulny. 3. Abstraktn len je v tele abstraktnej triedy iba deklarovan, jeho defincia sa objavuje a v tele intannej podtriedy, ktor je od bzovej abstraktnej triedy odvoden. Pozrime sa na deklarciu abstraktnej triedy Bankovet:
// Deklarcia abstraktnej triedy. public abstract class Bankovet { // Deklarcia 1. abstraktnej metdy. public abstract void Vloi(uint suma); // Deklarcia 2. abstraktnej metdy. public abstract void Uhradi(uint suma); // Deklarcia abstraktnej skalrnej vlastnosti, ktor je uren // len na tanie. public abstract uint Stav { get; } }

V tele naej abstraktnej triedy sa nachdzaj vhradne abstraktn leny: dve abstraktn metdy a jedna abstraktn skalrna vlastnos. Je dleit poukza na skutonos, e abstraktn leny abstraktnej triedy s zavdzan len prostrednctvom svojich deklaranch prkazov (prototypov). Keby sme chceli do tela deklarovanej abstraktnej triedy umiestni defincie abstraktnch lenov, kompiltor by ns zastavil s hlsenm udvajcim nemonos uskutonenia takejto opercie. Na druh stranu, v deklarcii abstraktnej triedy sa mu nachdza aj neabstraktn leny. Pritom plat, e akkovek neabstraktn len vyskytujci sa v tele abstraktnej triedy mus by v tejto triede riadne definovan. Od deklarovanej abstraktnej triedy odvodme intann triedu BenBankovet:
// Deklarcia podtriedy abstraktnej triedy. public class BenBankovet : Bankovet { // Defincie skromnch dtovch poloiek triedy. private uint stav, minimlnyZostatok; private string slo, majite; // Defincia parametrickho intannho kontruktora. public BenBankovet(string slo, string majite, uint minimlnyZostatok, uint poiatonVklad) {

75

Objektovo orientovan programovanie v jazyku C# 3.0


this.slo = slo; this.majite = majite; this.minimlnyZostatok = minimlnyZostatok; stav += poiatonVklad; } // Defincia 1. prekrvajcej intannej metdy. public override void Vloi(uint suma) { stav += suma; } // Defincia 2. prekrvajcej intannej metdy. public override void Uhradi(uint suma) { if (!((int)stav - (int)suma < minimlnyZostatok)) stav -= suma; } // Defincia prekrvajcej intannej skalrnej vlastnosti. public override uint Stav { get { return this.stav; } } }

Vetky zdeden abstraktn leny abstraktnej bzovej triedy s v tele intannej odvodenej triedy explicitne prekryt. To je nevyhnutn predpoklad na to, aby sme jednotliv implementovan leny mohli obdari poadovanou aplikanou logikou. Kee deklarovan podtrieda je intannho charakteru, meme vytvori jej intanciu (bankov et) a vykona niekoko bankovch transakci:
class Program { static void Main(string[] args) { // Intancicia podtriedy. BenBankovet et = new BenBankovet("1234567", "Jonatn Vesel", 500, 5000); // Prv vklad peaz na bankov et. et.Vloi(10000); // Prv hrada peaz z bankovho tu. et.Uhradi(4000); // Druh hrada peaz z bankovho tu. et.Uhradi(12000); Console.WriteLine("Stav na te: {0} USD.", et.Stav); Console.Read(); } }

Po spusten programu zistme, e aktulny stav na naom benom bankovom te je 11000 USD. To je spsoben odmietnutm poslednej transakcie z dvodu prekroenia minimlneho zostatku na bankovom te. Vizualizcia vzahu medzi bzovou abstraktnou triedou a intannou odvodenou triedou je znzornen na obr. 28.
76

Objektovo orientovan programovanie v jazyku C# 3.0

Obr. 28: Vzah medzi bzovou abstraktnou triedou a odvodenou intannou triedou

2.6 Zapeaten triedy


Zapeaten trieda je v programovacom jazyku C# 3.0 trieda, ktor nie je mon poui ako bzov triedu v procese verejnej jednoduchej dedinosti. Nie je teda mon vytvra podtriedy zapeatenej triedy. Hoci od zapeatenej triedy nemono dedi, jej schopnos generova intancie nie je nijakm spsobom obmedzen. Ako zapeaten s zvyajne deklarovan triedy, ktor disponuj plnou funkcionalitou. V deklarcii zapeatenej triedy sa vyskytuje modifiktor sealed:
[M] sealed class X { // Telo zapeatenej triedy. }

kde: [M] je prstupov modifiktor zapeatenej triedy.


77

Objektovo orientovan programovanie v jazyku C# 3.0

X je identifiktor zapeatenej triedy. Nasleduje deklarcia zapeatenej triedy NovFormulr:


using System; using System.Windows.Forms; using System.IO; namespace diz { // Deklarcia zapeatenej triedy. public sealed class NovFormulr : Form { // Defincie skromnch dtovch poloiek triedy. private const int WM_CREATE = 0x0001; private const int WM_CLOSE = 0x0010; private const int WM_SIZE = 0x0005; private StreamWriter sw; // Defincia intannho kontruktora triedy. public NovFormulr() { sw = new System.IO.StreamWriter (Application.StartupPath + "\\Sbor.txt"); sw.WriteLine("***** ZZNAMNK SPRV OPERANHO " + "SYSTMU *****"); sw.WriteLine("------- Zaiatok zznamu -------"); } // Defincia prekrvajcej metdy WndProc. protected override void WndProc(ref Message m) { switch (m.Msg) { // Zachytenie sprvy WM_CREATE. case WM_CREATE: sw.WriteLine("Okno aplikcie bolo vytvoren " + " (as [" + DateTime.Now.Hour + ":" + DateTime.Now.Minute + ":" + DateTime.Now.Second + "], sprva " + "WM_CREATE)."); break; // Zachytenie sprvy WM_SIZE. case WM_SIZE: // Ak bolo okno aplikcie minimalizovan... if ((int)(m.WParam) == 1) sw.WriteLine("Okno aplikcie bolo " + "minimalizovan (as [" + DateTime.Now.Hour + ":" + DateTime.Now.Minute + ":" + DateTime.Now.Second + "], sprva " + "WM_SIZE; WParam == 1)."); // Ak prilo k maximalizcii okna aplikcie... else if ((int)(m.WParam) == 2) sw.WriteLine("Okno aplikcie bolo " + "maximalizovan (as [" + DateTime.Now.Hour + ":" + DateTime.Now.Minute + ":" + DateTime.Now.Second + "], sprva " + "WM_SIZE; WParam == 2).");

78

Objektovo orientovan programovanie v jazyku C# 3.0


break; // Zachytenie sprvy WM_CLOSE. case WM_CLOSE: sw.WriteLine("Okno aplikcie bolo uzatvoren " + " (as [" + DateTime.Now.Hour + ":" + DateTime.Now.Minute + ":" + DateTime.Now.Second + "], sprva " + "WM_CLOSE)."); sw.WriteLine("------- Koniec zznamu -------"); sw.Close(); break; } // Volanie metdy WndProc bzovej triedy. base.WndProc(ref m); } // Defincia metdy Zobrazi, ktor zabezpeuje // zviditenenie okna aplikcie na obrazovke potaa. public void Zobrazi() { this.Show(); } } }

Intancie deklarovanej zapeatenej triedy bud psobi ako formulre, ktor doku monitorova priebehy vybratch akci svojich ivotnch cyklov. Predmetom zznamu bud tieto akcie: vytvorenie formulra, minimalizovanie formulra, maximalizovanie formulra a uzatvorenie formulra. Ke nastane ktorkovek z vymenovanch akci, jej asov vskyt sa ulo do externho textovho sboru. Komunikcia medzi operanm systmom a formulrom je uskutoovan na bze mechanizmu sprv. Ak djde k uritej udalosti, operan systm pod formulru informciu o vzniku udalosti zaslanm sprvy. Tto sprvu nsledne filtruje procedra okna formulra, ktor rozhodne, ak bude reakcia na prjem prslunej sprvy. Diagram zapeatenej triedy je zobrazen na obr. 29.

Obr. 29: Diagram zapeatenej triedy


79

Objektovo orientovan programovanie v jazyku C# 3.0

Intanciciu zapeatenej triedy meme realizova naprklad v tele spracovatea udalosti Click tlaidla, ktor sa nachdza na hlavnom aplikanom formulri:
private void btnZobraziFormulr_Click(object sender, EventArgs e) { // Generovanie novej intancie zapeatenej triedy (novho formulra). NovFormulr nf = new NovFormulr(); nf.Zobrazi(); }

Obsah textovho sboru s informciami o priebehu ivotnho cyklu formulra meme vidie na obr. 30.

Obr. 30: Monitoring ivotnho cyklu formulra ako intancie zapeatenej triedy

2.7 Parcilne triedy


V programovacom jazyku C# 3.0 smieme deklarciu triedy rozdeli do viacerch fragmentov, priom tieto fragmenty mu by uloen v rznych zdrojovch sboroch zostavenia aplikcie .NET. Ak je trieda deklarovan takmto spsobom, nazvame ju parcilnou. Pri preklade musia by vetky zdrojov sbory s jednotlivmi deklaranmi fragmentmi parcilnej triedy dostupn a viditen, pretoe kompiltor z nich zostav finlnu deklarciu parcilnej triedy. V deklaranch fragmentoch parcilnej triedy sa vyskytuje modifiktor partial:
[M] partial class X { // 1. fragment parcilnej triedy. } [M] partial class X { // 2. fragment parcilnej triedy. }

80

Objektovo orientovan programovanie v jazyku C# 3.0

kde: [M] je prstupov modifiktor parcilnej triedy. X je identifiktor parcilnej triedy. Zostavenie finlnej deklarcie parcilnej triedy z deklaranch fragmentov je schematicky znzornen na obr. 31.

Obr. 31: Generovanie finlnej deklarcie parcilnej triedy a jej intancicia Nasleduje praktick ukka deklarcie parcilnej triedy Doktorand. Zdrojov kd parcilnej triedy je rozdelen na dve asti, z ktorch kad je uloen v samostatnom zdrojovom sbore. Deklaran fragment parcilnej triedy uloen v sbore Program.cs:
namespace ParcilneTriedy { // 1. deklaran fragment parcilnej triedy. internal partial class Doktorand { private string meno, priezvisko; private byte kredityZaVedeckinnos; public Doktorand(string meno, string priezvisko, byte kredityZaVedu) { this.meno = meno;

81

Objektovo orientovan programovanie v jazyku C# 3.0


this.priezvisko = priezvisko; this.kredityZaVedeckinnos = kredityZaVedu; } } }

Deklaran fragment parcilnej triedy uloen v sbore PT2.cs:


using System; namespace ParcilneTriedy { // 2. deklaran fragment parcilnej triedy. internal partial class Doktorand { public void ZapsaSaNaDizertanSkku() { if (this.kredityZaVedeckinnos < 180) Console.WriteLine("Nemete sa zapsa na " + "dizertan skku."); else Console.WriteLine("Boli ste zapsan na " + "dizertan skku."); } } }

Intancicia parcilnej triedy prebieha poda tandardnch pravidiel v tele hlavnej metdy Main:
class Program { static void Main(string[] args) { // Intancicia parcilnej triedy. Doktorand d1 = new Doktorand("Jn", "Hornk", 190); d1.ZapsaSaNaDizertanSkku(); Console.Read(); } }

Pri zobrazovan grafickch diagramov parcilnych tried pracuje Nvrhr tried tak, e najskr vyhotov finlnu deklarciu parcilnej triedy a a potom zobraz jej vizulny obraz.

82

Objektovo orientovan programovanie v jazyku C# 3.0

Obr. 32: Vizualizcia parcilnej triedy vo vizulnom Nvrhrovi tried

2.8 Statick triedy


Ponc verziou 2.0 programovacieho jazyka C# je mon v zdrojovom kde vytvra statick triedy. V deklaranom prkaze statickej triedy sa nachdza modifiktor static:
internal static class X { // Telo statickej triedy. }

Statick trieda me obsahova iba defincie statickch lenov, ako s statick dtov poloky, statick kontruktor, statick metdy i statick vlastnosti. Pre kad statick triedu platia nasledujce pravidl: 1. 2. 3. 4. Statick trieda neme by intanciovan. Statick trieda neme psobi ako bzov trieda. Statick trieda je implicitne zapeaten. Statick trieda nesmie obsahova defincie intannho kontruktora a finalizra.

Pokraujeme uvedenm zdrojovho kdu statickej triedy, ktor implementuje funkcionalitu pre vykresovanie rastrovch bitovch mp23:
// Deklarcia statickej triedy. static class Obrzok { // Defincia skromnej statickej dtovej poloky. private static Image bitovMapa; // Defincia statickho kontruktora. static Obrzok() {
23

Predstaven zdrojov kd statickej triedy predpoklad, e je direktvou using zaveden menn priestor System.Drawing.

83

Objektovo orientovan programovanie v jazyku C# 3.0


bitovMapa = null; } // Defincia statickej metdy. public static void Vykresli(string cesta, Graphics grafickObjekt) { bitovMapa = Image.FromFile(cesta); grafickObjekt.DrawImage(bitovMapa, new Point(10, 10)); bitovMapa.Dispose(); } }

V tele statickej triedy nie s umiestnen iadne in leny, len statick. Parametrick statick metda prijma absoltnu cestu k fyzickmu sboru s rastrovmi dtami, rovnako ako aj odkaz na intanciu triedy Graphics (tto intancia psob ako primrny grafick objekt, prostrednctvom ktorho s realizovan grafick opercie svisiace s plochou aplikanho formulra). Dta rastrovej bitovej mapy natame do intancie triedy Image z mennho priestoru System.Drawing. Vimnime si, e s natanm dt nm pomha parametrick metda FromFile triedy Image, ktor je sama statick. Metda FromFile vytvor intanciu triedy Image a vrti odkaz, ktor ukladme do definovanej odkazovej premennej. Za vykreslenie bitovej mapy na plochu aplikanho formulra je zodpovedn intann metda DrawImage primrneho grafickho objektu. Metde DrawImage musme odovzda dva artefakty: 1. Odkaz na intanciu triedy Image, v ktorej je uchovan bitov mapa. 2. Intanciu hodnotovej truktry Point, ktor determinuje sradnice bodu, na ktorom zane vykresovanie bitovej mapy. Sradnice bodu, ktor je reprezentovan intanciou truktry Point, bud toton so sradnicami avho hornho rohu obdnikovho reginu, do ktorho bude bitov mapa vykreslen. Ak vetky opercie prebehn spene, na aplikanom formulri sa objav poadovan bitov mapa. Podotknime, e statick metda nezavdza truktrovan sprvu chb, a teda nepriamo oakva, e jej bud dodan korektn argumenty. Kee po vykreslen bitovej mapy s ou u neplnujeme alej manipulova, meme systmov zdroje asociovan s intanciou triedy Image uvoni volanm metdy Dispose. Praktick pouitie statickej triedy je vemi jednoduch, pretoe nemusme pracova so iadnymi objektmi. Jednoducho vyjadrme n zmer spusti statick metdu:
private void btnVykresliBitovMapu_Click(object sender, EventArgs e) { // Aktivcia statickej metdy statickej triedy. Obrzok.Vykresli(@"c:\Lesn kvety.jpg", this.CreateGraphics()); }

84

Objektovo orientovan programovanie v jazyku C# 3.0

Statick metdu volme v spojen so statickou triedou. Prvm odovzdvanm argumentom je doslovn textov reazec (doslovnos je indikovan symbolom @ zapsanm pred reazcom) charakterizujci absoltnu cestu k sboru s bitovou mapou. Druhm argumentom je odkaz na primrny grafick objekt, ktor je spojen s aktulnym aplikanm formulrom (aktulnou intanciou triedy Form).

2.9 Anonymn triedy a inicializtory intanci anonymnch a pomenovanch tried


Pri objektovo orientovanom programovan v jazyku C# 3.0 mu vvojri pracova s dvoma zkladnmi typmi tried. Ide o pomenovan a anonymn triedy. Pomenovan trieda je kad trieda, ktor je sprvne deklarovan a disponuje svojm identifiktorom. Vetky triedy, ktor deklaruj programtori, patria k pomenovanm triedam. Na druh stranu, ponajc verziou 3.0 jazyka C# 3.0 meme vytvra aj anonymn triedy. Pre anonymn triedy platia nasledujce pravidl: Anonymn triedu nedeklaruje programtor, ale kompiltor. Na zklade syntaktickho predpisu zostroj kompiltor kompletn deklarciu anonymnej triedy. Anonymn trieda nem identifiktor, ktor by bol priamo prstupn pre programtora. Kee vvojr nepozn identifiktor implicitne vygenerovanej triedy, tto trieda sa mu jav ako anonymn. Hoci z pohadu programtora je kompiltorom zostaven trieda naozaj anonymn, povaujeme za dleit podotkn, e aj anonymn trieda m svoj identifiktor. Ten je vak vytvran automaticky kompiltorom, take preklada je ten, ktor samoinne prisudzuje nzov anonymnej triede. Spravidla neexistuje iaden zmyslupln dvod, aby sa vvojr pokal zska identifiktor anonymnej triedy24. Navye, identifiktor anonymnej triedy sa me li v rznych prekladovch relcich. Intancicia anonymnej triedy sa realizuje opertorom new. Po spenej intancicii vracia opertor new odkaz na alokovan a inicializovan intanciu anonymnej triedy. Vrten odkaz bude uloen do odkazovej premennej, ktorej dtov typ bude musie by kompiltorom implicitne inferovan. Nevyhnutnos aktivcie mechanizmu typovej inferencie je podmienen neznalosou identifiktora anonymnej triedy.

24

Napriek tomu, e nejde o tandardn programov operciu, je mon identifiktor anonymnej triedy zisti pomocou mechanizmu reflexie. Reflexia je proces dynamickej analzy dtovch typov uloench v zostaven aplikcie .NET.

85

Objektovo orientovan programovanie v jazyku C# 3.0

Intancia anonymnej triedy je inicializovan pomocou mnoiny tzv. inicializtorov intanci anonymnch tried. Inicializtory s hodnoty, ktormi bud inicializovan automaticky generovan skromn dtov poloky intancie anonymnej triedy. Okrem prpravy spravy dtovch poloiek zostrojuje kompiltor aj kolekciu verejne prstupnch skalrnych intannch vlastnost, ktor slia na prstup k skromnm dtovm polokm. Medzi potom automaticky vygenerovanch skromnch dtovch poloiek a potom verejne prstupnch skalrnych intannch vlastnost existuje relcia typu 1:1. Je vak nutn si uvedomi, e verejne prstupn skalrne intann vlastnosti, ktor s do tela anonymnej triedy umiestnen, slia len na tanie hodnt skromnch dtovch poloiek. V telch tchto vlastnost absentuje vetva set, a preto nemu by pouit na modifikciu hodnt dtovch poloiek. Veobecn vzor, opisujci intanciciu anonymnej triedy, je takto:
var obj = new {SIV1 = IN1, SIV2 = IN2, ..., SIVN = INN};

kde: SIV1...N s identifiktory verejne prstupnch skalrnych intannch vlastnost anonymnej triedy. IN1...N s inicializtory. Zoznmme sa s fragmentom zdrojovho kdu jazyka C# 3.0, v ktorom dochdza k intancicii anonymnej triedy:
// Intancicia anonymnej triedy. var obj = new { Kniha = "C# - praktick pklady", Autor = "Jn Hank", Vydavate = "Grada Publishing", RokVydania = 2006, PoetStrn = 288, ISBN = "80-247-0988-0" };

Vzhadom na to, e opertor new nie je nasledovan iadnym identifiktorom triedy, kompiltor doke usdi, e bude musie zostavi deklarciu anonymnej triedy. Postupuje teda tak, e vytvor hlaviku a telo triedy. Triedu samozrejme pomenuje, aby sa mohol na u priamo odkazova. Kompiltor alej pokrauje definciou estice skromnch dtovch poloiek, ktor bud uchovva dta intancie anonymnej triedy. Po zhotoven dtovch poloiek vytvor kompiltor rovnak poet verejne prstupnch skalrnych intannch vlastnost urench len na tanie. Okrem u spomenutch lenov vlo kompiltor do tela anonymnej triedy aj parametrick intann kontruktor. Je to prve tento kontruktor, ktor je zodpovedn za korektn inicializciu zaloenej intancie anonymnej triedy poda pokynov programtora. Po spenej
86

Objektovo orientovan programovanie v jazyku C# 3.0

intancicii bude intancia anonymnej triedy alokovan na riadenej halde a nleite inicializovan. Opertor new nm poskytne odkaz na vytvoren intanciu, ktor ukladme do odkazovej premennej s identifiktorom obj. Dodajme, e dtov typ premennej obj je za prispenia mechanizmu typovej inferencie automaticky uren. Ak budeme chcie vypsa na obrazovku potaa informcie o knihe, pouijeme automaticky vygenerovan verejne prstupn skalrne intann vlastnosti:
Console.WriteLine("Informcie o knihe:\n" + "Nzov: " + obj.Kniha + "\nAutor: " + obj.Autor + "\nVydavate: " + obj.Vydavate + "\nRok vydania: " + obj.RokVydania + "\nPoet strn: " + obj.PoetStrn + "\nISBN: " + obj.ISBN);

Inicializtory intanci tried smieme vyui aj pri zakladan intanci pomenovanch tried. Najskr uvdzame deklarciu pomenovanej triedy, ktor budeme vzpt potrebova pri praktickej ukke inicializtorov:
class Kniha { private string nzov, autor, vydavate, isbn; private ushort rokVydania, poetStrn; public string Nzov { get { return nzov; } set { nzov = value; } } public string Autor { get { return autor; } set { autor = value; } } public string Vydavate { get { return vydavate; } set { vydavate = value; } } public ushort RokVydania { get { return rokVydania; } set { rokVydania = value; } } public ushort PoetStrn { get { return poetStrn; } set { poetStrn = value; } } public string ISBN { get { return isbn; } set { isbn = value; } } }

87

Objektovo orientovan programovanie v jazyku C# 3.0

Syntaktick skladba triedy je vemi jednoduch. Inicializtory nm umonia efektvne skontruova pouiten intanciu triedy:
// Inicializcia intancie triedy pomocou inicializtorov. Kniha kniha = new Kniha() { Nzov = "C# - praktick pklady", Autor = "Jn Hank", Vydavate = "Grada Publishing", RokVydania = 2006, PoetStrn = 288, ISBN = "80-247-0988-0" };

Intancicia triedy sa riadi tmto predpisom: 1. Najskr je na riadenej halde alokovan pamov priestor pre intanciu triedy. 2. Dochdza k spusteniu kontruktora. O tom, ak kontruktor to bude, rozhoduje syntaktick znenie intancianho prkazu. Ak sa pozrieme na pouitie opertora new, tak vidme, e pri intancicii sme pouili vraz new Kniha(). Alokovan intancia triedy bude preto inicializovan bezparametrickm implicitnm intannm kontruktorom. Kontruktor je implicitn preto, e ho vytvra automaticky kompiltor. (Pripomeme, e tto akciu kompiltor uskutouje vdy, ke nie je v tele triedy explicitne definovan iaden intann kontruktor.) 3. Po spracovan kontruktora je zahjen inicializcia predpsan inicializtormi. Pomocou verejne prstupnch skalrnych intannch vlastnost zskame prstup k skromnm dtovm polokm intancie triedy a ulome do nich hodnoty inicializtorov. 4. Odkaz na alokovan a inicializovan intanciu triedy je uloen do odkazovej premennej. Z preskmanho pracovnho modelu inicializtorov intanci tried jasne vidme, e tieto programov entity nepreberaj funkciu kontruktora, len ju dopaj. Ak by pomenovan trieda, ktorej intanciu chceme zska, definovala adekvtny parametrick kontruktor, tak by sme mohli primrne vyui ten a nemuseli by sme sa spolieha na inicializtory. Naopak, s vhodou meme inicializtory upotrebi pri tch triedach, ktor iaden kontruktor nedefinuj (o je prpad aj naej vyie uvedenej triedy). Aj ke kompiltor automaticky zostav bezparametrick intann kontruktor, ten ponka len tandardn25, v iadnom prpade nie pouvatesky konfigurovaten, inicializciu dtovej sekcie objektu.
25

tandardnou inicializciou mme na mysli uvedenie dtovch poloiek intancie triedy do vchodiskovho stavu. Dtov poloky primitvnych integrlnych hodnotovch dtovch typov bud inicializovan nulami. Dtov poloky primitvnych relnych hodnotovch dtovch typov bud inicializovan rovnako nulami, len

88

Objektovo orientovan programovanie v jazyku C# 3.0

2.10 Polymorfizmus implementovan pomocou verejnej jednoduchej dedinosti


Polymorfizmus determinuje schopnos objektov reagova inak na prjem identickej sprvy. V programovacom jazyku C# 3.0 me by polymorfizmus implementovan dvomi spsobmi: 1. Polymorfizmus implementovan pomocou verejnej jednoduchej dedinosti. 2. Polymorfizmus implementovan pomocou rozhrania. V tejto kapitole sa budeme venova vkladu prvho variantu, a teda polymorfizmu implementovanho pomocou verejnej jednoduchej dedinosti. Podstata polymorfizmu v tomto vyjadren spova v prekryt zdedenho lena bzovej triedy v triede odvodenej. Zdeden len bzovej triedy meme prekry rovnakm druhom lena, ktor bude disponova odlinou funkcionalitou. Aby sme mohli v odvodenej triede prekry zdeden implementciu lena bzovej triedy, mus by takto len v bzovej triede definovan ako virtulny. Pre nae alie potreby budeme uvaova o metde ako o lene triedy, s ktorm budeme pracova. Ke v tele bzovej triedy definujeme virtulnu metdu, vysielame kompiltoru signl, e tto metda bude mc by v odvodenej triede prekryt. Ak m by ist metda bzovej triedy virtulna, mus sa v jej hlavike nachdza modifiktor virtual. Generick syntaktick ukka deklarcie bzovej triedy s jednou virtulnou metdou:
class A { public virtual void m() { // Implementcia virtulnej metdy bzovej triedy. } }

Metda m bzovej triedy A je explicitne virtulna, o znamen, e odvoden trieda bude mc v prpade zujmu prekry zdeden implementciu tejto virtulnej metdy. V programovacom jazyku C# 3.0 nie s intann metdy tried implicitne virtulne. Implicitn virtualita intannch metd je prirodzen naprklad pre jazyk Java, v ktorom ke zavedieme do tela triedy definciu metdy, je automaticky (implicitne) povaovan za virtulnu. V jazyku C# 3.0 vak nie je implicitnou technikou prekrvanie, ale ukrvanie zdedench lenov bzovej triedy. Preto ak chceme uplatni prekrytie zdedenej intannej metdy bzovej triedy, mus by takto metda virtulna.
v relnej reprezentcii s jednoduchou alebo dvojnsobnou presnosou. Dtov poloky logickho hodnotovho dtovho typu bool bud inicializovan logickou nepravdou (false). Dtov poloky znakovho hodnotovho dtovho typu char bud inicializovan nulovmi znakmi. Dtov poloky primitvnych odkazovch dtovch typov (string a object) bud inicializovan nulovmi odkazmi (hodnotami null).

89

Objektovo orientovan programovanie v jazyku C# 3.0

V tele odvodenej triedy definujeme rovnomenn metdu s modifiktorom override:


class B : A { public override void m() { // Implementcia intannej metdy odvodenej triedy, // ktor prekrva rovnomenn zdeden metdu bzovej triedy. } }

Prekrvajca metda odvodenej triedy s modifiktorom override mus s prekrvanou (virtulnou) metdou bzovej triedy zhodn v tchto aspektoch: signatra (identifiktor a zoznam formlnych parametrov), dtov typ nvratovej hodnoty, prstupov modifiktor. Implementcia prekrvajcej metdy bude samozrejme odlin.

by

O tom, ktor metda bude v svislosti so zaloenou intanciou aktivovan, rozhoduje pri polymorfizme implementovanom pomocou verejnej jednoduchej dedinosti typ zrodenej intancie. Preskmajme nasledujci fragment zdrojovho kdu jazyka C# 3.0:
A obj = new B(); obj.m();

Rozoberme prv intancian prkaz. V tomto prkaze definujeme odkazov premenn s identifiktorom obj. Do tejto odkazovej premennej je mon uloi objektov referenciu na intanciu bzovej triedy A. My vak aplikujeme opertor new na odvoden triedu, o znamen, e vytvrame jej intanciu. Len o je dokonen proces intancicie odvodenej triedy, opertor new vracia v podobe svojej nvratovej hodnoty objektov referenciu na vytvoren intanciu odvodenej triedy. Tto objektov referenciu je vak mon uloi aj do odkazovej premennej, ktorej typom je bzov trieda. Je to preto, e medzi triedami A a B existuje puto vybudovan na zklade verejnej jednoduchej dedinosti, priom B je odvodenou triedou a A je bzovou triedou. Intancian prkaz verifikuje korektnos tvrdenia, poda ktorho sa potomok me vyskytn vade tam, kde je oakvan jeho rodi. Z tohto titulu je mon do odkazovej premennej s typom bzovej triedy uloi objektov referenciu na intanciu odvodenej triedy. Druh prkaz predstavuje volanie verejne prstupnej intannej metdy m. Kee sme povedali, e o tom, ktor metda bude aktivovan, rozhoduje typ zrodenej intancie, tak mus by zrejm, e tento prkaz vol prekrvajcu metdu intancie odvodenej triedy. A to aj napriek tomu, e na vyvolanie metdy sme pouili odkazov premenn, ktorej typom je bzov trieda.
90

Objektovo orientovan programovanie v jazyku C# 3.0

2.11 Polymorfizmus implementovan pomocou rozhrania


Druh spsob, poda ktorho je mon navrhn polymorfn sprvanie intanci tried v jazyku C# 3.0, reprezentuje odlin implementcia identickho rozhrania viacermi triedami. Aby sme vak mohli kvalifikovane hovori o implementcii polymorfizmu prostrednctvom rozhrania, musme sa najskr zoznmi s pojmom rozhranie a jeho chpanm v jazyku C# 3.0. Rozhranie je predpis vymedzujci tl sprvania sa entt, ktor sa rozhodn prslun rozhranie implementova. V jazyku C# 3.0 je rozhranie deskriptorom, ktor zdruuje mnoinu deklaranch prkazov metd, vlastnost, udalost a delegtov. Rozhranie sce charakterizuje leny prostrednctvom deklaranch prkazov, no u nedefinuje ich implementciu26. Vetky leny deklarovan v rozhran bud definovan v triede, ktor sa rozhodne dan rozhranie implementova. Povedan inak, rozhranie vrav o sa m urobi, avak u nezmieuje konkrtny spsob ako sa to m urobi. Rozhranie deklarujeme poda nasledujceho generickho modelu:
[M] interface IRozhranie { // Deklarcie lenov rozhrania. }

kde: [M] je prstupov modifiktor, ktor uruje prstupov prva jednak samotnho rozhrania, a taktie aj lenov, ktor rozhranie deklaruje27. IRozhranie je identifiktor rozhrania28. Uvaujme deklarciu rozhrania IPotaovGrafika:
public interface IPotaovGrafika { void VykonaGrafickTransformciu(string zdrojovBitmapa, string cieovBitmapa); }

26

Z pohadu jazyka C++ by sme mohli poveda, e rozhranie je sborom prototypov lenov bez vopred naprogramovanej funkcionality. Deklaran prkazy, resp. prototypy, charakterizuj signatry lenov rozhrania, no abstrahuj od konkrtnej funkcionality tchto lenov. 27 Pokia nie je explicitne uren iaden prstupov modifiktor rozhrania, tak je rozhranie deklarovan s implicitne internmi prstupovmi prvami (ako keby bol aplikovan modifiktor internal). 28 Poda odporania vhodnch nomenklatrnych smernc sa rozhrania v jazyku C# 3.0 (a podobne aj vo vetkch ostatnch .NET-kompatibilnch programovacch jazykoch) pomenvaj so zaiatonm psmenom I (z angl. Interface). Hoci nie je obligatrna, budeme tto pomenovaciu zsadu uplatova v celej publikcii. Je to koniec koncov programtorsky prvetiv, pretoe u na zklade identifiktora entity dokeme zisti, i ide o triedu, alebo rozhranie.

91

Objektovo orientovan programovanie v jazyku C# 3.0

Toto rozhranie obsahuje deklarciu jednej verejne prstupnej parametrickej metdy. Ako meme dedukova z nzvu deklarovanej metdy, jej lohou bude spracovanie grafickej transformcie. Predmetom transformcie sa stane bitov mapa, ktorej rastrov dta bud uloen vo vstupnom grafickom sbore. Absoltna cesta k vstupnmu grafickmu sboru bude vo forme reazcovej kontanty uloen do prvho formlneho parametra transformanej metdy. Po spracovan grafickej transformcie bude modifikovan bitov mapa uloen do novho (vstupnho) fyzickho grafickho sboru, ktor pecifikuje druh formlny parameter transformanej metdy. Rozhranie samo osebe predstavuje len predpis, poda ktorho sa bud musie sprva triedy, ktor sa rozhodn dan rozhranie implementova. Implementcia rozhrania IPotaovGrafika triedou Grafika vyzer v jazyku C# 3.0 takto:
// Deklarcia triedy, ktor implementuje rozhranie. class Grafika : IPotaovGrafika { // Defincia metdy, ktor je deklarovan v rozhran. public void VykonaGrafickTransformciu(string zdrojovBitmapa, string cieovBitmapa) { int i, j; // Kontrukcia objektu triedy Bitmap, ktor bude zapuzdrova // rastrov dta natan zo vstupnho grafickho sboru. Bitmap bitovMapa = new Bitmap(zdrojovBitmapa); Color farbaObrazovhoBodu, inverznFarba; // Dvojica cyklov uskutouje inverziu bitovej mapy. for (i = 0; i < bitovMapa.Width; i++) { for (j = 0; j < bitovMapa.Height; j++) { farbaObrazovhoBodu = bitovMapa.GetPixel(i, j); inverznFarba = Color.FromArgb( 255 - farbaObrazovhoBodu.R, 255 - farbaObrazovhoBodu.G, 255 - farbaObrazovhoBodu.B); bitovMapa.SetPixel(i, j, inverznFarba); } } // Po vykonan grafickej transformcie je upraven bitov mapa // uloen do novho grafickho sboru. bitovMapa.Save(cieovBitmapa); // Kee s objektom triedy Bitmap u nebudeme pracova, // meme s nm asociovan zdroje explicitne uvoni. bitovMapa.Dispose(); } }

Zo syntaktickho pohadu sa technika implementcie rozhrania triedou pona na aplikciu verejnej jednoduchej dedinosti. Hoci je stvrnenie zdrojovho kdu identick s dedinosou, v tomto prpade ide o implementciu rozhrania. Ako sme u spomenuli, ak sa trieda rozhodne ist rozhranie implementova, mus prija zvzok definova
92

Objektovo orientovan programovanie v jazyku C# 3.0

vetky leny, ktor prslun rozhranie deklaruje. V naej praktickej ukke obsahuje rozhranie len jednu metdu, ktorej definciu deklarovan trieda zavdza. Zdrojov kd umiestnen v tele metdy VykonaGrafickTransformciu realizuje inverziu vstupnej bitovej mapy. Po vykonan inverzie je transformovan bitov mapa uloen do vstupnho grafickho sboru. Grafick modely rozhrania a implementujcej triedy zobrazen v Nvrhrovi tried s znzornen na obr. 33.

Obr. 33: Vizulny model rozhrania a implementujcej triedy Algoritmus vykonvajci inverziu bitovej mapy pracuje nasledujcim spsobom: 1. Pre kad obrazov bod, ktor je sasou bitovej mapy, je njden jeho farebn vektor. Farebn vektor je vyjadren v priestore RGB, priom je tvoren usporiadanou trojicou hodnt (zloiek). Zloky farebnho vektora podvaj informcie o intenzite zastpenia troch farebnch zloiek: R erven, G zelen a B modr. Intenzita zastpenia ervenej, zelenej a modrej zloky v konenom dsledku uruje intenzitu vslednej farby, ktorou bude obrazov bod vykreslen na obrazovke potaa. Intenzita zastpenia zloiek farebnch vektorov je bene kvantifikovan pomocou celoselnej alebo relnej stupnice hodnt. Pri celoselnej stupnici me intenzita zloky farebnho vektora nadobda hodnoty z intervalu <0, 255>. Pri relnej stupnici sa zasa pouva interval <0, 1>. Naprklad, obrazov bod s maximlnou intenzitou svojich zloiek disponuje farebnm vektorom v tvare [255, 255, 255] (v celoselnom vyjadren), resp. [1, 1, 1] (v relnom vyjadren). Zo vetkch obrazovch bodov bitovej mapy vyberieme jeden, s ktorm budeme alej pracova. Nech sa vybrat obrazov bod vol a nech jeho farebn vektor m nasledujce zloenie: . Prijmime dohovor, e zloky farebnho vektora analyzovanho obrazovho bodu budeme kvantifikova pomocou celoselnej stupnice hodnt.
93

Objektovo orientovan programovanie v jazyku C# 3.0

2. Pri inverzii s zloky farebnho vektora obrazovho bodu transformovan tak, e vznikne nov obrazov bod s transformovanm (invertovanm) farebnm vektorom. Ak invertovanmu obrazovmu bodu prisdime identifiktor , tak potom vpoet jeho farebnho vektora stanovuje nasledujci matematick vzah:

Ukme si prklad: Nech je vstupn obrazov bod vykreslen odtieom ervenej farby s farebnm vektorom [237, 28, 36]. Po inverzii zskame nov farebn vektor [18, 227, 219], ktor predstavuje tyrkysov farbu. 3. Algoritmus teda pracuje tak, e najskr ur farebn vektory obrazovch bodov a potom ich prevedie na ich inverzn ekvivalenty. Grafick transformcia sa uskutouje na bze obrazovho bodu, o znamen, e finlny invertovan obraz nezskame skr, ne bud grafickej transformcii podroben vetky obrazov body, z ktorch je editovan bitov mapa zloen. Ak poet obrazovch bodov bitovej mapy (ako objem vstupnch dt) ozname premennou , tak opercie zistenie aktulneho farebnho vektora, vpoet inverznho farebnho vektora a aplikcia transformovanho farebnho vektora bud musie by spracovan -krt. Pre ben bitov mapu s rozmermi 1024x768 obrazovch bodov to znamen realizciu viac ako 786-tisc grafickch transformci. Vzhadom na to, e natan bitov mapa je v objekte triedy Bitmap uloen vo forme dvojrozmernej dtovej mrieky, ako algoritmicky najjednoduchie rieenie sa jav pouitie dvojice cyklov, pomocou ktorch manipulujeme s farebnmi vektormi jednotlivch obrazovch bodov. Na zistenie pvodnch farebnch vektorov pouvame intann metdu GetPixel objektu triedy Bitmap, km s aplikciou transformovanch farebnch vektorov nm pome metda SetPixel rovnakho objektu. Dodajme, e metdy GetPixel a SetPixel patria k tzv. provm metdam, ktor sa vdy pouvaj spolone. Vo chvli, ke je inverzia farebnch vektorov obrazovch bodov bitovej mapy hotov, volme intann metdu Save objektu triedy Bitmap a modifikovan bitov mapu ukladme do novho fyzickho grafickho sboru. Kee objekt triedy Bitmap u nemienime naalej pouva, meme poiada o explicitn dealokciu systmovch prostriedkov, ktor s s tmto objektom asociovan. Na to nm sli intann metda Dispose29.

29

Volanie metdy Dispose nad objektom triedy Bitmap vak neznamen, e dochdza k likvidcii tohto objektu. Metda Dispose zabezpeuje uvonenie alokovanch prostriedkov, ktor slili najm na uskladnenie rastrovch dt natanej bitovej mapy. Objekt triedy Bitmap je preto aj po aktivcii metdy Dispose stle dosiahnuten z programovho kdu, a teda iv. Programtori by vak takto objekt u nemali naalej pouva, pretoe nie je zaruen jeho dtovo konzistentn stav. Objekt triedy Bitmap (a objekt akejkovek triedy, v svislosti s ktorm smie by zavolan metda Dispose) bude zlikvidovan vo chvli, ke djde

94

Objektovo orientovan programovanie v jazyku C# 3.0

Triedu Grafika s implementovanm rozhranm IPotaovGrafika by sme mohli prakticky poui naprklad takto:
using System.Diagnostics; class Program { static void Main(string[] args) { Grafika g = new Grafika(); Stopwatch sw = new Stopwatch(); sw.Start(); Console.WriteLine("Vykonvam grafick transformciu..."); g.VykonaGrafickTransformciu(@"c:\obr_01.jpg", @"c:\obr_02.png"); sw.Stop(); Console.WriteLine("Grafick transformcia je hotov."); Console.WriteLine("Opercia trvala {0} s.", sw.Elapsed.TotalSeconds); Console.Read(); } }

Spracovanie grafickej transformcie je za prispenia naej triedy vemi jednoduch. Vo chvli, ke mme alokovan a inicializovan intanciu triedy Grafika, zavolme jej verejne prstupn intann metdu VykonaGrafickTransformciu, ktorej odovzdme zmyslupln kolekciu vstupnch argumentov. Program informuje pouvatea nielen o uskutonen grafickej transformcie, ale rovnako aj o nameranom exekunom ase, ktor bol na jej spracovanie potrebn. Exekun as meriame pomocou objektu triedy Stopwatch z mennho priestoru System.Diagnostics. O polymorfizme implementovanom rozhranm vravme vtedy, ak dve triedy zaved odlin implementciu identickho rozhrania. To sa udeje vtedy, ak navrhneme triedu Grafika2, do tela ktorej zavedieme definciu metdy VykonaGrafickTransformciu s odlinou funkcionalitou. Definovan metda triedy Grafika2 bude uskutoova in typ grafickej transformcie my sme zvolili prevod bitovej mapy do sivotnu. Zdrojov kd jazyka C# 3.0, ktor zobrazuje deklarciu triedy, uvdzame alej:
// Deklarovan trieda zavdza odlin implementciu rozhrania. class Grafika2 : IPotaovGrafika { public void VykonaGrafickTransformciu(string zdrojovBitmapa, string cieovBitmapa) { int i, j, I; Bitmap bitovMapa = new Bitmap(zdrojovBitmapa); Color farbaObrazovhoBodu; for (i = 0; i < bitovMapa.Width; i++) { for (j = 0; j < bitovMapa.Height; j++) { farbaObrazovhoBodu = bitovMapa.GetPixel(i, j); k zrueniu aj poslednho odkazu, ktor bol na tento objekt nasmerovan. Potom automatick sprvca pamte finalizuje objekt a odstrni ho z riadenej haldy.

95

Objektovo orientovan programovanie v jazyku C# 3.0


I = (int)(0.299 * farbaObrazovhoBodu.R + 0.587 * farbaObrazovhoBodu.G + 0.114 * farbaObrazovhoBodu.B); bitovMapa.SetPixel(i, j, Color.FromArgb(I, I, I)); } } bitovMapa.Save(cieovBitmapa); bitovMapa.Dispose(); } }

Algoritmus grafickej transformcie je pri prevode obrazu do sivotnu zaloen na vpote intenzity jasu pre farby vykreslen v odtieoch sivej. Vychdzame pritom z matematickho vzorca, ktor reflektuje mieru citlivosti udskho oka na jednotliv zloky farebnch vektorov:

kde: je vsledn intenzita jasu zodpovedajca sivotnovmu obrazu. , a s zloky farebnho vektora spracvanho obrazovho bodu. Predostret matematick rovnica vyjadruje, s akou intenzitou vnma udsk oko jednotliv farebn zloky modelu RGB. Z pouitch multiplikatvnych koeficientov je zrejm, e najcitlivejie je vnman zelen farba (koeficient 0,587), potom erven farba (koeficient 0,299) a nakoniec modr farba (koeficient 0,114). Povedan priamoiarejie, vo farebnom obraze si vmame najviac intenzitu odtieov zelenej farby, o nieo menej s pre ns signifikantn odtiene ervenej farby a vbec najniiu citlivos preukazujeme voi odtieom modrej farby. seln hodnoty modelu RGB, o ktorch sme sa zmienili, nm podvaj informcie o intenzite jasu uritej farby, resp. farebnho odtiea. Naprklad, najjasnejia je bezpochyby biela farba, ktorej farebn vektor m hodnotu [255, 255, 255]. Vyie uveden vzah doke poda vstupnch informci o zlokch farebnho vektora obrazovho bodu (alebo presnejie o intenzite zloiek farebnho vektora) vypota celkov jas, ktor je typick pre obrazov bod vykreslen v sivotne. Cel matematick algoritmus si najlepie objasnme na praktickom prklade. Nadviaeme pritom na predchdzajcu rozpravu o bitovej mape, z ktorej sme si vybrali jeden obrazov bod s nzvom P1. Intenzita jasu tohto obrazovho bodu je determinovan trojicou selnch hodnt zodpovedajcich zlokm jeho farebnho vektora vyjadrench v modeli RGB. Ak s zloky farebnho vektora obrazovho bodu , tak obrazov bod preveden do odtieov sivej bude ma takto seln interpretciu: =

96

Objektovo orientovan programovanie v jazyku C# 3.0

Po vykonan grafickej transformcie u obrazov bod nebude farebn, pretoe jeho intenzita jasu bude prislcha niektormu z odtieov sivej farby.

Obr. 34: Polymorfizmus implementovan pomocou rozhrania Intancie tried Grafika a Grafika2 sa sprvaj polymorfne, pretoe na rovnak podnet (iados o vykonanie grafickej transformcie) reaguj odline (intancia triedy Grafika vyhotov inverzn obraz, zatia o intancia triedy Grafika2 vytvor sivotnov obraz). Zdrojov kd jazyka C# 3.0, ktor intanciuje triedu Grafika2 a vykonva tvorbu sivotnovho obrazu, vyzer takto:
class Program { static void Main(string[] args) { Grafika2 g = new Grafika2(); Stopwatch sw = new Stopwatch(); sw.Start(); Console.WriteLine("Vykonvam grafick transformciu..."); g.VykonaGrafickTransformciu(@"c:\obr_01.jpg", @"c:\obr_03.png"); sw.Stop(); Console.WriteLine("Grafick transformcia je hotov."); Console.WriteLine("Opercia trvala {0} s.", sw.Elapsed.TotalSeconds); Console.Read(); } }

97

Objektovo orientovan programovanie v jazyku C# 3.0

Vizualizciu polymorfnho sprvania intanci tried, ktor zavdzaj odlin implementciu totonho rozhrania uvdzame na obr. 35.

Obr. 35: Schematick demontrcia polymorfnho sprvania intanci tried, ktor zavdzaj odlin implementciu rovnakho rozhrania

2.12 Delegti
Delegt je v jazyku C# 3.0 pouvatesky deklarovan odkazov dtov typ, ktorho intancia doke v sebe zapuzdrova odkaz na cieov intann alebo statick metdu. Len o je intancia delegta prepojen s cieovou metdou, mono dan metdu vyvola nepriamo, prostrednctvom intancie delegta. Poda svojej praktickej aplikcie sa intancia delegta podob na pouitie smernka na funkciu, ktor je znmy z prostredia programovacch jazykov C a C++. Pre njdenie vhodnch analgi medzi smernkmi na funkcie a intanciami delegtov najskr ozrejmme pouitie smernkov na funkcie v jazykoch C/C++, a potom sa budeme sstredi na vklad delegtov v jazyku C# 3.0. V jazykoch C a C++ meme definova pecilnu smernkov premenn, do ktorej smie by uloen smernk na vstupn bod tela istej cieovej funkcie30. Kad funkcia je v rmci fyzickho procesu aplikcie umiestnen na uritej pamovej adrese. Adresa, ktor identifikuje prv prkaz tela funkcie je znma ako adresa vstupnho bodu tela funkcie. Prca so smernkmi na funkcie sa uskutouje poda tejto tridy:

30

Smernky na funkcie s nepomerne zloitejm mechanizmom ako tandardn smernky. V naom ponman budeme za tandardn smernky povaova smernky predstavujce pamov adresy, na ktorch sa nachdzaj objekty neobjektovch alebo objektovch dtovch typov.

98

Objektovo orientovan programovanie v jazyku C# 3.0

1. Defincia smernkovej premennej, do ktorej me by uloen smernk na funkciu. 2. Inicializcia smernkovej premennej smernkom ukazujcim na vstupn bod tela cieovej funkcie31. 3. Nepriama aktivcia cieovej funkcie pomocou smernka na funkciu, ktor je uloen v definovanej smernkovej premennej. Nasledujci definin prkaz jazyka C zaklad nov smernkov premenn, ktor me by inicializovan smernkom na vstupn bod tela funkcie:
int (*p_f)(char *x);

Definovan smernkov premenn sa vol p_f a me by inicializovan smernkom na vstupn bod tela akejkovek cieovej funkcie, ktor vyhovuje tmto kritrim: 1. Funkcia vracia celoseln nvratov hodnotu typu int. 2. Funkcia je parametrick, priom definuje jeden formlny parameter: tmto formlnym parametrom je smernkov premenn typu char*32. Skr, ako meme definovan smernkov premenn inicializova, musme pripravi deklarciu (funkn prototyp) a definciu cieovej funkcie33. Pre nae potreby sme zvolili funkciu ZistitDlzkuRetazca, ktor doke analyzova poet znakov v ubovonom textovom reazci.
#include <stdio.h> // Deklarcia cieovej funkcie (funkn prototyp). int ZistitDlzkuRetazca(char *p); // Defincia hlavnej funkcie. int main() { // Defincia smernkovej premennej, do ktorej bude mc by // uloen smernk na funkciu. int (*p_f)(char *x); return 0; }

31

Prv dva kroky tridy (defincia a inicializcia smernkovej premennej) mono spoji do jednho agregovanho kroku, tzv. defininej inicializcie smernkovej premennej. Definin inicializciu sa odpora poui vtedy, ak u pri vytvran smernkovej premennej poznme jej konkrtnu inicializan hodnotu. 32 Podotknime, e identifiktor formlneho parametra me v defininom prkaze absentova. Z pohadu kompiltora je dleit, aby bol korektne zadan dtov typ formlneho parametra, identifiktor u nemus by nevyhnutne prtomn. Napriek tomu budeme identifiktory vdy uvdza, pretoe ich prispenm je zapsan zdrojov kd zrozumitenej a lepie itaten. 33 Hoci jazyk C nevyaduje, aby bola kad definovan funkcia opatren svojm prototypom, riadime sa v tomto smere modelom jazyka C++ a vetky definovan funkcie vdy sprvne deklarujeme. Pripomeme, e ak sa defincia funkcie v jazyku C nachdza pred volanm tejto funkcie, vystupuje zrove ako prototyp funkcie.

99

Objektovo orientovan programovanie v jazyku C# 3.0


// Defincia cieovej funkcie. int ZistitDlzkuRetazca(char *p) { int znaky = 0; while(*p != '\0') { znaky++; p++; } return znaky; }

al fragment zdrojovho kdu jazyka C predvdza, ako prebieha inicializcia smernkovej premennej a nepriama aktivcia cieovej funkcie:
int main() { int (*p_f)(char *x); int znaky; // Inicializcia smernkovej premennej smernkom na cieov funkciu. p_f = ZistitDlzkuRetazca; // Nepriame vyvolanie cieovej funkcie pomocou smernka na funkciu. znaky = p_f("Paralelne programovanie"); printf("Dlzka retazca (znaky): %d.", znaky); getchar(); return 0; }

Inicializcia smernkovej premennej sa uskutouje v priraovacom prkaze. Vimnime si, e na pravej strane od opertora priradenia sa nachdza identifiktor cieovej funkcie. Ak kompiltor analyzuje prtomnos identifiktora cieovej funkcie v tomto programovom kontexte, implicitne ho konvertuje na smernk na vstupn bod tela cieovej funkcie. Tmto smernkom je potom inicializovan smernkov premenn. Po svojej inicializcii meme smernkov premenn poui tak, ako keby sme pracovali so samotnou cieovou funkciou. Vzhadom na to, e naa funkcia je parametrick, priom oakva smernk na doasn pole s textovmi znakmi, odovzdvame jej reazcov kontantu. Nasleduje spustenie kdu funkcie, analza predmetnho textovho reazca a vrtenie celoselnej nvratovej hodnoty, ktor predstavuje poet znakov reazca34. Hoci sme cieov funkciu nepriamo aktivovali prostrednctvom identifiktora smernkovej premennej vo forme, v ktorej sme identifiktor smernkovej premennej stotonili s nzvom cieovej funkcie, meme poui aj in variant. V om dme explicitne najavo, e v skutonosti dochdza k dereferencii smernka na funkciu, ktor je uloen v smernkovej premennej.

34

Naa pouvatesk funkcia ZistitDlzkuRetazca sa sprva rovnako ako vstavan kninin funkcia jazyka C s nzvom strlen, ktor je deklarovan v hlavikovom sbore string.h. Nvratovou hodnotou oboch funkci je skuton poet znakov v skmanom textovom reazci bez nulovho (ukonovacieho) znaku.

100

Objektovo orientovan programovanie v jazyku C# 3.0


int main() { int (*p_f)(char * x); int znaky; p_f = ZistitDlzkuRetazca; // Explicitn dereferencia smernka na funkciu, ktor sa nachdza // v smernkovej premennej. znaky = (*p_f)("Paralelne programovanie"); printf("Dlzka retazca (znaky): %d.", znaky); getchar(); return 0; }

S delegtmi v jazyku C# 3.0 pracujeme podobne ako so smernkovmi premennmi obsahujcimi smernky na funkcie v jazykoch C a C++. Kee delegt je pouvatesky deklarovanm odkazovm dtovm typom, prvm krokom je jeho deklarcia. Nasledujci deklaran prkaz zavdza deklarciu delegta s identifiktorom Delegt:
// Deklarcia delegta ako novho pouvatesky deklarovanho // odkazovho dtovho typu. internal delegate int Delegt(string reazec);

Deklarovan delegt disponuje internmi prstupovmi prvami a jeho intancia bude mc by asociovan s cieovou intannou alebo statickou metdou, ktor vyhovuje tmto poiadavkm: 1. Metda vracia celoseln nvratov hodnotu primitvneho dtovho typu int. 2. Metda je parametrick, pracuje s jednm formlnym parametrom, ktorho typom je primitvny odkazov dtov typ string. Formlny parameter metdy bude inicializovan odkazom na intanciu triedy System.String, v ktorej je zapuzdren textov reazec. Deklarcia delegta sa syntakticky podob na definciu smernkovej premennej jazyka C/C++, do ktorej me by uloen smernk na funkciu. Smantick rozdiel vak spova v tom, e delegt je novm dtovm typom: jeho kompletn deklarciu vykon kompiltor jazyka C# 3..0 vo svojej vlastnej rii. Ak by sme sa pozreli na ekvivalentn nzkorovov MSIL kd, uvideli by sme, e kompiltor automaticky vytvoril triedu delegta, ktor je podtriedou systmovej triedy System.MulticastDelegate. V tele triedy delegta s situovan defincie pre intann kontruktor a trojicu parametrickch intannch metd s nzvami BeginInvoke, EndInvoke a Invoke.

101

Objektovo orientovan programovanie v jazyku C# 3.0

Druhm krokom pri prci s delegtom je definovanie cieovej metdy, ktor bude s jeho intanciou spojen35. Syntaktick obraz defincie metdy ZistiDkuReazca vyzer takto:
class Program { internal delegate int Delegt(string reazec); static void Main(string[] args) { // Telo hlavnej metdy je zatia przdne. } // Defincia metdy, ktor bude spojen s intanciou delegta. static int ZistiDkuReazca(string reazec) { return reazec.Length; } }

Pre programtorov, ktor prichdzaj z jazykov C/C++, je dleit oznmenie, e v jazyku C# 3.0 pracujeme bene len s definciami, nie s deklarciami metd36. Definovan metda je statick, o je dan technickmi poiadavkami na prehadnej zdrojov kd. Keby sme toti chceli intanciu delegta spoji s intannou (a teda nestatickou) cieovou metdou, museli by sme deklarova triedu a v nej definova poadovan intann metdu. Napokon zalome intanciu delegta a ulome do nej odkaz na cieov statick metdu:
static void Main(string[] args) { // Intancicia delegta a asociovanie zaloenej intancie // s cieovou statickou metdou. Delegt del = new Delegt(ZistiDkuReazca); // Indirektn aktivcia cieovej statickej metdy pomocou // zostrojenej intancie delegta. int znaky = del("Paraleln programovanie");
35

Nam cieom je ukza zkladn pouitie delegtov, a preto budeme nleite definova cieov metdu, ktor bude s intanciou delegta asociovan. V praktickom nasaden vak nemusia vvojri vdy cieov metdy definova, pretoe mu poui metdy tried, resp. ich intanci, ktor u existuj a nachdzaj sa v spolonej bzovej kninici (FCL) vvojovo-exekunej platformy Microsoft .NET Framework 3.5. 36 Jazyk C# 3.0 nevyaduje pouitie funknch prototypov. Za istch okolnost vak meme s prototypmi funkci pracova. Ide predovetkm o situcie, kedy sme nten spolupracova s natvnymi funkciami aplikanho programovho rozhrania Win32 API. Funkcie tvoriace jadro Win32 API maj natvnu povahu (nejde o riaden kd) a ak chceme s nimi kooperova, musme do zdrojovho kdu jazyka C# 3.0 zavies deklarcie ich riadench prototypov. Tak sa na syntaktickej rovni vytvor prepojenie medzi vrstvami riadenho (.NET) a natvneho kdu (Win32 API). Interoperabilita je realizovan pomocou nzkorovovch softvrovch sluieb Platform Invoke (P/Invoke).

102

Objektovo orientovan programovanie v jazyku C# 3.0


Console.WriteLine("Dka reazca (znaky): {0}.", znaky); Console.Read(); }

Kee je deklarovan delegt odkazov dtov typ, jeho intanciu vytvorme pomocou opertora new. Vo chvli, ke je na riadenej halde alokovan intancia delegta, dochdza k jej inicializcii. V procese inicializcie je do intancie zapuzdren odkaz na cieov statick metdu s uvedenm identifiktorom. Napokon je odkaz na intanciu delegta uloen do odkazovej premennej, ktor je vytvoren v rmci intancianho prkazu. Ke mme inicializovan intanciu delegta, meme prostrednctvom nej nepriamo zavola cieov statick metdu. Vimnime si, e odkazov premenn (cez ktor je intancia delegta dosiahnuten) pouvame podobne, ako by to bola cieov metda, ktor chceme spusti. Po aktivcii metdy bud vykonan vetky prkazy, ktor sa v jej tele nachdzaj (v naom prpade pjde len o jeden prkaz). Napokon nm metda poskytne svoju nvratov hodnotu, ktor ukladme do vopred pripravenej premennej. Predchdzajci vpis zdrojovho kdu jazyka C# 3.0 sa d prepsa nasledujcim spsobom:
static void Main(string[] args) { // Syntakticky zjednoduen intancicia delegta. Delegt del = ZistiDkuReazca; // Cieov metdu volme explicitne pomocou intannej // metdy Invoke delegta. int znaky = del.Invoke("Paraleln programovanie"); Console.WriteLine("Dka reazca (znaky): {0}.", znaky); Console.Read(); }

Li sa len syntaktick strnka zdrojovho kdu, finlny efekt je rovnak. Charakterizujme modifikcie, ktor sme v kde uskutonili: 1. Po prv, zdrojov kd vyuva zjednoduen formu intancicie a inicializcie delegta. Kd explicitne nepouva opertor new, a teda ani nie je vidie priamu aktivciu intannho kontruktora. Z pohadu jazykov C/C++ sa cel intancian prkaz pona na definin inicializciu odkazovej premennej del. Hoci kd navodzuje dojem, e do uvedenej premennej je priraden odkaz na vstupn bod tela cieovej metdy, nie je to tak. Do odkazovej premennej je toti uloen objektov referencia, ktor je nasmerovan na intanciu zrodenho delegta. Tto intancia le na riadenej halde a obsahuje pamov adresu vstupnho bodu tela cieovej metdy. 2. Po druh, v zdrojovom kde je explicitne aktivovan metda Invoke intancie delegta. V skutonosti je metda Invoke volan vdy, ak nie je stanoven inak.
103

Objektovo orientovan programovanie v jazyku C# 3.0

V svislosti s aktivciou cieovej metdy je dleit uvies, e zdrojov kd tejto metdy je spracvan synchrnne. To znamen, e vykonvanie zdrojovho kdu hlavnej metdy Main bude pozastaven dovtedy, pokia nebud spracovan vetky prkazy synchrnne aktivovanej cieovej metdy. Exekcia kdu v tele hlavnej metdy bude pokraova v okamihu, ke synchrnne spusten cieov metda vykon cel svoju innos. alej si ukeme, ako intanciu delegta prepoji s cieovou intannou (nestatickou) metdou:
// Deklarcia triedy. internal class HraciaKocka { // Defincie skromnch dtovch poloiek triedy. private uint slo, estka; private Random genertor; // Defincia verejne prstupnho bezparametrickho kontruktora. public HraciaKocka() { genertor = new Random(); } // Defincia intannej metdy triedy. public void Hodi(ushort poetHodov) { for (int i = 1; i <= poetHodov; i++) { slo = (uint)genertor.Next(1, 7); Console.WriteLine("Bolo hoden slo {0}.", slo); if (slo == 6) estka++; } if (estka == 0) Console.WriteLine("slo 6 nepadlo ani jedenkrt."); else { Console.WriteLine("slo 6 padlo {0}krt.", estka); Console.WriteLine("Vaa spenos bola " + ((float)estka / poetHodov * 100).ToString("0") + " %."); } } } // Deklarcia delegta. internal delegate void Delegt(ushort x); class Program { static void Main(string[] args) { HraciaKocka kocka = new HraciaKocka(); // Vytvorenie intancie delegta a spojenie // intancie s cieovou intannou metdou. Delegt prvDelegt = new Delegt(kocka.Hodi); // Aktivovanie cieovej intannej metdy pomocou

104

Objektovo orientovan programovanie v jazyku C# 3.0


// intancie delegta. prvDelegt.Invoke(10); Console.ReadLine(); } }

Asociovanie intancie delegta s intannou cieovou metdou je jednoduch, pretoe vetko, o musme urobi, je odovzda intannmu kontruktoru delegta odkaz na poadovan metdu. Kee cieov metda je intann a nie statick, vdy musme pecifikova odkazov premenn, prostrednctvom ktorej je prslun intancia dosiahnuten. Bodkovm opertorom (.) nsledne urme metdu, s ktorou chceme pracova.

2.12.1 Spojenie intancie delegta s anonymnou cieovou metdou


Ponc verziou 2.0 programovacieho jazyka C# je mon prepoji intanciu delegta nielen s pomenovanou intannou alebo statickou cieovou metdou, ale taktie s anonymnou metdou. Anonymn metda je metda, ktor je automaticky generovan kompiltorom jazyka C# poda pokynov programtora, priom kompiltor tto metdu implicitne pomenuje. Identifiktor metdy vak nie je znmy vvojrovi, take z jeho pohadu je zostaven metda anonymn.37
class Program { // Deklarcia delegta. delegate void Delegt(int min, int max); static void Main(string[] args) { // Intancicia delegta a spojenie intancie // s anonymnou metdou. Delegt druhDelegt = delegate(int min, int max) { Random genertor = new Random(); for (int i = 0; i < 10; ++i) { Console.WriteLine("{0}. slo je {1}.", i + 1, genertor.Next(min, max + 1)); } }; druhDelegt(1, 100); Console.Read(); } }

37

Hoci pomocou mechanizmu reflexie je mon diagnostikova identifiktor anonymnej metdy, v bench podmienkach nie je potrebn (a spravidla ani uiton) tento identifiktor pozna. Identifiktor anonymnej metdy sa me odliova v rznych prekladovch relcich zdrojovho kdu.

105

Objektovo orientovan programovanie v jazyku C# 3.0

Pozrime sa bliie na prkaz, ktor zaklad nov intanciu deklarovanho delegta. Na pravej strane od opertora priradenia sa nachdza kov slovo delegate s urenm signatry anonymnej metdy. Ako si meme vimn, v naej praktickej ukke bude anonymn metda parametrick, priom jej formlne parametre bud mc prija dve celoseln hodnoty. Po pecifikcii signatry anonymnej metdy dochdza k defincii tela tejto metdy. Telo anonymnej metdy je (podobne ako telo pomenovanej metdy) tvoren programovmi prkazmi, ktor sa nachdzaj v bloku ohranienom zloenmi ztvorkami ({}). Za uzatvracou zloenou ztvorkou nakoniec zadvame symbol bodkoiarky, pretoe musme ukoni prkaz, ktor intanciuje a inicializuje delegta. Pouitie anonymnch metd v svislosti s intanciami delegtov je vemi uiton technika, ktor ns zbavuje povinnosti za kadch okolnost definova samostatn metdy, ktor bud previazan s intanciami delegtov. Namiesto toho kompiltoru odovzdme poadovan znenie zoznamu formlnych parametrov a programovch prkazov, na o nm kompiltor automaticky vygeneruje korektn anonymn metdu.

2.12.2 Kovariancia a kontravariancia delegtov


Programovac jazyk C# vo verzich 1.0 a 1.1 vyadoval, aby bola signatra deklarovanho delegta plne zhodn so signatrou cieovej metdy, s ktorou bude intancia tohto delegta spojen. Vo verzii 2.0 prilo k uvoneniu spomenutho formalizmu. Jazyk C# 2.0 (a rovnako aj jazyk C# 3.0) definuje dve vlastnosti delegtov, ktor vymedzuj pravidl pre prpustn odlinosti signatr. Tieto vlastnosti s znme ako kovariancia a kontravariancia delegtov. Poda kovariancie je mon, aby bol dtov typ nvratovej hodnoty cieovej metdy pecifickej ako dtov typ nvratovej hodnoty deklarovanho delegta. Praktick aplikciu kovariancie demontruje nasledujci fragment zdrojovho kdu jazyka C# 3.0:
// Deklarcia bzovej triedy. class A { // Defincia virtulnej metdy bzovej triedy. public virtual A m() { return this; } }

106

Objektovo orientovan programovanie v jazyku C# 3.0


// Deklarcia odvodenej triedy. class B : A { // Defincia intannej metdy odvodenej triedy.38 public B w() { return this; } } class Program { // Deklarcia delegta. delegate A Delegt(); static void Main(string[] args) { // Intancicia a inicializcia delegta. Delegt del = new Delegt(metda); // Indirektn aktivcia cieovej metdy. Console.WriteLine(del().ToString()); Console.Read(); } // Defincia cieovej metdy. static B metda() { B b = new B(); return b.w(); } }

Z deklarcie delegta vyplva, e dtovm typom jeho nvratovej hodnoty je bzov trieda A. Z tohto titulu meme vyhlsi, e deklarovan delegt bude mc by po svojej intancicii prepojen s takou cieovou metdou, ktor v podobe svojej nvratovej hodnoty vracia odkaz na intanciu triedy A alebo odkaz na intanciu akejkovek podtriedy triedy A. Ke sa pozrieme na definciu cieovej statickej metdy, s ktorou je intancia delegta spojen, vidme, e dtovm typom nvratovej hodnoty tejto metdy je trieda B. Pretoe trieda B je podtriedou triedy A, je poda pravidiel kovariancie spojenie intancie delegta a cieovej metdy plne korektn. Po tom, ako bude prostrednctvom intancie delegta vyvolan cieov statick metda, odohraj sa tieto innosti: V riadenej halde sa alokuje intancia podtriedy B. Alokovan intancia podtriedy B je inicializovan bezparametrickm intannm kontruktorom. Aktivuje sa metda w intancie podtriedy B. Metda w vrti odkaz na aktulnu intanciu podtriedy B.

38

Metda odvodenej triedy neprekrva zdeden metdu bzovej triedy.

107

Objektovo orientovan programovanie v jazyku C# 3.0

Statick metda prijme poskytnut odkaz na intanciu podtriedy B a odole ho sp klientskemu programovmu kdu (hlavnej metde Main). V tele hlavnej metdy je navrten odkaz na intanciu podtriedy B konvertovan do textovej podoby. Vsledkom konverznho procesu je zobrazenie kvalifikovanho mena triedy, z ktorej intancia vznikla. Kontravariancia delegtov sa sstreuje na rozdielnos medzi dtovmi typmi formlnych parametrov cieovej metdy a deklarovanho delegta. Poda kontravariancie je mon, aby cieov metda disponovala generickejmi dtovmi typmi svojich formlnych parametrov v porovnan s dtovmi typmi formlnych parametrov, ktor s uveden v deklarcii delegta. Nasleduje praktick ukka kontravariancie delegtov v jazyku C# 3.0:
// Deklarcia bzovej triedy. class A { // Defincia prekrvajcej metdy bzovej triedy. public override string ToString() { return "A"; } } // Deklarcia odvodenej triedy. class B : A { // Defincia prekrvajcej metdy odvodenej triedy. public override string ToString() { return "B"; } } class Program { // Deklarcia delegta. delegate string Delegt(B b); static void Main(string[] args) { // Intancicia a inicializcia delegta. Delegt del = metda; B obj = new B(); // Nepriama aktivcia cieovej metdy. string s = del(obj); Console.WriteLine(s); Console.Read(); }

108

Objektovo orientovan programovanie v jazyku C# 3.0


// Defincia cieovej metdy. static string metda(A a) { return a.ToString(); } }

Komentr k zdrojovmu kdu: V kde deklarujeme dve triedy, A je bzov trieda a B je odvoden trieda. Do tela bzovej triedy A je zaveden defincia prekrvajcej metdy s identifiktorom ToString. Tto metda bzovej triedy A prekrva rovnomenn zdeden metdu primrnej bzovej triedy System.Object. Ak teda zalome intanciu bzovej triedy A a zavolme jej metdu ToString, zskame textov reazec A. Odvoden trieda B poskytuje komparatvnu funkcionalitu, s tm rozdielom, e definovan metda ToString prekrva rovnomenn zdeden metdu bzovej triedy A. Analogicky, v spojen s intanciou podtriedy B bude volan spomenut prekrvajca metda. Na vstupe teda zskame textov reazec B. Interesantn je prkaz, ktor deklaruje delegta. Deklaran prkaz definuje jeden formlny parameter, ktorho dtovm typom je podtrieda B. Meme teda poveda, e intanciu delegta budeme mc asociova s akoukovek cieovou metdou, ktorej formlny parameter doke prija odkaz na intanciu podtriedy B. Vzah medzi deklarovanm delegtom a definovanou cieovou statickou metdou je vybudovan na bze kontravariancie. To znamen, e je dovolen, aby cieov statick metda definovala formlny parameter, ktorho dtovm typom je bzov trieda A. Ke bude pomocou intancie delegta nepriamo spusten cieov statick metda, jej formlny parameter zska odkaz na intanciu podtriedy B. Tento odkaz bude implicitne konvertovan na odkaz na intanciu bzovej triedy A, priom tmto skonvertovanm odkazom bude inicializovan formlny parameter cieovej statickej metdy. Predostret mechanizmus je realizovaten a vdy bude fungova. Je to preto, e do formlneho parametra, ktorho dtovm typom je bzov trieda A me by kedykovek uloen odkaz na intanciu odvodenej triedy B. Funknos charakterizovanho mechanizmu je dan jednm zo zkladnch princpov objektovo orientovanho programovania, poda ktorho sa me potomok vyskytn vade tam, kde je oakvan jeho rodi.

2.13 -vrazy a -kalkul


V kolekcii syntakticko-smantickch inovci jazyka C# 3.0 maj svoje pevn miesto vrazy (lambda-vrazy). Lambda-vrazy s sasou irej matematicko-informatickej vedeckej terie, ktor sa nazva -kalkul (lambda-kalkul). -kalkul patr k jednej z paradigiem tvorby potaovho softvru, ktorej sa vrav funkcionlne programovanie. Funkcionlne programovanie sa na stavbu softvru pozer inak ako imperatvne programovanie. Pripomeme, e v ponman imperatvnej paradigmy je program
109

Objektovo orientovan programovanie v jazyku C# 3.0

povaovan za konen a neprzdnu mnoinu intrukci, ktor s spracvan jedna za druhou a ktor formuj jednotliv kroky implementovanch imperatvnych algoritmov. Imperatvne programovanie je vvojrom blzke, pretoe sa s nm stretvaj u od nepamti: jazyky BASIC, C, C++, C#, Visual Basic a mnoh alie meme zaradi do kategrie imperatvnych jazykov. Na druh stranu, funkcionlne programovanie je postaven na aparte -kalkulu a potaov program definuje z matematickho hadiska. Z pohadu funkcionlneho programovania je program indikovan ako konen a neprzdna mnoina funkci. Na funkcie, ktor zapuzdruj poadovan algoritmy, s aplikovan rzne transformcie (najm redukcie a konverzie), vaka ktorm sa program dopracuje k poadovanmu vsledku. -kalkul intenzvne pracuje s -vrazmi, prostrednctvom ktorch s funkcie anonymne definovan. -kalkul vo svojom jadre pracuje s unrnymi funkciami, teda s funkciami, ktor s schopn pracova len s jednm argumentom. Argumentom unrnej funkcie me by alia unrna funkcia a unrna funkcia me in unrnu funkciu vraca tie ako svoju nvratov hodnotu. Unrna funkcia je definovan anonymne, o znamen, e ide o anonymn funkciu, ktor nem vlastn identifiktor. Na definciu unrnych anonymnch funkci sa pouvaj -vrazy. -vraz vytvra funkciu a podva rovnako informcie o jej formlnom parametre. Naprklad matematick zpis funkcie vyjadrme nasledujcim -vrazom: . -vrazy zapisujeme vdy do ztvoriek, presne tak, ako sme uviedli. Kad -vraz formuj tieto tyri asti: 1. 2. 3. 4. lambda-symbol ( ), formlny parameter funkcie ( ), vertiklny oddeova (|), telo funkcie, resp. telo -vrazu (

).

V matematike by sme na vpoet hodnoty funkcie so vstupnm argumentom 2 pouili zpis . V -kalkule zapeme vraz , kde hodnota 2 predstavuje argument, ktor bude dosaden do formlneho parametra ( ) a pouije sa v tele funkcie na urenie jej nvratovej hodnoty. Nvratov hodnota funkcie je v skutonosti hodnota -vrazu. Je zrejm, e hodnotou -vrazu bude slo 9. -vraz je z formlnej strnky definovan nasledujcim spsobom: 1. X je premenn, ktor je definovan svojm identifiktorom. 2. je abstrakcia, v rmci ktorej je X premenn a V je telo -vrazu. Termn abstrakcia meme substituova termnom defincia anonymnej funkcie. 3. je aplikcia, teda volanie anonymnej funkcie s argumentom A.
110

Objektovo orientovan programovanie v jazyku C# 3.0

Identifiktorom premennej X me by aj symbol zloen z viacerch znakov. Premenn, ktor sa nachdzaj v -vrazoch, rozdeujeme na viazan a von. Klasifikan kritrium je celkom jednoduch. Pokia je premenn asociovan s lambdasymbolom, je ponman ako viazan. V opanom prpade ide o von premenn. V vraze je x viazanou premennou. Ke predchdzajci -vraz upravme na , tak x zostva i naalej viazanou premennou, no premenn y je von (neexistuje iaden -symbol, ktor by bol s ou spojen). Kee -kalkul doke pracova len s unrnymi funkciami, musme relnu funkciu s viacermi premennmi (formlnymi parametrami) v tomto prostred modelova ako kompozciu jednej unrnej funkcie, ktor ako argument prijma aliu unrnu funkciu. Uvaujme tento prklad: Nech je poet tranzistorov umiestnench v jednom viacjadrovom procesore dan funkciou , kde je poet exekunch jadier uloench v procesorovom balen. Povedzme, e budeme chcie sledova celkov poet intalovanch tranzistorov v kolekcii viacjadrovch procesorov, ktor je vyroben poas jednho vrobnho cyklu. Tejto relcii nech zodpoved funkcia , kde je celkov poet vyprodukovanch procesorov. Definciu funkcie by sme mohli zapsa aj takto: . Pouitm nstrojov -kalkulu zapeme vzahy medzi funkciami nasledujcim spsobom: 1. abstrakcia: 2. abstrakcia: Aplikcia pre 100 tvorjadrovch procesorov, ktor s vyroben v jednom cykle, bude potom vyzera takto:

V zloenom -vraze mono rozpozna vntorn (vnoren) abstrakciu:

Vyhodnotenie zloenho -vrazu prebieha v tchto krokoch: 1. Najskr nahradme viazan premenn ( a ) konkrtnymi hodnotami:

2. Vyhodnotme vntorn a vonkajiu abstrakciu:

111

Objektovo orientovan programovanie v jazyku C# 3.0

3. Vsledn hodnota analyzovanho -vrazu je . Na zklade vypotanej hodnoty meme poveda, e 100 procesorov osadench tyrmi jadrami obsahuje 40 milird tranzistorov. Vyhodnocovanie -vrazov sa uskutouje pomocou vyhodnocovacch pravidiel, ktor sa nazvaj konverzie. -kalkul pozn tri zkladn typy konverznch operci: konverzia, -redukcia a -redukcia.

2.14 -vrazy v jazyku C# 3.0


Implementcia -vrazov do jazyka C# 3.0 je alm evolunm stupom pouitia anonymnch metd. -vraz sa v jazyku C# 3.0 definuje poda nasledujceho vzoru: (formlne parametre) => telo -vrazu Ak je mnoina formlnych parametrov jednoprvkov, ztvorky v zpise nie s povinn. V opanom prpade musme uvdza ztvorky, v ktorch s jednotliv formlne parametre oddelen iarkami. Formlne parametre s reprezentovan identifiktormi, ktor mu by doplnen explicitnmi pecifikciami dtovch typov. Pokia parameter nedisponuje priamo zadanm dtovm typom, kompiltor sa poksi jeho typ odvodi implicitne na zklade kontextu, v akom je parameter pouit. Tto akciu vykonva mechanizmus typovej inferencie. Podstatou mechanizmu typovej inferencie je strojov dedukcia dtovho typu analyzovanej entity. Bez ohadu na to, i je dtov typ parametra zadan explicitne, alebo je implicitne inferovan, typ formlneho parametra je uren vdy v ase prekladu zdrojovho kdu. Symbol => predstavuje -opertor. Tento opertor sa pouva len v -vrazoch, priom psob ako oddeova formlnych parametrov a tiel -vrazov. -opertor => m rovnak prioritu ako priraovac opertor (=) a je asociatvny v smere sprava doava. Telo -vrazu je tvoren syntakticky a smanticky sprvne zapsanou postupnosou operandov a opertorov, ktor mono spracova a vyhodnoti. Kee -vrazy s vemi zko prepojen s anonymnmi metdami, tak telo -vrazu bude zaliate do automaticky vygenerovanej anonymnej metdy. Samozrejme, aby mohla by vygenerovan anonymn metda pouiten, musme deklarova a intanciova delegta, ktor bude s anonymnou metdou prostrednctvom syntaxe -vrazu asociovan. Nasledujci vpis zdrojovho kdu jazyka C# 3.0 demontruje elementrne pouitie vrazu:

112

Objektovo orientovan programovanie v jazyku C# 3.0


class Program { // Deklarcia delegta. delegate int Del(int a); static void Main(string[] args) { // Intancicia delegta a inicializcia zrodenej // intancie delegta -vrazom. Del d = new Del(x => x + 10 * 2); // Aktivcia cieovej anonymnej metdy. Console.WriteLine(d(10)); Console.Read(); } }

Deklarcia delegta nm vrav, e jeho intancia bude mc by asociovan s metdou, ktor prijma jeden 32-bitov celoseln argument a vracia rovnako dlh nvratov hodnotu. V tele hlavnej metdy Main je vznamn hne prv prkaz, ktor predstavuje definin inicializciu odkazovej premennej. Vraz, nachdzajci sa napravo od priraovacieho opertora, vytvra intanciu delegta, ktor automaticky spja s implicitne generovanou anonymnou metdou. V tele samoinne zhotovenej anonymnej metdy je uloen telo definovanho -vrazu. -vraz, ktor pouvame, m v -kalkule takto podobu:

Ekvivalentn -vraz zapsan poda syntaktickch pravidiel jazyka C# 3.0 vyzer takto:
x => x + 10 * 2

Formlnym parametrom je premenn x, ktor nem explicitne determinovan dtov typ. Ak absentuje priama pecifikcia dtovho typu, vieme, e kompiltor vyuije mechanizmus typovej inferencie a dtov typ ur implicitne. Telo -vrazu tvor jednoduch aritmetick vraz, ktorho typ bude op implicitne inferovan. Z intancianho prkazu je zrejm, e -vraz je v podobe vstupnho argumentu odovzdan formlnemu parametru intannho kontruktora delegta. Hoci zpis zdrojovho kdu naznauje tto operciu, v skutonosti je situcia in. -vraz bude konvertovan na parametrick anonymn metdu, telo ktorej bude toton s telom vrazu. Po intancicii delegta bude zroden intancia spojen s anonymnou metdou. Kompiltor vie, e je nutn zostavi parametrick anonymn metdu, pretoe deklarovan delegt je rovnako parametrick. Konene, kontruktor intancie delegta zska odkaz na implicitne definovan anonymn metdu. Po spracovan intancianho prkazu je vytvoren vzba medzi intanciou delegta a anonymnou metdou. Tto metda vak nie je spusten okamite k aktivcii metdy

113

Objektovo orientovan programovanie v jazyku C# 3.0

prostrednctvom intancie delegta dochdza a vtedy, ke je stanoven vstupn argument, ktor bude metde ponknut. To sa deje v nasledujcom prkaze:
Console.WriteLine(d(10));

Vraz d(10) zahajuje synchrnnu aktivciu cieovej anonymnej metdy s tm, e metde je odovzdan celoseln kontanta. Vo vzahu k -kalkulu je vraz d(10) ekvivalentom aplikcie funkcie. Pri alej analze zistme, e prebehne tento reazec operci: 1. Intancia delegta nepriamo vyvol cieov parametrick anonymn metdu. 2. Formlny parameter cieovej anonymnej metdy sa inicializuje kpiou argumentu (implicitn s dta odovzdvan hodnotou), teda kpiou celoselnej kontanty. 3. Vyhodnot sa -vraz uloen v tele cieovej anonymnej metdy. Hodnota vrazu je 30 ( . Tto hodnotu vrti anonymn metda vo forme svojej nvratovej hodnoty. 4. 32-bitov nvratov hodnota anonymnej metdy sa konvertuje na postupnos textovch znakov, odole sa do vstupnho dtovho prdu a zobraz sa na obrazovke potaa. Pre signatru deklarovanho delegta a formu definovanho pravidl: -vrazu platia tieto

-vraz mus obsahova toko formlnych parametrov, koko formlnych parametrov je definovanch v deklarcii delegta. Dtov typ kadho formlneho parametra -vrazu mus by implicitne konvertovaten na dtov typ zodpovedajceho formlneho parametra definovanho v deklarcii delegta. Dtov typ nvratovej hodnoty -vrazu mus by implicitne konvertovaten na dtov typ nvratovej hodnoty, ktor je uveden v deklarcii delegta. Vaka flexibilnej jazykovej pecifikcii C# 3.0 mono intancian prkaz uveden v predchdzajcom fragmente zdrojovho kdu prepsa aj takmto spsobom:
// Syntakticky jednoduch zpis intancianho prkazu. Del d = x => x + 10 * 2;

114

Objektovo orientovan programovanie v jazyku C# 3.0

Napriek tomu, e sme modifikovali syntaktick obraz prkazu, jeho pvodn smantika zostala zachovan. Pri tdiu podobne navrhnutch intancianch prkazov delegtov kooperujcich s -vrazmi vak musme presne pozna praktick implikcie, ktor zo syntakticky jednoduchie zapsanch prkazov plyn. V prpade potreby meme formlny parameter uvies s explicitne urenm dtovm typom:
// Explicitn stanovenie dtovho typu formlneho parametra Del d = (int x) => x + 10 * 2; -vrazu.

Upozorujeme, e ak zapeme dtov typ formlneho parametra, tak typ i identifiktor parametra musia by vloen do ztvoriek (inak kompiltor generuje chybov hlsenie). Pouitie -vrazu ns zbavuje povinnosti definova samostatn cieov metdu, ktor bude spojen s intanciou deklarovanho delegta. Nemusme dokonca definova ani anonymn metdu, pretoe t kompiltor vytvra automaticky poda znenia -vrazu. -vraz smieme poui naprklad pri projektovan programu, ktor na zklade vstupnch dt klasifikuje nrast vkonnosti pvodne sekvennho algoritmu poda Amdahlovho zkona.

2.15 Praktick aplikcia -vrazov v jazyku C# 3.0


Americk vedec Gene Amdahl vynaiel v roku 1967 matematick vzorec na urenie nrastu vkonnosti medzi sekvennou a paralelnou verziou potaovho programu. Amdahlov zkon je dan nasledujcim matematickm vzahom:

kde: je nrast vkonnosti po paralelizcii pvodne plne sekvennho programu. je relatvna poetnos sekvennch algoritmov potaovho programu. je relatvna poetnos paralelnch algoritmov potaovho programu. je poet procesorov potaa, resp. poet exekunch jadier viacjadrovho procesora. Kee set relatvnych poetnost sekvennch a paralelnch algoritmov potaovho programu bude vdy rovn 1, meme vzorec reflektujci Amdahlov zkon modifikova takto:

115

Objektovo orientovan programovanie v jazyku C# 3.0

Uveme prklad praktickho nasadenia Amdahlovho zkona:

Prklad predstavuje program, ktorho algoritmick skladba je z 50 % tvoren sekvennmi algoritmami a z alch 50 % paralelnmi algoritmami. Takto program teda presne polovicu loh riei pomocou sekvennch algoritmov a druh polovicu pomocou paralelnch algoritmov. Samozrejme, rozdiely existuj v povahch algoritmov. Zatia o sekvenn algoritmy s spracvan synchrnne, pre paraleln algoritmy je prznan asynchrnna exekcia. Paraleln algoritmy doku prostrednctvom dtovho alebo lohovho paralelizmu rozdeli vpotovo nron problm na menie asti (podproblmy), ktor mu by realizovan v rovnakom ase na viacerch procesoroch viacprocesorovch strojov alebo na viacerch jadrch viacjadrovch procesorov. (V tomto ponman abstrahujeme od pseudoparalelizmu a namiesto neho pracujeme so skutonm paralelizmom.) Praktick prklad pribliuje situciu, kedy je program v spomenutej algoritmickej skladbe spusten na potai osadenom dvojjadrovm procesorom. Z vpotu vyplva, e maximlny teoretick nrast vkonnosti bude 33 %, o znamen, e po paralelnej optimalizcii bude program pracova o tretinu rchlejie ako predtm.
class Program { delegate float Del(float s, float p, int n); static void Main(string[] args) { Del d = (s, p, n) => 1 / (s + p / n); float nrastRchlosti = d(0.5f, 0.5f, 2); Console.WriteLine("Nrast rchlosti paralelizovanej " + "verzie programu je {0} %.", ((nrastRchlosti - 1) * 100).ToString("0.00")); Console.Read(); } }

2.16 -prkazy v jazyku C# 3.0


V programovacom jazyku C# 3.0 je mon pracova aj s tzv. -prkazmi, o ktorch hovorme vtedy, ke telo -vrazu tvor konen a neprzdna mnoina programovch prkazov. Generick vzah pre definciu -prkazu m nasledujcu podobu: (formlne parametre) =>
116

Objektovo orientovan programovanie v jazyku C# 3.0

{ prkaz1; prkaz2; ... prkazn; } -prkaz nachdza uplatnenie naprklad pri paralelnej inicializcii tvorcovej matice celoselnmi hodnotami:
using using using using using using System; System.Diagnostics; System.Collections.Generic; System.Linq; System.Text; System.Threading;

namespace diz { class Program { static void Main(string[] args) { int[,] pole = new int[10000, 10000]; Stopwatch sw = new Stopwatch(); sw.Start(); Console.WriteLine("Inicializcia matice bola zahjen."); // Kontrukcia Parallel.For vyuva -prkaz. Parallel.For(0, 10000, i => { for (int j = 0; j < 10000; j++) { pole[i,j] = 2 * i + j; } }); sw.Stop(); Console.WriteLine("Matica je inicializovan."); Console.WriteLine("Exekun as: {0} s.", sw.Elapsed.TotalSeconds); Console.Read(); } } }

Tento program vyuva riaden kninicu Parallel Extensions (znmu tie ako Parallel FX) spolonosti Microsoft na podporu paralelnho spracovania programovch intrukci. Aby sme mohli vyuva triedy pre podporu paralelizcie, musme vykona dve akcie: 1. Do aktulne otvorenho projektu jazyka C# 3.0 vlome odkaz na zostavenie kninice Parallel Extensions. To vykonme takto:

117

Objektovo orientovan programovanie v jazyku C# 3.0

Z ponuky Project vyberieme prkaz Add Reference. Ke sa objav dialgov okno Add Reference, uistme sa, e je vybrat zloka .NET. V zozname vyhadme zostavenie System.Threading, ktor zodpoved kninici Parallel Extensions. Po kliknut na tlaidlo OK sa odkaz na kninicu Parallel Extensions vlo do projektu jazyka C# 3.0. 2. Do zdrojovho sboru vlome prkaz using a zabezpeme import mennho priestoru System.Threading. Kee mme za lohu inicializova tvorcov maticu typu 10000 x 10000, budeme potrebova 2 programov cykly. Pre potreby tohto praktickho experimentu sme sa rozhodli paralelizova nadraden cyklus. Namiesto toho, aby sme pouili tandardn cyklus for, aplikujeme jednu z mnoiny preaench definci statickej metdy For triedy Parallel. T predstavuje cyklus for s monosou paralelizcie jeho iterci. -prkaz je umiestnen v signatre statickej metdy Parallel.For, ktor implementuje techniku imperatvneho dtovho paralelizmu. Praktick experimenty na potai osadenom 2-jadrovm procesorom AMD Turion 64 X2 a 2 GB operanej pamte ukzali, e paralelizcia zniuje exekun as potrebn na spracovanie inicializanej asti algoritmu o pribline 42 % (obr. 36).

Nrast vkonnosti po paralelizcii algoritmu


Paraleln inicializcia (PI) Sekvenn inicializcia (SI)

0,77

Exekun as (s)
1,32

Obr. 36: Vizualizcia nrastu vkonnosti po paralelizcii pvodne sekvennho inicializanho algoritmu

118

Zver

Zver
Ven vvojri, programtori a softvrov experti, akujeme vm za v zujem o tto knihu. Pevne verme, e sa jej poradilo splni vyten cie a e ste s ou boli spokojn. Kee ako vvojri modernho potaovho softvru sa vzdelvame cel ivot, dovoujeme si pripoji kolekciu odkazov na alie hodnotn informan zdroje: 1. Visual C# Developer Center http://msdn.microsoft.com/enus/vcsharp/default.aspx. 2. C# 3.0 Language Specification
http://download.microsoft.com/download/3/8/8/388e7205-bc10-4226-b2a875351c669b09/csharp%20language%20specification.doc.

3. Blogs from the C# Team http://msdn.microsoft.com/enus/vcsharp/aa336719.aspx. 4. C# Samples for Visual Studio 2008 http://code.msdn.microsoft.com/csharpsamples. 5. Visual C# Technical Articles http://msdn.microsoft.com/enus/vcsharp/bb466181.aspx. 6. How Do I Videos Visual C# http://msdn.microsoft.com/enus/vcsharp/bb798022.aspx. 7. Visual Studio 2008 and .NET Framework 3.5 Training Kit http://www.microsoft.com/DOWNLOADS/details.aspx?familyid=8BDAA8360BBA-4393-94DB-6C3C4A0C98A1&displaylang=en. 8. MSDN Forums Visual C# http://forums.microsoft.com/MSDN/default.aspx?ForumGroupID=9&SiteID=1. 9. Webcasty v eskom a slovenskom jazyku http://www.microsoft.com/cze/msdn/webcasts/default.mspx. 10. Praktick cvienia v slovenskom jazyku http://www.microsoft.com/slovakia/msdn/hols/default.mspx. 11. MSDN Magazine http://msdn.microsoft.com/en-us/magazine/default.aspx. 12. C# Corner http://www.c-sharpcorner.com/.

Prajeme vm vea spechov pri vytvran tch najlepch potaovch aplikci v jazyku C# 3.0!

Autor

120

O autorovi

O autorovi
Ing. Jn Hank, Microsoft MVP, vytudoval Ekonomick univerzitu v Bratislave. Tu, na Katedre aplikovanej informatiky Fakulty hospodrskej informatiky (KAI FHI), pracuje ako vysokokolsk pedagg. Predna a vedie seminre tkajce sa programovania a vvoja potaovho softvru v programovacch jazykoch C, C++ a C#. Okrem spomenutej trojice jazykov patr k jeho obbenm programovacm prostriedkom tie Visual Basic a C++/CLI. Aktvne vynachdza nov postupy tvorby softvru, ktor bude pomha nielen tudentom, ale aj irokej verejnosti. Je nadenm autorom odbornej potaovej literatry. V jeho portfliu mete njs nasledujce knin tituly: 1. Inovcie v jazyku Visual Basic 2008. Praha: Microsoft, 2008. 2. Visual Basic 2008: Grafick transformcie a ich optimalizcie. Bratislava: Microsoft Slovakia, 2008. 3. Programovanie B Zbierka prednok (Uebn pomcka na programovanie v jazyku C++). Bratislava: Vydavatestvo EKONM, 2008. 4. Programovanie A Zbierka prednok (Uebn pomcka na programovanie v jazyku C). Bratislava: Vydavatestvo EKONM, 2008. 5. Expanzvne ablny: Prruka pre tvorbu "code snippets" pre Visual Studio. Bratislava: Microsoft Slovakia, 2008. 6. Kryptografia: Prruka pre praktick odskanie symetrickho ifrovania v .NET Framework-u. Bratislava: Microsoft Slovakia, 2007. 7. Prruka pre praktick odskanie vvoja nad Windows Mobile 6.0. Bratislava: Microsoft Slovakia, 2007. 8. Prruka pre praktick odskanie vvoja nad DirectX. Bratislava: Microsoft Slovakia, 2007. 9. Prruka pre praktick odskanie automatizcie aplikci Microsoft Office 2007. Bratislava: Microsoft Slovakia, 2007. 10. Visual Basic 2005 pro pokroil. Brno: Zoner Press, 2006. 11. C# - praktick pklady. Praha: Grada Publishing, 2006 (kniha zskala ocenenie Najspenejia novinka vydavatestva Grada v oblasti programovania za rok 2006). 12. Programujeme v jazycch C++ s Managed Extensions a C++/CLI. Praha: Microsoft, 2006. 13. Pechzme z jazyka Visual Basic 6.0 na jazyk Visual Basic 2005. Praha: Microsoft, 2005.
121

O autorovi

14. Visual Basic .NET 2003 Zanme programovat. Praha: Grada Publishing, 2004. V rokoch 2006, 2007 a 2008 bol jeho prnos vvojrskym komunitm ocenen celosvetovmi vvojrskymi titulmi Microsoft Most Valuable Professional (MVP) s kompetenciou Visual Developer Visual C++. Kontakt s vvojrmi a programtormi udriava najm prostrednctvom technickch seminrov a odbornch konferenci, na ktorch vystupuje. Za vetky vyberme tieto: Konferencia Software Developer 2007, prspevok na tmu Pedstaven produktu Visual C++ 2005 a jazyka C++/CLI. Praha 19. 6. 2007. Technick seminr Novinky vo Visual C++ 2005. Microsoft Slovakia. Bratislava 3. 10. 2006. Technick seminr Visual Basic 2005 a jeho cesta k Windows Vista. Microsoft Slovakia. Bratislava 27. 4. 2006. V sasnosti psob ako stly spolupracovnk potaovch asopisov PC World a Connect!. V minulosti zastval pozciu odbornho redaktora rovnako v magaznoch Software Developer, ComputerWorld, Infoware, PC Revue a Chip. Dovedna publikoval viac ako 250 odbornch a populrnych prc venovanch vvoju potaovho softvru. Ak sa chcete s autorom spoji, mete vyui jeho adresu elektronickej poty: hanja@stonline.sk. Akademick blog autora mete sledova na adrese: http://blog.aspnet.sk/hanja/.

122

Pouit literatra

Pouit literatra
1. 2. 3. 4. Akhter, S., Roberts, J.: Multi-core Programming. Hillsboro: Intel Press, 2006. Hank, J.: Inovcie v jazyku Visual Basic 2008. Praha: Microsoft, 2008. Hank, J.: Visual Basic 2005 pro pokroil. Brno: Zoner Press, 2006. Hank, J.: Programujeme v jazycch C++ s Managed Extensions a C++/CLI. Praha: Microsoft, 2006. 5. Hank, J.: C# - praktick pklady. Praha: Grada Publishing, 2006. 6. Hank, J.: VB 6.0 VB 2005: Pechzme z jazyka Visual Basic 6.0 na jazyk Visual Basic 2005. Praha: Microsoft, 2005. 7. Hank, J.: Visual Basic .NET 2003 Zanme programovat. Praha: Grada Publishing, 2004. 8. Kraval, I.: Zklady objektov orientovanho programovn za pomoci jazyka Microsoft Visual Basic 5.0. Brno: Computer Press, 1998. 9. Kraval, I., Ivachiv, P.: Zklady komponentn technologie COM. Brno: Computer Press, 1998. 10. Vanek, J., Papk, M., Pergl, R., Vanek, T.: Teoretick zklady informatiky. Praha: Kernberg Publishing, 2007.

123

Pouit literatra

Jn Hank Objektovo orientovan programovanie v jazyku C# 3.0 (Prruka pre vvojrov, programtorov a softvrovch expertov) Recenzenti: Vydanie: Rok prvho vydania: Nklad: Jazykov korektra: Vydal: Tla: Ing. Ji Burian, Mgr. Miroslav Kubovk prv 2008 150 ks Ing. Peter Kubica Artax a.s., abovesk 16, 616 00 Brno pre Microsoft s.r.o., Vyskoilova 1461/2a, 140 00 Praha 4 Artax a.s., abovesk 16, 616 00 Brno

ISBN: 978-80-87017-02-9

124

Pouit literatra

Ing. Jn Hank je Microsoft MVP (Most Valuable Professional najcennej odbornk) s kompetenciou Visual Developer Visual C++. Je autorom 15 odbornch knh, prruiek a praktickch cvien o programovan a vvoji potaovho softvru. Pracuje ako vysokokolsk pedagg na Katedre aplikovanej informatiky Fakulty hospodrskej informatiky Ekonomickej univerzity v Bratislave. Predna a vedie seminre z programovania v jazykoch C, C++ a C#. V rmci svojej vedeckej innosti sa zaober problematikou truktrovanho, objektovo orientovanho, komponentovho, funkcionlneho a paralelnho programovania. ISBN: 978-80-87017-02-9
125

You might also like