620 likes | 850 Views
Okruhy: Teoretické základy objektově orientovaného programování Zavedení pojmů objektu pomocí postulátů Zavedení pojmu třída Zavedeni pojmu polymorfismus Zavedení pojmu dědičnost Zavedení pojmu kolekce objektů Polohy proměnných v sytému tvořeném pomocí objektově orientovaného programování
E N D
Okruhy: • Teoretické základy objektově orientovaného programování • Zavedení pojmů objektu pomocí postulátů • Zavedení pojmu třída • Zavedeni pojmu polymorfismus • Zavedení pojmu dědičnost • Zavedení pojmu kolekce objektů • Polohy proměnných v sytému tvořeném pomocí objektově orientovaného programování • Třívrstvý model aplikace v objektově orientovaném programování • Chyby začátečníků v OOP • Literatura : Ktaval, I.Základy objektově orientovaného programování Computer Press. Brno 1998. ISBN80-7226-047-2 • Přednášky.
Teoretické základy programování • Vývojové větve a paradigmatu programování • Během uplynulých padesáti let zaznamenaly přístupy k vývoji počítačového softwaru nebývalý rozmach. Při bližší analýze můžeme determina tři základní větve programování: • 1. Strukturované programování. • 2. Objektově orientované programování. • 3. Komponentové programování. • Každá z uvedených větví přichází s vlastní paradigmatu vývoje počítačového softwaru.
1. Strukturované programování • Strukturované (procedurální) programování se zaměřuje na návrh imperativních programů, které realizují algoritmy prostřednictvím tří základních grafů řízení, resp. řídících konstrukcí, kterými jsou: sekvence, selekce a iterace • Strukturované programování využívá strukturované algoritmy. Strukturovaný algoritmus můžeme charakterizovat induktivní-rekurzivní způsobem: • Každý jednotlivý krok je strukturovaným algoritmem. • 2. Základní řídící konstrukce (sekvence, selekce a iterace) strukturovaných algoritmů představují také strukturovaný algoritmus. • 3. Strukturovaným algoritmem je všechno to, co získáme opakovaným použitím premis položených v 1. a 2. kroku tohoto postupu. • Z praktického hlediska je strukturovaný program tvořený množinou funkcí, které mezi sebou vedou prospěšný informační dialog, co můžeme matematicky formalizovat takto: • P = F = (f1, f2, ..., fn) • Jedna z funkcí strukturovaného programu má výsadní postavení, přičemž se klasifikuje jako hlavní funkce programu.
Z Deklarace proměnných Informace o typu programu Načtení vstupních hodnot A,B,C,D C<B D=B:B=C:C=D B<A D=B:B=A:A=D C<B D=B:B=C:C=D Deklarace proměnných K
Option Explicit On • Imports System.Console • Module Module1 • Sub Main() 'Vstupí bod do programu • Dim A, B, C, D As String 'Deklarace proměnných • Dim Pomoc As String • Console.WriteLine("Tento program setřídí tři čísla") 'Tisk na orazovku • Console.Write("Napiš číslo A: ") • A = Console.ReadLine 'Čtení z klávesnice • Console.Write("Napiš číslo B: ") • B = Console.ReadLine • Console.Write("Napiš číslo D: ") • D = Console.ReadLine • If Val(D) < Val(B) Then 'Setřídění bublinkovou metodou c je pomocná proměnná • C = D • D = B • B = C • End If • If Val(B) < Val(A) Then • C = B • B = A • A = C • End If • If Val(D) < Val(B) Then • C = D • D = B • B = C • End If • Console.WriteLine("Nyní A = " & A & " " & "Nyní B = " & B & " Nyní D = " & D) • Pomoc = ReadLine() • End Sub • End Module
Z K Vstupní hlášení + zadání programu Podprogram: Zadani Generování řady čísel a jejich vypsání Podprogram: Generuj Setřiď Podprogram: Setrid Pomoc < > "" ano ne
Module Module1 • Sub Main() • Dim A, B, C As String • vstup(A, B, C) • Porovnej(A, B) • Porovnej(B, C) • Porovnej(A, B) • vystup(A, B, C) • End Sub • Private Sub vstup(ByRef K1 As String, ByRef K2 As String, ByRef K3 As String) • WriteLine("Program pro setřídění tří čísel") • Write("Zadejte číslo A = ") • K1 = ReadLine() • Write("Zadejte číslo B = ") • K2 = ReadLine() • Write("Zadejte číslo C = ") • K3 = ReadLine() • End Sub • Private Sub Porovnej(ByRef M1 As String, ByRef M2 As String) • Dim Pom, N1, N2 As Single • N1 = Val(M1) • N2 = Val(M2) • If N1 > N2 Then • Pom = N2 • N2 = N1 • N1 = Pom • End If • M1 = Str(N1) • M2 = Str(N2) • End Sub • Private Sub vystup(ByVal S1 As String, ByVal S2 As String, ByVal S3 As String) • WriteLine("Po setřídění je A = " + S1 + " B = " + S2 + " C = " + S3) • Read() • End Sub • End Module
Mezi hlavní funkcí a ostatními, tzv.. uživatelsky definovanými, funkcemi existují těsné datové vazby. Při volání uživatelsky definované funkce, která zajišťuje zpracování stejného parciálního algoritmu, je možné této funkci předat kvanta vstupních dat. Vstupní data specifikované při volání funkce se nazývají argumenty. V roli argumentů mohou vystupovat datové objekty, které jsou na syntaktické úrovni reprezentovány hodnotami primitivních datových typů, resp. instancemi uživatelsky deklarovaných datových typů. Je pochopitelné, že pokud jsou funkci předávány určité argumenty, musí funkce disponovat prostředkem, pomocí kterého bude schopna tyto argumenty přijmout a uchovat. Tímto prostředkem jsou ve strukturovaných programech formální parametry, které z technického hlediska představují lokální proměnné funkce určené jen pro absorpci argumentů. Pokud funkce strukturovaného programu definuje ve své signature alespoň jeden formální parametr, charakterizujeme ji jako parametrickú funkci. Naproti tomu, funkce s prázdnou signaturou se označují termínem bezparametrické funkce. Strukturované programovací jazyky obvykle realizují dva základní mechanismy předávání argumentů formálním parametrům: 1. Mechanismus předávání argumentů hodnotou. 2. Mechanismus předávání argumentů odkazem.
Mechanismus předávání argumentů hodnotou je bezpečnějším mechanismem předávání datových objektů volaným funkcím. Existuje totiž garance, že volaná funkce nejsou schopny provádět potenciálně nebezpečné programové operace, které by vedly k porušení datové integrity. Protože jednotlivé programovací jazyky preferují ochranu datové integrity, mechanismus předávání argumentů hodnotou je v nich realizován zpravidla implicitně. • Za určitých okolností použití mechanizmu předávání argumentů hodnotou váže s nežádoucím postranní režií. Zmíněné režijní náklady jsou alokovány zejména tehdy, když volající funkce poskytuje volající funkci kapacitně náročné datové objekty.Možností, jak eliminovat paměťové zatížení systému, je upřednostnit mechanismus předávání argumentů odkazem.Toto riešenie je oveľa efektívnejšie, pretože nech už budeme pracovať s ľubovoľným počtom volaných funkcií, v pamäti bude alokovaný vždy len jeden dátový objekt. Všetky aktivované funkcie získajú pamäťovú adresu, prostredníctvom ktorej je daný objekt dosiahnuteľný.
1. krok 2. krok 3. krok 4. krok 5. krok
1. krok 2. krok 3. krok 4. krok 5. krok
Za normálních okolností můžeme kategorizovat všechny uživatelsky definované funkce ve strukturovaném programu podle toho, zda jistou návratové hodnoty vracejí, nebo ne. Funkce bez návratové hodnoty jsou z hlediska sémantického totožné s procedurami, tedy bloky zdrojového kódu, které jsou zpracovány bez toho, aby podávali zprávu o výsledku provedených aktivit. Podobně, jak může komunikovat hlavní funkce se všemi uživatelsky definovanými funkcemi, mohou kooperovat i jednotlivé uživatelsky definované funkce mezi sebou. Přitom platí všechna pravidla, které jsme rozebrali výše. Funkce múže na příklad v jazyce VB.Net být deklarována bez návratové hodnoty : Private Function Vstup(ByRef A As String, ByVal C As Single) Jako podprogram: Private Sub Vstup(ByRef A As String, ByVal C As Single) S návratovou hodnorou: Private Function Vstup(ByRef A As String, ByVal C As Single)as Boolean Manipulace s argumenty a návratové hodnoty je základním rámecem pro řízení toku dat v strukturovaných programech. Pro úplnost dodejme, že existují i jiné mechanismy, které umožňují transport dat mezi více funkcemi navzájem. Typickým příkladem je použití globálních datových objektů, které jsou zapouzdřeny v globálních proměnných. K takovýmto proměnným mají přístup všechny funkce, které se nacházejí v příslušné překladové jednotce zdrojového kódu.
Pokud dojde k vyvolání funkce, řízení programu je přesměrovány na kód vstupního bodu těla příslušné funkce. Pokud jsou funkci předávány argumenty, alokuje se prostor pro formální parametry, do kterých jsou argumenty uloženy. V další etapě je zahájena exekuce programových příkazů, které jsou umístěny v těle volané funkce. Z technického hlediska nízkoúrovňové interpretace funkce jsou všechny programové příkazy vyjádřené strojovém (nativním) kódu třídy x86. Po zpracování všech programových příkazů uložených v těle funkce je vrácena návratová hodnota funkce a řízení programu je přesměrovány zpět do volajícího funkce. Uživatelsky definované funkce strukturovaného programu mohou být mimo přímé aktivace vyvolávány i rekurzivně. Teoretická informatika rozlišuje několik variant rekurzie, pro potřeby této publikace se budeme soustředit jen na přímou a nepřímourekurzi. Při přímé rekurzii je vytvořena nová instance totožné funkce předtím, než se ukončí zpracování všech příkazů v těle této funkce. Při přímé rekurzii volaná funkce aktivuje "sama sebe" v určitém okamžiku svého zpracování. Přestože empiricky může rekurzivní volání funkce působit nejprve netradičně, z technického hlediska není žádný rozdíl mezi voláním nerekurzívnej a rekurzivní funkce.
Přímá rekurze se provádí opakovaně, přičemž při každém opakování je volána nová instance funkce s modifikovanou soupravou argumentů (rekurzivní funkce budou vždy parametrické). Jelikož při přímé rekurzii jedna instance funkce zrodí novou instanci funkce, můžeme sledovat celý řetězec funkcí, které vznikají v průběhu rekurzivně řešeného problému. Řetězec jednotlivých instancí volající funkce musí být vždy konečný (bez ohledu na to, zda pracujeme s přímou, nebo nepřímou rekurziou) vždy konečný (bez ohledu na to, zda pracujeme s přímou, nebo nepřímou rekurziou) Při každém zrodu nové instance funkce se tato funkce musí rozhodnout, zda parciální část problému, kterou řeší, je rekurzivní, nebo základní věc. Pokud funkce identifikuje, že jde o rekurzivní případ, tak v procesu dekompozice původně komplexního problému ještě nebyla dosažena taková úroveň problému, kterou by bylo možné okamžitě vyřešit. Podproblém na příslušné úrovni je proto nutné opět dekomponovat na jednodušší problémy. Rekurzivně případy generují rekurzivní volání funkce, které znamenají zakládání nových a nových instancí funkce v operační paměti. Proces rekurzivního volání funkce se musí podle přijatých předpokladů ukončit tehdy, když jistá instance v řetězci rekurzivního volání funkcí narazí na základní případ.
Je zřejmé, že nekonečná rekurze nemůže existovat. Tento stav je ve skutečnosti velmi nebezpečný, protože by se v praktických podmínkách skončil vyčerpáním systémových zdrojů, které operační systém dedikuje fyzickému procesu strukturovaného programu. Samozřejmě, otázkou zůstává, za jak dlouho bude schopna rekurzivně volána funkce dosáhnout základní případ. Všechny instance funkce vytvořené v procesu přímé rekurzie lze vizuálně reprezentovat jako úrovně vnořování se rekurzivně volané funkce. Po dosažení základního případu se rekurzivně volána funkce "vyvstává zpět", přičemž každá z vytvořených instancí poskytuje svému nadřazenému protějšku výsledek své činnosti. Nepřímá rekurze je jen variací přímé rekurzie: při ní rekurzivně volána funkce aktivuje jinou uživatelsky definovanou funkci a tato zase zpětně volá původní funkci. Rekurzivně volané funkce se uplatňují při řešení problémů, které mají rekurzivní povahu. Přestože je syntaktická-sémantické vyjádření rekurzivně volaného funkce přirozené av mnoha případech i elegantní, je třeba poukázat na vyšší prostorovou složitost rekurzivně implementovaných algoritmů. Kapacitní náročnost je způsobena generováním instancí rekurzivně volaného funkce, které musí být alokovány v operační paměti počítače. Vyšší zátěž je vázána také s výkonem komunikačního mechanismu mezi jednotlivými odděleními rekurzivně volané funkce.
Objektově orientované programování Ačkoli základy paradigmatu objektově oriento- vaného vývoje počítačového softwaru byly teoreticky položeny již v 60. letech 20. století, praktický rozmach zaznamenal tento model tvorby softwaru přibližně o třicet let později. Objektově orientované programování se snaží řešit jeden ze základních problémů strukturovaného programování, kterým je separace datových objektů a funkcí (podprogramů), které s těmito datovými objekty manipulují. Obecná teorie objektově orientovaného programování vychází z následujících axiomy:
1. Objekt je základní logická entita, která je charakterizována svým identifikátorem, vlastnostmi a činnostmi. Identifikátor objektu je jednoznačné určení objektu v systému, resp. v objektově orientovaném prostředí. Vlastnosti objektu jsou dány jeho atributy a představují znaky, kterými objekt disponuje. Činnosti objektu jsou podloženy jeho metodami a tvoří behaviorální složku objektu. Podle množiny metod můžeme diagnostikovat styl chování objektu vůči klientům, resp. vůči jiným objektem v jeho prostředí. 2. Objekt je výsledkem objektového modelování, tedy procesu, jehož prostřednictvím se vytvářejí virtuální ekvivalenty fyzických objektů, s nimiž pracujeme v reálném světě. 3. Jelikož fyzické objekty jsou zpravidla velmi složité, během objektového modelování se uplatňuje princip objektové abstrakce, v rámci níž odhlédnout od těch atributů a činností fyzických objektů, které pro nás nejsou důležité (obr. 2). Objektová abstrakce nám dovoluje soustředit se pouze na ty vlastnosti a činnosti objektu, které jsou významné z hlediska vytvářeného systému, resp. aplikace.
4. Každý objekt je svéprávou jednotkou, která obsahuje vlastní atributy a metody. Atributy jsou reprezentovány datovými položkami, které jsou určeny pro úschovu dat objektu. Metody ztělesňují činnosti prováděné objektem. Metody mohou přímo pracovat s atributy objektu. Nahlédnutí na objekt jako monolitický kontejner, ve kterém se nacházejí atributy a metody, je principem zapouzdření (obr. 3).
5.Objekt je z vnějšího pohledu "černou skříňkou", protože jiné objekty nevidí jeho atributy ani metody. Tím, že objekt ukrývá své atributy, zabezpečuje ochranu dat, které obsahuje. Není tedy možné, aby tyto data modifikované potenciálně nebezpečným způsobem jiným objektem, resp. jinou entitou vyskytující se ve venkovním prostředí objektu. V obecné teorii objektově orientovaného programování je uveden princip známý jako ukrývání dat. 6. S daty objektu mohou přímo pracovat pouze metody objektu. Ty jsou upraveny tak, aby se datová část objektu nikdy nedostala do nekonzistentného stavu. Podobně jako atributy, tak metody jsou v objektu ukryté, a tedy nikdo (kromě objektu samotného) neví, jak je ve skutečnosti prováděna činnost, jejíž realizace je příslušnou metodou garantována. Tento princip se nazývá ukrývání implementace a umožňuje uživatelům využívat služby objektu i bez znalosti toho, jak jsou tyto služby implementovány. 7. Atributy objektu formují jeho vnitřní paměť. Objekt tedy ví o své existenci, přičemž jeho aktuální stav vždy reflektují hodnoty jeho atributů. Stav objektu může být kdykoliv diagnostikován prostřednictvím metod k tomu určených.
8. Komunikace ve vztazích jiný objekt" se uskutečňuje pomocí „uživatel à objekt" a „objekt à jiný objekt" uskutečňuje se pomocí mechanismu zpráv. Každý objekt je schopen přijmout a zpracovat jistou množinu zpráv. Kolekce zpráv, na které dokáže objekt reagovat, je zaznamená v protokolu zpráv. Protokol zpráv determinuje vzájemné relace mezi jednotlivými správami a metodami objektu. Pomocí protokolu zpráv je možné vždy jednoznačně určit, která metoda bude aktivována jako reakce na příjem samé zprávy. Mezi zprávami a metodami uvedenými v protokolu zpráv existuje relace typu 1:1. Každá zpráva je tedy mapován na právě jednu metodu. Pokud přijde zpráva od uživatele, resp. jiného objektu, objekt ji zachytí a zpracuje. Zpracování zprávy znamená vyhledání zprávy v seznamu zpráv, který je uveden v protokolu zpráv (obr. 4). Proces dále pokračuje aktivováním metody, která je s přijatou zprávou asociována. Objekt vykoná požadovanou činnost as jejím výsledkem seznámí uživatele.
9.Zprávy, které jsou objektu zasílány můžeme rozdělit na bezparametrické a parametrické. Bezparametrické zprávy s sebou nenesou žádná data a jako takové jsou určeny pouze pro zjištění aktuálního stavu objektu. Naopak, parametrické zprávy integrují data, které modifikují aktuální stav objektu. Zatímco parametrické zprávy mění vnitřní paměť objektu, bezparametrické zprávy přímé modifikace nedopustil. Mezi zprávami a metodami objektu existuje přímá korelace: bezparametrické zprávy aktivují bezparametrické metody a parametrické zprávy spouštějí parametrické metody.
10. Z hlediska časové latence při čekání na výsledek zaslání zprávy můžeme zprávy klasifikovat na synchronní a asynchronní. Abychom mohli lépe vysvětlit rozdíly mezi synchronními a asynchronními zprávami, budeme uvažovat abstraktní komunikační modely s více objekty. První objekt označíme identifikátorem A, druhému objektu přiřadíme identifikátor B a třetí objekt pojmenujeme identifikátorem C. Zaměříme se na zkoumání dvou situací: a.) Analýza synchronního komunikačního modelu. b.) Analýza asynchronního komunikačního modelu. ad a ) V synchronního komunikačního modelu pracujeme s dvěma objekty: A a B. Komunikace mezi uvedenými objekty se začíná tím, že objekt A pošle synchronní zprávu objektu B. Objekt B zprávu pomocí protokolu zpráv zpracuje a synchronně spustí metodu, která je s danou zprávou propojena. Objekt B tedy začne provádět operace, které jsou naprogramovány v těle metody, kterou si objekt A přál spustit. Důležité je poukázat na skutečnost, že objekt A nemůže provádět žádné další aktivity (např. rozesílat jiné zprávy), pokud metoda objektu B nedokončí svou činnost. Řečeno jinak, objekt A musí čekat na návrat synchronně aktivované metody objektu B. Je zřejmé, že synchronní komunikační model vytváří pevnou vazbu mezi komunikujícími objekty. Časová latence, která vzniká po doručení zprávy, je signifikantní. Vizuální zobrazení synchronního komunikačního modelu mezi objekty můžeme vidět na obrázku. 5.
Komentář k synchronním komunikačnímu modelu (obr. 5): V čase t1 zasílá objekt A synchronně zprávu (SS) objektu B. Objekt B zajišťuje zpracování synchronní zprávy (SSS) protokolem zpráv. Po diagnostice zprávy objekt B začíná synchronně aktivaci přidružené metody (SAM). Volána metoda je zpracovávané synchronně (SSM), což znamená, že objekt A je znehybnění do okamžiku, kdy tato metoda ukončí svou činnost. Po vrácení návratové hodnoty (VNH) a její zpracování (SNH) v čase tn se řízení vrací zpět objektu A. Přímá časová závislost (PCZ), vyjadřující inoperabilitu objektu A, je dána intervalem <t1, tn>. Objekt A nemůže zaslat další zprávu objektu B (nebo jinému objektu) dříve, než v době tn +1. Obr. 5: Synchronní komunikační model mezi objekty
Asynchronní komunikační model eliminuje citelně časovou latenci, která vzniká v synchronního komunikačního modelu. V tomto modelu se komunikace mezi zúčastněnými objekty odehrává následujícím způsobem: Objekt A pošle asynchronní řízení objektu B. Řízení se v této chvíli okamžitě vrací zpět objektu A, který může zahájit provedení dalších operací. Objekt B zasílanou zprávu přijme, diagnostikuje ji pomocí protokolu zpráv a asynchronní spustí metodu asociované s příslušnou správou. Když metoda objektu B skončí svou činnost, bude o jejím výsledku informován objekt A. Jak můžeme zaregistrovat, asynchronní komunikační model je paralelizácii úkolů nakloněn mnohem více než synchronní model. Protože objekt předávající asynchronní zprávu není znehybnění během výkonu metody poptávaného objektu, smí pokračovat ve své práci. Vizuální interpretaci asynchronního komunikačního modelu mezi objekty znázorňuje obrázek 6.
Komentář k asynchronního komunikačnímu modelu (obr. 6): V zájmu šetření asynchronního komunikačního modelu musíme analyzovat více než dva objekty. V našem modelu provádíme výzkum na třech objektech s identifikátory A, B a C. V čase t1 zasílá objekt A objektu B 1. asynchronní zprávu (AS1). Objekt B zpracuje asynchronní zprávu (SAS1) a asynchronní spustí metodu spojenou s touto zprávou (AAM1). Protože objekt A nečeká na dokončení asynchronně aktivované metody objektu B, může v době t2 zaslat další asynchronní zprávu (AS2) objektu C. Objekt C doručenou asynchronní zprávu zpracuje (SAS2) a asynchronní spustí svázanou metodu (AAM2). Obě asynchronní aktivované metody objektů B a C pracují paralelně. Obr.6. Asynchronní komunikační model mezi objekty
Jejich finální exekuční čas je variabilní: v našem modelu předpokládáme, že asynchronní aktivována metoda objektu B vrátí svou návratové hodnoty v čase tn, zatímco asynchronní aktivována metoda objektu C nám poskytne návratové hodnoty v čase tn + s. Všimněme si, že v asynchronním komunikačním modelu je přímá časová závislost (PCZ) mnohem méně významná než v synchronního komunikačního modelu. Protože objekt A po zaslání zprávy objektu B nečeká na zpracování příslušné metody, může již v době t2 (přičemž platí, že t2 <tn) vytvořit a zaslat jinou asynchronní zprávu. 11. Protokol zpráv představuje veřejně přístupné rozhraní objektu a je třeba upozornit na skutečnost, že uživatelé objektu mají přístup pouze k tomuto veřejně přístupnému rozhraní (atributy i metody objektu jsou skryté). To však stačí, protože rozhraní nabízí kompletní aparát, jehož prostřednictvím mohou uživatelé využívat všechny služby objektu.
12.Objekty s funkčně spřízněnými atributy a metodami patří do stejné třídy objektů. Třídu objektů můžeme charakterizovat jako množinu funkčně ekvivalentních objektů. Objekty jsou instancemi stejné třídy (Poz. 3.) . Každý objekt třídy má své vlastní atributy a metody (Poz. 4.) Poznámka 3.: Ačkoliv obecná teorie objektově orientovaného programování nespecifikuje třídu jako základní předpis pro vytváření objektů, hybridní programovací jazyky s největší penetrací na trhu takovou specifikaci uplatňují. V jejich prostředí je nutné nejdříve deklarovat třídu, která determinuje fyzickou reprezentaci a možnosti použití budoucích objektů (instancí dané třídy). Poznámka 4.: V konkrétní implementaci objektově orientovaného programování v hybridním programovacím jazyce je situace odlišná. Přestože každý objekt má svou vlastní sadou atributů, metody objektů téže třídy jsou v operační paměti uloženy právě jednou. Samotná činnost metody pak probíhá tak, že metoda si po své aktivaci vyhledá objekt, v souvislosti s kterým bude zpracována.
13. Objekty mohou dědit vlastnosti a činnosti od jiných objektů. To se děje v procesu dědičnosti, kdy potomci přebírají charakteristické rysy svých rodičů. Třídy objektů mohou vytvářet různé varianty dědičnosti. Pokud potomek dědí své schopnosti pouze od jednoho rodiče, jde o jednoduchou dědičnost. Naopak, když potomek zdědil své schopnosti od několika rodičů současně, říkáme o vícenásobné dědičnosti. Potomci však nejsou odkázáni pouze na ty schopnosti, které zdědili po svých rodičích. K již nabytým (zděděný) vlastnostem a činnostem mohou přidávat nové vlastnosti a činnosti. Z hierarchie objektů, které vzniknou na bázi dědičnosti, je zřejmé, že potomci jsou vždy přinejmenším tak funkčně vyspělí než jejich rodiče. Zpravidla jsou však potomci vyspělejší než jejich předkové, protože mají možnost rozšířit aparát svých schopností. To nás přivádí k zajímavé a vskutku jedinečné vlastnosti objektově orientovaného programování, z níž vyplývá, že potomek se může vyskytnout všude tam, kde je očekávaný jeho rodič. Je tedy možné provést substituci rodiče potomkům bez vzniku kolizních stavů. Podotkněme, že naopak tento proces nefunguje. Totiž tam, kde je očekávaný potomek, nemůže být dosazen rodič tak, aby nedošlo ke vzniku chybových stavů. Je to proto, že rodič není schopen plně zastoupit svého potomka, protože ten může být funkčně vyspělejší než on.
Vztahy mezi objekty nemusí být generovány pouze na základě dědičnosti. Kromě dědičnosti, je možné modelovat vazby mezi objekty i pomocí asociativní relací. K těmto relacím patří agregace a kompozice. Jejich podstata spočívá v tom, že objekt může vzniknout složením z jiných objektů. V tomto kontextu rozlišujeme hlavní (nadřazený) objekt a množinu podobjektů, které nadřazený objekt obsahuje. Agregační-kompoziční vztahy se využívají především při konstrukci složitých objektů, které vykonávají širokou škálu činností. Nadřazený objekt pak může delegovat pravomoci k provádění určitých činností na různý počet vnořených objektů. Podle síly vazby, jaká panuje mezi nadřazeným objektem a podobjektů, jsou jejich vztahy definované pomocí agregace nebo kompozice. Obecně, kompozice reprezentuje silnější asociativní vazbu, přičemž říká, že nadřazený objekt nemůže poskytovat svým uživatelům všechny služby v odpovídající kvalitě, pokud je alespoň jeden vnořený objekt nefunkční, resp. Neexistence. Zatímco při kompozici nemohou podobjektů pracovat samostatně bez nadřazeného objektu, agregace tento způsob použití podobjektů umožňuje. Obdobně, jako u již zmíněných komunikačních modelech, nadřazený objekt komunikuje s vnořenými objekty pomocí mechanismu zpráv. Všechny vnořené objekty disponují svými protokoly zpráv, které formují jejich veřejně přístupné rozhraní. Obr. 7:
15. Pokud dva objekty reagují na zaslání totožné zprávy odlišným způsobem, říkáme, že se chovají polymorfie. Polymorfizmus je aspekt objektově orientovaného programování, který úzce souvisí s dědičností a umožňuje vzájemnou substituci objektů (potomci jsou schopni zastoupit svých předků). Obr. 8: polymorfní chování instancí tříd
Vizualizaci programu, který byl vytvořen v ryze objektově orientovaném programovacím jazyce, uvádí obr.. 9. Obr. 9: Ryze objektově orientovaný program
Hybridní a objektově orientované programovací jazyky Většina v praxi rozšířených programovacích jazyků patří do kategorie hybridních programovacích jazyků, protože v sobě kombinuje možnosti pro vývoj strukturovaného a objektově orientovaného počítačového softwaru. U některých jazycích je jejich zařazení do této kategorie dané požadavkem na zachování zpětné kompatibility. K hybridním programovacím jazykem patří C #, C + +, Visual Basic, Delphi a Java. Vedle hybridních programovacích jazycích existují i ryze objektově orientované jazyky, ke kterým patří zejména dynamické jazyky řešící úkoly pro potřeby umělé inteligence, simulace, počítačové grafiky atd.. Množinu ryze objektově orientovaných programovacích jazyků je Smalltalk, CLOS, Eiffel, ESP a Object-Prolog. Program vytvořený v ryze objektově orientovaných jazycích není závislý na hlavní funkce, resp. metody, která zahajuje zpracování programů vytvořených v hybridních programovacích jazycích. V ryze objektových programech se exekuce začíná zasláním zprávy z rozhraní programu objektům, které na tuto zprávu příslušným způsobem reagují.
. Komponentové programování Komponentové programování je modulární nadstavbou objektově orientovaného programování. Komponentové programování využívá celý aparát objektově orientovaného programování, přičemž pomocí objektů vytváří komponenty, které charakterizujeme jako softwarové jednotky vyššího kvalitativního stupně. Základní princip komponentního programování spočívá ve vytváření komponent, které jsou natolik inteligentní, aby dokázali na sebe převzít odpovědnost za realizaci množiny příbuzných činností aplikace, resp. počítačového systému. Komponentové programování vychází z premisy, že software by měl být vytvářen přesně tak, jak produkty průmyslové výroby, které se vyrábějí hromadně v pásové výrobě. Velmi oblíbená je analogie zejména s automobilovým průmyslem, kde se auta vyrábějí na výrobní lince. Výrobní proces je značně komplikovaný, ale je dobře strukturovaný do jednotlivých výrobních fází. V každém stádiu se podoba finálního výrobku mění v závislosti na komponent, které jsou do něj instalovány. Pokud je možné vyrobit auto jako umně navrženou a implementovanou kombinaci několika tisíců různých technických komponentů, proč by podobným stylem nemohl být produkován i počítačový software? Komponentové programování říká, že i v softwarovém světě lze zhotovit samostatné programové součástky, z nichž se pak zkonstruován finální program. Aby bylo možné naplnit tuto ideu, musí být přijata následující postuláty:
1. Aplikace (A) je konečnou neprázdného množinou prvků (K), kterou můžeme matematicky definovat takto: 2.Jeden z komponentů aplikace zaujímá stanovisko primárního prvku. Primární komponent je bázový prvek, který zajišťuje jadernou funkcionalitu komponentové aplikace. Pokud by aplikace nedisponovala primárním komponentům, nemohla by fungovat. 3. Kromě primárního prvku může být aplikace tvořena libovolnou přípustnou množinou dalších (komplementárních) komponentů. Každý z komplementárních komponentů je odpovědný za vykonávání určité množiny činností aplikace. Pokud odhlédneme od nutné přítomnosti primárního prvku, tak můžeme konstatovat, že finální podoba aplikace může být značně variabilní, a tedy konfigurovatelná. Protože komponenty jsou navrženy na modulární bázi, můžeme vytvořit rozmanitou kolekci komplementárních komponentů. Modularita komponent je výhodná nejen z pohledu vývojářů, ale i cílových uživatelů. V závislosti na svých potřeb mohou uživatelé přímo ovlivnit konečnou komponentní skladbu aplikace.
Softwarové firmy často produkují různé verze komponentových aplikací, které se liší množstvím instalovaných komponent. Uvažujme třeba aplikaci na zpracování grafických obrazů, která v základní verzi obsahuje dvě složky: primární komponent provádějící načítání a zobrazování bitových map různých grafických formátů a jeden doplňkový prvek provádějící grafické transformace, jakými jsou inverze bitové mapy, převod bitové mapy do sivotónu a prahovanie bitové mapy . Tvůrce komponentové aplikace však může dodávat i jiné doplňkové komponenty, které si uživatel může zakoupit (např. komponent umožňující vytvářet z kolekcí bitových map videosoubory). Uživatel se může rozhodnout, které prvky zakoupit a které ne. Softwarová firma může zase kategorizovat komponentové aplikace podle počtu implementovaných komponent (např. základní, pokročilá zda luxusní verze komponentové aplikace). Vizuální podobu komponentové aplikace můžeme vidět na obrázku. 10.
4. Každý prvek je charakterizován těmito vlastnostmi: a.) Identifikace. Komponent musí být jednoznačně identifikovatelný (a to jak v aplikaci, tak v informačním a operačním systému). Díky jednoznačné identifikaci mohou existovat dva stejné komponenty, které se liší pouze svými identifikačními čísly. Podotknul, že v praktických podmínkách je identifikační číslo dílu často shodné s číslem verze komponentu. b.) Zapouzdření. Komponent zabudovány veškerou požadovanou funkcionalitu v sobě. Přestože z vnějšího pohledu to není zřejmé, ve svém nitru obsahuje komponentu soupravu objektů s delegovanými pravomocemi pro provádění specifikovaných činností (obr. 11). S objekty komunikuje komponent pomocí mechanismu předávání a přijímání zpráv. Obr. 11: Obr.11.Primární komponenta -interní kompozice primárního prvku
c.) Rozhraní. Podobně jako objekty, i součásti mají své veřejně přístupné rozhraní, pomocí kterých využívají uživatelé jejich služby. Při funkčně spřízněných součástech je rozhraní standardizované, unifikované a typizované. Komponent stejně ukrývá data a provádění činností, které provádí. Všechny tyto aspekty jsou před vnějším světem vhodně ukryté. d.) Připravenost k použití. Komponent působí za každých okolností jako hotová softwarová součástka, která poskytuje komplexní automatizaci vybraných činností. Za předpokladu, že klient má ke komponentu přístup, může okamžitě začít využívat jeho služby prostřednictvím veřejně přístupného rozhraní. e.) Opětovná použitelnost. Pokud je prvek vyvinutý, odladěný, otestován a optimalizován, můžeme ho použít tolikrát, kolikrát potřebujeme. Komponentové programování v tomto směru dále rozvíjí myšlenku objektového programování, jejímž smyslem je značný nárůst produktivity vývojářů pomocí opakované použitelnosti jednou vytvořené softwarové entity. f.)Anonymita uživatelů. Funkcionalita komponentu je zcela oddělena od jeho aplikace. Komponenta musí poskytovat služby v odpovídajícím čase a kvalitě jakémukoli uživateli, který má zájem komponent použít. Protože neexistuje žádná fixace na uživatele, báze praktického využití části je velmi široká. g.)Interoperabilita. Komponenty musí být schopny mezi sebou spolupracovat, i když byly vytvořeny v různých integrovaných vývojových prostředích a programovacích jazycích. V zájmu uplatnění bezproblémové komunikace mezi součástmi musí být interoperabilita zajištěna na nízké, zpravidla binární úrovni.
5. Vybrané komponenty mohou vytvářet celky, které se sami o sobě mohou stát komponenty. Proces skládání komponent pracuje na podobných principech jako agregace, resp. kompozice objektů v objektově orientovaného programování. Identifikujeme tedy nadřazený komponent a soupravu podkomponentov (obr. 12). Obr.12 Skládání komponent
Zavedení pojmu objekt pomocí postulátů • Objekt obsahuje vnitřní paměť • Objekt obsahuje metody objektu • Přijímá a zpracovává zprávy z vnějšku • Objekt může obsahovat jiné objekty • Polymorfismus • Dědičnost Základní postuláty Ad1. Vnitřní paměť Objekt má vlastnost si něco pamatovat. Tato vnitřní paměť se někdy nazývá atributy objektu. Zaleží na programovacím jazyku , jak je tato vnitřní paměť , atributy, implementována konkrétně. V každém jazyku takováto možnost vytvářet objektům vnitřní paměť existuje. Vnitřní paměť objektu je z vnějšku nepřístupná,. Je pouze soukromou záležitostí objektu
Ad 2. Metody objektu jsou procedury nebo funkce (resp. obecněji posloupnosti kódu programu), které vykonávají nějakou činnost nad vnitřní pamětí objektu (a pouze nad ní). Také metody objektu jsou z vnějšku neviditelné – nepřístupné. Z uvedeného vyplývá, že nemůžeme metodu objektu zavolat přímo. Vnitřní paměť a metody objektu jsou vůči sobě velmi přátelské v tom smyslu, že jsou uvnitř objektu navzájem viditelné. Jinými slovy metoda objektu je to co je schopno pracovat s vnitřní pamětí objektu a nic jiného. Poznámka: Metody a atributy objektu jsou zevně neviditelné, a tedy takto definovaný objekt je totálně uzavřen vůči okolí v programu – a byl by tedy bez dalších definic nefunkční strukturou - černou programátorskou dírou. Ad 3. Schopnost přijímat zprávy z vnějšku v každém jazyce je schopnost přijímat zprávy z vnějšku implementována jinak. Avšak každý použitelný objekt obsahuje tzv. protokol zpráv, což je přiřazení zprávy versus metoda objektu. Každá zpráva v protokolu zpráv ma přiřazenu právě jednu metodu objektu. Přijmout a zpracovat zprávu pro objekt znamená, že objekt v protokolu zpráv nalezne odpovídající zprávu., kní nalezne odpovídající přiřazenou metodu a spustí ji se vstupními přijatými parametry a po vykonání metody vrátí zprávě výstupní parametry. Každá zprava může tedy mít vstupní a výstupní parametry. Důležité je, že protože metodu nevidíme , jedinou možností jak pracovat s objektem je poslat mu zprávu.
Vnitřní paměť Protokol zpráv Metody Objekt Objekt Objekt obsahuje vnitřní paměť obsahuje metody objektu má schopnost přijímat a zpracovávat zprávy může obsahovat jiné objekty Postuláty objektu
Ad 2. Metody objektu jsou procedury nebo funkce (resp. obecněji posloupnosti kódu programu), které vykonávají nějakou činnost nad vnitřní pamětí objektu (a pouze nad ní). Také metody objektu jsou z vnějšku neviditelné – nepřístupné. Z uvedeného vyplývá, že nemůžeme metodu objektu zavolat přímo. Vnitřní paměť a metody objektu jsou vůči sobě velmi přátelské v tom smyslu, že jsou uvnitř objektu navzájem viditelné. Jinými slovy metoda objektu je to co je schopno pracovat s vnitřní pamětí objektu a nic jiného. Poznámka: Metody a atributy objektu jsou zevně neviditelné, a tedy takto definovaný objekt je totálně uzavřen vůči okolí v programu – a byl by tedy bez dalších definic nefunkční strukturou - černou programátorskou dírou. Ad 3. Schopnost přijímat zprávy z vnějšku v každém jazyce je schopnost přijímat zprávy z vnějšku implementována jinak. Avšak každý použitelný objekt obsahuje tzv. protokol zpráv, což je přiřazení zprávy versus metoda objektu. Každá zpráva v protokolu zpráv ma přiřazenu právě jednu metodu objektu. Přijmout a zpracovat zprávu pro objekt znamená, že objekt v protokolu zpráv nalezne odpovídající zprávu., kní nalezne odpovídající přiřazenou metodu a spustí ji se vstupními přijatými parametry a po vykonání metody vrátí zprávě výstupní parametry. Každá zprava může tedy mít vstupní a výstupní parametry. Důležité je, že protože metodu nevidíme , jedinou možností jak pracovat s objektem je poslat mu zprávu.
Poznámka: Je třeba si uvědomit, že postuláty se nedokazují ale jsou základem pro odvozování určité teorie. Nyní nás čeká pouze logická cesta od postulátů k složitým tvrzením. Nyní v tomto stadiu studia víme co je jeden objekt. Zatím nehovoříme o třídách dědičnosti atd. Teoretický příklad definice objektu podle postulátů Způsob vytváření objektu je v různých jazycích různý. Většina jazyků v praxi používaných – jazyky Visual studia, Delphi atd. – k deklaraci objektu nutně potřebuje pojem třída, tento pojem je pro nás v tomto stadiu odvozování neznámý. Vytvořme si tedy pomyslný objektově orientovaný jazyk který umožní deklaraci objektu pomocí postulátů. Začátek deklarace Vytvoř jeden nový objekt OBJ1 ‘Abychom se na něj mohli odvolávat Nechť se objekt skládá z těchto objektů OBJV1, OBJV1,.. ‘Vnitřních objektů Nechť objekt má takovouto paměť ‘Následuje deklarace vnitřní paměti Nechť objekt má takovéto metody ‘Následuje deklaracemetod Nechť objekt má následující protokol zpráv ‘Následuje deklaracezpráv, kterým objekt bude rozumět a na které bude spouštět metody uvedené v předešlé deklaraci.
Uzavřenost objektu - encapsulating Encapsulating tvoří z objektu uzavřenou část programu, která se chová jako černá skříňka. Správně objektově navržený program obsahuje objekty , tedy samostatné uzavřené struktury, které obsahují další objekty atd. – vznikají tak vnořené objektové struktury. Každý z objektů je uzavřený a komunikuje s okolím pomocí zpráv. Objektový přístup má některé výhody proti neobjektovému, otázkou je jaké?. Proč činit strukturu programu složitější o takové struktury, jaké jsou objekty? Čím kladným se projeví v programování dodržování zásady uzavřenosti objektu, tj. nepřístupnosti metod a atributů a možností komunikace pouze přes zprávy? Jak vypadá program složený ze samých černých schránek? Jedno je jasné encapsulating vede k náročnějšímu.postupu při návrhu programu. Tvorba návrhu se jím na první pohled zdržuje, protože nutí tvůrce programu správně určit, co který objekt bude umět a co umět nebude. Tvůrce programu musí tedy nejprve určit kompetence objektu v programu. Výhody vysvětleme na příkladu.
record Bankovní účet Funkce A Funkce B Funkce C Majitel účtu Mějme bankovní systém vytvořený na základě metody procedurálního případně strukturo- vaného programování. Neobsahuje tedy žádné objekty a skládá se z procedur a funkcí, z globálních a lokálních proměnných. Při programování tohoto typu se využívalo částečně uzavřených datových struktur nazývaných záznam – record. Představme si bankovní systémkde jedním z rekordů je Bankovní účet. Účet musí znát Majitele účtu.