Объектно-ориентированное программирование в PL/SQL
Объектные типы
Объектным типом называется определяемый пользователем тип данных, который инкапсулирует структуру данных и подпрограммы .
Переменные, используемые в структуре данных объектного типа, называются атрибутами, или переменными объектного типа. Функции и процедуры, определяющие поведение объекта, называются методами.
При объявлении переменной объектного типа создается объект с атрибутами и методами, определяемым его типом.
Информация об объектном типе сохраняется в базе данных.
К преимуществам применения объектных типов можно отнести следующие их возможности:
- использование объектных типов позволяет перемещать код управления данными из блоков PL/SQL в методы объекта с помощью инкапсуляции данных;
- объектный тип ограничивает доступ к структуре объекта, предоставляя свои методы для работы с данными;
- объектные типы хорошо реализуются классами объектно-ориентированных языков программирования.
Спецификация и тело объектного типа
Объектный тип состоит из двух частей: спецификации и тела.
Спецификация типа доступна в клиентском приложении. Тело типа скрыто, но разработчик существующего в базе данных типа имеет возможность изменять реализацию методов.
Спецификация типа создается оператором CREATE TYPE , который, с некоторыми сокращениями, может иметь следующее формальное описание:
CREATE [OR REPLACE] TYPE [schema .] type_name { { IS | AS } OBJECT } [ { attribute datatype [sqlj_object_type_attr] } ] | { [ {[[[NOT] OVERRIDING] [[NOT] FINAL] [[NOT] INSTANTIABLE]] { { MEMBER | STATIC } { procedure_spec | function_spec } | {{ MAP | ORDER } MEMBER function_spec}}}] .,:} [[NOT] FINAL] [[NOT] INSTANTIABLE];
Определение функции ( function_spec ) указывается как
FUNCTION name (parameter datatype .,:) { RETURN datatype }
Определение процедуры ( procedure_spec ) указывается как
PROCEDURE name (parameter datatype .,:)
Тело типа создается оператором CREATE TYPE BODY , который, с некоторыми сокращениями, может иметь следующее формальное описание:
[CREATE TYPE BODY type_name {IS | AS} { {MAP | ORDER} MEMBER function_body; | MEMBER {procedure_body | function_body};} [MEMBER {procedure_body | function_body};]... END;]
Создание объектного типа выполняется в два этапа: сначала оператором CREATE TYPE создается спецификация типа, а затем оператором CREATE TYPE BODY создается тело типа .
Например:
- Создание объектного типа CREATE TYPE MyT AS OBJECT ( r1 REAL, - Атрибуты типа r2 REAL, MEMBER FUNCTION plus (x MyT) RETURN MyT ); CREATE TYPE BODY MyT AS MEMBER FUNCTION plus (x MyT) RETURN MyT IS BEGIN RETURN MyT (r1 + x.r1, r2 + x.r2); END plus; END; - Применение переменной объектного типа: DECLARE- Создается объект с1 типа MyT с1 MyT; BEGIN - Вызов конструктора с1 := MyT (1,1); END;
На атрибут объектного типа накладываются следующие ограничения:
- типом атрибута может быть любой тип данных Oracle за исключением некоторых типов, включая типы LONG, LONG RAW, NCHAR, NCLOB, NVARCHAR2, ROWID, BOOLEAN, PLS_INTEGER, RECORD, REF CURSOR, %TYPE и %ROWTYPE, а также типы, определенные в пакете PL/SQL;
- при объявлении атрибута его нельзя инициализировать, используя оператор присваивания или ключевое слово DEFAULT ;
- на атрибут не может быть наложено ограничение NOT NULL.
Типом атрибута может быть любой допустимый тип или другой объектный тип, называемый в этом случае вложенным объектным типом.
Объектные типы могут применяться при создании таблиц как типы полей.
Например:
CREATE TYPE typ1 AS OBJECT (a1 NUMBER, MEMBER FUNCTION getf1 RETURN NUMBER); - : - Создание таблицы CREATE TABLE tbl1(col typ1); - : - Вызов метода объектного типа SELECT col.getf1() FROM tbl1;
Спецификация объектного типа должна включать объявление каждого общедоступного метода, реализация которого записывается в теле объектного типа.
Перед названием метода объектного типа при спецификации объектного типа и описании тела этого типа всегда указывается ключевое слово MEMBER.
Для квалификации атрибутов в методах объектного типа можно использовать ключевое слово SELF, рассматриваемое как ссылка на данный объект. Однако синтаксис языка PL/SQL не требует обязательной квалификации атрибута. Параметр SELF может быть указан первым параметром функции и процедуры и явным способом. Если параметр SELF явно не указывается, то для функции предполагается определение параметра с опцией IN (входной параметр), а для процедуры - с опцией IN OUT (входной-выходной параметр).
Объектный тип может иметь перегружаемые методы.
Сравнение значений объектного типа
В отличие от значений скалярных типов для значений объектных типов не существует единого правила их сравнения. В языке PL/SQL определены ключевые слова MAP и ORDER , которые позволяют специфицировать метод, определяющий правила сравнения значений объектного типа. Объектный тип может иметь только один метод, выполняющий сравнение экземпляров данного типа, - MAP-метод или ORDER-метод.
В зависимости от значения объектного типа MAP-метод можно рассматривать как некоторую функцию хеширования.
ORDER-метод - это функция с двумя параметрами (первый из которых является встроенным по умолчанию), возвращающая значение скалярного типа ( DATE, NUMBER, VARCHAR2, CHARACTER или REAL ), получаемое при сравнении первого параметра, всегда равного SELF, со вторым параметром, указывающим объект этого же типа.
В SQL-операторах всегда можно сравнивать два значения объектного типа на эквивалентность - полное совпадение значений всех атрибутов, но выполнять сравнение на упорядочивание можно только в том случае, если объектный тип имеет MAP-метод или ORDER-метод.
Конструкторы объектного типа
Oracle по умолчанию для каждого объектного типа создает конструктор, одноименный с названием типа.
Конструктор используется для инициализации и возвращения экземпляра объектного типа. При инициализации объекта вызывается конструктор со списком параметров, которые определяют атрибуты в порядке их объявления.