O'Reilly Databases

oreilly.comSafari Books Online.Conferences.

We've expanded our coverage and improved our search! Search for all things Database across O'Reilly!

Search Search Tips

advertisement
AddThis Social Bookmark Button

Listen Print Subscribe to Databases Subscribe to Newsletters

Inherit the Database: Oracle9i's Support for Object Type Inheritance
Pages: 1, 2, 3, 4, 5

Options for Method Definition



You can define or make available methods in object types in the following ways:

  • Inherit a method: If the method is defined in any supertype in the hierarchy, that method is automatically available for use with the current type. You don't need to write any additional code in the object-type definition.

  • Create a new method: You can always create an entirely new method in an object type, one that doesn't appear in any supertype. You can, by the way, create STATIC methods that are associated with the object type and not with any object instantiated from the object type.

  • Overload a supertype method: You can create a method that has the same name as a method in a supertype, but has either a distinct parameter list or a different method type (function vs. procedure, for example). This constitutes an overloading (or static polymorphism) of the supertype method in the subtype.

  • Override a supertype method: You can also replace or substitute a supertype method in your subtype by specifying OVERRIDING MEMBER in the header definition.

Overloading has, of course, been available for years in PL/SQL. You can overload multiple programs with the same name in packages (the most common location for overloading) and any declaration section in a block.

The interesting aspect of overloading in object types is that you might be overloading a method from a supertype. In this case, you can't actually tell by looking at the subtype definition that what you've done is an overloading. It's the only program with that name present. You have to be able to examine the entire hierarchy to discover the overloading. Consider the object type for corporation shown in Listing 3.

Listing 3. Object type for corporation.

CREATE OR REPLACE TYPE corporation_ot 
   UNDER person_ot (

   CEOcompensation NUMBER,
   layoffs NUMBER,
   
   MEMBER procedure maximizeProfits,
   
   -- Show a corporation
   OVERRIDING MEMBER procedure show ,
   
   -- override of generic method.
   OVERRIDING MEMBER procedure  showPunishment,
   
   -- implementation of non-instantiable method
   OVERRIDING MEMBER procedure showPoliticalPower,
      
   MEMBER FUNCTION age (merger_date_in IN DATE) 
      RETURN INTERVAL YEAR TO MONTH 
   )
   INSTANTIABLE 
   NOT FINAL;
/

I've added an overloading of the age function (the person_ot contains the "original" age program). For corporations, I allow you to specify a merger date. If NOT NULL, then the computation of the age of the corporation changes from the default person age function. Here's a comparison of the two implementations, first the person age function:

MEMBER FUNCTION age 
   RETURN INTERVAL YEAR TO MONTH
IS
   retval INTERVAL YEAR TO MONTH;
BEGIN
   RETURN (SYSDATE - SELF.dob)
     YEAR TO MONTH;
END;

and now the corporation's age function:

MEMBER FUNCTION age (
   merger_date_in IN DATE) 
   RETURN INTERVAL YEAR TO MONTH
IS
   retval INTERVAL YEAR TO MONTH;
BEGIN
   IF merger_date_in > SELF.dob
   THEN
      RETURN (SYSDATE - merger_date_in) 
         YEAR TO MONTH;
   ELSE
      RETURN (SYSDATE - SELF.dob)
         YEAR TO MONTH;
   END IF;
END;

In other words, if a merger date is provided, use that to calculate the age of the corporation. Otherwise, rely on the "date of birth" of the corporation, obtained from the person-defined attribute. I do not include the OVERRRIDING keyword in my definition of this function since it isn't overriding the person.age function. Instead, corporation.age offers a second, overloaded implementation.

Remember that in my hierarchy, person is a supertype of corporation. I've defined a method in person to return the age of a person.

Interestingly, I can invoke either one of the age functions against a corporation object as shown here:

DECLARE
   oracle corporation_ot := 
      corporation_ot (
         'Artificial', -- species
         'Oracle Corporation',
         NULL,
         '01-JAN-1979',
         NULL,
         NULL
      );  
BEGIN
   IF -- person.age
      oracle.age 
      >
      -- corporation.age
      oracle.age (SYSDATE)
   THEN
      DBMS_OUTPUT.PUT_LINE (
         'Impossible!');
   END IF;
END;

A Closer Look at Method Overriding

When you override an inherited method, you define a method in a subtype of the same name and have that method do something different from the supertype's version.

The compensation calculation for a manager will be different, for example, from that of other employees, so a specialized program will be needed in that object-type definition.

When a subtype overrides a method, then instances of the subtype will invoke that method rather than the overridden one. If the subtype itself has subtypes, those more specific types inherit the override of the method instead of the version of the supertype.

You'll only successfully override a method if your subtype's OVERRIDING member definition contains precisely the same signature (name, parameter list, RETURN clause if a function) as the supertype method. If the signature is different, then you've defined an overloading rather than an overriding method.

Keep the following restrictions in mind when you're figuring out when and how to overload methods:

  • You can override only methods that aren't declared to be final in the supertype.

  • Order methods (methods used to provide a sense of order or sequence to objects instantiated from the type) may be defined only in the root type of a type hierarchy. You can't override these methods.

  • You can't define an overridden method as a static method (one that's associated with the type itself and not with an object instantiated from the type).

  • A member method in a subtype isn't permitted to override a static method in the supertype.

  • If a method being overridden contains default values for parameters, then the overriding method must provide the same default values for the same parameters. The header of the programs must be entirely identical.

Polymorphism and Dynamic Method Dispatch

Polymorphism is the name given to a language's ability to choose from multiple methods of the same name and execute the appropriate method. There are two kinds of polymorphism:

  1. Static polymorphism: The decision about which method to execute is made at the time the code is compiled. In PL/SQL, static polymorphism is also known as overloading.

  2. Dynamic polymorphism: The decision about which method to execute is made at the time the code is executed, at runtime. This is also known as dynamic method dispatch and is available for the first time in PL/SQL with support for object-type inheritance.

Both types of polymorphism are very powerful features. Static polymorphism or overloading makes it easy for us to create simple, intuitive APIs or application programmatic interfaces for developers to use. Rather than having to remember 10 different names for "define a dynamic SQL column," for example, I can simply call the DBMS_SQL.DEFINE_COLUMN procedure; the PL/SQL compiler automatically figures out which program I need to run based on the parameter list.

Dynamic polymorphism is dramatically more useful and intriguing because it gives us so much more flexibility in the way we manipulate our objects. Suppose my PL/SQL block invokes a method on a type. The execution engine then uses the type of the object instance that invokes it to determine which implementation of the method to use. There can be multiple implementations due to either overloading or overriding. The call is then dispatched to that type's implementation for execution. This process of selecting a method implementation is called dynamic method dispatch since it's done at runtime, not at compile time.

PL/SQL dispatches a method call to the "nearest" implementation, working up the inheritance hierarchy from the current or specified type to its supertypes, if any.

Pages: 1, 2, 3, 4, 5

Next Pagearrow




Tagged Articles

Be the first to post this article to del.icio.us

Sponsored Resources

  • Inside Lightroom

Related to this Article

Understanding Oracle Clinical Understanding Oracle Clinical
by Joan M. Johnson
June 2009
$9.99 USD

New Features in Oracle 9i New Features in Oracle 9i
by Howard J. Rogers
June 2009
$5.95 USD

Advertisement
O'Reilly Media

©2009, O'Reilly Media, Inc.
(707) 827-7000 / (800) 998-9938
All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.
About O'Reilly
Academic Solutions
Authors
Contacts
Customer Service
Jobs
Newsletters
O'Reilly Labs
Press Room
Privacy Policy
RSS Feeds
Terms of Service
User Groups
Writing for O'Reilly
Content Archive
Business Technology
Computer Technology
Google
Microsoft
Mobile
Network
Operating System
Digital Photography
Programming
Software
Web
Web Design
More O'Reilly Sites
O'Reilly Radar
Ignite
Tools of Change for Publishing
Digital Media
Inside iPhone
makezine.com
craftzine.com
hackszine.com
perl.com
xml.com

Partner Sites
InsideRIA
java.net
O'Reilly Insights on Forbes.com