PL/SQL v příkladech / Dědičnost a polymorfismus

Klíčovým konceptem objektově orientovaného programování (OOP) je dědičnost, která umožňuje seskupovat vlastnosti a chování do hierarchie. Tímto způsobem mohou nové objekty automaticky získat funkcionalitu (metody, proměnné, konstanty atp.) ze svého předka.

Ve výchozím stavu objekt dědičnost zakazuje, proto je nutná úprava modifikátorem NOT FINAL.

CREATE OR REPLACE TYPE Zamestnanec_T AS OBJECT(
    CeleJmeno VARCHAR2(100)
  , MEMBER FUNCTION mf_Vypis RETURN VARCHAR2
) NOT FINAL;
/
CREATE OR REPLACE TYPE BODY Zamestnanec_T AS

  MEMBER FUNCTION mf_Vypis
    RETURN VARCHAR2
  IS
  BEGIN
    RETURN CeleJmeno;
  END;

END;
/

Překrývání

Dalším velmi rozšířeným konceptem OOP je překrývání metod. To umožňuje podtypům měnit chování zděděných procedur a funkcí a přizpůsobit je konkrétním požadavkům.

Definice metody zůstává stejná jako v předkovi, jen je uvozena klíčovým slovem OVERRIDING.

CREATE OR REPLACE TYPE Programator_T UNDER Zamestnanec_T(
    Plat NUMBER

  , OVERRIDING MEMBER FUNCTION mf_Vypis
      RETURN VARCHAR2
);
/
CREATE OR REPLACE TYPE BODY Programator_T AS

  OVERRIDING MEMBER FUNCTION mf_Vypis
    RETURN VARCHAR2
  IS
  BEGIN
    RETURN CeleJmeno||', '||Plat;
  END;

END;
/

Použití překryté funkce mf_Vypis je přímočaré, v prvním případě se vypíše pouze celé jméno, v druhém jméno i plat.

DECLARE
  l_Zamestnanec Zamestnanec_T;
  l_Programator Programator_T;
BEGIN
  l_Zamestnanec:=Zamestnanec_T('Franta Vomacka');
  dbms_output.put_line(l_Zamestnanec.mf_Vypis);
  -- Franta Vomacka

  l_Programator:=Programator_T('Petr Novak', 20000);
  dbms_output.put_line(l_Programator.mf_Vypis);
  -- Petr Novak, 20000
END;

Polymorfismus

Zajímavá situace nastává, když je potomek přiřazen do proměnné předka, tedy do Zamestnanec_T. V tomto případě se vypíše jméno společně s platem. Je to proto, že objekt je ve skutečnosti instancí typu Programator_T. Technika, kdy objekty s různými typy reagují na volání specifickým způsobem, se nazývá polymorfismus.

DECLARE
  l_Zamestnanec Zamestnanec_T;
BEGIN
  l_Zamestnanec:=Programator_T('Petr Novak', 20000);
  dbms_output.put_line(l_Zamestnanec.mf_Vypis);
  -- Petr Novak, 20000
END;

Pokud je potřeba z nějakého důvodu vynutit implementaci definovanou v předkovi na potomkovi, který ji překrývá, je nutná explicitní konverze.

DECLARE
  l_Programator Programator_T;
BEGIN
  l_Programator:=Programator_T('Petr Novak', 20000);
  dbms_output.put_line((l_Programator AS Zamestnanec_T).mf_Vypis);
  -- Petr Novak
END;

Zanechte komentář

Vaše emailová adresa nebude zobrazena. Povinná pole jsou označena *