PL/SQL - Объектно-ориентированное программирование

Здравствуйте,野心勃勃的程序设计者们!Сегодня мы отправимся в увлекательное путешествие в мир объектно-ориентированного программирования (OOP) в PL/SQL. Не волнуйтесь, если вы новички в программировании – я буду вашим доброжелательным проводником, explaining everything step by step. Так что, погружаемся с головой!

PL/SQL - Object Oriented

Что такое объектно-ориентированное программирование?

Прежде чем мы начнем, давайте поймем, что такое OOP. Представьте, что вы строите дом из кирпичиков Lego. Каждый кирпичик представляет собой объект, и вы можете combine эти кирпичики по-разному, чтобы создавать более сложные структуры. Именно это делает OOP в программировании – он позволяет нам создавать и манипулировать объектами, представляющими реальные мироустройства.

Создание объекта

Теперь давайте узнаем, как создать (или "инстанцировать") объект в PL/SQL. Представьте это как оживление Lego-персонажа в вашем программном мире!

CREATE OR REPLACE TYPE person AS OBJECT (
name VARCHAR2(50),
age NUMBER,
MEMBER FUNCTION say_hello RETURN VARCHAR2
);

CREATE OR REPLACE TYPE BODY person AS
MEMBER FUNCTION say_hello RETURN VARCHAR2 IS
BEGIN
RETURN 'Hello, my name is ' || name || ' and I am ' || age || ' years old.';
END;
END;

DECLARE
john person;
BEGIN
john := person('John Doe', 30);
DBMS_OUTPUT.PUT_LINE(john.say_hello());
END;

В этом примере мы создали тип объекта person с двумя атрибутами (name и age) и методом (say_hello). Затем мы инстанцировали объект john и вызвали его метод say_hello.

Методы-члены

Методы-члены – это как особые способности, которыми обладают наши объекты. Давайте добавим другой метод к нашему объекту person:

CREATE OR REPLACE TYPE person AS OBJECT (
name VARCHAR2(50),
age NUMBER,
MEMBER FUNCTION say_hello RETURN VARCHAR2,
MEMBER PROCEDURE have_birthday
);

CREATE OR REPLACE TYPE BODY person AS
MEMBER FUNCTION say_hello RETURN VARCHAR2 IS
BEGIN
RETURN 'Hello, my name is ' || name || ' and I am ' || age || ' years old.';
END;

MEMBER PROCEDURE have_birthday IS
BEGIN
age := age + 1;
DBMS_OUTPUT.PUT_LINE(name || ' is now ' || age || ' years old.');
END;
END;

DECLARE
john person;
BEGIN
john := person('John Doe', 30);
john.have_birthday();
DBMS_OUTPUT.PUT_LINE(john.say_hello());
END;

Здесь мы добавили процедуру have_birthday, которая увеличивает возраст человека на 1. Это как дать нашему Lego-персонажу способность庆祝ать дни рождения!

Использование метода MAP

Метод MAP используется для сравнения объектов. Это как дать нашим объектам особый идентификационный жетон, который помогает нам сортировать их. Давайте посмотрим, как это работает:

CREATE OR REPLACE TYPE person AS OBJECT (
name VARCHAR2(50),
age NUMBER,
MAP MEMBER FUNCTION get_id RETURN NUMBER
);

CREATE OR REPLACE TYPE BODY person AS
MAP MEMBER FUNCTION get_id RETURN NUMBER IS
BEGIN
RETURN age;
END;
END;

DECLARE
john person := person('John Doe', 30);
jane person := person('Jane Smith', 25);
BEGIN
IF john > jane THEN
DBMS_OUTPUT.PUT_LINE(john.name || ' is older');
ELSE
DBMS_OUTPUT.PUT_LINE(jane.name || ' is older');
END IF;
END;

В этом примере мы используем age в качестве идентификатора для сравнения. Это как сравнивать Lego-персонажей по их росту!

Использование метода ORDER

Метод ORDER – это другой способ сравнения объектов, но он дает нам больше гибкости, чем метод MAP. Это как иметь особого судью для сравнения наших Lego-персонажей:

CREATE OR REPLACE TYPE person AS OBJECT (
name VARCHAR2(50),
age NUMBER,
ORDER MEMBER FUNCTION compare(p person) RETURN INTEGER
);

CREATE OR REPLACE TYPE BODY person AS
ORDER MEMBER FUNCTION compare(p person) RETURN INTEGER IS
BEGIN
IF self.age < p.age THEN
RETURN -1;
ELSIF self.age > p.age THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
END;

DECLARE
john person := person('John Doe', 30);
jane person := person('Jane Smith', 30);
BEGIN
IF john > jane THEN
DBMS_OUTPUT.PUT_LINE(john.name || ' is older');
ELSIF john < jane THEN
DBMS_OUTPUT.PUT_LINE(jane.name || ' is older');
ELSE
DBMS_OUTPUT.PUT_LINE('They are the same age');
END IF;
END;

Этот метод позволяет нам определять пользовательскую логику сравнения. Он особенно полезен, когда мы хотим сравнивать объекты на основе нескольких атрибутов.

Наследование для объектов PL/SQL

Наследование – это как создание генеалогического древа для наших объектов. Мы можем создавать новые типы объектов, наследующие свойства и методы существующих. Давайте посмотрим, как это делается:

CREATE OR REPLACE TYPE employee UNDER person (
job_title VARCHAR2(50),
salary NUMBER,
MEMBER FUNCTION get_annual_salary RETURN NUMBER
);

CREATE OR REPLACE TYPE BODY employee AS
MEMBER FUNCTION get_annual_salary RETURN NUMBER IS
BEGIN
RETURN salary * 12;
END;
END;

DECLARE
emp employee := employee('Alice Johnson', 35, 'Manager', 5000);
BEGIN
DBMS_OUTPUT.PUT_LINE(emp.say_hello());
DBMS_OUTPUT.PUT_LINE('Annual salary: $' || emp.get_annual_salary());
END;

Здесь employee является потомком person, наследуя его атрибуты и методы, добавляя при этом свои. Это как создание особого типа Lego-персонажа, который может делать все, что может обычный персонаж, plus больше!

Абстрактные объекты в PL/SQL

Абстрактные объекты – это как чертежи для других объектов. Они определяют структуру, но не могут быть инстанцированы напрямую. Давайте создадим абстрактный объект:

CREATE OR REPLACE TYPE shape AS OBJECT (
name VARCHAR2(50),
MEMBER FUNCTION get_area RETURN NUMBER
) NOT INSTANTIABLE NOT FINAL;

CREATE OR REPLACE TYPE circle UNDER shape (
radius NUMBER,
OVERRIDING MEMBER FUNCTION get_area RETURN NUMBER
);

CREATE OR REPLACE TYPE BODY circle AS
OVERRIDING MEMBER FUNCTION get_area RETURN NUMBER IS
BEGIN
RETURN 3.14159 * radius * radius;
END;
END;

DECLARE
c circle := circle('My Circle', 5);
BEGIN
DBMS_OUTPUT.PUT_LINE('Area of ' || c.name || ': ' || c.get_area());
END;

В этом примере shape является абстрактным объектом, который определяет общую структуру для всех форм. circle – это конкретная реализация shape. Это как иметь общее руководство по Lego (абстрактный объект) и затем создавать конкретные модели Lego на его основе!

Вот и все! Мы рассмотрели основы объектно-ориентированного программирования в PL/SQL. Помните, что практика делает perfect, так что не бойтесь экспериментировать с этими концепциями. Счастливого кодирования!

Метод Описание
Конструктор Создает и инициализирует объект
Метод-член Возвращает значение и может использоваться в SQL-выражениях
Процедура-член Выполняет действие, но не возвращает значение
Метод MAP Используется для сравнения объектов, основываясь на одном значении
Метод ORDER Используется для сравнения объектов, позволяет определять пользовательскую логику сравнения
Метод FINAL Не может быть перегружен в подтипе
Метод NOT INSTANTIABLE Должен быть перегружен в подтипе перед инстанцированием объектов

Credits: Image by storyset