Root Type: Food!
CREATE TYPE food_t AS OBJECT (
NAME VARCHAR2 (100),
food_group VARCHAR2 (100),
grown_in VARCHAR2 (100),
MEMBER FUNCTION price RETURN NUMBER,
MEMBER FUNCTION to_string RETURN VARCHAR2,
MEMBER PROCEDURE show_object
)
NOT FINAL;
Type created.
Implement the Methods
CREATE OR REPLACE TYPE BODY food_t
IS
MEMBER FUNCTION price
RETURN NUMBER
IS
BEGIN
RETURN (CASE SELF.food_group
WHEN 'PROTEIN'
THEN 3
WHEN 'CARBOHYDRATE'
THEN 2
WHEN 'VEGETABLE'
THEN 1
END
);
END;
MEMBER FUNCTION to_string
RETURN VARCHAR2
IS
BEGIN
RETURN 'FOOD! '
|| SELF.NAME
|| ' - '
|| SELF.food_group
|| ' - '
|| SELF.grown_in;
END;
MEMBER PROCEDURE show_object
IS BEGIN
DBMS_OUTPUT.PUT_LINE ( '=== Display name of ' || SELF.name || ' ===' );
DBMS_OUTPUT.PUT_LINE (SELF.to_string());
END;
END;
Type created.
Every Dessert is a Food
CREATE TYPE dessert_t UNDER food_t (
contains_chocolate CHAR (1),
year_created NUMBER (4),
OVERRIDING MEMBER FUNCTION price RETURN NUMBER,
OVERRIDING MEMBER FUNCTION to_string RETURN VARCHAR2
)
NOT FINAL;
Type created.
Implement the Body
CREATE OR REPLACE TYPE BODY dessert_t
IS
OVERRIDING MEMBER FUNCTION price
RETURN NUMBER
IS
multiplier NUMBER := 1;
BEGIN
IF SELF.contains_chocolate = 'Y'
THEN
multiplier := 2;
END IF;
IF SELF.year_created < 1900
THEN
multiplier := multiplier + 0.5;
END IF;
RETURN (10.00 * multiplier);
END;
OVERRIDING MEMBER FUNCTION to_string
RETURN VARCHAR2
IS
BEGIN
/* ONLY display the dessert information.... */
RETURN 'DESSERT! With Chocolate? '
|| SELF.contains_chocolate
|| '-'
|| SELF.year_created
|| chr(10)
|| (SELF as food_t).to_string;
END;
END;
Type created.
Every Cake is a Dessert
CREATE TYPE cake_t UNDER dessert_t (
diameter NUMBER,
inscription VARCHAR2 (200),
OVERRIDING MEMBER FUNCTION to_string RETURN VARCHAR2
)
Type created.
Implement the Body
CREATE OR REPLACE TYPE BODY cake_t
IS
OVERRIDING MEMBER FUNCTION to_string
RETURN VARCHAR2
IS
BEGIN
/* Call two supertype methods... */
RETURN 'CAKE! With diameter: '
|| self.diameter
|| ' and inscription '
|| SELF.inscription
|| chr(10)
|| (SELF as dessert_t).to_string
;
END;
END;
Type created.
And Now the Magic of Dynamic Polymorphism
DECLARE
TYPE foodstuffs_nt IS TABLE OF food_t;
fridge_contents foodstuffs_nt
:= foodstuffs_nt (food_t ('Eggs benedict', 'PROTEIN', 'Farm'),
dessert_t ('Strawberries and cream',
'FRUIT',
'Backyard',
'N',
2001
),
cake_t ('Chocolate Supreme',
'CARBOHYDATE',
'Kitchen',
'Y',
2001,
8,
'Happy Birthday, Veva'
)
);
BEGIN
FOR indx IN fridge_contents.FIRST .. fridge_contents.LAST
LOOP
fridge_contents (indx).show_object();
END LOOP;
END;
=== Display name of Eggs benedict ===
FOOD! Eggs benedict - PROTEIN - Farm
=== Display name of Strawberries and cream ===
DESSERT! With Chocolate? N-2001 FOOD! Strawberries and cream - FRUIT - Backyard
=== Display name of Chocolate Supreme ===
CAKE! With diameter: 8 and inscription Happy Birthday, Veva DESSERT! With Chocolate? Y-2001 FOOD! Chocolate Supreme - CARBOHYDATE - Kitchen
DROP TYPE cake_t FORCE
Type dropped.
DROP TYPE dessert_t FORCE
Type dropped.
DROP TYPE food_t FORCE
Type dropped.