我想调用一个重写的PL / sql方法.这是一个例子:
-- super class create or replace type test as object ( n number,member procedure proc(SELF in out nocopy test,s varchar2) ) alter type test not final / create or replace type body test is member procedure proc(SELF in out nocopy test,s varchar2) is begin dbms_output.put_line('test1: n='||nvl(self.n,'null')||' s='||s); self.n := to_number(s); end; end; / -- derived class create or replace type test2 under test ( overriding member procedure proc(SELF in out nocopy test2,s varchar2) ) /
现在我想调用proc方法的继承版本.当我尝试做一个像treat一样的显式转换(self as test).proc(s);由于PLS-00363,它不会编译:表达式’SYS_TREAT’不能用作赋值目标
当我使用局部变量时,类型体编译:
create or replace type body test2 is overriding member procedure proc(SELF in out nocopy test2,s varchar2) is O test; begin O := treat(self as test); O.proc(s); end; end; /
但是,当我像这样运行我的例子
declare obj test2; begin obj := test2(0); obj.proc('1'); end;
…它抛出ORA-21780:超过了最大对象持续时间.
有没有办法调用test :: proc(没有序列化/反序列化)?
并且…在调用proc之后,如何将任何已更改的属性(即n)反映在obj中?
更新(谢谢,tbone):
我使用模板方法(‘之前’和’之后’)改变了方法的组织.每当我需要扩展方法时,我都会添加它们.
create or replace type test as object ( n number,member procedure proc (SELF in out nocopy test,s varchar2),member procedure afterProc (SELF in out nocopy test,s varchar2) member procedure beforeProc(SELF in out nocopy test,) not final / create or replace type body test is member procedure proc(SELF in out nocopy test,s varchar2) is begin beforeProc(s); dbms_output.put_line('test1: n='||nvl(n,'null')||' s='||s); n := to_number(s); afterProc(s); end; member procedure afterProc (SELF in out nocopy test,s varchar2) is begin null; end; member procedure beforeProc(SELF in out nocopy test,s varchar2) is begin null; end; end; /
要访问超级方法,请尝试常规调用或通用表达式.例如,使用人超类型和学生子类型:
CREATE OR REPLACE TYPE person_typ AS OBJECT ( idno number,name varchar2(30),phone varchar2(20),MAP MEMBER FUNCTION get_idno RETURN NUMBER,MEMBER FUNCTION show RETURN VARCHAR2) NOT FINAL; CREATE OR REPLACE TYPE BODY person_typ AS MAP MEMBER FUNCTION get_idno RETURN NUMBER IS BEGIN RETURN idno; END; MEMBER FUNCTION show RETURN VARCHAR2 IS BEGIN -- function that can be overriden by subtypes MEMBER FUNCTION show RETURN VARCHAR2 IS BEGIN RETURN 'Id: ' || TO_CHAR(idno) || ',Name: ' || name; END; END; CREATE TYPE student_typ UNDER person_typ ( dept_id NUMBER,major VARCHAR2(30),OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2) NOT FINAL; CREATE TYPE BODY student_typ AS OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2 IS BEGIN RETURN (self AS person_typ).show || ' -- Major: ' || major ; END; END; -- Using Generalized Invocation DECLARE myvar student_typ := student_typ(100,'Sam','6505556666',100,'Math'); name VARCHAR2(100); BEGIN name := (myvar AS person_typ).show; --Generalized invocation END; -- Using Generalized Expression DECLARE myvar2 student_typ := student_typ(101,'Math'); name2 VARCHAR2(100); BEGIN name2 := person_typ.show((myvar2 AS person_typ)); -- Generalized expression END;
编辑:
如果你是10g,你需要组织一些不同的功能,但是从孩子那里调用super方法的功能相同:
CREATE TYPE BODY person_typ AS MAP MEMBER FUNCTION get_idno RETURN NUMBER IS BEGIN RETURN idno; END; -- static function that can be called by subtypes STATIC FUNCTION show_super (person_obj in person_typ) RETURN VARCHAR2 IS BEGIN RETURN 'Id: ' || TO_CHAR(person_obj.idno) || ',Name: ' || person_obj.name; END; -- function that can be overriden by subtypes MEMBER FUNCTION show RETURN VARCHAR2 IS BEGIN RETURN person_typ.show_super ( SELF ); END; END; CREATE TYPE student_typ UNDER person_typ ( dept_id NUMBER,OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2) NOT FINAL; CREATE TYPE BODY student_typ AS OVERRIDING MEMBER FUNCTION show RETURN VARCHAR2 IS BEGIN RETURN person_typ.show_super ( SELF ) || ' -- Major: ' || major ; END; END;
现在,您可以通过student方法调用show_super(),或者只调用student方法的show().
从文档中,希望有所帮助.