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