ORACLE PL/SQL 對象(object)學習筆記(三)

來源:互聯網
上載者:User

7、物件類型繼承

 

物件類型實現允許我們建立一個基底類型,或叫父類型,這種類型的屬性或方法可以被另一個物件類型繼承。然後可以建立一個子類型,或叫孩子類型,直接使用繼承過來的屬性或方法,或者用自己的屬性和方法重寫父類型的屬性或方法。

 

INSTANTIABLE關鍵字表示我們可以從該類型中執行個體化或者建立對象執行個體。

FINAL關鍵字是指該物件類型下面不再有子類型,沒有其他類型會繼承該物件類型。

 

下面這個例子說明了繼承關係,inventory_obj被book_obj繼承。

 

CREATE OR REPLACE TYPE inventory_obj AS OBJECT (</p><p> item_id NUMBER (10),</p><p> num_in_stock NUMBER (10),</p><p> reorder_status VARCHAR2 (20 CHAR),</p><p> price NUMBER(10,2),</p><p> CONSTRUCTOR FUNCTION inventory_obj (</p><p> item_id IN NUMBER,</p><p> num_in_stock IN NUMBER,</p><p> price IN NUMBER</p><p> )</p><p> RETURN SELF AS RESULT,</p><p> MEMBER PROCEDURE print_inventory,</p><p> MEMBER PROCEDURE print_status,</p><p> MEMBER PROCEDURE print_price</p><p>)</p><p>INSTANTIABLE NOT FINAL;</p><p>/</p><p>CREATE OR REPLACE TYPE BODY inventory_obj</p><p>AS</p><p> CONSTRUCTOR FUNCTION inventory_obj (</p><p> item_id IN NUMBER,</p><p> num_in_stock IN NUMBER,</p><p> price IN NUMBER</p><p> )</p><p> RETURN SELF AS RESULT</p><p> IS</p><p> BEGIN</p><p> SELF.item_id := item_id;</p><p> SELF.num_in_stock := num_in_stock;</p><p> SELF.price := price;</p><p> RETURN;</p><p> END;</p><p> MEMBER PROCEDURE print_inventory</p><p> IS</p><p> BEGIN</p><p> DBMS_OUTPUT.put_line ('INVENTORY FOR BOOKSTORE1');</p><p> DBMS_OUTPUT.put_line ('========================');</p><p> DBMS_OUTPUT.put_line ( 'Item number '</p><p> || SELF.item_id</p><p> || ' has '</p><p> || SELF.num_in_stock</p><p> || ' in stock'</p><p> );</p><p> END print_inventory;</p><p> MEMBER PROCEDURE print_status</p><p> IS</p><p> v_status VARCHAR2 (20);</p><p> BEGIN</p><p> IF SELF.num_in_stock > 0</p><p> THEN</p><p> v_status := 'IN STOCK';</p><p> ELSE</p><p> v_status := 'OUT OF STOCK';</p><p> END IF;</p><p> DBMS_OUTPUT.put_line ('INVENTORY STATUS FOR BOOKSTORE1');</p><p> DBMS_OUTPUT.put_line ('===============================');</p><p> DBMS_OUTPUT.put_line ('Item number ' || SELF.item_id || ' is '</p><p> || v_status</p><p> );</p><p> END print_status;</p><p> MEMBER PROCEDURE print_price</p><p> IS</p><p> v_discount_price discount_price_obj</p><p> := discount_price_obj (SELF.price);</p><p> BEGIN</p><p> DBMS_OUTPUT.put_line ('BOOKSTORE1 PRICES');</p><p> DBMS_OUTPUT.put_line ('=================');</p><p> DBMS_OUTPUT.put_line ('Item number ' || SELF.item_id);</p><p> DBMS_OUTPUT.put_line ('Retail cost: ' || SELF.price || ' US dollars');</p><p> DBMS_OUTPUT.put_line ( 'OUR LOW - LOW - LOW DISCOUNT PRICE: '</p><p> || v_discount_price.price</p><p> || ' US dollars'</p><p> );</p><p> END print_price;</p><p>END;</p><p>/</p><p>--繼承</p><p>CREATE OR REPLACE TYPE book_obj</p><p>UNDER inventory_obj ( --注意到這個地方用了關鍵字UNDER,而不是AS OBJECT</p><p> isbn CHAR (10 CHAR),</p><p> CATEGORY VARCHAR2 (20 CHAR),</p><p> title VARCHAR2 (100 CHAR),</p><p> num_pages NUMBER,</p><p> CONSTRUCTOR FUNCTION book_obj (</p><p> item_id NUMBER,</p><p> num_in_stock NUMBER,</p><p> price NUMBER,</p><p> isbn CHAR,</p><p> title VARCHAR2,</p><p> num_pages NUMBER</p><p> )</p><p> RETURN SELF AS RESULT,</p><p> MEMBER PROCEDURE print_book_information,</p><p> OVERRIDING MEMBER PROCEDURE print_price --OVERRIDING使子類型中的方法優先於父類型中的同名方法</p><p>)</p><p>INSTANTIABLE FINAL;</p><p>/</p><p>CREATE OR REPLACE TYPE BODY book_obj</p><p>IS</p><p> CONSTRUCTOR FUNCTION book_obj (</p><p> item_id NUMBER,</p><p> num_in_stock NUMBER,</p><p> price NUMBER,</p><p> isbn CHAR,</p><p> title VARCHAR2,</p><p> num_pages NUMBER</p><p> )</p><p> RETURN SELF AS RESULT</p><p> IS</p><p> BEGIN</p><p> SELF.item_id := item_id;</p><p> SELF.num_in_stock := num_in_stock;</p><p> SELF.price := price;</p><p> SELF.isbn := isbn;</p><p> SELF.title := title;</p><p> SELF.num_pages := num_pages;</p><p> RETURN;</p><p> END book_obj;</p><p> MEMBER PROCEDURE print_book_information</p><p> IS</p><p> BEGIN</p><p> DBMS_OUTPUT.put_line ('BOOK INFORMATION');</p><p> DBMS_OUTPUT.put_line ('================');</p><p> DBMS_OUTPUT.put_line ('Title: ' || SELF.title);</p><p> DBMS_OUTPUT.put_line ('# Pages: ' || SELF.num_pages);</p><p> DBMS_OUTPUT.put_line ('# In Stock: ' || SELF.num_in_stock);</p><p> END print_book_information;</p><p> OVERRIDING MEMBER PROCEDURE print_price</p><p> IS</p><p> BEGIN</p><p> DBMS_OUTPUT.put_line ('BOOKSTORE1 PRICES');</p><p> DBMS_OUTPUT.put_line ('================');</p><p> DBMS_OUTPUT.put_line ('Title: ' || SELF.title);</p><p> DBMS_OUTPUT.put_line ('Always low price of: ' || SELF.price);</p><p> END print_price;</p><p>END;</p><p>/</p><p>  

 

動態方法調度

 

看看下面這個樣本吧 就什麼都明白了

 

 

CREATE OR REPLACE TYPE abbrev_inventory_obj AS OBJECT (</p><p> item_id NUMBER (10),</p><p> price NUMBER (10, 2),</p><p> MEMBER PROCEDURE print_price</p><p>)</p><p>NOT FINAL INSTANTIABLE;</p><p>/</p><p>CREATE OR REPLACE TYPE BODY abbrev_inventory_obj</p><p>AS</p><p> MEMBER PROCEDURE print_price</p><p> IS</p><p> v_price NUMBER := SELF.price * .80;</p><p> BEGIN</p><p> DBMS_OUTPUT.put_line ('Wholesale Cost: ' || v_price);</p><p> END print_price;</p><p>END;</p><p>/</p><p>CREATE OR REPLACE TYPE abbrev_book_obj</p><p>UNDER abbrev_inventory_obj (</p><p> isbn VARCHAR2 (50),</p><p> OVERRIDING MEMBER PROCEDURE print_price</p><p>)</p><p>FINAL INSTANTIABLE;</p><p>/</p><p>CREATE OR REPLACE TYPE BODY abbrev_book_obj</p><p>AS</p><p> OVERRIDING MEMBER PROCEDURE print_price</p><p> IS</p><p> BEGIN</p><p> DBMS_OUTPUT.put_line ('Retail Cost: ' || SELF.price);</p><p> END print_price;</p><p>END;</p><p>/</p><p>--測試代碼</p><p>SET SERVEROUTPUT ON SIZE 1000000</p><p> DECLARE</p><p> v_wholesale abbrev_inventory_obj := abbrev_inventory_obj (22, 54.95);</p><p> v_retail abbrev_book_obj := abbrev_book_obj (22, 54.95, 23022843);</p><p> BEGIN</p><p> DBMS_OUTPUT.put_line ('SUBTYPE EXECUTION - FULL PRICE');</p><p> DBMS_OUTPUT.put_line ('==============================');</p><p> v_retail.print_price;</p><p> DBMS_OUTPUT.put_line (' ');</p><p> DBMS_OUTPUT.put_line ('BASE TYPE EXECUTION - REDUCED PRICE');</p><p> DBMS_OUTPUT.put_line ('===================================');</p><p> v_wholesale.print_price;</p><p> DBMS_OUTPUT.put_line (' ');</p><p> DBMS_OUTPUT.put_line ('EXAMPLE OF DYNAMIC DISPATCH');</p><p> DBMS_OUTPUT.put_line ('SUBTYPE METHOD RUN WHEN BASE TYPE IS EXECUTED');</p><p> DBMS_OUTPUT.put_line ('=============================================');</p><p> v_wholesale := v_retail;</p><p> v_wholesale.print_price;</p><p> END;</p><p> / </p><p>返回結果為</p><p>--一些不相關的輸出都省略了</p><p>Retail Cost:54.95</p><p>Wholesale Cost:43.96</p><p>Retail Cost:54.95 /*從這裡可以看出,最終的價格是用物件類型abbrev_inventory_obj執行的(v_wholesale.print_price;),但是結果卻是從abbrev_book_obj中獲得的(v_wholesale := v_retail;)。 */ </p><p>            

 

8、物件檢視

CREATE OR REPLACE TYPE discount_price_obj AS OBJECT (</p><p> discount_rate NUMBER (10, 4),</p><p> price NUMBER (10, 2),</p><p> MEMBER FUNCTION discount_price</p><p> RETURN NUMBER</p><p>)</p><p>INSTANTIABLE FINAL;</p><p>/</p><p>CREATE OR REPLACE TYPE BODY discount_price_obj</p><p>AS</p><p> MEMBER FUNCTION discount_price</p><p> RETURN NUMBER</p><p> IS</p><p> BEGIN</p><p> RETURN (SELF.price * (1 - SELF.discount_rate));</p><p> END discount_price;</p><p>END;</p><p>/</p><p>-- Creates the inventory_tbl relational table that includes</p><p>-- a column object.</p><p>CREATE TABLE inventory_tbl ( --建立對象表</p><p> item_id NUMBER (10) PRIMARY KEY,</p><p> num_in_stock NUMBER (10),</p><p> reorder_status VARCHAR2 (20 CHAR),</p><p> price discount_price_obj)</p><p>/</p><p>-- Recreates the inventory_obj object type to match the</p><p>-- inventory_tbl table for use with an object view.</p><p>CREATE OR REPLACE TYPE inventory_obj AS OBJECT (</p><p> item_id NUMBER (10),</p><p> reorder_status VARCHAR2 (20 CHAR),</p><p> price discount_price_obj,</p><p> MEMBER PROCEDURE print_inventory,</p><p> MEMBER PROCEDURE print_status,</p><p> MEMBER PROCEDURE print_price</p><p>)</p><p>INSTANTIABLE NOT FINAL;</p><p>/</p><p>-- Creates the inventory_vie view</p><p>CREATE VIEW inventory_vie</p><p> OF inventory_obj</p><p> WITH OBJECT IDENTIFIER (item_id)</p><p>AS</p><p> SELECT i.item_id, i.reorder_status, i.price</p><p> FROM inventory_tbl i</p><p>/</p><p>--往底層表inventory_tbl中插入一些資料 以方便接下來使用視圖進行查詢</p><p>INSERT INTO inventory_tbl</p><p> VALUES (1, 10, 'IN STOCK', discount_price_obj (.1, 75));</p><p>INSERT INTO inventory_tbl</p><p> VALUES (2, 13, 'IN STOCK', discount_price_obj (.1, 54.95));</p><p>INSERT INTO inventory_tbl</p><p> VALUES (3, 24, 'IN STOCK', discount_price_obj (.15, 43.95));</p><p>INSERT INTO inventory_tbl</p><p> VALUES (4, 13, 'IN STOCK', discount_price_obj (.1, 60));</p><p>INSERT INTO inventory_tbl</p><p> VALUES (5, 5, 'IN STOCK', discount_price_obj (.20, 42.95));</p><p>COMMIT ;</p><p>-- SELECT all records from the inventory_vie object view</p><p>SELECT *</p><p> FROM inventory_vie</p><p>/</p><p>--SELECT columns from the view, attributes from the column object,and use the discount_price method.</p><p>SELECT i.item_id, i.price.price, i.price.discount_rate,</p><p> i.price.discount_price ()</p><p> FROM inventory_vie i</p><p>/</p><p>  

 

插入和更新

雖然物件檢視不支援直接在其上進行插入和更新操作,但是可以建立一個INSTEAD OF觸發器來執行這兩種操作。

 

CREATE OR REPLACE TRIGGER inventory_trg</p><p> INSTEAD OF INSERT</p><p> ON inventory_vie</p><p> FOR EACH ROW</p><p>BEGIN</p><p> INSERT INTO inventory_tbl</p><p> VALUES (:NEW.item_id, NULL, :NEW.reorder_status, :NEW.price);</p><p>END;<br />

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.