Object Types
Object types define how to store data and define API operations, also known as method functions or procedures. Object types are also known as classes in many OO programming languages. Object types mirror that of an PL/SQL package, an object body implements the object type just as a package body implements a package specification. The object type hides the operation details known as encapsulation and also masks the complexity known as abstraction. The current method for visually representing object types is generally done in UML (Unified Modeling Language).
OO programming has two types of API interfaces in object types
Static | static methods allow you to access object type variables and methods without creating an instance of a class, static vaiables in PL/SQL are not available. you can implement static methods like package functions and procedures. |
Instance | Instance methods let you access object variables and methods of an instance of a class, they are only available after you have created an instance of an object type. |
Oracle lets you create object types and bodies as SQL datatypes, you can use these as SQL datatypes in four situtions
Objects can be of two types
Persistant | objects are stored in a database table and have a unique object identifier (standalone) or are embedded in another object (embedded) |
Transient | are not stored in the database and have a limited lifetime to the duration of their use in a PL/SQL block. |
Object Basics
Objects share there namespace with other objects except for triggers, you must grant execute on the object to allow other to use it. Classes cannot have a return type, a class instantiation returns a copy or instance of a class.
Object types have a some specialized functions, however you can only implement one MAP or Order not both
constructor | you can implement one or more but must follow the overriding rules, constructor functions return an instance of the object type, known in PL/SQL as self (not Java's this). |
map | it limits you to testing for equality based on a single number that identifies a class instance. It is more flexible and the order function because it can take parameters of any SQL datatype. |
order | allows to to pass an object instance into another object and compare whether they are equal. |
To implement an object you can follow below
Prototype | create or replace object type <object_name> {[map function <map_name> return {char | date | number| varchar2} | |
Create the object type | -- Object definition CREATE OR REPLACE TYPE hello_there IS OBJECT ( who VARCHAR2(20) , CONSTRUCTOR FUNCTION hello_there RETURN SELF AS RESULT , CONSTRUCTOR FUNCTION hello_there ( who VARCHAR2 ) RETURN SELF AS RESULT , MEMBER FUNCTION get_who RETURN VARCHAR2 , MEMBER PROCEDURE set_who (who VARCHAR2) , MEMBER PROCEDURE to_string ) INSTANTIABLE NOT FINAL; / -- Object Body CREATE OR REPLACE TYPE BODY hello_there IS CONSTRUCTOR FUNCTION hello_there RETURN SELF AS RESULT IS hello HELLO_THERE := hello_there('Generic Object.'); BEGIN self := hello; RETURN; END hello_there; CONSTRUCTOR FUNCTION hello_there (who VARCHAR2) RETURN SELF AS RESULT IS BEGIN self.who := who; RETURN; END hello_there; MEMBER FUNCTION get_who RETURN VARCHAR2 IS BEGIN RETURN self.who; END get_who; MEMBER PROCEDURE set_who (who VARCHAR2) IS BEGIN self.who := who; END set_who; MEMBER PROCEDURE to_string IS BEGIN dbms_output.put_line('Hello '||self.who); END to_string; END; / |
Using the Object | DECLARE hello HELLO_THERE := hello_there; -- you can also use hello_there() BEGIN hello.to_string(); END; / |
Getters and Setters
As in other OO programming languages it is common to use getters and setters methods, that modify or get instance variables.
Example | -- Object definition
CREATE OR REPLACE TYPE hello_there IS OBJECT
( who VARCHAR2(20)
, CONSTRUCTOR FUNCTION hello_there
RETURN SELF AS RESULT
, CONSTRUCTOR FUNCTION hello_there
( who VARCHAR2 )
RETURN SELF AS RESULT
, MEMBER FUNCTION get_who RETURN VARCHAR2
, MEMBER PROCEDURE set_who (who VARCHAR2)
, MEMBER PROCEDURE to_string )
INSTANTIABLE NOT FINAL;
/
-- Object Body
CREATE OR REPLACE TYPE BODY hello_there IS
CONSTRUCTOR FUNCTION hello_there RETURN SELF AS RESULT IS
hello HELLO_THERE := hello_there('Generic Object.');
BEGIN
self := hello;
RETURN;
END hello_there;
CONSTRUCTOR FUNCTION hello_there (who VARCHAR2) RETURN SELF AS RESULT IS
BEGIN
self.who := who;
RETURN;
END hello_there;
MEMBER FUNCTION get_who RETURN VARCHAR2 IS
BEGIN
RETURN self.who;
END get_who;
MEMBER PROCEDURE set_who (who VARCHAR2) IS
BEGIN
self.who := who;
END set_who;
MEMBER PROCEDURE to_string IS
BEGIN
dbms_output.put_line('Hello '||self.who);
END to_string;
END;
/ |
Static Member Methods
Static functions and procedures let you use an object type like a standard package. Static methods can create instances of their object type, but they are limited to working with instances of the object like external PL/SQL blocks.
Example | -- Object type definition |
Comparing Objects Values
In Java you use the equals method to compare objects, normally you override this method. In Oracle you have a master template that you implement through SQL DDL syntax, Oracle provides two predefined member functions - map and order. You can only implement one of these otherwise Oracle will throw an error. Subclasses cannot override either map or order.
MAP example | -- Create the object definition |
ORDER example | -- Create object definition CREATE OR REPLACE TYPE order_comp IS OBJECT ( who VARCHAR2(20), movie VARCHAR2(20), CONSTRUCTOR FUNCTION order_comp (who VARCHAR2,movie VARCHAR2) RETURN SELF AS RESULT, MEMBER FUNCTION to_string RETURN VARCHAR2, ORDER MEMBER FUNCTION equals (object order_comp) RETURN NUMBER ) INSTANTIABLE NOT FINAL; / -- Create the object body CREATE OR REPLACE TYPE BODY order_comp IS CONSTRUCTOR FUNCTION order_comp (who VARCHAR2, movie VARCHAR2) RETURN SELF AS RESULT IS BEGIN self.who := who; self.movie := movie; RETURN; END order_comp; MEMBER FUNCTION to_string RETURN VARCHAR2 IS BEGIN RETURN '['||self.movie||']['||self.who||']'; END to_string; ORDER MEMBER FUNCTION equals (object order_comp) RETURN NUMBER IS BEGIN IF self.movie < object.movie |
Inheritance and Polymorphim
Objects are extensible because you can add to their capabilities by building subclasses, subclasses inherit the behaviors of other classes, which become known as superclasses. Subclasses can also override functions and procedures of the superclass, this whole processes is know as morphing. Polymorphing is the process of multiple subclasses inheriting the behaviors of superclasses. Oracle only support single inheritance but you can overcome this limitation.
Orcale uses the keyword under (same as extends in Java) to subclass a superclass. You must state that you intend to override a method by using the keyword overriding. You cannot override the superclass variables the compiler will complain.
-- Create the object definition (superclass object) CREATE OR REPLACE TYPE order_comp IS OBJECT ( who VARCHAR2(20), movie VARCHAR2(20), CONSTRUCTOR FUNCTION order_comp (who VARCHAR2,movie VARCHAR2) RETURN SELF AS RESULT, MEMBER FUNCTION to_string RETURN VARCHAR2, ORDER MEMBER FUNCTION equals (object order_comp) RETURN NUMBER |