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 | 
|---|