Lekce 1 - Úvod do objektově orientovaného programování v Javě
Vítejte u první lekce kurzu o objektově orientovaném programování v
Javě. V tomto kurzu se naučíme objektově programovat a hlavně
objektově myslet. Je to něco trochu jiného, než jsme
dělali doteď a samotný program už nebudeme chápat jako několik řádek
příkazů, které interpret vykonává odshora dolů. Během kurzu vytvoříme
spoustu praktických aplikací
Minimální požadavky
Potřebujete ovládat Základní konstrukce jazyka Java.
Vznik objektově-orientovaného programování
Objektově orientované programování (dále jen OOP) nevzniklo náhodou, ale je důsledkem vývoje, který k němu směřoval. Jedná se o moderní metodiku vývoje softwaru, kterou podporuje většina programovacích jazyků. Častou chybou je, že se lidé domnívají, že OOP se využívá pouze při psaní určitého druhu programů a jinak je na škodu. Opak je pravdou - OOP je filosofie, je to nový pohled na funkci programu a komunikaci mezi jeho jednotlivými částmi. Mělo by se používat vždy, ať už děláme malou utilitku nebo složitý databázový systém. OOP není jen technika nebo nějaká doporučená struktura programu, je to hlavně nový způsob myšlení, nový náhled na problémy a nová éra ve vývoji softwaru.
Nejprve se podíváme do historie, jak se programovalo dříve a které konkrétní problémy OOP řeší. Je to totiž důležité k tomu, abychom pochopili, proč OOP vzniklo.
Evoluce metodik
Mezi tím, jak se programovalo před 40ti lety a jak se programuje dnes, je velký rozdíl. První počítače neoplývaly velkým výkonem a i jejich software nebyl nijak složitý. Vývoj hardwaru je však natolik rychlý, že se počet tranzistorů v mikroprocesorech každý rok zdvojnásobí (Moorův zákon). Bohužel, lidé se nedokáží rozvíjet tak rychle, jako se rozvíjí hardware. Stále rychlejší počítače vyžadují stále složitější a složitější software (resp. lidé toho chtějí po počítačích stále více a více). Když se v jedné chvíli zjistilo, že okolo 90 % softwaru je vytvořeno se zpožděním, s dodatečnými náklady nebo selhalo úplně, hledaly se nové cesty, jak programy psát. Vystřídalo se tak několik přístupů, přesněji se jim říká paradigma (chápejte jako směr myšlení). My si je zde popíšeme.
1. Strojový kód
Program byl jen souborem instrukcí, kde jsme neměli žádnou možnost pojmenovávat proměnné nebo zadávat matematické výrazy. Zdrojový kód byl samozřejmě specifický pro daný hardware (procesor). Toto paradigma bylo brzy nahrazeno.
Program sčítající dvě čísla (83 a -2) by vypadal např. takto:
2104 1105 3106 7001 0053 FFFE 0000
Jak vidíte, programovat ve strojovém kódu určitě není to pravé a i taková banalita má mnoho řádků.
2. Nestrukturované paradigma
Nestrukturovaný přístup je podobný assemblerům, jedná se o soubor
instrukcí, který se vykonává odshora dolů. Zdrojový kód již nebyl
závislý na hardwaru a byl lépe čitelný pro člověka, přístup na nějakou
dobu umožnil vytvářet komplexnější programy. Bylo tu však stále mnoho
úskalí: Jediná možnost, jak udělat něco vícekrát nebo jak se v kódu
větvit, byl příkaz GOTO
. Příkaz GOTO
nám
umožňoval "skákat" na jednotlivá místa v programu. Takovýto způsob psaní
programů je samozřejmě velice nepřehledný a brzy přestal postačovat pro
vývoj složitějších programů.
Náš příklad by vypadal v ASM takto:
ORG 100 LDA A ADD B STA C HLT DEC 83 DEC –2 DEC 0 END
Uvědomme si, že obrovské rozšíření počítačů za posledních několik dekád má na svědomí růst poptávky po softwaru a logicky také růst poptávky po programátorech. Jistě existují lidé, kteří dokáží bez chyby psát programy v ASM nebo jiných nízkých jazycích, ale kolik jich je? A kolik si asi za takovou nadlidskou práci účtují? Je potřeba psát programy tak, aby i méně zkušení programátoři dokázali psát kvalitní programy a nepotřebovali k tvorbě jednoduché utilitky 5 let praxe.
3. Strukturované programování
Strukturované programování je první paradigma, které se udrželo delší dobu a opravdu chvíli postačovalo pro vývoj nových programů. Programujeme pomocí cyklů a větvení. To je v podstatě to, kam jsme se doteď dostali.
Program lze rozložit do funkcí (metod), tomu jsme se nevěnovali, protože to v Javě (která je objektová) ani moc dobře nejde a raději jsme dali přednost tento mezikrok přeskočit a začít rovnou s OOP. U strukturovaného programování hovoříme o tzv. funkcionální dekompozici. Problém se rozloží na několik podproblémů a každý podproblém potom řeší určitá funkce s parametry. Nevýhodou je, že funkce umí jen jednu činnost, když chceme něco jiného, musíme napsat novou. Tuto nevýhodu lze částečně obejít pomocí parametrizace funkcí (počet parametrů poté ale rychle narůstá) nebo použitím nebezpečných globálních proměnných. Zástupci tohoto přístupu jsou například jazyky C a Pascal.
Sečtení dvou čísel by v jazyce C vypadalo takto:
int secti(int a, int b) { return a + b; } int main(void) { int soucet = secti(83, -2); return 0; }
Všichni asi tušíme, co program dělá: sečte čísla 83
a
-2
a výsledek uloží do proměnné soucet
. U všech
jazyků třetí generace je samozřejmě výhodou vysoká
čitelnost.
Jak již jsem se zmínil na začátku článku, někdy se uvádí, že se jednoduché programy mají psát neobjektově, tedy strukturovaně. Není to však pravda. Když opomineme fakt, že porušujeme filozofii OOP jako takovou, nikdy nemůžeme vědět, zda se tento program neuchytí a z malé utilitky se nestane něco vážnějšího. Potom opět nutně dospějeme do stavu, kdy program nebude možné dál rozšiřovat a budeme ho buď muset zahodit nebo celý přepsat s pomocí OOP.
Neobjektovým metodám psaní kódu se přezdívá spaghetti code pro jejich nepřehlednost (protože špagety jsou zamotané).
Objektově orientovaný přístup
Jedná se o filozofii a způsob myšlení, designu a implementace, kde klademe důraz na znovupoužitelnost. Přístup nalézá inspiraci v průmyslové revoluci - vynález základních komponent, které budeme dále využívat (např. když stavíme dům, nebudeme si pálit cihly a soustružit šroubky, prostě je již máme hotové).
Poskládání programu z komponent je výhodnější a levnější. Můžeme mu věřit, je otestovaný (o komponentách se ví, že fungují, jsou otestovány a udržovány). Pokud je někde chyba, stačí ji opravit na jednom místě. Jsme motivováni k psaní kódu přehledně a dobře, protože ho po nás používají druzí nebo my sami v dalších projektech (přiznejme si, že člověk je od přírody líný a kdyby nevěděl, že se jeho kód bude znovu využívat, nesnažil by se ho psát kvalitně 🙂).
Znalosti, které jsme se doteď naučili, samozřejmě budeme používat dál. Náš kód budeme pouze jinak strukturovat a to do komunikujících objektů.
Ještě si jen pro ilustraci ukažme opět náš příklad, tentokrát v
objektech. Aplikace je nyní rozdělená na dva soubory, mezi kterými si
můžete překlikávat. Funkce secti()
již nikde volně
nepoletuje, ale patří objektu Kalkulacka
, který je jednou z
komponent naší aplikace. Kód nám teď samozřejmě slouží jen jako náhled
principu a jak funguje si vysvětlíme v dalších lekcích:
{JAVA_OOP} {JAVA_MAIN_BLOCK} Kalkulacka kalkulacka = new Kalkulacka(); kalkulacka.secti(83, -2); {/JAVA_MAIN_BLOCK} {/JAVA_OOP}
{JAVA_OOP} public class Kalkulacka { private int a; private int b; private int soucet; public void secti(int a, int b) { soucet = a + b; System.out.println("Součet je: " + soucet); } } {/JAVA_OOP}
V příští lekci, První objektová aplikace v Javě - Hello object world, si vytvoříme svůj první objektový program.