10. Základní pojmy z OOPTato kapitola je určena těm, kteří nemají zkušenosti se žádným objektovým jazykem a stručně vysvětluje základní pojmy z objektově orientovaného programování (OOP). Ostatním postačí, když se seznámí s kap. 10.5..10.1. ObjektKaždý větší program se skládá z několika modulů - jeden se stará o výstup na obrazovku a zpracovává pokyny od uživatele, další provádí výpočty, ještě jiný posílá data po síti atd. Každý tento modul je naprogramován do značné míry samostatně, nejen proto, aby se v něm autor po půl roce sám vyznal, ale zejména se již hotové (a odladěné!) moduly dají použít v dalších programech.
Objekt je runtime entita (1) skládající se z proměnných, zvaných členské proměnné (member variables), a příslušejících funkcí, zvaných metody (methods). V členských proměnných je obsažen stav objektu, tj. vše, co si objekt "pamatuje", a metody vyjadřují jeho chování, tedy vše, co objekt "umí".
Uzavřenost (encapsulation) je jednou z nejdůležitějších vlastností objektů a má kromě bezpečnosti ještě výhodu skrytí vnitřní implementace a modularity - softwarový objekt může být při zachování rozhraní metod uvnitř zcela přeprogramován a může se libovolně měnit vnitřní struktura dat (členských proměnných), ale není třeba přizpůsobovat okolí. V programech se uzavřenost úplně striktně nedodržuje - například pokud objekt reprezentuje pouze datovou strukturu (nemá metody), nebo z důvodu rychlosti - a je možné povolit přímý přístup k libovolným členským proměnným (viz 11.4.). To by se však mělo týkat pouze těch proměnných, jejichž změnou zvenčí nelze uvést objekt do nekonzistentního ("nesmyslného") stavu - např. u souboru nastavení pozice pro čtení na zápornou hodnotu. Jeden objekt se samozřejmě může obsahovat další, vše záleží na zvolené rozlišovací schopnosti. Například pro některé aplikace lze počítač reprezentovat jedním objektem, pro jiné se bude skládat z dalších (motherboardu, harddisku, videokarty, řadiče atd.). 10.2. ZprávaSamotné objekty vydělené ze světa by byly k ničemu, a proto spolu komunikují pomocí tzv. zasílání zpráv.Zpráva je obecný pojem, jímž se označuje zaslání požadavku mezi objekty bez ohledu na způsob přenosu, (2) jehož výsledkem je volání metody cílového objektu. Zprávu obecně tvoří:
Mechanismus zasílání zpráv tak umožňuje, že se komunikující softwarové objekty mohou nalézat ve dvou různých procesech, programech nebo dokonce na dvou různých počítačích. Pro jednotlivé situace však není třeba objekty přizpůsobovat. 10.3. TřídaVětšina podstatných jmen v našem jazyce označuje třídu živých, neživých nebo abstraktních objektů. Například vaše škodovka a sousedův Mercedes jsou objekty patřící do třídy aut. Třídou se v podstatě rozumí obecné vlastnosti, které objekt musí mít, aby do ní mohl být zařazen - neboli: třída je popisem, vzorem, předlohou celé skupiny podobných objektů.V programovacím jazyce je třída (class (3) ) přesně popsána. Z hlediska syntaxe je třída obyčejnou deklarací datové struktury (podobně jako record v Pascalu nebo struct v C) rozšířenou o metody. Třída představuje objektový typ, objekt se nazývá instancí třídy.
Dosud vše nasvědčuje tomu, že třída je pouhou deklarací objektů a v programu fyzicky neexistuje - existují až její konkrétní objekty, které mají svůj stav uložen v členských proměnných. I samotná třída však může mít proměnné (class variables) a metody (class methods), nazývané též statické. Statické proměnné existují jen v jednom exempláři a všechny objekty dané třídy je sdílí - jsou tedy jakousi obdobou globálních proměnných pro danou třídu. Statické metody (4) mají tu výhodu, že je lze volat, i když (ještě) neexistuje žádná instance třídy - viz metoda main v příkladu 4.2.. 10.4. DědičnostJedna třída obvykle nestačí pro dostatečně přesnou klasifikaci podobných objektů, například do třídy aut patří dodávky, nákladní, osobní auta atd. Přitom podtřídy mají vlastnosti třídy nadřazené. Tuto myšlenku převzalo i OOP.Objektové jazyky umožňují konstruovat třídy tak, že od první (nejobecnější) se mohou odvozovat další přidáním nebo překrytím (předefinováním) metod (a příp. přidáním proměnných). Toto odvozování je možné dále opakovat a výsledné třídy jsou pak uspořádány do stromové hierarchie: Následník dané třídy ve stromu se nazývá potomek (subclass) a předchůdce rodič (superclass), podobně jako v rodokmenu. Třída v daném uzlu s výjimkou kořene dědí (tj. přejímá, jako by byly znovu definovány) všechny proměnné a metody rodiče (5) a tím, nepřímo, i všech nadřazených tříd. Při procházení stromu shora dolů tak získáváme čím dál specializovanější třídy. Díky dědičnosti se při programování lze vyhnout mnohým chybám (odvozená třída používá již odladěný kód z rodiče) a ušetří se i opětovné psaní kódu (metody rodičovské třídy není třeba znovu definovat). Na rozdíl od některých jiných jazyků (např. C++) Java nepodporuje tzv. vícenásobnou dědičnost, kdy může třída mít více než jednoho rodiče, neboť to obvykle přináší větší obtíže než výhody (např. narůstá komplexnost zdrojového textu). Případ, kdy by třída měla mít vlastnosti více rodičů, Java obchází pomocí rozhraní (interface), viz 11.6.. V Javě jsou všechny třídy uspořádány do jediného stromu, jehož kořenem je třída Object (viz 11.5.). Pokud v programu není uveden rodič nové třídy, je jím automaticky právě Object. (6) 10.5. VícetvarostV předchozí kapitole bylo naznačeno, že pokud daná třída dědí metody rodiče, jsou tyto přejaty a chovají se jako by byly v této třídě znovu definovány.To v podstatě vyjadřuje vícetvarost (polymorphism), která říká, že jméno akce (metody) je sdíleno třídami ve stromu dědičnosti a ta je implementována způsobem, který ji na dané úrovni přísluší. Stoprocentně to ovšem platí pouze o Javě, nikoliv například o Turbo Pascalu či C++. V praxi jde o to, jak se ve zděděných metodách volají překryté (předefinované) metody potomků:
V C++ či Turbo Pascalu lze dosáhnout stejného výsledku jako v Javě tím, že je metoda (zobraz()) deklarována jako virtuální. Pak se její volání provádí nepřímo přes tzv. tabulku virtuálních metod. Z pohledu C++ jsou tedy všechny nestatické metody v Javě virtuální.
|