Базы данных Oracle - статьи

         

Наследование конструкторов


Очередная трудность связана с тем, что в PL/SQL не поддерживает прямой вызов унаследованного конструктора. (Проще говоря, конструкторы базового типа не наследуются!). Например: пусть у нас есть класс t_ParentType в котором определен пользовательский (user-defined) конструктор:

---------------------------------------------------------------- --спецификация объектного типа t_ParentType: - ---------------------------------------------------------------- create or replace type t_ParentType as object ( v_Field1 varchar2(32), constructor function t_ParentType(v_pName varchar2) return self as result ) not final; ---------------------------------------------------------------- --тело объектного типа t_ParentType: - ---------------------------------------------------------------- create or replace type body t_ParentType as constructor function t_ParentType(v_pName varchar2) return self as result is begin self.v_Field1 := v_pName; return; end; end;

Теперь мы определяем объектный тип t_ChildType, который является наследником t_ParentType. В типе t_ChildType также определен пользовательский конструктор: ---------------------------------------------------------------- --Спецификация объектного типа t_ChildType, - --который является наследником : t_ParentType - ---------------------------------------------------------------- create or replace type t_ChildType under t_ParentType ( v_Field2 varchar2(64), constructor function t_ChildType(v_pName varchar2, v_pDescription varchar2) return self as result );

В реализации конструктора типа t_ChildType попытаемся вызвать унаследованный конструктор:

---------------------------------------------------------------- --Тело объектного типа t_ChildType - --в конструкторе необходимо вызвать унаследованный конструктор - ---------------------------------------------------------------- create or replace type body t_ChildType is constructor function t_ChildType(v_pName varchar2, v_pDescription varchar2) return self as result is begin t_ParentType(v_pName => v_pName); self.v_Field2 := v_pDescription; return; end; end;


Выясняется, что сделать это не удается:

liNE/COL ERROR -------- ----------------------------------------------------------------- 6/5 PLS-00306: wrong number or types of arguments in call to 'T_PARENTTYPE'

Итак: как же вызвать конструктор родительского типа, чтобы не дублирвать уже реализованный в нем код ?

Предлагается примерно тот же самый метод, что и в предыдущем разделе: создание экземпляра типа-предка, с последующим присвоением его полей полям текущего экземпляра. Для этого нам понадобится метод присвоения assign:

---------------------------------------------------------------- --Спецификация объектного типа t_ChildType, - --который является наследником : t_ParentType - --добавлен метод присваивания assign - ---------------------------------------------------------------- create or replace type t_ChildType under t_ParentType ( v_Field2 varchar2(64), constructor function t_ChildType(v_pName varchar2, v_pDescription varchar2) return self as result, member procedure assign(self in out nocopy t_ChildType, v_pObject in out nocopy t_ParentType), member function getName return varchar2 ); ---------------------------------------------------------------- --Тело объектного типа t_ChildType - --в конструкторе вызывается конструктор базового типа - ---------------------------------------------------------------- create or replace type body t_ChildType is constructor function t_ChildType(v_pName varchar2, v_pDescription varchar2) return self as result is --экземпляр объекта-предка v_xInheritedObject t_ParentType; begin --вызов конструктора базового типа v_xInheritedObject := new t_ParentType(v_pName => v_pName); -передача данных текущему экземпляру self.assign(v_xInheritedObject); - self.v_Field2 := v_pDescription; return; end; -------------------------------------------------------------- --метод присваивания экземпляра базового типа текущему - --оьъекту (self) - -------------------------------------------------------------- member procedure assign(self in out nocopy t_ChildType, v_pObject in out nocopy t_ParentType) is begin self.v_Field1 := v_pObject.v_Field1; end; member function getName return varchar2 is begin return self.v_Field1 ' - ' self.v_Field2; end; end;

Вышеописанная методика демонстрируется в данном примере.


Содержание раздела