Base or Root Object Type
CREATE TYPE food_t AS OBJECT (
NAME VARCHAR2 (100)
, food_group VARCHAR2 (100)
, grown_in VARCHAR2 (100)
,
-- Generic foods cannot have a price, but we can
-- insist that all subtypes DO implement a price
-- function.
NOT INSTANTIABLE MEMBER FUNCTION price
RETURN NUMBER
)
NOT FINAL NOT INSTANTIABLE;
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
)
NOT FINAL;
Type created.
An Object Type Body
CREATE OR REPLACE TYPE BODY dessert_t
IS
OVERRIDING MEMBER FUNCTION price
RETURN NUMBER
IS
multiplier NUMBER := 1;
BEGIN
DBMS_OUTPUT.put_line ('Dessert price!');
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;
END;
Type created.
Every Cake is a Dessert
CREATE TYPE cake_t UNDER dessert_t (
diameter NUMBER
, inscription VARCHAR2 (200)
,
-- Inscription and diameter determine the price
OVERRIDING MEMBER FUNCTION price
RETURN NUMBER
)
Type created.
Cake-Specific Price Function
CREATE OR REPLACE TYPE BODY cake_t
IS
OVERRIDING MEMBER FUNCTION price
RETURN NUMBER
IS
BEGIN
DBMS_OUTPUT.put_line ('Cake price!');
RETURN ( 5.00 -- base price
+ 0.25 * (LENGTH (SELF.inscription)) -- $.25 per letter
+ 0.50 * diameter
);
END;
END;
Type created.
Can I Declare a Food Variable?
DECLARE
my_favorite_vegetable food_t
:= food_t ('Brussel Sprouts', 'VEGETABLE', 'farm');
BEGIN
DBMS_OUTPUT.put_line (my_favorite_vegetable.price);
END;
ORA-06550: line 3, column 31: PLS-00713: attempting to instantiate a type that is NOT INSTANTIABLEMore Details: https://docs.oracle.com/error-help/db/ora-06550
DECLARE
last_resort_dessert dessert_t
:= dessert_t ('Jello', 'PROTEIN', 'bowl', 'N', 1887);
heavenly_cake cake_t
:= cake_t ('Marzepan Delight'
, 'CARBOHYDRATE'
, 'bakery'
, 'N'
, 1634
, 8
, 'Happy Birthday!'
);
BEGIN
DBMS_OUTPUT.put_line (last_resort_dessert.price);
DBMS_OUTPUT.put_line (heavenly_cake.price);
END;
Dessert price!
15
Cake price!
12.75
DECLARE
TYPE foodstuffs_nt IS TABLE OF food_t;
fridge_contents foodstuffs_nt
:= foodstuffs_nt (dessert_t ('Strawberries and cream'
, 'FRUIT'
, 'Backyard'
, 'N'
, 2001
)
, 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
DBMS_OUTPUT.put_line ( 'Price of '
|| fridge_contents (indx).NAME
|| ' = '
|| fridge_contents (indx).price
);
END LOOP;
END;
Dessert price!
Price of Strawberries and cream = 10
Dessert price!
Price of Strawberries and cream = 10
Cake price!
Price of Chocolate Supreme = 14
Store Object Type Instances in Tables
CREATE TABLE food_tab (food food_t)
Table created.
Cakes and Desserts are Foods
DECLARE
s_and_c dessert_t
:= dessert_t ('Strawberries and cream',
'FRUIT',
'Backyard',
'N',
2001);
choc_sup cake_t
:= cake_t ('Chocolate Supreme',
'CARBOHYDATE',
'Kitchen',
'Y',
2001,
8,
'Happy Birthday, Veva');
BEGIN
INSERT INTO food_tab
VALUES (s_and_c);
INSERT INTO food_tab
VALUES (choc_sup);
END;
1 row(s) inserted.
SELECT COUNT (*) FROM food_tab
COUNT(*) | 2 |
---|