Hledáme nového kolegu do redakce - 100% home office, 100% flexibilní pracovní doba. Více informací.
Využij akce až 80 % zdarma při nákupu e-learningu - více informací. Zároveň pouze tento týden sleva až 80 % na e-learning týkající se Swift

1. diel - Úvod do objektovo orientovaného programovania v Kotlin

Vitajte u prvej lekcie kurzu o objektovo orientovanom programovaní v Kotlin. Kurz Základná konštrukcia jazyka Kotlin už máme za sebou, minule sme ju dokončili lekcií Matematické funkcie v Kotlin. V tomto kurze sa naučíme objektovo programovať a hlavne objektovo myslieť. Je to niečo trochu iné, než sme robili doteraz a samotný program už nebudeme chápať ako niekoľko riadkov príkazov, ktoré interpret vykonáva zhora nadol.

Objektovo orientované programovanie (ďalej len OOP) nevzniklo náhodou, ale je dôsledkom vývoja, ktorý k nemu smeroval. Jedná sa o moderné metodiku vývoja softvéru, ktorú podporuje väčšina programovacích jazykov. Častou chybou je, že sa ľudia domnievajú, že OOP sa využíva iba pri písaní určitého druhu programov a inak je na škodu. Opak je pravdou - OOP je filozofia, je to nový pohľad na funkciu programu a komunikáciu medzi jeho jednotlivými časťami. Malo by sa používať vždy, či už robíme malú utilitku alebo zložitý databázový systém. OOP nie je len technika alebo nejaká odporúčaná štruktúra programu, je to hlavne nový spôsob myslenia, nový náhľad na problémy a nová éra vo vývoji softvéru.

Najprv sa pozrieme do histórie, ako sa programovalo skôr a ktoré konkrétne problémy OOP rieši. Je to totiž dôležité na to, aby sme pochopili, prečo OOP vzniklo.

Evolúcia metodík

Medzi tým, ako sa programovalo pred 40tich rokmi a ako sa programuje dnes, je veľký rozdiel. Prvé počítače neboli zariadené veľkým výkonom a aj ich softvér nebol nijako zložitý. Vývoj hardvéru je však natoľko rýchly, že sa počet tranzistorov v mikroprocesoroch každý rok zdvojnásobí (Moorov zákon). Bohužiaľ, ľudia sa nedokážu rozvíjať tak rýchlo, ako sa rozvíja hardvér. Stále rýchlejšie počítače vyžadujú stále zložitejšie a zložitejšie softvér (resp. Ľudia toho chcú po počítačoch stále viac a viac). Keď sa v jednej chvíli zistilo, že okolo 90% softvéru je vytvorené s oneskorením, s dodatočnými nákladmi alebo zlyhalo úplne, hľadali sa nové cesty, ako programy písať. Vystriedalo sa tak niekoľko prístupov, presnejšie sa im hovorí paradigma (chápte ako smer myslenia). My si ich tu popíšeme.

1. Strojový kód

Program bol len súbor inštrukcií, kde sme nemali žiadnu možnosť pomenovávať premenné alebo zadávať matematické výrazy. Zdrojový kód bol samozrejme špecifický pre daný hardvér (procesor). Toto paradigma bolo čoskoro nahradené.

2. Neštruktúrované paradigma

Neštruktúrovaný prístup je podobný assemblerům, jedná sa o súbor inštrukcií, ktorý sa vykonáva zhora nadol. Zdrojový kód už nebol závislý na hardvéri a bol lepšie čitateľný pre človeka, prístup na nejakú dobu umožnil vytvárať komplexnejšie programy. Bolo tu však stále veľa úskalí: Jediná možnosť, ako urobiť niečo viackrát alebo ako sa v kóde vetviť, bol príkaz GOTO. GOTO nám umožňovalo "skákať" na jednotlivé miesta v programe. Miesta bola predtým špecifikovaná číslom riadku zdrojového kódu, čo je samozrejme nepraktické. Keď do kódu vložíme nový riadok, čísla prestanú súhlasiť a celý kód je rozbitý. Neskôr vznikla možnosť definovať tzv. "Návestie". Takto sa obchádzala napr. Absencia cyklov. Takýto spôsob písania programov je samozrejme veľmi neprehľadný a čoskoro prestal postačovať pre vývoj zložitejších programov.

Uvedomme si, že obrovské rozšírenie počítačov za posledných niekoľko dekád má na svedomí rast dopytu po softvéru a logicky tiež rast dopytu po programátoroch. Iste existujú ľudia, ktorí dokážu bez chyby písať programy v ASM alebo iných nízkych jazykoch, ale koľko ich je? A koľko si asi za takú nadľudskú prácu účtujú? Je potreba písať programy tak, aby aj menej skúsení programátori dokázali písať kvalitné programy a nepotrebovali k tvorbe jednoduchej utilitky 5 rokov praxe.

3. Štruktúrované programovanie

Štruktúrované programovanie je prvý paradigma, ktoré sa udržalo dlhšiu dobu a naozaj chvíľu postačovalo pre vývoj nových programov. Programujeme pomocou cyklov a vetvenia. To je v podstate to, kam sme sa doteraz dostali.

Program možno rozložiť do funkcií (metód), tomu sme sa nevenovali. Radšej som dal prednosť tento medzikrok preskočiť a začať rovno s OOP. U štruktúrovaného programovania hovoríme o tzv. Funkcionálne dekompozícii. Problém sa rozloží na niekoľko podproblémů a každý Podproblém potom rieši určitá funkcie s parametrami. Nevýhodou je, že funkcia vie len jednu činnosť, keď chceme niečo iné, musíme napísať novú. Neexistuje totiž spôsob, ako vziať starý kód a len trochu ho modifikovať, musíme písať znovu a znovu - vznikajú zbytočné náklady a chyby. Túto nevýhodu možno čiastočne obísť pomocou parametrizácie funkcií (počet parametrov potom ale rýchlo narastá) alebo použitím globálnych premenných. S globálnymi dátami vzniká však nové nebezpečenstvo - funkcie majú prístup k dátam ostatných. To je začiatok konca, nikdy totiž neustrážime, aby niekde nedošlo k prepísaniu glob. dát medzi funkciami a začne dochádzať k nekontrolovateľným problémom. Celý program sa potom skladá z nezapouzdřených blokov kódu a zle sa udržiava. Každá úprava programu zvyšuje zložitosť, program potom nutne dôjde do stavu, kedy náklady na pridávanie nových funkcií vzrastú na toľko, že sa program už neoplatí rozširovať. Zástupcovia tohto prístupu sú napríklad jazyky C a Pascal.

Medzi štruktúrovaným programovaním a objektovo orientovaným programovaním existoval ešte medzičlánok, tzv. Modulárne programovanie, ktoré nám umožňuje zapouzdřit určitú funkcionalitu do modulov. Stále však neexistuje spôsob, ako už napísaný kód modifikovať a znovu využiť.

Ako už som sa zmienil na začiatku článku, niekedy sa uvádza, že sa jednoduché programy majú písať neobjektové, teda štruktúrovane. Nie je to však pravda. Keď vynecháme fakt, že porušujeme filozofiu OOP ako takú, nikdy nemôžeme vedieť, či sa tento program neuchytia az malej utilitky sa nestane niečo vážnejšieho. Potom opäť nutne dospejeme do stavu, kedy program nebude možné ďalej rozširovať a budeme ho buď musieť zahodiť alebo celý prepísať s pomocou OOP.

Neobjektovým metódam písania kódu sa prezýva "spaghetti code" pre ich neprehľadnosť (pretože špagety sú zamotané).

Objektovo orientovaný prístup

Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!

Jedná sa o filozofiu a spôsob myslenia, dizajnu a implementácia, kde kladieme dôraz na znovupoužitel­nost. Prístup nachádza inšpiráciu v priemyselnej revolúcii - vynález základných komponentov, ktoré budeme ďalej využívať (napr. Keď staviame dom, nebudeme si páliť tehly a sústružiť skrutky, proste je už máme hotové).

Poskladanie programu z komponentov je výhodnejšie a lacnejšie. Môžeme mu veriť, je otestovaný (o komponentoch sa vie, že fungujú, sú otestované a udržiavané). Ak je niekde chyba, stačí ju opraviť na jednom mieste. Sme motivovaní k písania kódu prehľadne a dobre, pretože ho po nás používajú druhí alebo my sami v ďalších projektoch (priznajme si, že človek je od prírody lenivý a keby nevedel, že sa jeho kód bude znovu využívať, nesnažil by sa ho písať kvalitne :) ).

Znalosti, ktoré sme sa doteraz naučili, samozrejme budeme používať ďalej. Náš kód budeme iba inak štruktúrovať a to do komunikujúcich objektov.

Ako OOP funguje

Snažíme sa nasimulovať realitu tak, ako ju sme zvyknutí vnímať. Môžeme teda povedať, že sa odpútavame od toho, ako program vidí počítač (stroj) a píšeme program skôr z pohľadu programátora (človeka). Ako sme vtedy nahradili assembler ľudsky čitateľnými matematickými zápisy, teraz ideme ešte ďalej a nahradíme aj tie. Ide teda o určitú úroveň abstrakcie nad programom. To má značné výhody už len v tom, že je to pre nás prirodzenejšie a prehľadnejšie.

Základnou jednotkou je objekt, ktorý zodpovedá nejakému objektu z reálneho sveta (napr. Objekt človek alebo databázy).

Objekty v objektovo orientovanom programovaní

Objekt má svoje atribúty a metódy.

Atribúty

Atribúty objektu sú vlastnosti čiže dáta, ktoré uchováva (napr. U človeka jmeno a vek, u databázy heslo). Jedná sa o prosté premenné, s ktorými sme už stokrát pracovali. Niekedy o nich hovoríme ako o vnútornom stave objektu.

Metódy

Metódy sú schopnosťami, ktoré vedia objekt vykonávať. U človeka by to mohli byť metódy: jdiDoPrace(), pozdrav() alebo mrkni(). U databázy pridejZaznam() alebo vyhledej()). Metódy môžu mať parametre a môžu tiež vracať nejakú hodnotu. Veľmi dobre ich poznáme, používali sme napr. Metódu split() na objekte String. String je vlastne objekt, ktorý reprezentuje v realite nejaký text. Vidíte, že si môžeme jednoducho predstaviť, že rokujeme s reťazcom textu, niečo mu prikazovať alebo na ňom niečo nastavovať. Obsahuje metódy, ktoré reťazec vedia vykonávať (kopírovanie, mazanie, splitování ...) a má tiež nejaké atribúty, napr. delka, ktorý značí jeho dĺžku.

Objekty v objektovo orientovanom programovaní

V starších jazykoch metódy nepatrili objektom, ale voľne sa nachádzali v moduloch (jednotkách). Miesto text.split() by sme teda postarom písali split(text). Nevýhodou samozrejme bolo najmä to, že funkcia split() tu nikam nepatrí. Nebol spôsob, akým si vyvolať zoznam toho, čo sa s reťazcom dá robiť a v kóde bol neporiadok. Navyše sme nemohli mať 2 metódy s rovnakým názvom, v OOP môžeme mať uzivatel.vymaz() a clanek.vymaz(). To je veľmi prehľadné a jednoduché. Vo štruktúrovanom programe by sme museli písať: vymaz_uzivatele(uzivatel) a vymaz_clanek(clanek). Takýchto hlúpych metód by sme museli mať niekde rozhádzaných tisíce. Ak vám to pripomína jazyk PHP, bohužiaľ máte pravdu. PHP je v tomto naozaj hrozné a to z toho dôvodu, že jeho návrh je starý. Síce sa časom plne preorientovalo na objekty, ale jeho základy sa už nezmení. Kotlín je našťastie jazyk moderný a je silne postavená na objektoch.

V dnešnej lekcii si vysvetlíme len úplné základy, teda ako objekty vytvárať a ako zapouzdřit ich vnútornú logiku. Ďalším funkciám OOP (hovorím najmä o dedičnosti) budú venované ďalšie lekcie, aby toho nebolo naraz veľa :)

Trieda

S pojmom trieda sme sa už tiež stretli, chápali sme ju ako súbor príkazov. Trieda však umožňuje oveľa viac. Trieda je vzor, podľa ktorého sa objekty vytvára. Definuje ich vlastnosti a schopnosti.

Objekt, ktorý sa vytvorí podľa triedy, sa nazýva inštancia. Instance majú rovnaké rozhranie ako trieda, podľa ktorej sa vytvára, ale navzájom sa líšia svojimi dátami (atribúty). Majme napríklad triedu Clovek a od nej si vytvorme inštancie karel a josef. Obe inštancie majú iste tie isté metódy a atribúty, ako trieda (napr. jmeno a vek) a metódy (jdiDoPrace() a pozdrav()), ale hodnoty v nich sa líši (prvá inštancia má v atribúte jmeno hodnotu "Karel" a vo vek 22, druhá "Josef" a 45).

Komunikácia medzi objektmi prebieha pomocou odovzdávania správ, vďaka čomu je syntaxe prehľadná. Správa zvyčajne vyzerá takto: prijemce.jmenoMetody(parametry). Napr. karel.pozdrav(sousedka) by mohlo spôsobiť, že inštancia karel pozdraví inštanciu sousedka.

OOP stojí na základných troch pilieroch:

  • zapuzdrenie
  • dedičnosť
  • Polymorfizmus.

Vysvetlime si prvý z nich.

Zapuzdrenie

Zapuzdrenie umožňuje skryť niektoré metódy a atribúty tak, aby zostali použiteľné len pre triedu zvnútra. Objekt si môžeme predstaviť ako čiernu skrinku (anglicky blackbox), ktorá má určité rozhranie (interface), cez ktoré jej odovzdávame inštrukcie / dáta a ona je spracováva.

Nevieme, ako to vo vnútri funguje, ale vieme, ako sa navonok chová a používa. Nemôžeme teda spôsobiť nejakú chybu, pretože využívame a vidíme len to, čo tvorca triedy sprístupnil.

Príkladom môže byť trieda Clovek, ktorá bude mať atribút datumNarozeni a na jeho základe ďalšie atribúty: plnolety a vek. Keby niekto objektu zvonku zmenil datumNarozeni, prestali by platiť premenné plnolety a vek. Hovoríme, že vnútorný stav objektu by bol nekonzistentné. Toto sa nám v štruktúrovanom programovaní môže pokojne stáť. V OOP však objekt zapouzdříme a atribút datumNarozeni označíme ako privátne, zvonka teda nebude viditeľný. Naopak von vystavíme metódu zmenDatumNarozeni(), ktorá dosadí nové dátum narodenia do premennej datumNarozeni a zároveň vykoná potrebný prepočet veku a prehodnotenie plnoletosti. Použitie objektu je bezpečné a aplikácia stabilné.

Zapuzdrenie teda donúti programátorov používať objekt len tým správnym spôsobom. Rozhranie (interface) triedy rozdelí na verejne prístupné (public) a vnútornú štruktúru (private).

V budúcej lekcii, Prvý objektová aplikácie v Kotlin - Hello object world , si vytvoríme svoj prvý objektový program.


 

Všetky články v sekcii
Objektovo orientované programovanie v Kotlin
Článok pre vás napísal Samuel Kodytek
Avatar
Ako sa ti páči článok?
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje všem jazykům okolo JVM. Rád pomáhá lidem, kteří se zajímají o programování. Věří, že všichni mají šanci se naučit programovat, jen je potřeba prorazit tu bariéru, který se říká lenost.
Aktivity

 

 

Komentáre

Avatar
Tomáš Prokeš:16.12.2018 10:21

"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"
"Zapouzdření tedy donutí programátory používat objekt jen tím správným způsobem. Rozhraní (interface) třídy rozdělí na veřejně přístupné (public) a vnitřní strukturu (private)."

Kéž by tomu tam bylo. To předpokládá odpovědného, geniálního až neomylného programátora (těch zapouzdřených objektů). A pak by nebylo možné vytvářet malware (viry a pod.).

 
Odpovedať
16.12.2018 10:21
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zobrazené 1 správy z 1.