Anda dapat menggunakan pernyataan CREATE TYPE untuk mendefinisikan spesifikasi tipe objek dan pernyataan CREATE TYPE BODY untuk membuat badan tipe objek. Topik ini memberikan contoh penggunaan pernyataan CREATE TYPE dan CREATE TYPE BODY.
Contoh berikut menciptakan tipe objek addr_object_type yang memiliki atribut tetapi tidak memiliki metode:
CREATE OR REPLACE TYPE addr_object_type AS OBJECT (
street VARCHAR2(30),
city VARCHAR2(20),
state CHAR(2),
zip NUMBER(5)
);Karena tipe objek ini tidak memiliki metode, badan tipe objek tidak diperlukan. Contoh ini menciptakan tipe komposit yang memungkinkan Anda mengelompokkan objek terkait sebagai satu atribut.
Metode anggota
Metode anggota adalah fungsi atau prosedur yang didefinisikan di dalam tipe objek dan hanya dapat dipanggil melalui instance dari tipe tersebut. Metode anggota memiliki akses ke serta dapat mengubah atribut dari instance objek tempat mereka beroperasi.
Contoh berikut menciptakan tipe objek emp_obj_type:
CREATE OR REPLACE TYPE emp_obj_type AS OBJECT (
empno NUMBER(4),
ename VARCHAR2(20),
addr addr_object_type,
MEMBER PROCEDURE display_emp(SELF IN OUT emp_obj_type)
);Tipe objek emp_obj_type mencakup metode anggota bernama display_emp. Metode display_emp menggunakan parameter SELF, yang meneruskan instance objek tempat metode dipanggil.
Tipe data parameter SELF sama dengan tipe objek yang sedang didefinisikan. Parameter SELF selalu merujuk pada instance yang memanggil metode dan merupakan parameter pertama dalam prosedur atau fungsi anggota, baik dinyatakan secara eksplisit maupun tidak.
Contoh berikut mendefinisikan badan tipe objek untuk emp_obj_type:
CREATE OR REPLACE TYPE BODY emp_obj_type AS
MEMBER PROCEDURE display_emp (SELF IN OUT emp_obj_type)
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Nomor Pegawai : ' || empno);
DBMS_OUTPUT.PUT_LINE('Nama : ' || ename);
DBMS_OUTPUT.PUT_LINE('Jalan : ' || addr.street);
DBMS_OUTPUT.PUT_LINE('Kota/Provinsi/Kode Pos: ' || addr.city || ', ' ||
addr.state || ' ' || LPAD(addr.zip,5,'0'));
END;
END;Anda juga dapat menggunakan parameter SELF dalam badan tipe objek. Untuk menunjukkan bagaimana parameter SELF digunakan dalam pernyataan CREATE TYPE BODY, badan tipe objek sebelumnya dapat ditulis ulang sebagai berikut:
CREATE OR REPLACE TYPE BODY emp_obj_type AS
MEMBER PROCEDURE display_emp (SELF IN OUT emp_obj_type)
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Nomor Pegawai : ' || SELF.empno);
DBMS_OUTPUT.PUT_LINE('Nama : ' || SELF.ename);
DBMS_OUTPUT.PUT_LINE('Jalan : ' || SELF.addr.street);
DBMS_OUTPUT.PUT_LINE('Kota/Provinsi/Kode Pos: ' || SELF.addr.city || ', ' ||
SELF.addr.state || ' ' || LPAD(SELF.addr.zip,5,'0'));
END;
END;Kedua versi badan emp_obj_type setara.
Metode statis
Seperti metode anggota, metode statis dimiliki oleh tipe objek. Namun, metode statis dipanggil menggunakan nama tipe objek, bukan melalui instance objek. Sebagai contoh, untuk memanggil fungsi statis bernama get_count yang didefinisikan dalam tipe objek emp_obj_type, Anda dapat menulis seperti berikut:
emp_obj_type.get_count();Metode statis tidak memiliki akses ke dan tidak dapat mengubah atribut dari instance objek. Biasanya, metode statis tidak bekerja dengan instance dari tipe objek.
Spesifikasi tipe objek berikut mencakup fungsi statis get_dname dan prosedur anggota display_dept:
CREATE OR REPLACE TYPE dept_obj_type AS OBJECT (
deptno NUMBER(2),
STATIC FUNCTION get_dname(p_deptno IN NUMBER) RETURN VARCHAR2,
MEMBER PROCEDURE display_dept
);Badan tipe objek untuk dept_obj_type mendefinisikan fungsi statis bernama get_dname dan prosedur anggota bernama display_dept.
CREATE OR REPLACE TYPE BODY dept_obj_type AS
STATIC FUNCTION get_dname(p_deptno IN NUMBER) RETURN VARCHAR2
IS
v_dname VARCHAR2(14);
BEGIN
CASE p_deptno
WHEN 10 THEN v_dname := 'AKUNTANSI';
WHEN 20 THEN v_dname := 'PENELITIAN';
WHEN 30 THEN v_dname := 'PENJUALAN';
WHEN 40 THEN v_dname := 'OPERASI';
ELSE v_dname := 'TIDAK DIKENAL';
END CASE;
RETURN v_dname;
END;
MEMBER PROCEDURE display_dept
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('Nomor Dept : ' || SELF.deptno);
DBMS_OUTPUT.PUT_LINE('Nama Dept : ' ||
dept_obj_type.get_dname(SELF.deptno));
END;
END;Dalam fungsi statis get_dname, referensi ke SELF tidak diperbolehkan karena fungsi statis dipanggil secara independen dari instance objek dan tidak memiliki akses implisit ke atribut objek apa pun.
Prosedur anggota display_dept dapat mengakses atribut deptno dari instance objek yang dilewatkan dalam parameter SELF. Anda tidak perlu mendeklarasikan parameter SELF secara eksplisit dalam daftar parameter display_dept.
Pernyataan DBMS_OUTPUT.PUT_LINE terakhir dalam prosedur display_dept mencakup panggilan ke fungsi statis get_dname, yang memenuhi syarat dengan nama tipe objeknya, dept_obj_type.
Metode konstruktor
Metode konstruktor adalah fungsi yang menciptakan instance dari tipe objek, biasanya dengan menetapkan nilai ke anggota objek. Tipe objek dapat mendefinisikan beberapa konstruktor untuk menyelesaikan tugas yang berbeda. Metode konstruktor adalah fungsi anggota yang dipanggil dengan parameter SELF, dan namanya sesuai dengan nama tipe objek.
Sebagai contoh, jika Anda mendefinisikan tipe objek bernama address, setiap konstruktor akan diberi nama address. Anda dapat membebani konstruktor dengan membuat satu atau lebih fungsi konstruktor yang berbeda dengan nama yang sama tetapi dengan tipe parameter yang berbeda.
Kompiler SPL menyediakan konstruktor default untuk setiap tipe objek. Konstruktor default adalah fungsi anggota dengan nama yang sesuai dengan nama tipe objek dan daftar parameternya sesuai dengan anggota tipe objek secara berurutan. Contoh berikut menciptakan tipe objek bernama address:
CREATE TYPE address AS OBJECT
(
street_address VARCHAR2(40),
postal_code VARCHAR2(10),
city VARCHAR2(40),
state VARCHAR2(2)
)Kompiler SPL menyediakan konstruktor default dengan tanda tangan berikut:
CONSTRUCTOR FUNCTION address
(
street_address VARCHAR2(40),
postal_code VARCHAR2(10),
city VARCHAR2(40),
state VARCHAR2(2)
)Badan konstruktor default menetapkan setiap anggota menjadi NULL.
Jika Anda ingin membuat konstruktor kustom, deklarasikan konstruktor menggunakan kata kunci constructor dalam pernyataan CREATE TYPE dan definisikan dalam pernyataan CREATE TYPE BODY. Sebagai contoh, jika Anda ingin membuat konstruktor kustom untuk tipe objek address yang menghitung kota dan provinsi berdasarkan street_address dan postal_code, tulis sebagai berikut:
CREATE TYPE address AS OBJECT
(
street_address VARCHAR2(40),
postal_code VARCHAR2(10),
city VARCHAR2(40),
state VARCHAR2(2),
CONSTRUCTOR FUNCTION address
(
street_address VARCHAR2,
postal_code VARCHAR2
) RETURN self AS RESULT
)
CREATE TYPE BODY address AS
CONSTRUCTOR FUNCTION address
(
street_address VARCHAR2,
postal_code VARCHAR2
) RETURN self AS RESULT
IS
BEGIN
self.street_address := street_address;
self.postal_code := postal_code;
self.city := postal_code_to_city(postal_code);
self.state := postal_code_to_state(postal_code);
RETURN;
END;
END;Untuk membuat instance dari tipe objek, Anda dapat memanggil salah satu metode konstruktor untuk tipe objek tersebut. Sebagai contoh:
DECLARE
cust_addr address := address('100 Main Street', 02203');
BEGIN
DBMS_OUTPUT.PUT_LINE(cust_addr.city); -- menampilkan Boston
DBMS_OUTPUT.PUT_LINE(cust_addr.state); -- menampilkan MA
END;Konstruktor kustom biasanya digunakan untuk menghitung nilai anggota ketika informasi yang diberikan tidak lengkap. Contoh sebelumnya menghitung nilai untuk kota dan provinsi berdasarkan kode pos yang diberikan.
Konstruktor kustom juga digunakan untuk menegakkan aturan bisnis yang membatasi status suatu objek. Sebagai contoh, jika Anda mendefinisikan tipe objek untuk mewakili pembayaran, Anda dapat menggunakan konstruktor kustom untuk memastikan bahwa tidak ada objek dari tipe objek pembayaran yang dapat dibuat dengan jumlah yang NULL, negatif, atau nol. Konstruktor default menetapkan payment.amount menjadi NULL. Oleh karena itu, Anda harus membuat konstruktor kustom dengan tanda tangan yang cocok dengan konstruktor default untuk melarang jumlah NULL.