The Gambas Object Model
1. Objects & Classes
Een
object in Gambas is een gegevensstruktuur die , , en aanbiedt.
Objecten worden benaderd door verwijzing ernaar, "by reference", d.w.z. door gebruik van een wijzer of pointer. Dat gebeurt door gebruik van een variabele waarvan de waarde het adres is van de object data structuur in het geheugen.
Je kan het adres van een object zien door de
PRINT instructie:
DIM aStr AS NEW String[]
PRINT aStr
(String[] 0x80dccf8)
Deze gegevensstruktuur wordt beschreven in een klasse class .
1.1. Classes
Dus ieder Gambas object heeft een klasse
class die al zijn zichtbare eigenschappen, methodes en gebeurtenissen beschrijft: public properties, methods en events.
Deze class is zelf een Gambas object, waarvan de klasse
Class heet.
Een statische klasse,
static class , is een class waarvan alle "members"
static zijn (zie later). In Gambas wordt een static class
module genoemd.
Voorbeeld
De
System class is een statische class: al zijn methodes zijn statisch, en je kan geen object maken waarvan de class
System zou zijn.
Een virtuele klasse,
, is een verborgen pseudo-klasse die je niet kan expliciet kan gebruiken.
1.2. Properties, en variabelen
Eigenschappen en methodes laten toe de data structuur te bewerken.
Een eigenschap, een methode of een variabele kan statisch zijn:
static:
-
Een statische variabele wordt gedeeld door alle instanties van dezelfde klasse.
-
Een statische eigenschap of kan alleen statische variabelen wijzigen.
Een methode of een variabele kan publiek
public of prive
private zijn. Een eigenschap is altijd publiek.
Private symbolen kunnen alleen gebruikt worden van in de klasse.
Publieke symbolen kunnen overal gebruikt worden, op voorwaarde dat je het object kan bereiken via een referentie die naar het object verwijst.
1.3. Events
Een is een gebeurtenis-signaal dat door een object uitgestuurd worden als er iets mee gebeurt.
Als een object een gebeurtenis-signaal geeft, zal het een verwijzing bijhouden in zijn
observer of ouder,
parent object.
Deze observer is zelf een object dat
event handlers levert. Een
handler is niet meer dan een publieke methode, public , die aangeroepen wordt iedere keer dat de plaatsvindt.
Standaard is de observer het huidig object op het moment dat een nieuwe instantie van een object aangegeven wordt.
Om gebeurtenis-signalen te geven moet een object een naam voor de gebeurtenis,
event name, hebben. Deze gebeurtenisnaam wordt toegewezen bij de "instanciation" van het object, bij het gebruik van de
NEW instructie, en het is de prefix van alle event handler methoden.
Voorbeeld
Dit creëert een
Button control die events maakt.
DIM hButton AS Button
hButton = NEW Button(ME) AS "ButtonEventName"
Als geen event name is opgegegeven, dan kan het object geen gebeurtenis-signalen geven.
Een object kan gesloten worden zodat het geen gebeurtenis-signalen meer kan geven, en het kan terug geopend worden waarna het terug gebeurtenis-signalen kan geven.
Zie
Object.Lock en
Object.Unlock methoden.
Sommige gebeurtenis-signalen of events kunnen geannuleerd worden door de event handler door het gebruik van de
STOP EVENT instructie.
Het effect daarvan hangt af van het .
1.4. References of verwijzingen
Er is geen huisvuilophaling (garbage collection) in Gambas. Dus ieder object heeft zelf een teller,
reference counter, die wordt verhoogd telkens het object een verwijzing krijgt vanuit een , array, collection of ander object. De teller wordt verlaagd als die verwijzing wordt losgelaten.
Deze teller is nul op het moment dat het object wordt gemaakt, en hij komt terug op nul nadat alle verwijzingen terug zijn vrijgemaakt, en dan is het object ook terug vrij.
1.5. Invalid objects of ongeldige objecten
Een object kan
of ongeldig worden. Dat kan bv doordat het gelinkt is met een intern object dat niet beheerd wordt door Gambas en dat vernietigd werd.
Een ongeldig object invalid object gebruiken geeft een fout.
1.6. Speciale methoden
Speciale methoden zijn methoden die gedeclareerd worden in klassen, en die een naam hebben die begint met een plat streepje, de underscore. Ze worden door de interpreter op volgende momenten gebruikt:
-
Als een object gemaakt wordt.
-
Als een object vrijgegeven wordt.
-
Als een objectklasse, object class , wordt geladen.
-
Als een objectklasse object class terug wordt afgeladen.
-
Als een object wordt gebruikt als een gegevensrij of array.
-
When enumerating the object.
-
Als een object gebruikt wordt als functie.
-
Als geprobeerd wordt een onbekende methode of eigenschap van het object, of , te gebruiken.
Zie
/wiki/api/cat/special voor meer informatie.
2. Inheritance of overerving
Overerving is de manier voor een klasse om een gespecialiseerde versie te worden van een andere bestaande klasse.
2.1. Wat is geërfd?
De class erft van zijn ouder iedere methode , eigenschap , constante en gebeurtenis, .
Je moet het sleutelwoord
ME gebruiken om aan de geërfde elementen binnen in de class te kunnen.
2.2. Welke klasse kan een ouder klasse zijn?
Je kan erven van iedere klasse, zelfs van een zelfgemaakte.
Bijvoorbeeld kan je iets doen als
een eigen MyListBox class die
ListBox erft
maar die toelaat een label te hangen aan ieder onderdeel uit de lijst.
Let op, je kan geen
INHERITS
gebruiken in een form class file, omdat de forms al erven van de
Form class.
De diepgang van erven is beperkt tot 16. Dit is een constante die vast in de Gambas interpreter is ingebouwd.
2.3. Virtual dispatching
Bij het aanroepen van een of het gebruiken van een eigenschap van een object reference, zal Gambas altijd
virtual dispatching gebruiken.
Dat betekent dat de echte class van het object altijd wordt gebruikt en niet het type van de dat naar het object verwijst - net zoals het in Gambas 1.0 was.
2.4. Inheritance en constructor
In tegenstelling tot de andere bekende object talen gebruikt iedere klasse in de erf-keten de parameters die doorgegeven worden aan de constructor.
Veronderstel de volgende erf-keten:
MyListBox ---erft van--> ListBox ---erft van---> Control
-
Control._new() bestaat niet.
-
ListBox._new() gebruikt 1 parameter: de parent control.
-
MyListBox._new() neemt 1 parameter: een naam - dit is maar een voorbeeld.
Dus
NEW MyListBox
zal twee parameters aanvaarden.
-
De eerste gaat naar MyListBox._new().
-
De tweede naar ListBox._new().
Opgelet: de
ListBox._new() zal eerst aangeroepen worden,
zodat je zeker bent dat de
ListBox control bestaat
als je in MyListBox._new() komt.
Argumenten moeten dus in de omgekeerde volgorden worden opgegeven!
Dan maak je een MyListBox control op volgende manier:
hMyListBox = NEW MyListBox("Name", hContainer)
3. Components
Gambas component zijn buitenstaande gedeelde code-bibliotheken die geschreven kunnen zijn in C, C++ of in Gambas en die nieuwe functies en of klassen toevoegen aan de Gambas interpreter.
Classes worden gegroepeerd volgens de component waar ze uit komen.
3.1. Default internal component of standaard interne component
De interpreter bevat een interne component
gb die alle standaard klassen van de taal definiëert.
Deze component wordt altijd standaard geladen en kan maakt deel uit van de taal.
3.2. Symbool tabel
Elke component heeft zijn eigen private class symbool tabel, zodat class namen niet kunnen botsen.
3.3 Globale symbool tabel
Omdat componenten moeten samen werken is er een globale symbooltabel, waar alle klassen worden opgeslagen die door componenten en het huidige project worden geëxporteerd.
Als er een botsing van namen optreed in deze globale symbooltabel, zal de laatst geladen klasse de vorige met dezelfde naam vervangen met inachtname van overerving. Met andere woorden, ze zal de bestaande klasse uitbreiden.
Deze laatste mogelijkheid kan gebruikt worden voor:
-
Het uitbreiden van een al gedeclareerde class door nieuwe methodes of eigenschappen toe te voegen. Bv de
gb.qt4
Application class herimplementeert gb
Application class.
-
Het vervangen van methodes van een reeds gedeclareerde klasse. Bv de
gb.form.dialog
component vervangt de meeste van de statische methodes van de Dialog class.
3.4 Project symbooltabel
Je project heeft zijn eigen prive symbool, juist zoals elke component, en kan elk van zijn klassen exporteren naar de globale symbooltabel door gebruik te maken van het sleutelwoord
EXPORT .
De project klassen worden geladen na alle andere componenten. Dus kan je geëxporteerde class eender welke klasse, in eender welke component gedeclareerd, overschrijven.
Zie ook