PL/SQL - 객체 지향 프로그래밍

안녕하세요, 야심찬 프로그래머 여러분! 오늘 우리는 PL/SQL에서 객체 지향 프로그래밍(OOP)의 세계에 흥미로운 여정을 떠납니다. 프로그래밍에 처음이라면 걱정 마세요 - 나는 친절한 안내자로서 단계별로 모든 것을 설명해 드릴 것입니다. 그럼 시작해 볼까요!

PL/SQL - Object Oriented

객체 지향 프로그래밍이란?

시작하기 전에 OOP에 대해 이해해 보겠습니다. 레고 블록으로 집을 짓는 것을 상상해 보세요. 각 블록은 객체를 나타내며, 이 블록들을 다양한 방법으로 결합하여 더 복잡한 구조를 만들 수 있습니다. OOP는 프로그래밍에서 이와 같은 작업을 수행합니다 - 실제 세계의 엔티티를 나타내는 객체를 생성하고 조작할 수 있게 해줍니다.

객체 인스턴스화

이제 PL/SQL에서 객체를 생성(또는 "인스턴스화")하는 방법을 배우겠습니다. 이를 레고 캐릭터를 프로그래밍 세계에서 소생시키는 것으로 생각해 보세요!

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 '안녕하세요, 제 이름은 ' || name || '이고 저는 ' || age || '살입니다.';
END;
END;

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

이 예제에서 우리는 person 객체 유형을 생성하였고, 두 속성(nameage)과 메서드(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 '안녕하세요, 제 이름은 ' || name || '이고 저는 ' || age || '살입니다.';
END;

MEMBER PROCEDURE have_birthday IS
BEGIN
age := age + 1;
DBMS_OUTPUT.PUT_LINE(name || '는 이제 ' || age || '살입니다.');
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살 더 늘립니다. 이는 우리의 레고 캐릭터가 생일을 축하할 수 있는 능력을 주는 것과 같습니다!

맵 메서드 사용

맵 메서드는 객체를 비교하는 데 사용됩니다. 이는 우리의 객체에게 특별한 ID 카드를 주는 것처럼 생각할 수 있습니다. 그럼 이 작동 방식을 보겠습니다:

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 || '는 더 나이가 많습니다.');
ELSE
DBMS_OUTPUT.PUT_LINE(jane.name || '는 더 나이가 많습니다.');
END IF;
END;

이 예제에서 우리는 age를 비교의 기준으로 사용합니다. 이는 레고 캐릭터를 그들의 키에 따라 비교하는 것과 같습니다!

주문 메서드 사용

주문 메서드는 객체를 비교하는 또 다른 방법으로, 맵 메서드보다 더 많은 유연성을 제공합니다. 이는 우리의 레고 캐릭터를 비교하는 특별한 심판을 가지는 것과 같습니다:

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 || '는 더 나이가 많습니다.');
ELSIF john < jane THEN
DBMS_OUTPUT.PUT_LINE(jane.name || '는 더 나이가 많습니다.');
ELSE
DBMS_OUTPUT.PUT_LINE('그들은 같은 나이입니다.');
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('연봉: $' || emp.get_annual_salary());
END;

여기서 employeeperson의 자식으로, 그 속성과 메서드를 상속하면서 자신만의 속성과 메서드를 추가합니다. 이는 레고 캐릭터가 일반 캐릭터로서 할 수 있는 모든 것을 할 수 있고, 더 많은 것을 추가할 수 있는 것과 같습니다!

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('면적: ' || c.name || ': ' || c.get_area());
END;

이 예제에서 shape는 모든 형태의 공통 구조를 정의하는 추상 객체이고, circleshape의 구체적인 구현입니다. 이는 일반 레고 지침서(추상 객체)를 가지고 특정 레고 모델을 만드는 것과 같습니다!

그리고 이렇게 우리는 PL/SQL에서 객체 지향 프로그래밍의 기본을 다루었습니다. 연습이 완벽을 만드는 것을 기억하시고, 이 개념들을 실험해 보세요. 행복하게 코딩하세요!

메서드 설명
생성자 객체를 생성하고 초기화합니다
멤버 함수 값을 반환하고 SQL 문에서 사용할 수 있습니다
멤버 절차 작업을 수행하지만 값은 반환하지 않습니다
맵 메서드 객체를 비교하는 데 사용되며 단일 값에 기반합니다
주문 메서드 객체를 비교하는 데 사용되며 사용자 정의 비교 로직을 허용합니다
최종 메서드 서브타입에서 재정의할 수 없습니다
인스턴스화 불가 메서드 서브타입에서 재정의되지 않으면 객체를 인스턴스화할 수 없습니다

Credits: Image by storyset