2016年3月13日 星期日

物件導向四(多型、Final、抽象)(PL/SQL 三十一)

※多型

※父類別的宣告與實作

CREATE OR REPLACE TYPE father_obj IS OBJECT(
    attr_empno NUMBER(4),
    attr_ename VARCHAR2(10),
    attr_job VARCHAR2(9),
    
    MEMBER FUNCTION to_string RETURN VARCHAR2
) NOT FINAL;
    
    
    
CREATE OR REPLACE TYPE BODY father_obj IS
    MEMBER FUNCTION to_string RETURN VARCHAR2 IS
    BEGIN
        RETURN SELF.attr_empno || ':' || SELF.attr_ename || ':' || SELF.attr_job;
    END;
END;



※第一個子類別的宣告與實作

CREATE OR REPLACE TYPE son_obj UNDER father_obj(
    attr_sal NUMBER(7,2),
    attr_comm NUMBER(7,2),
    
    OVERRIDING MEMBER FUNCTION to_string RETURN VARCHAR2
) NOT FINAL;
    
    
    
CREATE OR REPLACE TYPE BODY son_obj IS
    OVERRIDING MEMBER FUNCTION to_string RETURN VARCHAR2 IS
    BEGIN
        RETURN SELF.attr_ename || ':' || SELF.attr_sal;
    END;
END;



※第二個子類別的宣告與實作

CREATE OR REPLACE TYPE son2_obj UNDER father_obj(
    attr_hiredate DATE,
    
    OVERRIDING MEMBER FUNCTION to_string RETURN VARCHAR2
) NOT FINAL;
    
    
    
CREATE OR REPLACE TYPE BODY son2_obj IS
    OVERRIDING MEMBER FUNCTION to_string RETURN VARCHAR2 IS
    BEGIN
        RETURN SELF.attr_hiredate || ':' || SELF.attr_empno;
    END;
END;



※測試

DECLARE
    s1 father_obj;
    s2 father_obj;
BEGIN
    s1 := son_obj(7698, 'BLAKE', 'MANAGER', 2850, NULL);
    s2 := son2_obj(7698, 'BLAKE', 'MANAGER', TO_DATE('17-12-1980','DD-MM-YYYY'));
    DBMS_OUTPUT.PUT_LINE(s1.to_string);
    DBMS_OUTPUT.PUT_LINE(s2.to_string);
END;

※s1和s2都可以向上轉型,而 to_string 為自己的實作方法


※Final

※宣告Final類別

CREATE OR REPLACE TYPE final_obj IS OBJECT(
    attr_empno NUMBER(4)
) FINAL;
    
CREATE OR REPLACE TYPE xxx UNDER final_obj();

※預設就是FINAL,所以不寫也是一樣

※編譯時會出「PLS-00590: 嘗試在 FINAL 類型之下建立子類型」的錯



※宣告Final方法

CREATE OR REPLACE TYPE final_obj IS OBJECT(
    attr_empno NUMBER(4),
    FINAL MEMBER FUNCTION to_string RETURN VARCHAR2
) NOT FINAL;
    
CREATE OR REPLACE TYPE xxx UNDER final_obj(
    OVERRIDING MEMBER FUNCTION to_string RETURN VARCHAR2
);

※編譯時會出「PLS-00637: 無法覆寫或隱藏 FINAL 方法」的錯



※抽象


※宣告抽象類別

CREATE OR REPLACE TYPE abstract_obj IS OBJECT(
    attr_empno NUMBER(4),
    NOT INSTANTIABLE MEMBER FUNCTION to_string RETURN VARCHAR2
) NOT INSTANTIABLE NOT FINAL;

※和java一樣,有抽象方法的一定是抽象類別,在Oracle裡,NOT INSTANTIABLE兩邊都要寫,但是抽象類別不一定是抽象方法,所以拿掉方法的抽象,編譯也是會過

※NOT INSTANTIABLE 和 NOT FINAL誰在前面都可以



※繼承與實作

CREATE OR REPLACE TYPE instance_abs UNDER abstract_obj(
    OVERRIDING MEMBER FUNCTION to_string RETURN VARCHAR2
);
    
    
    
CREATE OR REPLACE TYPE BODY instance_abs IS
    OVERRIDING MEMBER FUNCTION to_string RETURN VARCHAR2 IS
    BEGIN
        RETURN 'success';
    END;
END;

※和之前都一樣



※測試

DECLARE
    abs abstract_obj;
BEGIN
    abs := instance_abs(1111);
    DBMS_OUTPUT.PUT_LINE(abs.to_string());
END;

※由子類別為父類別進行實例化,最後使用覆寫的 to_string 方法

沒有留言:

張貼留言