PL/SQL允许定义一个对象类型,该对象类型允许创建复合类型。使用对象可实现具有特定数据结构的真实世界对象以及操作它的方法。对象具有属性和方法,对象的属性用于存储对象的状态,并使用方法来建模其行为。
创建对象
对象是使用CREATE [OR REPLACE] TYPE语句创建的。以下是创建一个由几个属性组成的简单address对象的例子:
CREATE OR REPLACE TYPE address AS OBJECT
(
house_no varchar2(10),
street varchar2(30),
city varchar2(20),
state varchar2(10),
pincode varchar2(10)
);
/
下面再创建另一个对象:customer,将属性和方法包装在一起,以具有面向对象的感觉:
CREATE OR REPLACE TYPE customer AS OBJECT
(
code number(5),
name varchar2(30),
contact_no varchar2(12),
addr address,
member procedure display
);
/
实例化对象
定义对象类型为实例化对象提供模板(或蓝图)。要使用这个对象,需要创建这个对象的实例。
构造函数是返回一个新对象作为其值的函数。每个对象都有一个系统定义的构造方法。构造函数的名称与对象类型相同。可以使用实例名称和访问运算符(.)来访问对象的属性和方法,如下所示:
DECLARE
residence address;
BEGIN
residence := address('1502A', '人民大道', '海口', '海南','201901');
dbms_output.put_line('House No: '|| residence.house_no);
dbms_output.put_line('Street: '|| residence.street);
dbms_output.put_line('City: '|| residence.city);
dbms_output.put_line('Province: '|| residence.state);
dbms_output.put_line('Pincode: '|| residence.pincode);
END;
/
1、成员方法
成员方法用于操作对象的属性。在声明对象类型的同时提供成员方法的声明。 对象体定义了成员方法的代码。对象体是使用CREATE TYPE BODY语句创建的。
2、对象比较
比较方法用于比较对象。 有两种方法来比较对象:
Map方法
Map方法是一个函数,它的值取决于属性的值。 例如:对于customer对象,如果customer对象的code属性的值对于两个customer是相同的,则两个customer可以是相同的。 所以这两个对象之间的关系将取决于code属性的值。
例如:
创建rectangle类型:
CREATE OR REPLACE TYPE rectangle AS OBJECT
(
length number,
width number,
member function enlarge(inc number) return rectangle,
member procedure display,
map member function measure return number
);
/
创建rectangle类型主体:
CREATE OR REPLACE TYPE BODY rectangle AS
MEMBER FUNCTION enlarge(inc number) return rectangle IS
BEGIN
return rectangle(self.length + inc, self.width + inc);
END enlarge;
MEMBER PROCEDURE display IS
BEGIN
dbms_output.put_line('Length: '|| length);
dbms_output.put_line('Width: '|| width);
END display;
MAP MEMBER FUNCTION measure return number IS
BEGIN
return (sqrt(length*length + width*width));
END measure;
END;
/
使用矩形对象及其成员函数:
DECLARE
r1 rectangle;
r2 rectangle;
r3 rectangle;
inc_factor number := 5;
BEGIN
r1 := rectangle(3, 4);
r2 := rectangle(5, 7);
r3 := r1.enlarge(inc_factor);
r3.display;
IF (r1 > r2) THEN -- calling measure function
r1.display;
ELSE
r2.display;
END IF;
END;
/
排序方法
排序方法实现了一些用于比较两个对象的内部逻辑。例如:对于一个矩形对象,如果矩形的两边都较大,则该矩形比另一个矩形大。
例如:
创建rectangle类型:
CREATE OR REPLACE TYPE rectangle AS OBJECT
(
length number,
width number,
member procedure display,
order member function measure(r rectangle) return number
);
/
创建rectangle类型主体:
CREATE OR REPLACE TYPE BODY rectangle AS
MEMBER PROCEDURE display IS
BEGIN
dbms_output.put_line('Length: '|| length);
dbms_output.put_line('Width: '|| width);
END display;
ORDER MEMBER FUNCTION measure(r rectangle) return number IS
BEGIN
IF(sqrt(self.length*self.length + self.width*self.width)>
sqrt(r.length*r.length + r.width*r.width)) THEN
return(1);
ELSE
return(-1);
END IF;
END measure;
END;
/
测试:
DECLARE
r1 rectangle;
r2 rectangle;
BEGIN
r1 := rectangle(23, 44);
r2 := rectangle(15, 17);
r1.display;
r2.display;
IF (r1 > r2) THEN -- calling measure function
r1.display;
ELSE
r2.display;
END IF;
END;
/
继承对象
PL/SQL允许从现有的基础对象创建对象。为了实现继承,基类对象应该声明为NOT FINAL,默认是FINAL。
首先创建Rectangle基础对象,使TableTop对象继承该基础对象,例如:
-- 创建基础类型
CREATE OR REPLACE TYPE rectangle FORCE AS OBJECT
(
length number,
width number,
member function enlarge(inc number) return rectangle,
NOT FINAL member procedure display
) NOT FINAL
/
-- 创建基础类型的主体
CREATE OR REPLACE TYPE BODY rectangle AS
MEMBER FUNCTION enlarge(inc number) return rectangle IS
BEGIN
return rectangle(self.length + inc, self.width + inc);
END enlarge;
MEMBER PROCEDURE display IS
BEGIN
dbms_output.put_line('Length: '|| length);
dbms_output.put_line('Width: '|| width);
END display;
END;
/
-- 创建子对象tabletop,继承基础对象rectangle
CREATE OR REPLACE TYPE tabletop UNDER rectangle
(
material varchar2(20),
OVERRIDING member procedure display
)
/
-- 为子对象tabletop创建类型主体
CREATE OR REPLACE TYPE BODY tabletop AS
OVERRIDING MEMBER PROCEDURE display IS
BEGIN
dbms_output.put_line('Length: '|| length);
dbms_output.put_line('Width: '|| width);
dbms_output.put_line('Material: '|| material);
END display;
END;
/
-- 测试
DECLARE
t1 tabletop;
t2 tabletop;
BEGIN
t1:= tabletop(20, 10, 'Wood');
t2 := tabletop(50, 30, 'Steel');
t1.display;
t2.display;
END;
/
抽象对象
NOT INSTANTIABLE子句用来声明一个抽象对象。不能直接使用抽象对象,必须创建抽象对象的子类型或子类型才能使用它的功能。
CREATE OR REPLACE TYPE rectangle AS OBJECT
(
length number,
width number,
NOT INSTANTIABLE NOT FINAL MEMBER PROCEDURE display
) NOT INSTANTIABLE NOT FINAL
/