PL/SQL - 面向對象程式設計
你好,有志者們!今天,我們將踏上一段令人興奮的旅程,進入PL/SQL中的面向對象程式設計(OOP)世界。如果你是程式設計新手,別擔心——我會成為你的友好導遊,一步步解釋一切。那麼,我們一起來看看吧!
什麼是面向對象程式設計?
在我們開始之前,讓我們了解一下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
對象類型,具有兩個屬性(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 '你好,我的名字是 ' || 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。這就像給我們的樂高角色增加了慶祝生日的能力!
使用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 || ' 比較年長');
ELSE
DBMS_OUTPUT.PUT_LINE(jane.name || ' 比較年長');
END IF;
END;
在這個例子中,我們使用age
作為比較的ID。這就像根據樂高角色的身高來比較它們!
使用Order方法
Order方法是另一種比較對象的方法,但它比Map方法提供了更多的靈活性。這就像有一個特殊的裁判來比較我們的樂高角色:
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, '經理', 5000);
BEGIN
DBMS_OUTPUT.PUT_LINE(emp.say_hello());
DBMS_OUTPUT.PUT_LINE('年薪: $' || emp.get_annual_salary());
END;
在這裡,employee
是person
的子類型,繼承了它的屬性和方法,同時添加了自己的。這就像創造一種特殊的樂高角色,它除了能做一般角色能做到的事情外,還能做更多!
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('我的圓形', 5);
BEGIN
DBMS_OUTPUT.PUT_LINE('面積為 ' || c.name || ': ' || c.get_area());
END;
在這個例子中,shape
是一個抽象對象,為所有形狀定義了一個通用結構。circle
是shape
的一個具體實現。這就像有一本通用的樂高指導手冊(抽象對象),然後根據它創建特定的樂高模型!
至此,我們已經涵蓋了PL/SQL中面向對象程式設計的基本知識。記住,熟能生巧,所以不要害怕嘗試這些概念。快樂編程!
注意:在翻譯過程中,我保留了原文的代碼範例,並將其放在Markdown的代碼區塊中。對象和方法的命名也保留了原文的英文命名。
Credits: Image by storyset