根据 Alex 的建议(使用关联数组),我创建了一个封装对象的包,因此我们可以以抽象的方式使用它们,就像它们是引用一样:
create or replace type cla as object -- complex class
(
name varchar2(10)
);
create or replace package eo as -- package to encapsulate objects
type ao_t -- type for hash (associative array)
is table of cla
index by varchar2(100);
o ao_t; -- hash of objects
end;
declare
o1 varchar2(100);
o2 varchar2(100);
begin
o1 := 'o1'; -- objects are hash indexes now
eo.o(o1) := new cla('hi'); -- store new object into the hash
o2 := o1; -- assign object == assign index
eo.o(o1).name := 'bye'; -- change object attribute
dbms_output.put_line('eo.o(o1).name: ' || eo.o(o1).name);
dbms_output.put_line('eo.o(o2).name: ' || eo.o(o2).name); -- equal?
end;
现在“bye”被写入两次,正如对象引用所预期的那样。诀窍是 o1 和 o2 都包含同一对象的相同索引(〜引用)。语法有点复杂,但在访问属性和方法时仍然与标准对象操作非常相似。
将一个对象分配给其他对象与标准对象分配完全相同:
o2 := o1;
与使用对象作为函数参数相同:
afunc(o1);
在内部,afunc() 将仅使用具有相同特殊语法的 o1 来访问方法或属性(并且无需分配特殊语法):
eo.o(o1).attrib := 5;
eo.o(o1).method('nice');
o3 := o1;
使用此技巧的唯一要求是将散列(类型和变量)添加到我们要封装的每个类的 eo 包中。
Update:基于变量名的索引值:
o1 := 'o1';
例如,如果我们在函数中创建对象,则可能会出现问题,因为该函数必须知道程序其余部分中使用的所有值以避免重复值。解决方案是从哈希大小中获取值:
o1 := eo.o.count;
这给我们带来了另一个问题:哈希内容是持久的(因为它位于包中),因此当我们创建对象时,越来越多的对象将被添加到哈希中(即使对象是由相同的函数创建的)。解决方案是在处理完对象后从哈希中删除该对象:
eo.o(o1) = null;
所以固定的程序是:
create or replace type cla as object -- complex class
(
name varchar2(10)
);
create or replace package eo as -- package to encapsulate objects
type ao_t -- type for hash (associative array)
is table of cla
index by varchar2(100);
o ao_t; -- hash of objects
end;
declare
o1 varchar2(100);
o2 varchar2(100);
begin
o1 := eo.o.count; -- index based on hash size
eo.o(o1) := new cla('hi'); -- store new object into the hash
o2 := o1; -- assign object == assign index
eo.o(o1).name := 'bye'; -- change object attribute
dbms_output.put_line('eo.o(o1).name: ' || eo.o(o1).name);
dbms_output.put_line('eo.o(o2).name: ' || eo.o(o2).name); -- equal?
eo.o(o1) = null; -- remove object
eo.o(o2) = null; -- remove object (redundant)
end;