Friday, December 25, 2009

Type Inheritance













Type Inheritance

Inheritance relates to two or more objects where one object behaves as a child of a parent object and derives the properties of the base (parent) object. The child object is said to "inherit" the properties of the parent object. For example, a literature book object can inherit the common properties pertaining to a book object.


In object-oriented languages such as Java and C++, inheritance is implemented by means of superclasses and subclasses constructed to form a class hierarchy. In PL/SQL, an object type takes the role of a Java or C++ class and PL/SQL 9i supports object type inheritance by means of supertypes and sub- types. Objects are organized as instances of types, and types can be related in a tree fashion by means of type hierarchies. The hierarchy so formed constitutes a supertype/subtype hierarchy with subtypes inheriting attributes (data) and methods (behavior) from their supertypes. In fact, a subtype inherits all of the attributes and methods from all its supertypes in the resulting object type hierarchy and not just the immediate subtype.


Inheritance leads to substitutability and dynamic polymorphism. PL/SQL 9i supports substitutability—that is, the ability to use the value of a subtype where a supertype is expected. PL/SQL 9i also supports dynamic polymorphism by means of dynamic method dispatch, which is the ability to determine at runtime and execute the most specific method in the object hierarchy that corresponds to the instance of the object type that invokes the method.


This section discusses the inheritance features of object types and the construction of a type hierarchy in PL/SQL. Dynamic polymorphism is discussed in a subsequent section.


Typical inheritance hierarchies are shown in Figures 10-2 and 10-3.






Figure 10-2: A typical Book hierarchy





Figure 10-3: A typical Vehicle hierarchy


A careful analysis of the hierarchy shown in Figure 10-2 reveals the following:




  • The root type of the hierarchy is Book.




  • Four subtypes evolve from Book: Literature, Technical, Politics, and Religion.




  • A Literature book in turn can be a Fiction book, a Nonfiction book, or a Poetry book.




  • A Fiction book can be a Novel or a Short Story.




  • Finally, a Novel can be on a Mystery topic, a Horror topic, or a Drama topic.




  • The Book hierarchy has five levels, including the root level, and all types defined at a level other than the root level are subtypes of their preceding level types and supertypes of their succeeding level types.




  • All the categories of books defined share certain common properties, such as title, author, ISBN#, publisher, and so on. The type of the book, whether Literature, Fiction, Novel, or Mystery, is immaterial while describing these common properties. Also, each type can have properties specific only to that type. For example, a Novel type can have a property called can_be_filmed that's not common to the Poetry type.




  • The common properties and behavior of a supertype that a subtype inherits are defined only once in the supertype and are available to all its subtypes in the hierarchy.




PL/SQL 9i supports single inheritance, where a subtype can inherit attributes and methods from only one direct supertype. However, a subtype can inherit from another subtype that in turn inherits from a supertype and so on, indirectly making it inherit from multiple supertypes. The following features are significant to the implementation of supertypes and subtypes in SQL and PL/SQL in Oracle9i:




  • A "root" type that acts as the primary supertype and forms the basis for all subtypes




  • The UNDER clause of the CREATE OR REPLACE TYPE statement for all subtypes




  • The INSTANTIABLE, NOT INSTANTIABLE, and FINAL, NOT FINAL clauses of the CREATE OR REPLACE statement for the object type




  • The INSTANTIABLE, NOT INSTANTIABLE; FINAL, NOT FINAL; and OVERRIDING clauses in the member method specification of the CREATE OR REPLACE TYPE statement




Here's an example of defining a supertype and one of its subtypes using the Book hierarchy outlined previously:



CREATE OR REPLACE TYPE book_type AS OBJECT
( title VARHCHAR2(50),
author VARCHAR2(30),
ISBN NUMBER,
publisher VARCHAR2(50),
prize_awarded VARCHAR2(1)
)
INSTANTIABLE
NOT FINAL;
/
CREATE OR REPLACE TYPE literature_type UNDER book_type
( category VARCHAR2(20),
award_name VARCHAR2(20)
)
INSTANTIABLE
NOT FINAL;
/

The following points are worth noting:




  • The book_type object type serves as the root in the object type hierarchy and has five attributes: title, author, ISBN, publisher, and prize_awarded.




  • The book_type is defined as INSTANTIABLE and NOT FINAL. INSTANTIABLE specifies that object instances of this type can be defined. In other words, variables of this object type can be declared in PL/SQL. NOT FINAL specifies that subtypes can be defined with this type as the parent. If, on the other hand, FINAL is specified, this type can't be a supertype.




  • The literature_type is a subtype of book_type. The UNDER clause is used to specify this. It has two attributes, category and award_name, and is INSTANTIABLE and NOT FINAL.








Caution�

Never specify the combination NOT INSTANTIABLE and FINAL when you define an object type. Doing so would mean it's not a base for a subtype and object instances can't be defined based on it, which means it can't be used in any way.





Constructing a Type Hierarchy in PL/SQL



As mentioned previously, object types enable you to build a type hierarchy by means of supertypes and subtypes. You can implement the hierarchy depicted in Figure 10-2 in PL/SQL using inheritance concepts. This section focuses on the method to do this. Here are the steps involved:




  1. Create a root type with the NOT FINAL clause.




  2. Create subtypes starting from the root type and proceeding to the successive level, providing specification of each subtype at each node in the hierarchy. For each such subtype, decide whether it should be INSTANTIABLE or NOT, and whether it should be FINAL or NOT. Specifying FINAL leaves the object type as a leaf node in the hierarchy.




  3. Within each object type, define member methods. For each method, decide whether it should be INSTANTIABLE or NOT, meaning it can be overridden in a subtype or is an abstract method in a supertype, which means it specifies only the method signature and the actual implementation is done in each subtype inherited from it. A method is defined with the OVERRIDING clause in two cases: to provide an implementation of a NOT INSTANTIABLE method in the supertype or to override a generic method defined in a supertype. Also, decide whether any method is FINAL or NOT, meaning it can't be overridden in a subtype.




  4. Implement the type body for each type in the hierarchy that isn't declared as FINAL.




  5. Decide whether to overload, override, or inherit or create new methods at each node of the hierarchy.




  6. Finally, write code that performs specific functions using the types and their methods.




Keeping in mind these steps, here's the code that constructs the Book hierarchy depicted in Figure 10-2. First, I create type specifications:




CREATE OR REPLACE TYPE book_type AS OBJECT
( title VARCHAR2(50),
author VARCHAR2(30),
ISBN NUMBER,
publisher VARCHAR2(50),
prize_awarded VARCHAR2(1),
NOT INSTANTIABLE MEMBER PROCEDURE display_info
)
NOT INSTANTIABLE
NOT FINAL;
/
CREATE OR REPLACE TYPE literature_type UNDER book_type
( category VARCHAR2(20),
award_name VARCHAR2(20),
OVERRIDING MEMBER PROCEDURE display_info
)
INSTANTIABLE
NOT FINAL;
/
CREATE OR REPLACE TYPE fiction_type UNDER literature_type
( based_upon VARCHAR2(20),
OVERRIDING MEMBER PROCEDURE display_info
)
INSTANTIABLE
NOT FINAL;
/
CREATE OR REPLACE TYPE novel_type UNDER fiction_type
( can_be_filmed VARCHAR2(1),
OVERRIDING MEMBER PROCEDURE display_info
)
INSTANTIABLE
NOT FINAL;
/

CREATE OR REPLACE TYPE mystery_type UNDER novel_type
( type_of_mystery VARCHAR2(20),
OVERRIDING MEMBER PROCEDURE display_info
)
INSTANTIABLE
FINAL;
/


The following points are worth noting:




  • A five-level hierarchy of types is defined by this code. The root type is book_type and is NOT INSTANTIABLE. It's also NOT FINAL, meaning sub-types can be defined based on the book_type.




  • The remaining four types, literature_type, fiction_type, novel_type, and mystery_type, are subtypes of the type in the level preceding them and supertypes for the types in the level succeeding each of them.




  • The root type defines a NON INSTANTIABLE method named display_info. This declaration acts as a template for the method and its implementation is to be provided in each of its subtypes. Each subtype must define its own version of this procedure.




Next, I define the type bodies with corresponding member methods. Here's the code:




CREATE OR REPLACE TYPE BODY literature_type
IS
OVERRIDING MEMBER PROCEDURE display_info
IS
BEGIN
DBMS_OUTPUT.PUT_LINE(rpad('Category',20)||' '||rpad('Books',60));
DBMS_OUTPUT.PUT_LINE(rpad('-',20,'-')||' '||rpad('-',60,'-'));
DBMS_OUTPUT.PUT_LINE(rpad(SELF.category,20)||' '||SELF.title||' by '||
SELF.author);
END;
END;
/
CREATE OR REPLACE TYPE BODY fiction_type
IS
OVERRIDING MEMBER PROCEDURE display_info
IS
BEGIN
DBMS_OUTPUT.PUT_LINE(rpad('Category',20)||' '||rpad('Books',60));
DBMS_OUTPUT.PUT_LINE(rpad('-',20,'-')||' '||rpad('-',60,'-'));
DBMS_OUTPUT.PUT_LINE(rpad(SELF.category,20)||' '||SELF.title||' by '||
SELF.author);
DBMS_OUTPUT.PUT_LINE('This title is based upon '||SELF.based_upon);
END;
END;
/
CREATE OR REPLACE TYPE BODY novel_type
IS
OVERRIDING MEMBER PROCEDURE display_info
IS
v_can_be_filmed VARCHAR2(20);
BEGIN
SELECT decode(SELF.can_be_filmed, 'Y', 'can be filmed',
'N', 'cannot be filmed')
INTO v_can_be_filmed
FROM dual;
DBMS_OUTPUT.PUT_LINE(rpad('Category',20)||' '||rpad('Books',60));
DBMS_OUTPUT.PUT_LINE(rpad('-',20,'-')||' '||rpad('-',60,'-'));
DBMS_OUTPUT.PUT_LINE(rpad(SELF.category,20)||' '||SELF.title||' by '||
SELF.author);
DBMS_OUTPUT.PUT_LINE('This title is a novel based upon '||SELF.based_upon||
'and'||v_can_be_filmed);
END;
END;
/
CREATE OR REPLACE TYPE BODY mystery_type
IS
OVERRIDING MEMBER PROCEDURE display_info
IS
v_can_be_filmed VARCHAR2(20);
BEGIN
SELECT decode(SELF.can_be_filmed, 'Y', 'can be filmed',
'N', ' cannot be filmed')
INTO v_can_be_filmed
FROM dual;
DBMS_OUTPUT.PUT_LINE(rpad('Category',20)||' '||rpad('Books',60));
DBMS_OUTPUT.PUT_LINE(rpad('-',20,'-')||' '||rpad('-',60,'-'));
DBMS_OUTPUT.PUT_LINE(rpad(SELF.category,20)||' '||SELF.title||' by '||
SELF.author);
DBMS_OUTPUT.PUT_LINE('This title is a novel based upon '||SELF.based_upon||
', '||v_can_be_filmed||
'and is a mystery of'||SELF.type_of_mystery||' type');
END;
END;
/



The following points are worth noting:




  • The type body of each subtype overrides the noninstantiable member method display_info in the root type.




  • The display_info procedure displays the information specific to it and the information derived from all of its supertypes. This is evident from the fact that all the attributes of all supertypes of each subtype can be accessed from that subtype. This is one of the main advantages of inheritance.




  • The display_info procedure in each subtype OVERRIDES the nonimplemented method with the same name in the root supertype.




Now that the methods are in place, I can write code to use the type hierarchy. Basically, this consists of instantiating objects starting from any type declared as INSTANTIABLE, initializing these objects, and invoking the methods on them. In the example type hierarchy, I can start from any subtype (excluding the root book_type). Here are two examples to illustrate this.


First, I start with literature_type. Here's the code:




SQL> declare
2 lit_classic literature_type;
3 begin
4 lit_classic := literature_type('DREAMS UNLIMITED','Bulusu Lakshman',
5 0112224444,'Books International', 'Y',
6 'Fiction','Booker Prize');
7 lit_classic.display_info;
8 end;
9 /
Category Books
--------------------- ------------------------------------
Fiction DREAMS UNLIMITED by Bulusu Lakshman

PL/SQL procedure successfully completed.


Second, I start with the lowest level subtype, mystery_type. Here's the code:




SQL> declare
2 classic_book mystery_type;
3 begin
4 classic_book := mystery_type('DREAMS UNLIMITED','Bulusu Lakshman',
5 0112224444,'Books International', 'Y',
6 'Fiction','Booker Prize','Scientific',
7 'Y','Medical Related');
8 classic_book.display_info;
9 end;
10 /
Category Books
--------------------- ------------------------------------
Fiction DREAMS UNLIMITED by Bulusu Lakshman
This title is a novel based upon Scientific, can be filmed and is a mystery of
Medical Related type

PL/SQL procedure successfully completed.












No comments: