El Modelo de Objetos de Gambas
1. Objetos y clases
Un
objeto en
Gambas es una estructura de datos que provee
propiedades,
variables,
métodos y
eventos.
Esta estructura de datos se describe a través de una
clase.
1.1. Clases
Cada objeto de
Gambas dispone de una
clase que describe todas sus propiedades públicas, métodos y eventos.
Esta clase a su vez es un objeto también, cuya clase es la clase llamada
Class.
A
static class is a class whose all members are
static (see below). In
Gambas, a static
clase is also named a
module.
A
virtual class is an hidden pseudo-class that you cannot explicitely manipulate.
1.2. Properties, methods and variables
Properties and methods allow to manipulate the data structure.
A property, a method or a variable can be
static:
- A static variable will be shared by all instances of the same class.
- A static property or método can only modify static variables.
A method or a variable can be either
public or
private. A property is always public.
Private symbols can only be used from the class inside.
Public symbols can be used everywhere, provided you have a reference pointing at the object.
1.3. Events
Events are signals sent by an object when something happens on it.
If an object raises events, it will hold a reference on its
observer, or
parent object.
This observer is another object that implements
event handlers. An
evento handler is just a public
método
that is called each time the
evento is raised.
By default, the observer is the current object where the newly instanciated object is declared.
To raise events, an object must have an
event name. This event name is assigned at object instanciation, when using the
NEW instruction, and is the prefix of all event handler methods.
If no event name is specified, then the
objeto won't raise events.
An object can be locked so that it stops raising events, and can be unlocked so that it raises them again.
See the
Object.Lock and
Object.Unlock methods.
Some events can be cancelled by the event handler, by using the
STOP EVENT instruction.
The effect of this cancellation depends on the
evento.
1.4. References
There is no
garbage collector in
Gambas. So each object has a
reference counter that is incremented each time the object is referenced by any
variable, array, collection or other object, and decremented when it is released.
This reference counter is zero at object creation, and when it becomes zero again after a reference release, the object is freed.
1.5. Invalid objects
An object can become
invalid. Because, for example, it is linked to an internal object not managed by
Gambas that was destroyed.
Trying to use an invalid object raises an error.
1.6. Special methods
Special methods are methods declared in classes, whose name begins with an underscore character, and that are called by the interpreter in the following situations:
- When an object is created.
- When an object is freed.
- When the object class is loaded.
- When the object class is unloaded.
- When using an object as if it is an array.
- When enumerating the object.
- When using an object as if it is a function.
- When trying to use an unknown object método or propiedad.
See
/api/cat/special for more information.
2. Inheritance
Inheritance is the way for a class to become a specialized version of another class.
2.1. What is inherited?
The class inherits from its parent every
método,
propiedad, constant
and
evento.
 |
You must use the ME keyword to access the inherited elements from the class inside.
|
2.2. Which class can be a parent class?
You can inherited any class, even a native one!
For example, you can create
a custom MyListBox class that inherits
ListBox
but allows to associate a tag with each list item.
Note that you cannot use
INHERITS in a form class file, because forms already
inherits the
Form class.
 |
The inheritance tree depth cannot be greater than 16. This is a constant hard-coded inside the Gambas interpreter.
|
2.3. Virtual dispatching
When calling a
método or accessing a
propiedad from an object reference,
Gambas always
uses
virtual dispatching.
It means that the real class of the object is always used, and
not the type of the
variable that references the object - As it was in
Gambas 1.0.
2.4. Inheritance and constructor
Contrary to all the object language I know, each class in the inheritance
hierarchy consumes the parameters passed to the constructor.
Let's suppose we have the following inheritance tree:
MyListBox ---inherits--> ListBox ---inherits---> Control
- Control._new() does not exist.
- ListBox._new() takes one parameter: the parent control.
- MyListBox._new() takes one parameter: a name - It is just an example.
So
NEW MyListBox will take two parameters.
- The first will be sent to MyListBox._new().
- The second to ListBox._new().
Be careful: the
ListBox._new() will be called first,
so that you are sure that the
ListBox control exists
when you are in MyListBox._new().
So arguments must be specified in reverse order.
Then you will create a MyListBox control this way:
hMyListBox = NEW MyListBox("Name", hContainer)
3. Components
Gambas components are external shared libraries written in C, C++ or in
Gambas that add new functions and/or classes to the
Gambas interpreter.
Classes are grouped according to the component they come from.
3.1. Default internal component
The interpreter includes an internal component named
gb that defines all standard classes of the language.
This component is always loaded by default, and can be considered as part of the language.
3.2. Symbol tables
Each component has its own private class symbol table, so that class names do not conflict.
3.3 Global symbol table
So that components can work together, there is a global symbol table, where all classes exported by components and all classes exported by the current project are stored.
If there is a name conflict in this global symbol table, the last loaded class overrides the
previous loaded class with the same
name, by using inheritance. In other words, the overriding class extends the overriden one.
This last feature can be used for:
- Extending an already declared class by adding new methods or properties to it. For example, the gb.qt Application class reimplements the gb Application class.
- Overriding the methods of an already declared class. For example, the gb.form.dialog component replaces most of the static methods of the Dialog class.
3.4 Project symbol table
Your project has its own private symbol, like any
componente, and can export any of its classes to the global symbol table
by using the
EXPORT keyword.
The project classes are loaded after all components. So your exported
clase can override any exported classes declared in any
componente.