
- •Введение
- •1. Достоинства и недостатки реляционной и объектной моделей Задачи, недоступные для реляционного подхода
- •Задачи, недоступные для объектного подхода
- •Задачи, недоступные обеим моделям
- •2. Реализация объектного подхода в oracle
- •2.1. Хранение объектов в столбцах реляционных таблиц
- •2.2. Создание таблицы объектов
- •2.3. Ссылки на объект
- •2.4. Методы объектов
- •2.5. Конструкторы
- •2.6. Статические методы
- •2.7. Методы сравнения
- •2.8. Объектные представления
- •3. Реализация механизма наследования объектов в oracle
- •3.1. Особенности наследования объектов в oracle
- •3.2. Абстрактные объекты
- •4. Реализация полиморфизма в субд oracle
- •4.1. Полиморфизм типов
- •4.2. Расширение и сужение объектных типов
- •4.3. Оператор is of
- •4.4. Виртуальные методы
2.4. Методы объектов
Выше было рассмотрено определение типа, содержащее описание атрибутов («свойств»). Создадим тип сотрудников, в котором определен еще и метод:
CREATE OR REPLACE TYPE manager_typ AS OBJECT (
Man_Id NUMBER,
D_Id NUMBER,
Name VARCHAR2(30),
Hire_Day DATE,
Procent NUMBER(4,2),
Comments VARCHAR2(30),
Parent_Id NUMBER,
MEMBER FUNCTION DaysAtCompany RETURN NUMBER
);
/
Для описания тела метода-функции необходимо создать тело типа (аналогия пакет – тело пакета в PL/SQL):
CREATE OR REPLACE TYPE BODY manager_typ IS
MEMBER FUNCTION DaysAtCompany RETURN NUMBER IS
BEGIN
RETURN TRUNC(sysdate-Hire_Day);
END;
END;
/
-- создадим таблицу объектов-сотрудников:
CREATE TABLE Managers_ob OF manager_typ;
-- добавим строку в новую таблицу
INSERT INTO Managers_ob VALUES
(Managers_seq.NEXTVAL, 1, 'Соколов Николай', SYSDATE-5, 10, null, null);
-- пример обращения к методу:
SELECT m.*, m.DaysAtCompany() FROM Managers_ob m;
-- пример использования свойств и методов объекта внутри блока PL/SQL:
create or replace procedure ShowManagerInfo(m_id NUMBER) as
m manager_typ;
begin
-- выбираем объект из таблицы и помещаем его в локальный объект
select Value(m_ob) into m
from managers_ob m_ob where m_ob.man_id=m_id;
-- выводим свойства объекта
dbms_output.put_line('№: '||m.man_id);
dbms_output.put_line('Имя: '||m.name);
-- вызываем метод объекта
dbms_output.put_line('Стаж: '||m.DaysAtCompany());
exception
when NO_DATA_FOUND then
dbms_output.put_line('менеджера с таким номером нет');
end;
/
2.5. Конструкторы
Каждый создаваемый объект автоматически имеет конструктор по умолчанию. Об этом заботится сама СУБД. Но программист может сам создать альтернативный конструктор, использую параметр CONSTRUCTOR в объявлении метода объекта.
Для того чтобы метод являлся конструктором, он должен удовлетворять ряду ограничений:
название метода должно совпадать с названием объекта;
метод должен являться функцией, возвращающей тип SELF в качестве результата;
количество и типы формальных параметров функции не должны полностью совпадать с количеством и типом свойств объекта.
create or replace type some_typ IS OBJECT(
name varchar2(30),
CONSTRUCTOR FUNCTION some_typ RETURN SELF AS RESULT,
CONSTRUCTOR FUNCTION some_typ(N NUMBER) RETURN SELF AS RESULT
);
/
create or replace type body some_typ IS
CONSTRUCTOR FUNCTION some_typ RETURN SELF AS RESULT IS
BEGIN
Name:='Unknown';
RETURN;
END;
CONSTRUCTOR FUNCTION some_typ(N NUMBER) RETURN SELF AS RESULT IS
BEGIN
Name:=TO_CHAR(N);
RETURN;
END;
END;
/
declare
s1 some_typ;
s2 some_typ;
s3 some_typ;
begin
-- вызов конструктора по умолчанию
s1:=some_typ('Pete');
dbms_output.put_line(s1.Name);
-- вызов первого конструктора без параметров
s2:=some_typ();
dbms_output.put_line(s2.Name);
-- вызов второго конструктора с одним параметром
s3:=some_typ(10);
dbms_output.put_line(s3.Name);
end;
/
2.6. Статические методы
Методы класса являются статическими в том случае, если в их объявлении был указан параметр STATIC. Такие методы, по аналогии со статическими методами в других объектно-ориентированных языках программирования, могут вызываться без создания экземпляра объекта.
CREATE OR REPLACE TYPE datetime IS OBJECT(
CurDateTime DATE,
STATIC PROCEDURE PrintDateTime
);
/
CREATE OR REPLACE TYPE BODY datetime IS
STATIC PROCEDURE PrintDateTime AS
BEGIN
Dbms_output.put_line(sysdate); END;
END;
/
set serveroutput on
begin
datetime.PrintDateTime;
end;
/
Примечание: нельзя создать объект, состоящий только из статических методов. Чаще всего, при необходимости объединения внутри одного объекта нескольких статических методов, используют пакеты.