Referenční typy - třída
6. Metody
6.3. Nestatické metody
Nestatickou metodu (není deklarována klíčovým slovem static) lze volat pouze na konkrétní instanci třídy. Tato metoda může pracovat s datovými složkami této instance. Volání metody představuje zprávu poslanou instancí. Instanci třídy vytváříme pomocí konstruktoru – viz kapitola Konstruktory. Pokud voláme v těle nestatické metody další nestatickou metodu pro tutéž instanci, jméno instance nemusíme uvádět.
Nestatické metody třídy lze volat v nestatických metodách pomocí klíčového slova this. Jedná se o odkaz na konkrétní instanci třídy. Pomocí this lze také přistoupit k nestatickým datovým složkám.
Ilustrativní příklad TridaStatickaNestatickaSlozka
Program TridaStatickaNestatickaSlozka
- Popis: Deklarace nestatické třídy, deklarace statické a nestatické složky uvnitř této třídy
- Zadání: Deklarujte nestatickou třídu Trida, která bude obsahovat hlavní metodu Main, ve které vypíšete hodnoty deklarované statické celočíselné složky a a nestatické datové složky b, které jsou deklarovány uvnitř třídy. Deklarujte soukromou (privátní) nestatickou metodu Soucet uvnitř této třídy. Tato metoda navrací součet obou datových složek. Zkuste v metodě Main vypsat hodnoty obou datových složek, aniž by byly inicializovány, nebo by jim byly přiřazeny nějaké hodnoty
- Řešení: Bude postupně probráno v následujícím textu
V následujícím příkladu si zkusíme ve
statické metodě Main použít
statickou a nestatickou datovou složku – viz Kód 1. Jak
vidíme v prvním příkazu metody Main, šlo přistoupit k soukromé
statické datové složce. Ve druhém případu přístupu k soukromé nestatické složce bychom úspěšní nebyli. Kompilátor by zahlásil chybu. V kódu jsme také
deklarovali nestatickou soukromou metodu Soucet,
která navrací součet hodnoty ve statické a nestatické složce třídy. Jak vidíme,
tuto metodu nelze volat v rámci statické metody Main, i když je metoda Main
deklarována rámci téže třídy.
//Deklarace třídy class Trida { //Deklarace soukromé statické datové složky static int a; //Deklarace soukromé nestatické datové složky int b; //Deklarace soukromé nestatické metody třídy int Soucet() { return (a + this.b); } static void Main(string[] args) { //Použití soukromé statické datové složky Console.WriteLine(a); //Nelze použít soukromou nestatické datovou složku -> K.O. Console.WriteLine(b); //Nelze volat nestatickou metodu v rámci stejné třídy -> K.O. Console.WriteLine(Soucet()); //Čekání na stisk klávesy -> ukončení programu Console.ReadKey(); } }
Kód 1: Příklad volání nestatické metody ve statické metodě, použití soukromé statické a nestatické složky
Vraťme se k příkladu našeho auta.
Ilustrativní příklad AutoUjedTrasu
Program AutoUjedTrasu
- Popis: Deklarace veřejné metody třídy Auto
- Zadání: Deklarujte veřejnou metodu bez návratu s názvem UjedTrasu ve třídě Auto, která simuluje jízdu auta. Využijte deklarovaných datových složek v předchozím programu AutoNestatickeDatoveSlozky. Tato metoda přijímá jako vstupní reálný formální parametr pocetKm, který vyjadřuje počet km, které má auto ujet. V rámci této metody je volána další metoda SpotrebujPalivo, která zajistí spotřebu paliva pro jízdu auta (datová složka stavNadrze). Je zároveň nutné zvýšit počet ujetých kilometrů auta (datová složka ujetoKm). Deklarujte metodu StavNadrzeGraficky pro zobrazení grafického prvku, který ukazuje aktuální stav paliva v nádrži (návrat metody ve formě textového řetězce). Grafický ukazatel stavu paliva budou reprezentovat znaky "#" uzavřené v hranatých závorkách
- Řešení: Bude postupně probráno v následujícím textu (zdrojový kód tohoto příkladu bude využit pro sestavení konečné podoby třídy Auto)
Účelem našeho auta je jezdit různé trasy.
K tomu využijeme veřejnou metodu bez návratu s názvem UjedTrasu - viz Kód 2.
Vzdálenost, kterou má auto ujet, je specifikována pomocí formálního parametru pocetKm. Tento vstupní parametr je předán
hodnotou. V metodě zavoláme další metodu třídy spotrebujPalivo, která zajistí, že bude spotřebováno palivo v nádrži v závislosti na počtu ujetých kilometrů. Pro volání metody jsme využili
klíčového slova this a tečkové
notace (anglicky „Dot Notation“) , ale vzhledem k tomu, že metodu deklarujeme ve stejné třídě, to
není nutné. Mohli jsme pouze uvést název metody. Ujeté kilometry se nám také
musí odrazit v celkovém počtu ujetých kilometrů auta. Musíme tedy zvýšit hodnotu soukromé datové složky ujetoKm
o hodnotu počtu ujetých kilometrů na trase pomocí operátoru +=.
//Deklarace veřejné metody pro ujetí určité trasy public void UjedTrasu(double pocetKm) { //Volání metody pro spotřebu paliva this.SpotrebujPalivo(pocetKm); //Zvýšení celkového počtu ujetých kilometrů this.ujetoKm += pocetKm; }
Kód 2: Příklad deklarace veřejné metody UjedTrasu ve třídě Auto – spotřeba paliva na ujetí trasy
Naše auto by mělo spotřebovat pohonnou látku,
pokud uskuteční jízdu. Za tímto účelem byla deklarována soukromá metoda bez návratu s názvem SpotrebujPalivo, která přijímá počet ujetých
kilometrů na jízdu auta jako formální parametr pocetKm - viz Kód 3. Na základě výpočtu
spotřebovaného paliva pomocí spotřeby a ujetého počtu kilometrů spočteme
spotřebované palivo na jízdu (vypočtenou hodnotu uložíme do lokální proměnné spotrebovanePalivo). Vypočtenou hodnotu
spotřebovaného paliva musíme zároveň odebrat z nádrže pomocí operátoru -= (z datové složky stavNadrze).
//Deklarace soukromé metody pro výpočet spotřeby a snížení množství paliva private void SpotrebujPalivo(double pocetKm) { //Výpočet spotřebovaného paliva double spotrebovanePalivo = pocetKm / 100 * this.spotreba; //Odebrání spotřebovaného paliva z nádrže this.stavNadrze -= spotrebovanePalivo; }
Kód 3: Příklad deklarace soukromé metody SpotrebujPalivo ve třídě Auto – spotřeba paliva
Další veřejnou metodou StavNadrzeGraficky kterou budeme využívat, je zobrazení grafického ukazatele, který nám ukáže, jaký je aktuální stav paliva v nádrži - viz Kód 4. Grafický ukazatel ve formě textového řetězce bude zobrazen v hranatých závorkách, mezi nimiž jsou umístěny znaky "#", které zobrazují aktuální stav paliva v nádrži auta.
Počet
dílků tedy pro jednotlivé instance třídy Auto
bude konstantní, proto je tato datová složka deklarována jako statická (datová složka delkaGrafUkazatele). Pro
přístup k této datové složce jsme využili třídu Auto a pomocí tečkové notace přistoupili k této statické
složce (vzhledem k tomu, že jsme v rámci téže třídy, lze vynechat Auto.). V další příkazu jsme ve
výrazu využili funkci Round třídy Math, která nám zaokrouhlí na celé
číslo vypočtenou procentuální hodnotu objemu paliva v nádrži vzhledem k
celkové kapacitě nádrže. Pro zapsání počtu znaků "#" (reprezentujících
objem paliva v nádrži) jsme využili cyklus s krokem, protože víme,
kolik znaků má být zapsáno uvnitř hranatých závorek ukazatele. Pro připojení
znaků do textového řetězce zprava jsme využili operátor +=. Po vypsání znaků "#" musíme doplnit mezery do konce
hranaté závorky (mezery budou zobrazovat prázdnou nádrž). K tomu jsme
využili příkaz PadRight datového
typu string, který navrací řetězec
zadané délky, ve kterém je konec řetězce vyplněn mezerami. K výslednému
textovému řetězci připojíme konečnou hranatou závorku a pomocí příkazu return
předáme výsledkem do metody, ze které byla tato metoda volána.
//Deklarace veřejné metody pro grafiku zobrazující aktuální stav paliva v nádrži public string StavNadrzeGraficky() { //Deklarace grafického výstupu - textový řetězec - počátek hranaté závorky string grafickyUkazatel = "["; /*Výpočet procentuálního objemu paliva v nádrži a výpočet počtu dílků * v grafickém ukazateli, tj. počet znaků # uvnitř hranaté závorky*/ double pocetDilku = Math.Round((this.stavNadrze / this.kapacitaNadrze) * Auto.delkaGrafUkazatele); //Cyklus na připojení znaků do grafického výstupu for (int i = 0; i < pocetDilku; i++) grafickyUkazatel += "#"; //Doplnění mezer do celkové délky grafického ukazatele grafickyUkazatel = grafickyUkazatel.PadRight(Auto.delkaGrafUkazatele + 1); //Návrat grafického textového ukazatele stavu paliva v nádrži return (grafickyUkazatel += "]"); }
Kód 4: Deklarace veřejné metody StavNadrzeGraficky ve třídě Auto – grafický ukazatel spotřeby
paliva