Lekce 2 - Úvod - Objektově orientované programování ve VBA
V minulé lekci, Úvod - Evoluce metodik, jsme ukázali cestu, která vedla k dnešnímu objektově orientovanému programování.
V dnešním VBA tutoriálu si uvedeme objektově orientované programování. Vysvětlíme si, jak funguje a rozebereme pojmy třída, funkce, procedura a zapouzdření.
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 filozofie. 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.
Objektově orientované programování představuje nový způsob myšlení, nový náhled na problémy a novou éru ve vývoji softwaru.
Objektově orientovaný přístup
Objektově orientovaný přístup představuje 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í, protože 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ů.
Jak OOP funguje
Snažíme se nasimulovat realitu tak, jak ji jsme zvyklí vnímat. Můžeme tedy říci, že se odpoutáváme od toho, jak program vidí počítač (stroj) a píšeme program spíše z pohledu programátora (člověka). Jako jsme tehdy nahradili assembler lidsky čitelnými matematickými zápisy, nyní jdeme ještě dál a nahradíme i ty. Jde tedy o určitou úroveň abstrakce nad programem. To má značné výhody už jen v tom, že je to pro nás přirozenější a přehlednější.
Základní jednotkou je objekt, který odpovídá nějakému
objektu z reálného světa, například objekt Člověk
nebo
Databáze
:
Objekt má své proměnné, funkce a procedury.
Proměnné
Proměnné objektu jsou vlastnosti neboli data, která
uchovává, například u člověka jmeno
a vek
, u
databáze heslo
. Jedná se o prosté proměnné, se
kterými jsme již stokrát pracovali. Někdy o nich hovoříme jako o
vnitřním stavu objektu.
Procedury a funkce
Procedury a funkce jsou schopnostmi, které umí objekt
vykonávat. U člověka by to mohly být procedury či funkce:
JdiDoPrace()
, Pozdrav()
nebo Mrkni()
. U
databáze PridejZaznam()
nebo Vyhledej()
. Procedury a
funkce mohou mít parametry. A funkce také mohou vracet
nějakou hodnotu.
Pokud procedura něco vrací, říká se ji funkce.
Funkce velmi dobře známe, používali jsme například funkci
Count()
na objektu Collection
. Collection
je vlastně objekt, který reprezentuje v realitě nějakou kolekci prvků.
Vidíme, že si můžeme jednoduše představit, že jednáme s kolekcí, které
se v tomto případě ptáme na počet v ní obsažených prvků:
Ve starších jazycích procedury a funkce nepatřily objektům, ale volně
se nacházely v modulech. Do této skupiny patří i VBA, i
když i ve VBA by se našlo pár dalších objektů. Bez znalostí OOP bychom
zjistili například délku řetězce takto: Len(retezec)
.
Nevýhodou je zejména to, že funkce Len()
zde nikam nepatří.
Není způsob, jakým si vyvolat seznam toho, co se s řetězcem dá dělat a v
kódu je nepořádek. Navíc nemůžeme mít dvě procedury či funkce se
stejným názvem.
Po absolvování lekcí tohoto kurzu se dostaneme na úroveň moderních
jazyků, kdy si vytvoříme objekt, který bude představovat
textový řetězec. Tohoto objektu se budeme moci dotazovat
například takto: retezec.Delka()
. Nebudeme tedy muset
přemýšlet, jak se ten příkaz Len
jmenuje. Objekt
retezec
nám totiž sám na sobě ukáže, s jakými procedurami a
funkcemi dokáže pracovat.
V OOP můžeme mít retezec.Delka()
a
clanek.Delka()
. To je velmi přehledné a jednoduché. Ve
strukturovaném programu bychom museli psát:
spocitej_delku1(retezec)
a spocitej_delku2(clanek)
,
přičemž druhá zmíněná funkce by se lišila od té první tím, že by
například nepočítala za řádkování. Takovýchto hloupých funkcí a
procedur bychom museli mít někde rozházených tisíce. Pokud nám to
připomíná jazyk PHP, tak bohužel máme pravdu. PHP je v
tomto opravdu hrozné, a to z toho důvodu, že jeho návrh je starý.
V tomto tutoriálu si vysvětlíme jen úplné základy, tedy jak objekty vytvářet a jak zapouzdřit jejich vnitřní logiku. Dalším funkcím OOP budou věnovány další díly, aby toho nebylo najednou moc .
Třídní modul
S pojmem třídní modul jsme se již také setkali. Chápali jsme ho jako soubor příkazů. Umožňuje však mnohem více.
Třídní modul je vzor, podle kterého se objekty vytváří. Definuje jejich vlastnosti a schopnosti.
Objekt, který se vytvoří podle třídního modulu, se nazývá instance. Instance mají stejné rozhraní jako třída, podle které se vytváří, ale navzájem se liší svými daty (proměnnými).
Mějme například třídní modul Clovek
a od ní si vytvořme
instance karel
a josef
. Obě instance mají jistě
ty samé procedury, funkce a proměnné jako třídní modul
(např. jmeno
, vek
, JdiDoPrace()
,
Pozdrav()
), ale hodnoty v nich se
liší (první instance má v proměnné jmeno
hodnotu Karel
a ve vek
22
, druhá
Josef
a 45
):
Komunikace mezi objekty probíhá pomocí předávání
zpráv, díky čemuž je syntaxe přehledná. Zpráva obvykle vypadá
takto: prijemce.JmenoProcedury(parametry)
. Např.
karel.Pozdrav(sousedka)
by mohl způsobit, že instance
karel
pozdraví instanci sousedka
.
OOP stojí na základních třech pilířích:
- Zapouzdření
- Dědičnost
- Polymorfismus
Vysvětleme si první z nich.
Zapouzdření
Zapouzdření umožňuje skrýt některé funkce, procedury a třídní proměnné tak, aby zůstaly použitelné jen pro třídní modul zevnitř. Objekt si můžeme představit jako černou skřínku (anglicky blackbox), která má určité rozhraní (interface), přes které jí předáváme instrukce/data a ona je zpracovává.
Nevíme, jak to uvnitř funguje, ale víme, jak se navenek chová a používá. Nemůžeme tedy způsobit nějakou chybu, protože využíváme a vidíme jen to, co tvůrce třídy zpřístupnil.
Příkladem může být třída Clovek
, která bude mít
proměnnou datumNarozeni
a na jeho základě další proměnné
plnolety
a vek
. Kdyby někdo objektu zvenčí změnil
datumNarozeni
, přestaly by platit proměnné plnolety
a vek
. Říkáme, že vnitřní stav objektu by byl
nekonzistentní. Toto se nám ve strukturovaném programování
může klidně stát.
V OOP však objekt zapouzdříme a proměnnou datumNarozeni
označíme jako privátní, zvenčí tedy nebude viditelný.
Naopak ven vystavíme proceduru ZmenDatumNarozeni()
, která dosadí
nové datum narození do proměnné datumNarozeni
a zároveň
provede potřebný přepočet věku a přehodnocení plnoletosti. Použití
objektu je bezpečné a aplikace stabilní.
Zapouzdření tedy donutí programátory používat objekt jen tím správným způsobem.
Rozhraní (interface) třídu rozdělí na část veřejně
přístupnou public
a vnitřní strukturu
private
.
V příští lekci, První objektová aplikace ve VBA - Hello object world, si vytvoříme svou první objektovou aplikaci Hello object world. Naučíme se tvořit třídní moduly, třídní proměnné, funkce a procedury.