Java - preťažovanie metód
Základy informatiky - jazyk Java
Úvod do programovania v jazyku Java
Java - objektovo orientovaný prístup
- >Java - konštruktory
>Java - prístupové metódy
>Java - dedičnosť
>Java - preťažovanie metód
>Java - polymorfizmus
>Java - abstraktné triedy
>Java - rozhrania
Vzorové príklady:
Java - implementácia numerických algoritmov
Java - triedy geometrických tvarov
Pokročilé témy:
Ako sme už povedali, v Jave dokážeme vytvárať hierarchiu tried. Teda hovoríme o nadradených a podradených triedach. Pojmom generická trieda sme označili triedu, ktorá definuje určité vlastnosti pre skupinu podriadených tried. Podtrieda dedí všetky verejné vlastnosti a metódy. Tu sa dostávame k jednej zaujímavosti: ak od nadradenej triedy zdedíme nejakú metódu, môžeme ju v triede potomka predefinovať? Odpoveď znie áno, a tento mechanizmus sa nazýva preťažovanie, resp. prekrývanie (overriding).
Obsah
Definícia preťažovania
Princíp preťažovania metód je vo vytvorení novej metódy v podtiede, ktorá danú metódu zdedila od nadradenej triedy. V podtiede bude pôvodná metóda prekrytá (preťažená). Preťažená metóda musí mať rovnaký počet a typ argumentov ako pôvodná metóda. Poznámka: metódy označené ako final sa preťažovať nedajú.
Zoberme si príklad z predchádzajúcej časti Java - dedičnosť, kde sme definovali hierarchiu tried reprezentujúcu zvieracie druhy.
Do triedy Zviera doplníme metódu pohniSa, ktorá bude reprezentovať pohyb zvieraťa. Túto metódu zároveň definujme aj v triedach potomkov:
public class Zviera {
// tu sa nachádza všetko z predchádzajúceho príkladu
// doplníme nasledujúce:
public void pohniSa(int k)
{
System.out.println("Presuvam sa o "+k+" metrov");
}
}
public class Cicavec extends Zviera{
public void pohniSa(int k)
{
System.out.println("Bezim "+k+" metrov");
}
}
public class Plaz extends Zviera {
public void pohniSa(int k)
{
System.out.println("Plazim sa"+k+" metrov");
}
}
public class Vtak extends Zviera {
public void pohniSa(int k)
{
System.out.println("Letím "+k+" metrov");
}
}
public class Pes extends Cicavec {
public void pohniSa(int k)
{
System.out.println("Skáčem ako pes "+k+" metrov");
}
}
Pre otestovanie tejto konštrukcie môžeme použiť nasledujúci kód:
public class program {
public static void main(String[] args) {
Zviera a = new Zviera();
Cicavec b = new Cicavec();
Vtak c = new Vtak();
Plaz d = new Plaz();
Pes e = new Pes();
//f je referencia na objekt Zviera, ale vytvorený bude objekt Pes
Zviera f = new Pes();
System.out.println("Nazov: " + a.nazov);
a.pohniSa(5);
System.out.println("Nazov: " + b.nazov);
b.pohniSa(5);
System.out.println("Nazov: " + c.nazov);
c.pohniSa(5);
System.out.println("Nazov: " + d.nazov);
d.pohniSa(5);
System.out.println("Nazov: " + e.nazov);
e.pohniSa(5);
System.out.println("Nazov: " + e.nazov);
f.pohniSa(4);
}
Výpis programu je nasledujúci:
Nazov: Zviera presúvam sa 5 metrov Nazov: Cicavec bežím 5 metrov Nazov: Vtak letím 5 metrov Nazov: Plaz plazím sa 5 metrov Nazov: Pes Skáčem ako pes 5 metrov Nazov: Pes Skáčem ako pes 4 metrov
Zaujímavosťou je tu vytvorenie objektu f. Objekt f je definovaný ako odkaz (referencia) na objekt Zviera, ale vytvorený je objekt typu Pes (new Pes). Preto pri zavolaní metódy pohniSa, sa zavolá metóda z triedy Pes a nie Zviera.
Rozhodovanie o tom, ktorá metóda sa v prípade obektu f vykoná, sa deje už pri kompilácii programu. Pri chybnom definovaní preťaženia nás teda informuje kompilátor. Uvažujme nasledujúci príklad:
class Zviera{
public void pohniSa(int k)
{
System.out.println("Presuvam sa o "+k+" metrov");
}
}
class Vtak extends Zviera{
public void pohniSa(int k)
{
System.out.println("Letím "+k+" metrov");
}
public void spievaj(){
System.out.println("Snažím sa spevať");
}
}
//----program-pre-testovanie-funkcnosti-navrhnutych-tried
public class program {
public static void main(String[] args) {
Zviera a = new Zviera();
Zviera c = new Vtak();
a.pohniSa(5);
c.pohniSa(5);
c.spievaj();
}
}
Kompilátor zahlási nasledujúcu chybu:
progam.java:30: cannot find symbol symbol : method spievaj() location: class Zviera b.spievaj(); ^
Táto chyba je tu preto, pretože trieda Zviera nemá metódu spievaj. A objekt b je odkaz na triedu Zviera.
Pravidlá pre preťažovanie
- Argumenty preťaženej metódy musia byť úplne rovnaké ako argumenty zdedenej metódy
- Návratový typ preťažovanej metódy by mal byť rovnaký (alebo podtyp) ako návratový typ pôvodnej metódy v rodičovskej triede.
- Úroveň prístupu nemôže byť reštriktívnejšia ako v pôvodnej triede. Napríklad: ak je v nadradenej triede metóda deklarovaná ako verejná (public), potom ako preťažené metóda nemôže byť private.
- Metódy môže byť preťažené, len ak sú zdedené z nadtriedy.
- Metóda deklarované ako final nemožno preťažovať.
- Metóda deklarovaná ako statická (static) sa nedá preťažiť, ale dá sa redeklarovavať.
- Ak sa metóda nedá zdediť, potom nemôže byť ani preťažené.
- Konštruktory nemôžu byť preťažené.[1]
Použitie výrazu super
V predchádzajúcej časti (Java - dedičnosť) bolo povedané, že výraz super znamená nadradenú triedu. Výraz super() sme použili v konštruktore odvodenej triedy, aby sme zavolali konštruktor rodičovskej triedy. Výraz super však vo všeobecnosti znamená "nadradenú" triedu. Ukážeme to v nasledujúcom príklade:
class Zviera{
public void pohniSa(int k)
{
System.out.println("Presuvam sa o "+k+" metrov");
}
}
class Plaz extends Zviera{
public void pohniSa(int k)
{
super.pohniSa(k);
System.out.println("plazím sa "+k+" metrov");
}
}
//-----------------------------------------------
public class program {
public static void main(String[] args) {
Zviera a = new Plaz();
a.pohniSa(5);
}
}
Výstup z programu bude nasledovný:
presúvam sa 5 metrov plazím sa 5 metrov
Vysvetlenie: pri zavolaní metódy pohniSa sa začne vykonávať metóda pohniSa v triede Plaz. Ako prvé volanie je super.pohniSa(k);, čiže zavolá sa metóda pohniSa z nadradenej triedy.
Zdroje a odkazy
- ↑ tutorialspoint.com - Java Overriding http://www.tutorialspoint.com/java/java_overriding.htm