OBSAH WEBU
ČTĚTE!
Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
temata:36-obejktova_orientace:main [2011/02/13 16:56] george |
temata:36-obejktova_orientace:main [2011/05/06 18:10] (aktuální) vagabund [36 - Objektová orientace] |
||
---|---|---|---|
Řádek 1: | Řádek 1: | ||
+ | ~~ODT~~ | ||
+ | |||
====== 36 - Objektová orientace ====== | ====== 36 - Objektová orientace ====== | ||
Řádek 10: | Řádek 12: | ||
- __čistě objektové jazyky__ - Smalltalk, Ruby, Python | - __čistě objektové jazyky__ - Smalltalk, Ruby, Python | ||
- __hybridni jazyky__ - objektově orientované - založeny na imperativním progragramování, částečně implementují vlastnosti objektového programování - C++, Java | - __hybridni jazyky__ - objektově orientované - založeny na imperativním progragramování, částečně implementují vlastnosti objektového programování - C++, Java | ||
+ | - mají základní kořenovou třídu (Java - třída Object) | ||
+ | - nemají základní třídu (C++) | ||
- __objektové rozšíření původně neobjektových jazyků__ - Object Pascal | - __objektové rozšíření původně neobjektových jazyků__ - Object Pascal | ||
===== Základní pojmy ===== | ===== Základní pojmy ===== | ||
* na těchto pojmech/metodách je objektově orientované programování založeno | * na těchto pojmech/metodách je objektově orientované programování založeno | ||
- | * **__Objekt, Abstrakce, Polymorfismus, Dědičnost__** | + | * **[[#1. Objekt|Objekt]], [[#2. Abstrakce|Abstrakce]], [[#3. Zapouzdření|Zapouzdření]], [[#4. Polymorfismus|Polymorfismus]], [[#5. Dědičnost|Dědičnost]]** |
==== 1. Objekt ==== | ==== 1. Objekt ==== | ||
Řádek 52: | Řádek 56: | ||
- existují i další internal, friend, ... | - existují i další internal, friend, ... | ||
- | ==== 3. Polymorfismus ==== | + | ==== 3. Zapouzdření ==== |
+ | * souvisí s abstrakcí | ||
+ | * uživatel nemůže měnit interní stav objektů libovolným (tedy i neočekávaným) způsobem, ale musí k tomu využívat poskytované rozhraní (operace nad objektem) | ||
+ | * každý objekt má protokol, který definuje, jak komunikovat s objektem | ||
+ | |||
+ | ==== 4. Polymorfismus ==== | ||
* mnohotvárnost | * mnohotvárnost | ||
Řádek 73: | Řádek 82: | ||
</note> | </note> | ||
- | ==== 4. Dědičnost ==== | + | === Časná a pozdní vazba === |
+ | |||
+ | * při překladu nemusí být zřejmé díky polymorfismu s jakým typem objektu budeme pracovat => **časná/statická vazba** | ||
+ | * => to může mít za následek, že nemusíme zvolit správnou metodu (pracujeme s objekty na abstraktní úrovni) | ||
+ | * => je třeba identifikovat potřebnou metodu až za běhu programu, kdy je nutné ji invokovat => **pozdní/dynamická vazba** | ||
+ | * => k implementaci se používají **VMT - tabulky virtuálních metod** => každá instance třídy, která obsahuje virtuální metody, obsahujeodkaz do VMT | ||
+ | * => VMT obsahuje ukazatele na konkrétní metody, které jsou pro daný typ platné | ||
+ | * u dynamický typovaných OO jazyků jsou všechny metody virtuální | ||
+ | |||
+ | ==== 5. Dědičnost ==== | ||
* způsob, jak implementovat sdílené chování | * způsob, jak implementovat sdílené chování | ||
* v případech, kdy chceme rozšířit nějakou třídu o dané vlastnosti | * v případech, kdy chceme rozšířit nějakou třídu o dané vlastnosti | ||
+ | * reflexivní, tranzitivní (dědí hierarchicky všechny třídy) a antisymetrická relace | ||
<note tip> //jako příklad jde uvést třída Hráč, která má vlastnosti, jméno, příjmení, věk => existují ovšem různé typy hráčů, jako je útočník, obránce, brankář => u každého si budeme ovšem chtít pamatovat jiné vlastnosti (střelené góly vs. zákroky) => proto vytvoříme dané třídy rozšířením základní třídy hráč => třídy budou sdílet pouze atributy z rozšiřované třídy// </note> | <note tip> //jako příklad jde uvést třída Hráč, která má vlastnosti, jméno, příjmení, věk => existují ovšem různé typy hráčů, jako je útočník, obránce, brankář => u každého si budeme ovšem chtít pamatovat jiné vlastnosti (střelené góly vs. zákroky) => proto vytvoříme dané třídy rozšířením základní třídy hráč => třídy budou sdílet pouze atributy z rozšiřované třídy// </note> | ||
- | * metoda/klíčové slovo super => požívá se např. v konstruktoru více specifické třídy, kdy se odkazujeme na třídu, z které dědí (voláme konstruktor děděné třídy) | + | * metoda/klíčové slovo ''super'' => požívá se např. v konstruktoru více specifické třídy, kdy se odkazujeme na třídu, z které dědí (voláme konstruktor děděné třídy) |
* **typy dědičnosti:** | * **typy dědičnosti:** | ||
- __vícenásobná__ | - __vícenásobná__ | ||
Řádek 91: | Řádek 110: | ||
* nemožnost dědičnosti více tříd se zajistí pomocí implementace rozhraní, kde počet není omezen | * nemožnost dědičnosti více tříd se zajistí pomocí implementace rozhraní, kde počet není omezen | ||
* Java | * Java | ||
+ | * **co dědíme:** | ||
+ | - __dědičnost implementace__ (Java - ''extends'') - rozšíření třídy => přebíráme už nadefinované metody | ||
+ | - __dědičnost rozhraní__ (Java - ''implements'') - nutí nás implementovat dané metody | ||
+ | * **redefinice metody** - přepsání třídy - viz. polymorfismus | ||
=== Rozhraní === | === Rozhraní === | ||
Řádek 98: | Řádek 121: | ||
* každé třídě uvést několik rozhraní | * každé třídě uvést několik rozhraní | ||
+ | ===== Datové a řídící abstrakce ===== | ||
+ | |||
+ | * ve většině případů požadujeme, aby nějaká množina objektů rozuměla stejným zprávám => je nepraktické mít v každém objektu znova implementované ty samé metody => výhodnější je naprogramovat šablonu | ||
+ | * **máme dvě možnosti:** | ||
+ | - __class-based__ - třídní jazyky (třídně orientované) | ||
+ | - __object-based__ - prototypovací jazyky (prototypově orientované) | ||
+ | |||
+ | ==== 1. Třídně orientované jazyky ==== | ||
+ | |||
+ | * zavádí pojem **třída** | ||
+ | * metadata objektu | ||
+ | * šablona (otisk), podle níž mohou být vytvářeny objekty (instance této třídy) | ||
+ | * stará se také o správu protokolu objektu, směrování zpráv a obsahuje implementace některých | ||
+ | * po zavedení pojmu třída lze na dědičnost nahlížet jako na vytváření podtypů a nadtypů | ||
+ | |||
+ | === Instanciace objektů === | ||
+ | |||
+ | * proces vytváření konkrétního objektu (instance) podle nějaké třídy | ||
+ | * po vytvoření objektu je třeba zavolat **konstruktor** (často metoda/klíčové slovo //new//) | ||
+ | metod => inicializuje datové položky objektu | ||
+ | * **vytváření kopií objektů:** | ||
+ | - __hluboká__ - kromě objektu samotného jsou kopírovány i obkekty, které instanční proměnné objektu referencují | ||
+ | - __mělká__ - hluboká kopie hloubky 0 - kopíruje jenom objekt samotný | ||
+ | |||
+ | === Destrukce objektů === | ||
+ | |||
+ | * proces rušení objektů/instancí | ||
+ | * **zde máme opět dvě metody:** | ||
+ | - __automaticky__ | ||
+ | * stará se o to //garbage collector// | ||
+ | * jednou za čas se vyhledají objekty, na které už neexistuje žádný odkaz | ||
+ | * těsně před zrušením se může zavolat metoda //finalizace// - zajistí úklid | ||
+ | * Java | ||
+ | - __manuálně__ | ||
+ | * o uvolňování se musíme starat sami | ||
+ | * používá se //destruktor// | ||
+ | * v případě špatného uvolňování vznikají úbytky paměti - //memory leaks// | ||
+ | * C++ | ||
+ | |||
+ | === Static === | ||
+ | |||
+ | * **je třeba rozlišovat mezi:** | ||
+ | - __instančními proměnnými a metodami__ | ||
+ | * každý objekt má svou hodnotu proměnných | ||
+ | * na zprávy reaguje daný objekt | ||
+ | - __třídními proměnnými a metodami__ | ||
+ | * posíláme zprávy třídě a nemusíme mít přitom vytvořený žádný objekt | ||
+ | * daná proměnná je pouze jedna - nevztahuje se k danému objektu ale třídě | ||
+ | |||
+ | ==== 2. Prototypově orientované jazyky ==== | ||
+ | |||
+ | * nejdůležítějšími vlastnostmi jsou [[#3. Zapouzdření|zapozdření]] a [[#4. Polymorfismus|polymorfismus]] | ||
+ | * znají pouze jediný typ objektů a nevyčleňují objekty, které by reprezentovaly nějakou třídu | ||
+ | * **nerozlišuje se mezi entitami a třídami ([[#Static]])** | ||
+ | * jsou pouze objekty, které obsahují členské proměnné a metody => tyto složky se nazývají **Sloty** | ||
+ | * pokud je objektu poslaná zpráva, prozkoumá množinu svých slotů | ||
+ | * nové objekty se vytváří mělkým kopírováním již existujících (**klonováním**) | ||
+ | * objekty mohou obsahovat **rodičovské sloty** | ||
+ | * ukazatele na objekt, z kterých byly vytvořeny | ||
+ | * při volání metody objekt nejprve projde své sloty a pokud nenajde, odkáže se přes rodičovský slot na rodičovský objekt (**delegace**) => po nalezení slotu (metody) je spuštěn kód => __jako příjemce je označen objekt, který delegaci provedl__ | ||
+ | * třídy se sdíleným chováním lze nahradit **rysy** | ||
+ | * objekty, které obsahují pouze metody | ||
+ | * nové objekty mají v rodičovském slotu ukazatele na rys | ||
+ | * provázáním rysů lze řešit dědičnost (některé jazyky umožňují mít více rodičovských slotů) | ||
+ | * jelikož sloty jde dynamicky měnit, lze dosáhnout //dynamické dědičnosti// | ||
+ | * k plnému nahrazení tříd nám ovšem rysy nestačí - je třeba zavést **prototypy** | ||
+ | * řeší problém instančních proměnných, kde každý objekt musí mít jejich samotnou kopii | ||
+ | * rys je doplněn objektem (šablonou), který: | ||
+ | - obsahuje sloty instančních proměnných s defaultními hodnotami | ||
+ | - ve svém rodičovském slotu odkazuje daný rys | ||
+ | * nová instance se vytvoří nakopírováním dané šablony (**viz obrázek**) | ||
+ | * jazyk SELF (1986) - dialekt Smalltalku založený na prototypech | ||
+ | * JavaScript - od SELFu se značně odlišuje | ||
+ | * vhodné pro názorné a vizuální modelování, prototypování a programování | ||
+ | * nevýhoda jazyků - vyšší režie | ||
+ | |||
+ | {{:temata:36-obejktova_orientace:prototyp.jpg|Prototyp, rys a klonování objektů}} | ||
+ | |||
+ | ===== Formální základ ===== | ||
+ | |||
+ | * jako u formálních jazyků není nezbytný pro návrh OO jazyka | ||
+ | * **lze rozdělit do dvou částí** | ||
+ | - syntaxe | ||
+ | * popisována pomocí kombinace (E)BNF - (Extended) Backus-Naurova forma, bezkontextových gramatik a slovního popisu s příklady | ||
+ | * dáno tím, že syntaxe je podobná modulárním jazykům - pár klíčových slov navíc | ||
+ | - sémantika | ||
+ | * zásadní změny oproti modulárním jazykům | ||
+ | * velmi složitá na popis formální, proto používá spíše slovní popis a příklady | ||
+ | |||
+ | ==== Backus-Naurova forma ==== | ||
+ | |||
+ | <code> | ||
+ | <if-stmt> | ||
+ | ::= if <condition> then <stmts> <else-if> | ||
+ | <else-if> | ||
+ | ::= endif ; | ||
+ | | else <stmts> endif ; | ||
+ | | <elsif> <else-if> | ||
+ | </code> | ||
+ | |||
+ | ==== ς-kalkul ==== | ||
+ | |||
+ | * //sigma kalkul// | ||
+ | * jeden z formálních popisů OOJ | ||
+ | * pro popis syntaxe a sémantiky | ||
+ | * stručný popis {{:temata:36-obejktova_orientace:sigma_kalkul_s3rvac.pdf|zde}} (zdroj - FIT-server) | ||
+ | |||
+ | ==== UML ==== | ||
+ | |||
+ | * další možný formalismus | ||
+ | * grafický jazyk | ||
+ | * více [[temata:31-uml:main|zde]] | ||
+ | |||
+ | ===== Překlad ===== | ||
+ | * ukládá popis každé třídy do speciálního prostoru | ||
+ | * vytváří graf závislostí jednotlivých tříd a poté je lineárně uspořádává => na to nemusí stačit jeden průchod | ||
+ | * náročná je práce s jmennými prostory a modifikátory viditelnosti | ||
+ | * **fáze:** | ||
+ | - __[[temata:22-prekladace:main#Lexikální analyzátor|lexikální]] a [[temata:22-prekladace:main#Syntaktický analyzátor|syntaktická]] analýza__ - podobná úroveň jako u modulárních jazyků | ||
+ | - __[[temata:22-prekladace:main#Sémantický analyzátor|sémantická]] analýza__ - oproti modulárním jazykům mnohem náročnější | ||
+ | * kontrola implicitního přetypování ([[#Časná a pozdní vazba]]) | ||
+ | * kontrola explicitního přetypování objektu ([[#4. Polymorfismus|Polymorfismus]]) | ||
+ | * [[#Modifikátory viditelnosti]] | ||
+ | * **interpret** | ||
+ | * k práci potřebujeme //workspace// - uchováváme si v něm všechny objekty, s kterými se pracuje | ||
===== Výhody a nevýhody ===== | ===== Výhody a nevýhody ===== | ||
Řádek 116: | Řádek 264: | ||
* režie na uložení objektů v paměti (např. odkaz na třídu objektu) | * režie na uložení objektů v paměti (např. odkaz na třídu objektu) | ||
+ | ===== Zdroj ===== | ||
+ | |||
+ | <note> | ||
+ | Při tvorbě tohoto tématu jsem čerpar především z [[https://wis.fit.vutbr.cz/FIT/st/course-files-st.php/course/IPP-IT/texts/IPP-II-ESF-1_1_printable.pdf|druhých skript IPP]]. Snažil jsem se udělat co nejpřehlednější výtah pro rychlé učení. | ||
+ | </note> | ||
===== Potvrzení ===== | ===== Potvrzení ===== | ||