Seriál o výuce objektově orientovaného programování postupuje k podkapitolám 2.12 Zapouzdření a 2.13 Lokální proměnné. V minulém díle jsme se věnovali kvalifikaci - klíčové slovo this a metodám vracejícím hodnotu.
2.12. Zapouzdření
Takto jsme vlastně definovali přístupové metody k atributům, které vůbec neuchováváme. To je ale relativně časté. Tvůrci programů se občas rozhodnou, že některé atributy nestojí za to, aby si je instance pamatovaly, protože je lze vždy v případě potřeby dostatečně rychle zjistit.
Zvenku třídy, tj. při volání jejích přístupových metod, nemáme šanci zjistit, jestli třída uvnitř pracuje se skutečnými, anebo s vypočítanými atributy. A to je dobře. Jednou ze základních a velice ceněných vlastností objektově orientovaných programů je schopnost tzv. zapouzdření. Lidově bychom mohli zapouzdření charakterizovat heslem:
„Nikdo nesmí mít šanci zjistit nic o tom, jak to dělám, že umím to, co umím.“
Takto osamoceně vyslovena vypadá možná tato zásada neurvale, ale věřte, že je to nejvíce ceněná vlastnost celého OOP. Čím jsou programy složitější, tím je důležitější, abychom ani omylem nemohli ovlivnit chod některé jiné části.
V této souvislosti se seznámíme se dvěma novými termíny
- Rozhraní třídy budeme chápat jako množinu informací, které o sobě třída zveřejní. Mezi rozhraní patří např. vše, co třída označí modifikátorem public.
- Implementace je způsob, jak je třída naprogramována.
Do rozhraní bychom měli zařadit pouze to, co ostatní části programu o dané třídě opravdu musí vědět. Když jsme například chtěli, aby ostatní programy mohly naši třídu požádat o vytvoření instance, museli jsme zveřejnit její konstruktor. Budeme-li chtít, aby ostatní programy mohly zjistit, kde je právě daný smrk nakreslen, musíme zveřejnit metody, pomocí nichž mohou tuto informaci získat.
Vše, co sice k implementaci požadovaných funkcí potřebuji, ale o čem se domnívám, že ostatní vědět nemusí, označím jako private. Nechci-li, aby ostatní části programu mohly pohybovat jednotlivými částmi smrčku bez mého vědomí, nesmím je k nim pustit – označím proto příslušné atributy jako private.
Poznámka:
Mezi public a private existují ještě mezistupně, ale o těch si povíme, až se s objektovým programováním trochu více seznámíme.
Do rozhraní se někdy počítají i informace, které z hlaviček nevyčtete, ale které by měly být uvedeny v dokumentaci. Sem patří informace o dalších podmínkách, které je třeba dodržet (např. že zadávané souřadnice vytvářeného tvaru musí být větší než 0, že instance metody Platno je jedináček apod.), o možných vedlejších efektech funkcí (např. co se stane, když obrazec „vycestuje“ z plátna) a řada dalších důležitých sdělení. Tento souhrn informací bývá označován jako kontrakt.
2.13 Lokální proměnné
Když jsme již definovali metody, které vracejí hodnoty fiktivních atributů, zkusme definovat meto-dy, které hodnoty těchto atributů nastavují. Definujme např. metodu setRozmer(int,int).
Protože je náš smrk sestaven z několika trojúhelníků různých velikostí, není přepočet jejich nových velikostí právě jednoduchý. Budeme při něm navíc potřebovat použít některá čísla několi-krát. Bylo by proto výhodné definovat určité lokální proměnné (Baltíkovy košíky), kam si bude-me ukládat mezivýsledky.
Lokální proměnné se definují naprosto stejně jako atributy. Jediným rozdílem je, že se definu-jí uvnitř metod a že mimo jejich metodu o nich nikdo neví. Bude-li proto jiná metoda definovat stejně pojmenované lokální proměnné, budou možná stejně pojmenované, ale budou to naprosto ji-né proměnné.
Poznámka:
Je to obdobné, jako když budete mít doma morče pojmenované Ferda (programátorsky: budete mít lokální proměnnou Ferda typu Morče) a váš kamarád na druhém konci města bude mít stej-ně pojmenované morče. Obě jsou to morčata, obě mají stejné jméno, ale nikdo nepředpokládá, že nakrmíte-li vašeho Ferdu, přestane mít kamarádův Ferda hlad. Stejně pohlížejte i na lokální proměnné metod.
Lokální proměnné mají ještě dvě důležité vlastnosti:
- Před jejich prvním použitím jim musíte přiřadit určitou počáteční hodnotu. Neučiníte-li tak, ohlásí překladač chybu, protože odmítá vytvořit program, který by pracoval s nějakým sme-tím, jež by se zrovna nacházelo v paměti na místě, které by pro danou proměnnou vyhradil.
- Jakmile metodu opustíte, proměnná se zruší a při příštím spuštění metody se znovu vytvoří. Není proto možné uchovávat v lokálních proměnných cokoliv, co si potřebujeme pamatovat mezi jednotlivými voláními dané metody. K tomu musíte použít atributy.
Takže nyní už všechno víme a můžeme začít programovat:
/**
* Nastavi novy rozmer stromku na platne.
*
* @param s nova sirka smrku
* @param v nova vyska smrku
*/
public void setRozmer( int s, int v )
{
//Zmenou velikosti celeho smrku se meni i pozice
//jeho jednotlivych casti - je treba nastavit obe
//Pri nastavovani muzeme vyjit z definice kontruktoru
//Pripravime si casto pocitane vyrazy
int s5 = s/5;
int v7 = v/7;
int x = getX();
int y = getY();
//Spocteme a nastavime novou pozici jednotlivych casti
horni.setPozice ( x + s5, y );
stredni.setPozice( x + s/10, y + v7 );
dolni.setPozice ( x, y + v7*2 );
//Spocteme a nastavime definitivni podobu casti
horni.setRozmer ( 3 * s5, 3 * v7 );
stredni.setRozmer( 4 * s5, 4 * v7 );
dolni.setRozmer ( s, 5 * v7 );
//Pri odmazavani dolnich dilu se muze umazat kus hornich
horni.kresli();
stredni.kresli();
}//public void setRozmer( int s, int w )Úkol 1:
Definujte pro třídu Smrk2 ještě metodu setPozice(int,int).
Úkol 2:
Definujte obě metody i pro svoje třídy Snehulak, Domek a Panak.
Rudolf Pecinovský
0 comments:
Post a Comment