29 Maret 2016

Model Object Gambas

1. Object dan Class

Object dalam Gambas adalah struktur data yang memiliki properti, variabel, metode dan event.
Object diakses "dengan referensi", yakni dengan menggunakan pointer untuk melakukan hal itu, atau dengan menggunakan variabel yang nilainya adalah alamat dari struktur data object di memori.
Anda dapat melihat alamat dari suatu object dengan menggunakan instruksi PRINT.
Contoh :
Dim aStr As New String[]
Print aStr
------------ output ------------
(String[] 0x80dccf8)

Struktur data object digambarkan oleh class.


1.1. Class

Setiap object di Gambas memiliki class yang menggambarkan semua public properti, metode dan event object tersebut. Di Gambas class juga merupakan suatu object, yang mana class adalah class bernama class. Kalau anda rada bingung dengan kata-kata "class bernama class" coba anda lihat kode yang penulis buat dibawah ini.
Public Sub Button1_Click()
'example by Zainudin Ahmad | gambaspi.blogspot.co.id
Dim hClass As Class '< --- class yang bernama class

hClass = Button '< - pemberian nilai object hClass dengan class button
Print hClass.Parent.Name '< --- menampilkan nama parent dari class button
End
------------ output ------------
Control

Sebuah static class adalah class yang semua membernya adalah statis. Di Gambas, class statis juga bernama modul.
Sebuah class statis tidak bisa digunakan untuk membuat object baru, dikarenakan hal itu akan membuat sebuah object tanpa variabel dinamis yang tidak berguna. Penulis akan menjelaskan maksud dari kata "tidak bisa ..." pada kalimat sebelumnya adalah jika class statis tersebut "bisa dibuat object baru" maka object tersebut ga ada bedanya dengan class statis tersebut, di Gambas class statis ada yang bisa dibuat object baru dan ada yang tidak bisa semua tergantung pembuatannya.
Contoh :
Class System adalah class statis, semua metode bersifat statis, dan anda tidak perlu membuat object yang classnya adalah System.
Sebuah class virtual adalah pseudo-class tersembunyi, hal itu membuat anda tidak dapat memanipulasi class secara eksplisit.


1.2. Properti, Metode dan Variabel

Properti dan Metode memungkinkan untuk memanipulasi struktur data.
Sebuah Properti, Metode atau Variabel bisa menjadi statis :
  • Suatu variabel statis akan dapat diakses oleh semua instance dari class yang sama.
  • Properti atau Metode statis hanya dapat memanipulasi variabel statis.
Sebuah Metode atau Variabel dapat berupa public atau private, sedangkan Properti selalu public.
Penggunaan simbol private membuat metode atau variabel hanya dapat digunakan dari dalam class, sedangkan penggunaan simbol public membuat metode dan variabel dapat digunakan dari mana saja selama anda memiliki referensi yang menunjuk ke object tersebut.


1.3. Referensi

Tidak ada garbage collector di Gambas. Jadi setiap object memiliki reference counter yang bertambah setiap kali object direferensikan oleh variabel, array, collection atau object lain, dan berkurang ketika dilepaskan.
Reference counter bernilai nol pada saat pembuatan object, dan menjadi nol lagi ketika referensi telah dilepaskan, dan object tersebut bebas.


1.4. Invalid Object

Sebuah object dapat menjadi invalid. Di karenakan, sebagai contoh, hal yang berhubungan dengan object internal yang tidak dikelola oleh Gambas karena telah dihancurkan.
Mencoba untuk menggunakan object yang invalid dapat membangkitkan/menimbulkan error.


1.5. Metode Khusus

Metode khusus adalah metode yang telah dideklarasikan di class secara default, yang namanya dimulai dengan karakter garis bawah, dan yang dipanggil(eksekusi) oleh interpreter dalam situasi berikut:
  • Ketika suatu object dibuat.
  • Ketika suatu object dibebaskan.
  • Ketika class object dimuat.
  • Ketika class object dibebaskan.
  • Ketika menggunakan object yang seolah-olah itu adalah array.
  • Ketika enumerasi object.
  • Ketika menggunakan object yang seolah-olah itu adalah fungsi.
  • Ketika sebuah object attach(ditambahkan) atau detach(dihilangkan) dari induknya.
  • Ketika mencoba untuk menggunakan metode atau properti object yang tidak diketahui.


2. Event dan Observer

2.1. Event

Event adalah sinyal yang dikirim oleh suatu object ketika sesuatu terjadi pada object tersebut.
Jika suatu object membangkitkan event, hal itu akan membuat object memegang referensi pada observer default(atau induk/parent object) object tersebut.
Observer default ini adalah suatu object yang mengimplementasikan event handler. Event Handler adalah metode public yang dipanggil setiap kali event dibangkitkan.
Secara default, observer adalah suatu object saat di mana object yang baru dibuat dideklarasikan.
Untuk bisa membangkitkan event, suatu object harus memiliki nama event. Nama event ini disertakan pada saat pembuatan object, ketika menggunakan instruksi NEW dan keyword AS, dan nama event juga merupakan awalan nama dari semua metode event handler.
Contoh :
'Contoh ini adalah membuat kontrol Button yang dapat membangkitkan event.

Public Sub Form_Open()
Dim hButton As Button
hButton = New Button(Me) As "ButtonEventName"
End

Public Sub ButtonEventName_Click()
Print "This is the 'Click' event handler for the previous button."
End

Jika tidak ada nama event yang ditentukan, maka object tidak akan membangkitkan event.


2.2. Default Object Parent (atau Default Observer Default)

Beberapa object dapat memiliki satu default object parent jika anda tidak mendefinisikan dengan menetapkan nama event dengan sintaks As "xxx".
Pada saat ini, satu-satunya object yang memiliki default object parent adalah Form, yang menggunakan dirinya sebagai default object parent.
Jika anda membuat Form dan menentukan nama event nya dengan sintaks As "xxx", maka membuat default nama event akan berubah.


2.3. Mengunci Object

Sebuah object dapat dikunci sehingga berhenti membangkitkan event, dan dapat dibuka kembali sehingga membangkitkan event lagi. Untuk mengunci event dengan menggunakan metode Object.Lock sedangkan untuk membukanya kembali dengan metode Object.Unlock.
Beberapa event dapat dibatalkan oleh event handler, dengan menggunakan instruksi STOP EVENT. Efek dari pembatalan ini tergantung pada event tersebut.
!
Suatu object terkunci secara otomatis selama pengeksekusian konstruktor sehinga object tersebut tidak dapat mengirim atau menerima event.



2.4. Observer

Observer adalah object yang memungkinkan anda untuk mencegat event yang dibangkitkan oleh object apapun, observer "mengamati" event-event tersebut.
Anda dapat mencegat event hanya pada saat sebelum atau setelah mereka dibangkitkan.
Untuk setiap event yang dicegat, Observer akan membangkitkan event dengan nama dan argumen yang sama. event yang dibangkitkan bukanlah event asli yang ditangani oleh parent/induk object.
Jika anda menggunakan instruksi STOP EVENT di dalam suatu event handler observer, maka event yang asli akan dibatalkan.
Contoh :
Private $hButton As Button
Private $hObserver As Observer

Public Sub Form_Open()
$hButton = New Button(Me) As "Button"
$hObserver = New Observer($hButton) As "Observer"
With $hButton
.Move(10, 10)
.Resize(100, 30)
.Text = "Click Me :)"
End With
End

Public Sub Observer_Click()
Debug "The button has been clicked. I cancel the event!"
Stop Event
End

Public Sub Button_Click()
Debug "If you see me this is a bug!"
End


3. Pewarisan (Inheritance)

Inheritance adalah cara untuk class menjadi versi yang lebih khusus dari class lainnya.


3.1. Apa yang diwariskan?

Class akan mewarisi setiap metode, properti, konstan dan event yang berasal dari induknya(parent).
!
Anda harus menggunakan keyword ME untuk mengakses elemen yang merupakan pewarisan dari pengimplementasian kode class .



3.2. Class apa saja yang bisa menjadi class induk/parent ?

Anda dapat melakukan pewarisan dari class apapun termasuk native class.
Misalnya, anda dapat membuat class MyListBox kustom yang mewarisi ListBox tetapi memungkinkan untuk mengaitkan tag dengan setiap list item.
Anda tidak dapat menggunakan INHERITS dalam file class form, karena form(file class form) sudah melakukkan pewarisan class Form.
!
Kedalaman pohon warisan tidak dapat lebih besar dari 16. Ini adalah hard-code konstan dalam interpreter Gambas.


3.3. Pengiriman Virtual

Saat memanggil metode atau mengakses properti dari sebuah referensi object, Gambas selalu menggunakan pengiriman virtual.
Hal ini berarti bahwa class yang sesungguhnya dari object selalu digunakan, dan bukan suatu tipe dari variabel yang merujuk ke suatu object - seperti di Gambas 1.0.


3.4. Warisan dan Konstruktor

Bertentangan dengan semua bahasa pemrograman berorientasi object yang saya tahu, setiap class dalam hirarki warisan menggunakan parameter yang dilewatkan ke konstruktor.
Misalkan kita memiliki pohon warisan sebagai berikut:
MyListBox ---inherits--> ListBox ---inherits---> Control
Control._new () tidak memiliki argumen.
ListBox._new () mengambil satu parameter: kontrol parent.
MyListBox._new() mengambil satu parameter: nama (Ini hanya sebuah contoh).
Anda bisa lihat deklarasi dari konstruktor ListBox dan MyListBox dibawah ini
ListBox : _new(hParent As Container) (konstruktor ListBox memiliki argumen parent)
MyListBox : _new(sName As String) (bagian ini hanya contoh, konstruktor memiliki argumen Nama)
Jadi statement New MyListBox akan mengambil dua parameter.
Yang pertama akan dikirim ke ListBox._new() .
Yang kedua untuk MyListBox._new() .
Hati-hati: ListBox._new() yang pertama dipanggil, jadi anda harus yakin bahwa kontrol ListBox ada ketika MyListBox._new() dipanggil.
Kemudian anda akan membuat kontrol MyListBox dengan cara dibawah ini :
hMyListBox = New MyListBox (hContainer, "Nama")
Jadi urutan argumen adalah sebagai berikut:
  • Argumen wajib diposisi pertama dan kemudian argumen opsional jika mereka tersedia.
  • Argumen class yang lebih tua ditetapkan untuk didahulukan.
!
Di Gambas 2.0, urutan atau argumen terbalik !


Misalnya, jika Anda memiliki warisan berikut:
MyForm --> Form --> Window
dengan konstruktor MyForm seperti :
Sub _new(FirstArg As String, SecondArg as Integer, Optional ThirdArg As Integer)
Catatan: konstruktor Form tidak memiliki argumen dan konstruktor Window mengambil argumen opsional parent.
Signature dari konstruktor akhir menjadi :
New MyForm(FirstArg As String, SecondArg As Integer, Optional Parent As Control, Optional ThirdArg As Integer)
Bentuk yang umum, untuk urutan argumen pohon waris tiga tingkat adalah :
  • argumen wajib konstruktor grand-parent/induknya-induk.
  • argumen wajib konstruktor parent/induk.
  • argumen wajib konstruktor akhir.
  • argumen opsional dari konstruktor grand-parent/induknya-induk.
  • argumen opsional dari konstruktor parent/induk.
  • argumen opsional dari konstruktor akhir.


3.5. Simbol Overriding

Ketika simbol ditimpa, signature dari simbol di class anak harus sama dengan signature dari simbol di class induk/parent.
Dengan aturan :
  • Suatu simbol dinamis harus diganti dengan simbol dinamis dan simbol statis dengan simbol statis.
  • Sebuah metode harus diganti dengan metode dengan signature yang sama persis(tipe data argumen yang sama dan (jika ada) juga tipe data nilai kembali sama).
  • Properti read/write harus diganti oleh Properti read/write dengan tipe data yang sama.
  • Properti read-only harus diganti oleh properti read-only dengan tipe data yang sama.
  • Suatu konstan dapat diganti dengan konstanta dengan tipe data yang sama.


4. Komponen

Komponen Gambas adalah shared library eksternal yang ditulis dalam bahasa C/C++ atau Gambas yang menambahkan fungsi dan/atau class baru untuk interpreter Gambas.
Class dikelompokkan sesuai dengan komponen mereka berasal.


4.1. Komponen Standar Internal

Interpreter mencakup komponen internal bernama gb yang mendefinisikan semua class standar bahasa.
Komponen ini selalu dimuat secara default, dan dapat dianggap sebagai bagian dari bahasa.


4.2. Tabel Simbol

Setiap komponen memiliki private tabel simbol class sendiri, sehingga nama class tidak bertentangan(jika ada nama class yang sama) antara komponen yang satu dengan komponen yang lainnya.


4.3. Tabel Simbol Global

Supaya komponen dapat bekerja sama, ada tabel simbol global, yang merupakan tempat menyimpan semua class yang diekspor oleh komponen dan semua class yang diekspor oleh proyek yang sedang digunakan.
Jika ada konflik(ada class yang memiliki nama yang sama) nama dalam tabel simbol global ini, class yang dimuat terakhir menimpa class yang telah dimuat sebelumnya dengan nama yang sama, dengan cara melakukan pewarisan(class yang menimpa dijadikan anak dari class yang ditimpa). Dengan kata lain, class pengganti akan memperluas(menambah fitur, dsb) class yang diganti.
Perluasan fitur bisa digunakan untuk:
  • Memperluas class yang sudah dideklarasikan dengan menambahkan metode baru atau properti untuk itu. Sebagai contoh, class gb.qt4.Application yang merupakan implementasi ulang dari class gb.Application. (contoh : di gb.qt4.application memiliki property MainWindow, dsb)
  • Menggantikan metode class yang sudah dideklarasikan. Sebagai contoh, komponen gb.form.dialog menggantikan sebagian besar metode statis pada class Dialog.


4.4. Tabel Simbol Proyek

Proyek anda memiliki private tabel simbol, sama seperti komponen, dan dapat mengekspor class untuk tabel simbol global dengan menggunakan keyword EXPORT.
Class proyek dimuat/load setelah semua class komponen dimuat/load. Jadi class anda yang diekspor(dalam proyek) dapat menimpa class yang diekspor yang telah dideklarasikan dalam komponen apapun.