203 lines
13 KiB
Markdown
203 lines
13 KiB
Markdown
# Metody
|
||
|
||
- Naprostá většina programů je netriviální a rozsáhlá
|
||
- Často potřebujeme jeden výpočet provést vícekrát
|
||
- Pokud všechen výkonný kód napíšeme jen do metody ```main```(), budou se části kódu opakovat
|
||
- Potřeba dekompozice
|
||
- Rozdělení problému na menší podproblémy
|
||
- Tyto podproblémy lze rozdělit ještě na menší podproblémy
|
||
- Tak postupujeme dále, až dostaneme elementární podproblémy, které jsou snadno řešitelné => postupujeme hierarchicky odshora dolů
|
||
- Snadno řešitelné elementární podproblémy mohou být reprezentovány metodami
|
||
- Použití metod
|
||
- Program se snáze navrhuje
|
||
- Je rozdělen na elementární části reprezentované metodami
|
||
- Je možné vytvářet program po krocích
|
||
- Zdrojový kód je přehlednější
|
||
- V daném místě se lze soustředit jen na jednu konkrétní část algoritmu
|
||
|
||
### Popis metod a terminologie
|
||
|
||
- metody jsou úseky kódu (podprogramy), které provádějí nějaký výpočet
|
||
- Metody by neměly být příliš dlouhé (cca na jednu obrazovku) a měly by dělat jednu jasně definovatelnou činnost popsanou jejich názvem
|
||
- Je třeba rozlišovat deklaraci/definici metody a volání/použití metody
|
||
|
||
### Deklarace metody
|
||
|
||
- Deklarace metody znamená, že vytvoříme (napíšeme) metodu
|
||
- včetně jejího názvu a výkonného kódu
|
||
- POZOR! – Tento kód se však provede až při volání metody
|
||
- Každá metoda se skládá z hlavičky a těla
|
||
- Hlavička metody
|
||
- Obsahuje „popis vlastností“ metody včetně jejího jména
|
||
- ``` právo static návratováHodnota název(parametry) ```
|
||
- Např. ``` public static double naDruhou(double x) ```
|
||
- ```public ``` je přístupové právo
|
||
- ```static ``` značí, že se jedná o statickou metody třídy
|
||
- Existují i metody bez ```static```, tzv. metody instance, kterých je ve skutečnosti většina
|
||
- Název metody začíná malým počátečním písmenem, každé další slovo víceslovného názvu začíná velkým písmenem
|
||
- Podobně jako u názvu proměnných
|
||
- U dokumentačního komentáře metody se uvádí alespoň jedna řádka popisující účel metody, případné parametry metody a návratová hodnota jsou popsány na dalších řádkách
|
||
- např.:
|
||
```java
|
||
/**
|
||
* Ukazka deklarace metod - vypocet vzdalenosti dvou bodu v rovine
|
||
* @author Tomas Potuzak
|
||
* @version 1.0 (2018-08-13)
|
||
*/
|
||
```
|
||
- Tělo metody
|
||
- Obsahuje výkonné příkazy uzavřené do složených závorek
|
||
- V Javě se otevírací závorka píše na řádku hlavičky metody
|
||
- Metoda je jednoznačně určena třídou, ve které je deklarována, svým názvem, počtem, typem a pořadím svých parametrů a návratovou hodnotou
|
||
- Přesto se ve vysvětlujícím textu (nikoliv ve zdrojovém kódu) běžně používá pouze název metody se závorkami (např. ``` naDruhou ```()), pokud nehrozí záměna za jinou metodu
|
||
- Každá metoda musí být deklarována přímo uvnitř třídy
|
||
- Není možné deklarovat metodu mimo třídu
|
||
- Není možné deklarovat metodu uvnitř jiné metody
|
||
- Metody se typicky deklarují po deklaraci proměnných (např. deklarace ```Scanner```u) kvůli přehlednosti
|
||
- Mohou být ale deklarovány kdekoliv uvnitř třídy
|
||
- Pořadí deklarace metod **je** (v Javě) **irelevantní**, každá metoda je platná (je viditelná) v celé třídě => metoda může být deklarována až za místem, kde již byla volána
|
||
|
||
### Volání (použití) metody
|
||
|
||
- Volání metody znamená, že se provede kód umístěný v těle metody na místě programu, kde metodu voláme (použijeme)
|
||
- Pokud chceme metodu použít (tj. chceme, aby provedla svou činnost (výpočet) na určitém místě), použijeme její jméno a do závorek napíšeme hodnoty skutečných parametrů, které nahradí formální parametry v hlavičce metody
|
||
- Pokud použijeme metodu ve stejné třídě, jako ve které je deklarována (tj. voláme ji z jiné metody téže třídy), voláme ji pouze jejím jménem a hodnotami parametrů
|
||
- ``` metoda(parametry); ```
|
||
- Pokud použijeme metodu vně třídy, ve které je deklarována, musíme před název metody přidat název třídy, ve které je deklarována (tečková notace)
|
||
- ``` Třída.metoda(parametry); ```
|
||
- Toto platí pouze pro metody označené klíčovým slovem ```static```
|
||
|
||
### Lokální proměnné
|
||
|
||
- Jsou definovány **UVNITŘ** metod
|
||
|
||
#### Viditelnost lokálních proměnných
|
||
|
||
- Jsou viditelné (tj. mohu je používat pro čtení a zápis) **pouze uvnitř metody**
|
||
- Jsou viditelné od místa (řádky), kde byly deklarovány
|
||
- Jsou viditelné do konce bloku, ve kterém byly deklarovány
|
||
- Rozdíl oproti proměnným definovaným UVNITŘ třídy, ale VNĚ metod (proměnné třídy), které jsou viditelné v rámci třídy i před místem deklarace (podobně jako metody)
|
||
- Pokud jsou deklarovány přímo v těle metody (tj. ne uvnitř vnořeného bloku), jejich viditelnost končí s tělem metody
|
||
- Pokud jsou definovány uvnitř vnořeného bloku (např. v příkazu if nebo v cyklu), jejich platnost končí koncem bloku
|
||
- Zastíní proměnnou třídy (a instance) pokud se jmenuje stejně
|
||
- Je možné deklarovat lokální proměnnou, která se jmenuje stejně jako proměnná třídy
|
||
- Společný název (identifikátor) pak odkazuje na **LOKÁLNÍ** proměnnou, ne na proměnnou třídy
|
||
- Potenciální zdroj problémů => je potřeba dát pozor, o jakou proměnnou se jedná (lokální/třídy/instance)
|
||
- IDE nástroje většinou druh proměnné odlišují barvou či řezem písma pro větší přehlednost
|
||
- Lokální proměnné ve vnořených blocích
|
||
- Všechny lokální proměnné deklarované před vnořeným blokem jsou platné (viditelné) i v tomto bloku => nelze definovat novou lokální proměnnou se stejným názvem
|
||
|
||
#### Inicializace lokálních proměnných
|
||
|
||
- Lokální proměnné nejsou implicitně inicializovány na ```0, 0.0, false``` nebo ```null```
|
||
- Na rozdíl od proměnných třídy (a proměnných instance)
|
||
- Je vhodné je inicializovat ručně (explicitně)
|
||
- Např. ``` int i = 0; ```
|
||
|
||
### Návratová hodnota metody a příkaz return
|
||
|
||
- Existují **dva typy metod**:
|
||
- Metody **s návratovou hodnotnou** (**funkce**)
|
||
- Metody **bez návratové hodnoty** (**procedury**)
|
||
|
||
#### Metody s návratovou hodnotou (funkce)
|
||
|
||
- Metoda může vracet návratovou hodnotu, která může být libovolného typu (základní datový typ, třída, pole, ...)
|
||
- Pokud metoda vrací návratovou hodnotu, jedná se o funkci
|
||
- Typ je specifikován těsně před názvem metody
|
||
- Pro určení návratové hodnoty uvnitř těla metody se používá příkaz (klíčové slovo) ```return```, za který se uvede výraz s odpovídajícím typem výsledné hodnoty
|
||
- ```return výraz;```
|
||
- Výraz může být libovolně komplikovaný nebo se může jednat o samotnou proměnnou (nebo výjimečně i pojmenovanou/nepojmenovanou konstantu)
|
||
- Volání metody s návratovou hodnotou
|
||
- Výsledkem volání metody je její návratová hodnota, ale může mít i další efekty
|
||
- Např. může ovlivnit hodnoty proměnných třídy (nebo mnohem častěji proměnných instance)
|
||
- Pokud je primárním výsledkem volání metody (funkce) její návratová hodnota, je většinou volána jako součást výrazu
|
||
- Pokud primárním výsledkem volání metody (funkce) je jiná činnost, kterou provádí, a návratová hodnota je (někdy) vedlejší, lze jí volat jako příkaz (tj. ne jako součást výrazu)
|
||
- Vrácená hodnota se zahodí (nikam se nepřiřadí a nepoužije se)
|
||
|
||
#### Metody bez návratové hodnoty (procedura)
|
||
|
||
- Metoda nevrací žádnou návratovou hodnotu, pouze provede nějakou činnost => pak se jedná o proceduru
|
||
- Při deklaraci metody se místo návratového typu uvede klíčové slovo void
|
||
- Např. ```public void vypisNahodnaCisla()```
|
||
- Volání metody bez návratové hodnoty
|
||
- Metoda se volá pouze jako příkaz, nemůže být součástí výrazu jako metoda s návratovou hodnotou
|
||
|
||
#### Použití příkazu return
|
||
|
||
- Příkaz return okamžitě ukončí metodu, bez ohledu na to, kde se v metodě nachází
|
||
- Příkazů return může být v jedné metodě více (např. v každé větvi příkazu ```if```)
|
||
- Pokud metoda vrací návratovou hodnotu (jedná se o funkci), nesmí existovat větev, ve které by příkaz return nebyl (došlo by k chybě překladu)
|
||
- Za ním už se nesmí nacházet žádný příkaz, protože se nikdy nemůže provést (dojde k chybě překladu)
|
||
- Např. pokud je použit v příkazu ```switch```, nemůžou být jednotlivé větve ukončeny příkazem ```break;```, protože tento příkaz je nedosažitelný
|
||
- Příkaz ```return``` se může použít k předčasnému ukončení metody (např. proto, že parametr nemá platnou hodnotu)
|
||
- Příkaz return se může použít i k předčasnému ukončení metody bez návratové hodnoty (procedury)
|
||
- Pak se použije samotný ```return;```
|
||
|
||
### Parametry metody
|
||
|
||
- Metoda může mít „neomezené“ množství parametrů
|
||
- Prakticky jich bývá pouze několik (žádný až cca 3 až 5)
|
||
- Více parametrů typicky svědčí o špatné dekompozici problému
|
||
- Parametry jsou popsány v závorce za názvem metody stejně jako deklarace proměnné typem a názvem
|
||
- Parametry mohou být libovolného typu
|
||
- Pokud má metoda více parametrů, jsou odděleny čárkou
|
||
- U každé proměnné musí být explicitně uveden datový typ, i když je více parametrů stejného datového typu za sebou
|
||
- Např. ```double static secti(double a, double b)```
|
||
|
||
#### Formální a skutečné parametry metody
|
||
|
||
- Parametry definované v hlavičce metody (při deklaraci metody) se nazývají **formální parametry**
|
||
- Při volání metody jsou v závorce uvedeny **skutečné parametry metody**
|
||
- Musejí odpovídat počtem a datovým typem (ve správném pořadí)
|
||
- Může se jednat o proměnné, pojmenované/nepojmenované konstanty a výrazy (datový typ výsledku výrazu musí odpovídat datovému typu formálního parametru)
|
||
- Ve formálních parametrech (proměnných) jsou do metody předány hodnoty skutečných parametrů metody
|
||
- Tyto hodnoty typicky ovlivňují chování metody
|
||
- Formální parametry mají v těle metody všechny vlastnosti lokálních proměnných, typicky se ale jejich hodnoty jen čtou
|
||
- Je možné do nich přiřadit hodnotu, tím se ale ztratí hodnota předaná do metody => do formálních parametrů nové hodnoty v těle metody nepřiřazovat
|
||
|
||
#### Mechanizmus předání parametrů do metody
|
||
|
||
- Parametry jsou předávány vždy **hodnotou**
|
||
- Platí pro základní datové typy i reference
|
||
- Hodnoty skutečných parametrů jsou překopírovány a vloženy do odpovídajících formálních parametrů, přes které jsou hodnoty dostupné v těle metody
|
||
- Změnit hodnotu formálních parametrů v těle metody je možné, ale změna se nijak neprojeví vně metody
|
||
- Kromě toho se přepíše hodnota předaná do metody
|
||
|
||
### Předávání řízení při volání metod
|
||
|
||
- Pokud je program rozdělen na metody, neběží lineárně od první řádky po poslední
|
||
- Při každém volání metody se „skočí“ na začátek těla metody a začne se provádět její kód
|
||
- Tzv. „předávání řízení“
|
||
- Při dosažení konce těla metody se skočí zpátky na místo, odkud byla metoda volána, a pokračuje se dalším příkazem
|
||
- Volání metody jako parametru jiné metody
|
||
- Pokud metoda vrací návratovou hodnotu a tato hodnota je použita jako parametr volání další metody, je možné si ji uložit do pomocné proměnné a tu pak použít jako parametr další metody
|
||
- Tento zápis je přehlednější
|
||
- Je však také možné volat metodu přímo ve volání další metody
|
||
- Tento zápis je úspornější, ale méně přehledný
|
||
- Oba zápisy se běžně používají
|
||
|
||
### Přetěžování metod (overloading)
|
||
|
||
- V jedné třídě může být deklarováno více metod se stejným jménem
|
||
- Metody se pak nazývají přetížené (overloaded)
|
||
|
||
#### Důvody k přetěžování metod
|
||
|
||
- Přetížené metody obvykle dělají podobnou činnost, ale mírně se liší
|
||
- Protože je možné metody přetížit, není nutné vymýšlet podobné názvy podobných metod, můžeme rovnou použít stejný název
|
||
- Dělají stejnou činnost pro různý datový typ
|
||
- Např. metoda ```Math.abs()``` je přetížena 4x pro typ
|
||
```int, long, float a double```
|
||
- Dělají stejnou činnost, ale s upřesněním
|
||
- Typicky přibudou další parametry
|
||
|
||
#### Požadavky na přetížené metody
|
||
|
||
- Přetížené metody MUSÍ mít různé hlavičky
|
||
- Musí se lišit počtem a/nebo typem a/nebo pořadím typů parametrů
|
||
- Nestačí, aby se lišily jen návratovou hodnotou
|
||
- Nestačí, aby se lišily jen názvem formálních parametrů
|
||
- Názvy formálních parametrů nejsou podstatné – používají se v těle metody, ale při jejím volání je důležitý pouze jejich typ
|
||
- Při volání překladač vybere podle skutečných parametrů metodu, která přesně odpovídá počtem, typem a pořadím parametrů
|
||
|