Polymorfizmus je funkcia jazyka, dovoľujúca úpravu odvodených funkcií. Je to ďalšia časť dedičnosti.
Vďaka polymorfizmu je možné zmeniť funkčnosť metód odvodenej triedy oproti základnej triede.
Virtuálne metódy
Virtuálne metódy [Virtual Methods] sú metódy základnej triedy, ktoré je neskôr možné nahradiť v odvodenej triede. Na ich definovanie sa používa modifikátor virtual. Ako príklad použijeme triedu Stvorec z minulého dielu, ktorá mohla byť napísaná o dosť jednoduchšie.
public class Stvorec { double a; public Stvorec(double dlzka) { this.a = dlzka; } public virtual double Obvod() { return 4*a; } }
Tento krát sme už v triede naozaj definovali len jednu stranu a tej priradili hodnotu v konštruktore. V metóde Obvod, ktorá vypočíta obvod sme už následne len použili vzorec 4*a. Túto metódu sme rozšírili modifikátorom virtual, preto ju bude možné nahradiť v odvodenej triede.
Nahradenie funkcie
Nahradenie funkcie [Overriding] je spôsob, akým nahradzujeme funkcie základnej triedy. Robí sa to práve modifikátorom override, čo si ukážeme na triede Obdlznik.
public class Obdlznik : Stvorec { double b; public Obdlznik(double a, double b) : base(a) { this.b = b; } public override double Obvod() { return 2*a+2*b; } }
V tejto odvodenej triede sme deklarovali premennú pre stranu b a následne ju v konštruktore priradili a zároveň sme využili konštruktor nadradenej triede, ktorý priradil premennú a. Pomocou modifikatoru override sme nahradily metódu Obvod a zmenili jej kód na 2*a+2*b, čo je vzorec na výpočet obvodu obdĺžnika.
Doplnenie metódy
Metódu, ktorá je označená ako virtuálna je možné okrem nahradenia aj doplniť. Robí sa to podobne ako pri nahradení, ale použijete slovíčko base. To zavolá metódu, ktorú sme nahradili a použije jej kód.
Namiesto metódy Obvod v triede obdĺžnik by ste mohli použiť nasledujúce.
public override double Obvod() { return base()/2 + 2*b; }
Toto použitie by pravdepodobne nemalo žiadny zmysel, ale bolo by možné. Týmto by sme použili metódu Obvod z triedy Stvorec, vydelili jej výsledok dvoma a pripočítali 2*b. Celý vzorec čo sme týmto vytvorili je (4*a)/2 + 2*b = 2*a+2*b.
Abstraktné triedy a funkcie
Triedy môžú byť označené modifikátorom abstract, ktorý zabezpečí, že nebude možné vytvoriť ich objekt. Toto sa oplatí používať, keď má základná trieda slúžiť len ako šablóna pre triedy rozšírene. Tento modifikátor je potom použiteľný aj na metódy. Takto vytvorené metódy potom nemajú žiaden kód a pri odvodených triedach je nutné ich nahradiť (na čo vás upozorní aj samotné IDE). Keďže abstraktné metódy nemajú vlastný kód, je nutné ich vložiť do abstraktných tried. Na ukážku týchto tried použijeme novú triedu Stvoruholnik od ktorej odvodíme štvorec aj obdĺžnik.
public abstract class Stvoruholnik { double a; double b; double c; double d; public abstract double Obvod; } public class Stvorec : Stvoruholnik { public Stvorec(int dlzka) : base() { a = dlzka; } public override double Obvod() { return 4*a; } } public class Obdlznik : Stvoruholnik { public Obdlznik(double a, double b) : base() { this.a = a; this.b = b; } public override double Obvod() { return 2*a+2*b; } }
Ako na príklade môžete vidieť, metóda Obvod v triede Stvoruholnik je prázdna a namiesto bloku kódu za ňou nasleduje bodkočiarka. Zároveň je ukázaná nutnosť priradenia konštruktora aj napriek tomu, že ho v základnej triede nemáte definovaný – pokiaľ totiž konštruktor nedefinujete, prekompiler doplní prázdny. V každej odvodenej triede musia byť nahradené všetky konštruktori základnej triedy.
Týmto sme si prešli polymorfizmus, abstraktné triedy a metódy, virtuálne triedy, nahradzovanie a doplňovanie metód. V ďalšom (v poradí už treťom diely o dedičnosti) si povieme niečo o rozhraniach.