Votes

Support definition of private attributes and methods in Object Types (details)
 
Dear Bryn,

I love PL/SQL and I am so happy that with Oracle9i we can now build true object type hierarchies with inheritance and dynamic polymorphism.

However...we still can't define private attributes and methods, and this seems like quite a violation of time-honored object-oriented principles.

Could you please add this capability to PL/SQL?

Thanks!

Most object oriented languages, like Java, have both public attributes, and private attributes. In fact, in Java, it is very common to make all attributes private, and expose them only through "getter" and "setter" methods. Oracle has objects created with CREATE TYPE type_name AS OBJECT, but all attributes are public. In fact, the default constructor method uses all of the attributes as parameters. This means that I can't protect attributes by adding validation code that must be executed to set the attribute. I can't have a hidden attribute used for internal processing.


Make CREATE TYPE BODY more like CREATE PACKAGE BODY, by allowing the declaration of attributes as well as methods.


/* This example is from the 10g PL/SQL Users Guide and reference. */
CREATE OR REPLACE TYPE rectangle AS OBJECT
(
  -- The type has 3 attributes.
  length NUMBER,
  width NUMBER,
  area NUMBER,
  -- Define a constructor that has only 2 parameters.
  CONSTRUCTOR FUNCTION rectangle(length NUMBER, width NUMBER)
    RETURN SELF AS RESULT
);

CREATE OR REPLACE TYPE BODY rectangle AS
  CONSTRUCTOR FUNCTION rectangle(length NUMBER, width NUMBER)
    RETURN SELF AS RESULT
AS
BEGIN
  SELF.length := length;
  SELF.width := width;
  -- We compute the area rather than accepting it as a parameter.
  SELF.area := length * width;
  RETURN;
END;
END;

/* Now to demonstrate what is wrong with this. */
DECLARE
  r rectangle;
BEGIN
  r := rectangle(10,5);
  DBMS_OUTPUT.PUT_LINE('Area of R:'||TO_CHAR(r.area));
  -- Look, I can change area to be whatever I want
  r.area := 23;
  DBMS_OUTPUT.PUT_LINE('Area of R:'||TO_CHAR(r.area));
END;


CREATE OR REPLACE TYPE rectangle AS OBJECT
(
  -- The type has 2 public attributes.
  length NUMBER,
  width NUMBER,
  -- Define a constructor that has only 2 parameters.
  CONSTRUCTOR FUNCTION rectangle(length NUMBER, width NUMBER)
    RETURN SELF AS RESULT,
  -- Define a getter for the area
  MEMBER FUNCTION get_area RETURN NUMBER
);

CREATE OR REPLACE TYPE BODY rectangle AS
  area NUMBER;
  CONSTRUCTOR FUNCTION rectangle(length NUMBER, width NUMBER)
    RETURN SELF AS RESULT
AS
BEGIN
  SELF.length := length;
  SELF.width := width;
  -- We compute the area rather than accepting it as a parameter.
  SELF.area := length * width;
  RETURN;
END;

MEMBER FUNCTION get_area RETURN NUMBER IS
BEGIN
  RETURN area;
END;
END;



Steven Feuerstein, PL/SQL Evangelist, Quest Software: "Help me help Oracle improve the PL/SQL language!"


Bryn Llewellyn: "We love to hear from PL/SQL developers. Let us know what is important to you!"

PL/SQL Obsession
Apex Evangelists
O'Reilly Books on Oracle
OTN PL/SQL Best Practices
OTN PL/SQL Page
Steven Feuerstein's Blog