Export page to Open Document format

36 - Objektová orientace

  • rozšiřuje modulární jazyky jazyky o možnost spojit konkrétní data s operacemi
  • využívá dekompozici do modulů - tvoří samostatné celky, které tvoří objektově orientovaný systém
  • hlavní 3 výhody objektové orientace:
    1. analogie mezi softwarovým modelem a reálným modelem
    2. flexibilita takovýchto softwarových modelů
    3. jejich znovupoužitelnost
  • OO jazyky: Simula 67, Smalltalk 72 a 80, C++, Java, C#, PHP, Python, Lisp, …
    1. čistě objektové jazyky - Smalltalk, Ruby, Python
    2. hybridni jazyky - objektově orientované - založeny na imperativním progragramování, částečně implementují vlastnosti objektového programování - C++, Java
      1. mají základní kořenovou třídu (Java - třída Object)
      2. nemají základní třídu (C++)
    3. objektové rozšíření původně neobjektových jazyků - Object Pascal

Základní pojmy

1. Objekt

  • entita
    1. zapouzdřující stavové informace (data reprezentovaná dalšími objekty)
      • vlastnosti objektu
      • instanční proměnné, atributy
    2. poskytující sadu operací nad tímto objektem nebo jeho částmi
      • chování objektu
      • komunikují mezi sebou pomocí zpráv (základní komunikační jednotka)
      • odesilatel (posílá zprávu), příjemce (reaguje na zprávu vhodnou metodou)
      • množina zpráv, kterým objekt rozumí je protokol/rozhraní objektu
  • spojuje tyto dvě základní části do jednoho celku
  • základní jednotka modularity i struktury v OO programu

Identita vs. Shoda

  • až OOP nás nuní tyto dvě věci přísněji rozlišovat
    1. shoda (==) - říká nám, zda jsou objekty obsahově stejné
    2. identita (===) - říká nám, zda se jedná o ukazatele na ten samý objekt

2. Abstrakce

  • schopnost programu zjednodušit některé aspekty informací / vlastnosti objektů, se kterými program pracuje
  • černá skříňka - pracujeme s ní pomocí definovaného rozhraní, ale už nás nezajímá, jak byla vytvořena a co je v ní
  • variant/invariant - část programu, kde se hodnoty proměnných mění/nemění při opakovaném průchodu této časti kódu

Modifikátory viditelnosti

  • mechanismus, kterým se dá docílit definování, které metody a proměnné budou komu přístupné
  • tímto mechanismem podrobněji konfigurujeme koncept zapouzdření
  • podle jazyka UML známe tři základní modifikátory
    1. soukromý (private) - přístupné pouze z metod stejné třídy
    2. chráněný (protected) - přístupné pouze ze stejné třídy + tříd odděděných
    3. veřejný (public) - dostupné všude
    4. existují i další internal, friend, …

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
  • reakce na stejnou zprávu se liší v závislosti na objektu, kterému byla zaslána
  • využívá se u rozhraní (Interface), kde více tříd implementuje jedno rozhraní

například mějme Interface Tvar, který deklaruje metodu vypocitejObsah() ⇒ dále si pak vytvoříme jednotlivé tvary - Ctverec a Obdelnik, ktere budou implementovat nase rozhrani Tvar ⇒ tedy musi definovat vsechny metody, ktere nase rozhrani obsahuje ⇒ v nasem pripade metodu vypocitejObsah(), ktera se bude list v zavislosti na zvolenem tvaru

Přetěžování metod

  • existuje i polymorfismus, kde posíláme jednomu objektu zprávy, které se liší pouze v parametrech (parametrický polymorfismus)

například nase třída Obdelnik by mohla mít hned několik konstruktorů:
> public Obdelnik() - vytvoří defaultní obdélník například o velikosti stran a=4, b=5 jednotek
> public Obdelnik(int a, int b) - vytvoří obdélník o zadaných velikostech
> public Obdelnik(Point bod) - vytvoří obdélník o velikostech definových v jiné třídě

Přetěžování operátorů

  • další možnost polymorfismu je polymorfismus operátorů

například operátor + může sečíst dvě čísla, může konkatenovat dva řetězce, může sečíst jednotlivé položky dvou asociativních polí

Č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í
  • 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

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

  • 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:
    1. vícenásobná
    • možnost dědit více tříd najednou
    • má více nevýhod než výhod (konflikty jmen, pořadí kon/destruktorů)
    • C++
    1. jednoduchá
    • možnost dědit pouze jednu třídu
    • řeší problém konfliktů jmen
    • nemožnost dědičnosti více tříd se zajistí pomocí implementace rozhraní, kde počet není omezen
    • Java
  • co dědíme:
    1. dědičnost implementace (Java - extends) - rozšíření třídy ⇒ přebíráme už nadefinované metody
    2. dědičnost rozhraní (Java - implements) - nutí nás implementovat dané metody
  • redefinice metody - přepsání třídy - viz. polymorfismus

Rozhraní

  • schéma, které deklaruje seznam metod (jména, parametry, návratové typy)
  • použití rozhraní na jistou třídu pak vynucuje implementaci všech metod uvedených v rozhraní ⇒ rozhraní nám může vynutit, co je třeba naimplementovat
  • 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:
    1. class-based - třídní jazyky (třídně orientované)
    2. 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ů:
    1. hluboká - kromě objektu samotného jsou kopírovány i obkekty, které instanční proměnné objektu referencují
    2. 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:
    1. 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
    2. 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:
    1. instančními proměnnými a metodami
    • každý objekt má svou hodnotu proměnných
    • na zprávy reaguje daný objekt
    1. 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 zapozdření a 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ý:
      1. obsahuje sloty instančních proměnných s defaultními hodnotami
      2. 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

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í
    1. 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
    2. 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

<if-stmt>
::= if <condition> then <stmts> <else-if>
<else-if>
::= endif ;
| else <stmts> endif ;
| <elsif> <else-if>

ς-kalkul

  • sigma kalkul
  • jeden z formálních popisů OOJ
  • pro popis syntaxe a sémantiky
  • stručný popis zde (zdroj - FIT-server)

UML

  • další možný formalismus
  • grafický jazyk
  • více 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:
    1. lexikální a syntaktická analýza - podobná úroveň jako u modulárních jazyků
    2. sémantická analýza - oproti modulárním jazykům mnohem náročnější
  • 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

+

  • vyšší míra abstrakce
  • jednodušší dekompozice problému
  • přirozenější práce (modelujeme reálné objekty)
  • udržovatelnost a rozšiřitelnost
  • znovupoužitelnost

-

  • v některých oblastech neexistuje analogie s reálnými objekty a pak je obtížné určit a definovat intuitivně ty softwarové
  • složitější sémantika - více času na naučení
  • nemožnost porušovat koncepci zapouzdření (obchází se Modifikátory viditelnosti)
  • výsledný generovaný kód je pomalejší
  • režie na uložení objektů v paměti (např. odkaz na třídu objektu)

Zdroj

Při tvorbě tohoto tématu jsem čerpar především z druhých skript IPP. Snažil jsem se udělat co nejpřehlednější výtah pro rychlé učení.

Potvrzení

36
Celé jménoOK!!!
Jirka Hynek2011-02-14 14:15:09 
vagy2011-02-15 12:39:52 
Tom Ofeig2011-05-11 22:42:00 
 3

Diskuze

Jirka Hynekgeorge, 2011/02/14 17:41

Dodělána kapitola Překladače na přání Honzy.

Jirka Hynekgeorge, 2011/03/01 19:26

Btw… k tomu přetěžování operátorů, jak jsme se dohadovali na srazu:

Přetěžování operátorů v Javě není.

Operátor == porovnává, jestli dvě reference jsou na stejný objekt.

String a = new String("ahoj");
String b = new String("ahoj");
if(a == b) {
	System.out.println("Jsou stejne");
}
else {
	System.out.println("Nejsou stejne");
}

Výsledek: Nejsou stejne

Nemá to nic společného s equals(), které slouží k porovnávání obsahu. Přetěžuje se v případě, že si vytvoříme vlastní objekt s vlastními pravidly porovnávání.

String a = new String("ahoj");
String b = new String("ahoj");
if(a.equals(b)) {
	System.out.println("Jsou stejne");
}
else {
	System.out.println("Nejsou stejne");
}

Výsledek: Jsou stejne … protože to porovnává obsah … pokud bych si vytvořil vlastni String, mohl bych si nadefinovat vlastní equals, že bych třeba řekl, že ahoj je stejný s reverzním joha, kdybych ale použil opět == , porovnávalo by to opět reference…

vagyvagabund, 2011/04/12 21:19

Dobry priklad. Tezko uverit, ze jsme to probirali vic jak pred mesicem

Jiří Husákxhusak05, 2013/05/28 16:36

Chybí návrhové vzory: singleton, abstraktní továrna, iterátor, dekorátor

Kameetest147.229.209.143, 2015/06/13 06:46

„rodicovsky slot=ukazatele na objekt, z kterých byly vytvořeny“

Odkial berete tuti hovadinu nechapem sak sa pozrite na tu ukazku so selfu…

Vložte svůj komentář
 
temata/36-obejktova_orientace/main.txt · Poslední úprava: 2011/05/06 18:10 autor: vagabund
Recent changes RSS feed Debian Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki