Seriál článkov. [cited 6.1.2010]. dostupné na. . 2. Hanák, Ján. Objektovo orientované programovanie v jazyku C#
3.0.
1 Základné pojmy OOP Termín OOP označuje objektovo orientované programovanie a označuje historicky novší spôsob programovania (a nielen programovania, ale aj iných OO činností), ktorý prichádza po štruktúrovanom programovaní. Základnými pojmami sú objekt, trieda, dedenie, polymorfizmus a dynamické viazanie. Objekt - predstavuje konkrétnu vec alebo pojem z danej problémovej oblasti - základná entita výpočtu, zaberá miesto v pamäti, má adresu, spája stav a chovanie (operácie), pripomína record (Pascal), struct (C), - predstavuje atomárnu jednotku modelu reálneho sveta, - umožňuje počítačovú implementáciu, - (inštancia - var). Trieda - reprezentuje abstrakciu svojich objektov, charakterizuje množinu objektov s rovnakými atribútmi, správaním a vzťahom k iným objektom. Trieda je abstraktný, objektový a odkazový používateľom deklarovaný dátový typ. Dedenie - je mechanizmus zdieľania atribútov, relácií a funkcií medzi triedami, umožňuje využiť implementáciu existujúcej triedy. Poskytuje určité riešenie problému otvorenosti - uzavretosti. Trieda, ktorá dedí, má časť: - zdedenú od predka, - inkrement - prekrytie zdedenej premennej, funkcie; nová časť. Prekrývanie z dôvodov: rozšírenia funkcie z nadtriedy, ohraničenia funkcie z nadtriedy, optimalizácie funkcie z nadtriedy. Dedenie možno charakterizovať z hľadiska: - počtu nadtried jednoduché - najviac jedna nadtrieda, násobné - viac ako jedna nadtrieda, len ťažko možno zmysluplne využiť, - kvality identické (jednoduchá inklúzia) premenných a funkcií, transformácia pri dedení premenných a funkcií, zakázané dedenie premenných a funkcií, - implementácie dynamické - v čase vykonávania programu sa vyhľadávajú funkcie v hierarchii nadtried, statické - dedenie sa uskutočňuje pri kompilácii, - dôvodu použitia hierarchizácia typov - generalizácia pojmov, zdieľanie implementácie - minimalizácia množstva nového kódu. Polymorfizmus -
schopnosť nadobúdať viac ako jednu formu,
-
v programovaní - premenná môže patriť do viac ako jedného typu. Typy zavádzajú ohraničenia na interakcie medzi objektami a chránia tak objekty od nekonzistentných interakcií s inými objektami. Polymorfizmus umožňuje flexibilitu z hľadiska typovej konzistencie. Polymorfizmus z hľadiska - programovacieho jazyka monomorfické - konvenčné, premenná môže patriť práve do jedného typu, polymorfické - premenná môže patriť do viac ako jedného typu, - funkcie - niektorý operand môže patriť do viac ako jedného typu, - typu - jeho operácie sú aplikovateľné na operandy viac ako jedného typu. Druhy polymorfizmu - univerzálny - funkcie pracujú s nekonečným počtom typov, - parametrický - typy sú navzájom disjuktné (vylučujúce sa - int, char), - inkluzívny - typický pre OOP, objekt podtriedy sa môže vyskytnúť tam, kde sa vyžaduje objekt niektorej z jeho nadtried. Podporuje rozšíriteľnosť software - bez zásahu do existujúceho kódu. Z hľadiska typu referencie sa delí na statický - určený deklaráciou a známy počas kompilácie, dynamický - mení sa počas vykonávania programu, - ad - hoc - funkcie pracujú s konečnou množinou typov. V nejakej forme ho využívajú aj konvenčné programovacie (procedurálne) jazyky. Sú dva druhy prekrývanie - rovnaké meno sa použije pre rôzne funkcie (v rôznych objektoch), pretypovanie - konverzia argumentu na typ, očakávaný funkciou. Dynamické viazanie - kód, ktorý sa vykoná pri volaní funkcie menom sa určí až v čase vykonávania programu, súvisí s inkluzívnym polymorfizmom - vyvolanie funkcie asociovanej s polymorfickou referenciou môže závisieť od dynamického typu tejto referencie.
1.1
Programovacie jazyky a OOP
Fortran Algol60 Pascal Modula-2 jazyk C Ada Simula 67 Lisp Smalltalk Act Flavors C++ Eiffel
prvý jazyk vysokej úrovne, numerické výpočty explicitný pojem typu, typová kontrola v čase kompilácie priekopnícky jazyk štruktúrovaného programovania, vlastné typy používateľa elegantný jazyk prvý jazyk modulárneho programovania, oddelenie interfejsu od implementácie, modul nie je typom spojenie jazyka nižšej úrovne so štruktúrovaným programovaním, veľmi populárny spája modulárne a paralelné programovanie, bohatý jazyk prvý jazyk OOP - výskumné účely, simulácie historicky druhý jazyk vysokej úrovne, beztypový jazyk - umelá inteligencia integrované prostredie, hlavný predstaviteľ experimentálny jazyk, spojenie OOP s paralelizmom “čistý” OOP jazyk, na lispovských počítačoch priama nadstavba C s OOP črtami výlučne pre OOP
Jazyky kompilačné - C++, Eiffel interpretačné - Smalltalk, CLOS - flexibilnejšie, menej efektívne Hranica medzi nimi nie je striktná. Zoznam OOP jazykov
1.2
Základné princípy OOP
Objektovo orientované programovanie (OOP) je v súčasnosti považované za najmodernejšiu a najrozšírenejšiu programovaciu techniku. Aj keď jeho princípy boli prvýkrát použité už v jazyku Simula 67 (v r.1967), jeho reálne použitie a rozvoj začína v prvom skutočne objektovo orientovanom jazyku Smalltalk-80, resp. ďalších O-O jazykoch (Lisp - 88, Eiffel - 88). Masové rozšírenie nastáva jeho zaradením do prekladačov jazykov Pascal (TP verzia 5.5), resp. C (C++) začiatkom 90 rokov. V Pascale sa jednalo o prostredie Turbo Vision (textové), ktoré je dnes nahradené grafickými prostriedkami, napr. Object Windows. Posledným vývojovým prostriedkom na báze Pascalu je Delphi, určené pre vývoj 32 bitových aplikácií pre operačný systém Windows, a Kylix pre vývoj aplikácií pod Linuxom. V súčasnosti sa stalo použitie metód a princípov OOP pravidlom nielen v prostredí vývojových nástrojov pod Windows, ale aj iných operačných systémov, databázových systémov, sieťových prostriedkov ako aj vývoja týchto prostriedkov (analýza, design). Objektovo orientovaný prístup je vhodný nielen na rozsiahle programové projekty, ale aj na malé aplikácie. Dôležité je, že sa výrazne zjednoduší prípravná fáza projektu a vznikne priestor pre individuálny prístup. Obľúbená metóda pokusov a omylov sa dokonca doporučuje, a to i vo veľkých projektoch (ale pod krycím názvom prototypovanie) - Yourdonova a Coadova metodika. Základnou úlohou je vybudovať systém objektov, ktorý by správne modeloval riešený problém. Začatie práce návrhom používateľského rozhrania, ako je to často bežné, môže viesť k deformácii štruktúry celého systému. Objektovo orientovaná analýza, design a implementácia preto tvorí jeden kompaktný celok pri práci na softwarovom projekte. Základným pojmom je objekt, ktorý predstavuje súhrn istých vlastností a činností. Z hľadiska syntaxe špecifikácia objektu predstavuje isté rozšírenie typu record, pričom vlastnosti objektu reprezentujú jeho dátové položky a činnosti nad jeho vlastnosťami tzv. metódy, reprezentované funkciami, resp. procedúrami. Objekt definuje tzv. triedu (class). Všetky objekty s rovnakými vlastnosťami (dáta, metódy) patria do jednej triedy. Popis triedy zodpovedá definícii typu. Realizácia objektu triedy sa nazýva inštancia (deklarujeme premennú, ktorej typom je názov nadefinovanej triedy). Zavedením objektu OOP umožňuje logické združovanie súvisiacich dát a zdrojového kódu (metód). Tejto vlastnosti OOP hovoríme zapúzdrenie (encapsulation). Druhou špecifickou črtou OOP je dedenie (dedičnosť - inheritance), ktoré spočíva v odovzdávaní vlastností (dát, metód) predka potomkovi. Potomok predstavuje typ predka, rozšírený o nové dáta a | alebo metódy. Tento mechanizmus umožňuje využívať v potomkovi všetko, čo už je hotové v predkovi (samozrejme bez možnosti spätného ovplyvnenia). Tretím význačným pojmom i mechanizmom v OOP je polymorfizmus (mnohoznačnosť), ktorý umožňuje položke objektu (metóde) patriť do viac ako jedného typu. Aktuálna príslušnosť do
odpovedajúceho typu je riešená dynamicky počas behu programu na základe tabuľky priradenia jednotlivých tried k danej metóde. V takom prípade hovoríme o tzv. pozdnej väzbe (late binding) na rozdiel od včasnej väzby (early binding), ktorá vzniká vtedy, keď metódy sú definované ako statické. Voľba typu metódy (statická, dynamická) je závažným problémom. Statická metóda je vykonaná podstatne rýchlejšie ako dynamická. Na druhej strane ale používateľ nemá v takom prípade možnosť prispôsobiť funkciu metódy v potomkoch svojim potrebám.
1.2.1 Rozsahy platnosti položiek inštancie Všetky dátové položky predka sú platné a prístupné i v každom potomkovi. Dátovú položku objektu nie je možné v potomkovi predefinovať. Pre metódy platí to isté s tým, že metódu definovanú v predkovi je možné v potomkovi predefinovať. Pri predefinovaní statickej metódy môže dôjsť i ku zmene počtu a typu parametrov, u virtuálnej metódy nie.
1.2.2 Konštruktor, deštruktor Konštruktor je zvláštna metóda, pri vyvolaní ktorej sa vytvorí spojenie medzi tabuľkou virtuálnych metód triedy objektov a aktuálnou inštanciou. Toto spojenie sa potom využíva pri volaní virtuálnej metódy. Z toho vyplýva, že ak je v objekte definovaná aspoň jedna virtuálna metóda, musí v ňom byť definovaný aj konštruktor. Volanie konštruktora sa obvykle používa pri dynamickej alokácii objektov, kedy sa po vykonaní alokácie automaticky vykoná i konštruktor. Konštruktor je vhodné volať ako prvú metódu objektu a sústrediť do neho i ďalšie akcie, súvisiace s inicializáciou objektu. Deštruktor je zvláštna metóda pre uvoľnenie dynamicky alokovaného objektu pomocou odkazu do tabuľky virtuálnych metód. Deštruktor teda musíme použiť vždy, ak máme objekt s virtuálnymi metódami a chceme s ním pracovať dynamicky. Deštruktor je vyvolávaný ako posledný, takže by mal obsahovať aj všetky upratovacie činnosti - napr. uvoľnenie všetkých dynamicky alokovaných dátových položiek. Deštruktor by mal tiež vždy byť virtuálny.
1.2.3 Príklad triedy a jej volania Trieda je istou šablónou objektu [1]. Volanie triedy označujeme ako inštanciu. Inštanciu (triedy) vytvára jej konštruktor. Definícia triedy sa začína kľúčovým slovom class + názov triedy + dvojica zložených zátvoriek s telom triedy, tvoreným jej atribútmi a metódami. Názov triedy (resp. každé slovo názvu pri viacslovnom názve) sa začína veľkým písmenom (camel caps – ťavia notácia), ostatné písmená sú malé. Je vhodné uložiť triedu do samostatného súboru s rovnakým názvom (s príponou php). Niektoré metódy triedy majú špeciálny názov, začínajúci predponou __ (dva podčiarniky) – tzv. magické metódy. Najčastejšou z nich je konštruktor, ktorý sa vykoná pri vytváraní každej inštancie triedy (pri každom volaní triedy). Jeho úlohou je vykonať prvotné nastavenie atribútov triedy.
Niekoľko poznámok. Kľúčové slová public a private budú vysvetlené neskôr (viditeľnosť). Pre názvy atribútov a metód tiež platí spomínaná notácia s tým rozdielom, že prvé písmeno názvu je malé. Zápis $this->constr znamená odkaz na atribút $constr aktuálnej triedy. Presnejšie - $this je pseudopremenná, ktorá sa odkazuje na aktuálnu inštanciu, teda na inštanciu, v ktorej sa nachádza. Pri takomto volaní atribútu mimo inštancie triedy vzniká fatálna chyba. Volanie triedy sa realizuje vytvorením jej inštancie pomocou konštruktora, čiže využitím kľúčového slova new plus názov triedy. Samozrejme, musíme do programu zaradiť zdrojový text triedy – príkaz include. V ukážke je inštancia triedy v premennej $inst_triedy a volanie atribútov, resp. metód triedy sa uskutočňuje prostredníctvom tejto premennej s odkazom na názov atribútu alebo metódy.
Výsledkom uvedeného príkladu je Atributy su ako klasicke premenne (v ramci Triedy) Konstruktor je specialna metoda vykonana pri kazdom volani Triedy
Ďalší príklad je komplexnejší, má štyri metódy s jednoduchými výpočtami a dynamickým pridaním atribútu pomocu špeciálnej funkcie __set(). Tvar triedy je