PL/SQL by Example / Inheritance and Polymorphism

A key concept of object-oriented programming (OOP) is inheritance, which allows grouping properties and behaviors into a hierarchy. This way, new objects can automatically acquire functionality (methods, variables, constants, etc.) from their ancestor.

By default, an object prohibits inheritance, so modification with the NOT FINAL modifier is necessary.

CREATE OR REPLACE TYPE Employee_T AS OBJECT(
    FullName VARCHAR2(100)
  , MEMBER FUNCTION mf_Display RETURN VARCHAR2
) NOT FINAL;
/
CREATE OR REPLACE TYPE BODY Employee_T AS

  MEMBER FUNCTION mf_Display
    RETURN VARCHAR2
  IS
  BEGIN
    RETURN FullName;
  END;

END;
/

Overriding

Another very common OOP concept is method overriding. This allows subtypes to change the behavior of inherited procedures and functions and adapt them to specific requirements.

The method definition remains the same as in the ancestor, only it is preceded by the keyword OVERRIDING.

CREATE OR REPLACE TYPE Programmer_T UNDER Employee_T(
    Salary NUMBER

  , OVERRIDING MEMBER FUNCTION mf_Display
      RETURN VARCHAR2
);
/
CREATE OR REPLACE TYPE BODY Programmer_T AS

  OVERRIDING MEMBER FUNCTION mf_Display
    RETURN VARCHAR2
  IS
  BEGIN
    RETURN FullName||', '||Salary;
  END;

END;
/

Using the overridden function mf_Display is straightforward; in the first case, only the full name is printed, in the second, both the name and salary.

DECLARE
  l_Employee Employee_T;
  l_Programmer Programmer_T;
BEGIN
  l_Employee:=Employee_T('Francis Sauce');
  dbms_output.put_line(l_Employee.mf_Display);
  -- Francis Sauce

  l_Programmer:=Programmer_T('Peter Novak', 20000);
  dbms_output.put_line(l_Programmer.mf_Display);
  -- Peter Novak, 20000
END;
/

Polymorphism

An interesting situation occurs when a descendant is assigned to a variable of the ancestor type, i.e., to Employee_T. In this case, the name along with the salary is printed. This is because the object is actually an instance of the type Programmer_T. The technique where objects of different types respond to calls in a specific way is called polymorphism.

DECLARE
  l_Employee Employee_T;
BEGIN
  l_Employee:=Programmer_T('Peter Novak', 20000);
  dbms_output.put_line(l_Employee.mf_Display);
  -- Peter Novak, 20000
END;
/

If, for some reason, it is necessary to enforce the implementation defined in the ancestor on a descendant that overrides it, explicit conversion is required.

DECLARE
  l_Programmer Programmer_T;
BEGIN
  l_Programmer:=Programmer_T('Peter Novak', 20000);
  dbms_output.put_line((l_Programmer AS Employee_T).mf_Display);
  -- Peter Novak
END;
/

Leave a reply

Your email address will not be published. Required fields are marked *