Algunas clases son nativas de gambas (como textbox) y otras las podemos crear nosotros. Una vez tenemos creada una clase podemos crear el objeto a utilizar creando una nueva instancia de esa clase
Por ejemplo yo puedo crear una clase a la que llamo C y que tiene el siguiente contenido:
Esa clase aún no tiene ningún objeto asociado, pero voy a crear dos objetos basados en esa clase
Ahora tengo dos objetos en mi código que están a mi disposición. Esos objetos tienen dos variables VAR1 y VAR2. Para referirnos a ellas
Obj1.VAR1=1
Obj1.VAR2=2
Obj2.VAR1=3
Obj2.VAR2=4
Obj1.VAR2=2
Obj2.VAR1=3
Obj2.VAR2=4
De manera que en este caso yo tengo una clase que ha sido instanciada dos veces. Tengo dos objetos basados en la misma clase. A efectos de comprensión recalco que esta clase me la he inventado yo en función de mis conveniencias, pero gambas provee un conjunto de clases que están a nuestra disposición (como la clase textbox). Por eso cuando yo hago
Dim T as new textbox
estoy creando un nuevo objeto T que está basado en la clase textbox y que por tanto tiene todas sus propiedades y eventos y por ello igual que yo hice en mi clase Obj1.Var1 para referirme a alguna de sus variables tendré que hacer T.text para referirme a alguna de las suyas.
Clases privadas, estáticas y públicas
Las clases privadas se definen poniendo en la primera línea de la clase el comando CREATE PRIVATE. Como resultado esa clase no puede ser instanciada. Las clases de este tipo se utilizan para crear clases hijas que hereden de esta.
Las clases estáticas se definen poniendo en la primera línea de la clase el comando CREATE STATIC. Las clases de este tipo se no pueden ser instanciadas.
Las clases pueden exportarse mediante el comando EXPORT al comienzo de la clase. La palabra clave EXPORT indica que esa clave debe ser exportada al exterior y será tratada como una clase nativa. Se utiliza fundamentalmente para la creación de componentes.
Punteros
Para los que tengais conocimientos básicos de otros lenguajes debeis entender que una clase es únicamente un conjunto de código apilado esperando a ser útil. Cuando creamos un objeto basado en una clase, ese objeto es definido con las propiedades, métodos y eventos públicos que esa clase tenga. Es por tanto el objeto asociado el que si tiene una dirección de memoria física.
Por eso es diferente usar o no usar NEW para la declaración de un objeto
dim T as textbox ---> esto crea un objeto T con una determinada posición en memoria
T=new textbox(contenedir). ---> esto crea otro objeto con otra posición de memoria y ubicado en el contenedor especificado.
Herencia
Una clase puede estar basada en otra al igual que un objeto se basa en una clase. Cuando basamos una clase en otra es para añadir nuevas características. Por ejemplo podríamos crear una clase basada en un textbox pero que solo admita números.
Esta nueva clase heredaría de su clase padre (textbox) todos los métodos, propiedades y eventos que este tiene y sobre ellos haría el código que fuera para conseguir que ese textbox solo admita números.
En ese código para referirnos a la clase padre (a sus propiedades, eventos o métodos) deberemos utilizar la palabra clave ME.
Para hacer que una clase herede de una clase padre se utiliza la palabra clave INHERITS clase_padre
Ejemplo que crea una clase que herede de textbox para crear un textbox que solo admita números
Clases genéricas
Existen dos clases genéricas. La clase class en la que están basadas todas las demás clases y la clase object en la que están basados todos los objetos.
Aún no tengo claro varios conceptos sobre esto. Escribo esto para corregirlo cuando conozca mejor el tema.
Respecto a las variables
estáticas/dinámicas
En una clase puede haber variables ESTATICAS o DINAMICAS.
Las variables dinamicas son como las anteriores. En el Obj1 tienen un valor y en el Obj2 tienen otro. Cad objeto tiene sus variables con sus valores correspondientes.
Las variables estátitas tienen UN SOLO VALOR para todas las clases. En el caso anterior yo podría haber definido una variable estática
Al asignarle un valor a Var3 lo he hecho tanto para OBJ1 como para OBJ2
Publica/privadas
Las variables pueden ser públicas o privadas. En el caso anterior fueron declaradas como públicas razón por la cual pude acceder a ellas y asignarles un valor. Las variables privadas no tienen alcance fuera de su clase.
Clases estáticas o dinámicas
Las clases dinámicas son instanciables. Es por ello que para crear una nueva instancia hay que hacer NEW (ver mas abajo métodos especiales). Las clases estáticas no son instanciables por lo que no se las define con NEW. Debe entenderse que al fin y al cabo un módulo es una clase estática.
Propiedades del objeto
Un objeto como sabemos puede necesitar variables para realizar su función, pero también tiene propiedades. Las propiedades de un objeto pueden ser ESTATICAS o DINAMICAS. Todas son públicas pues su razón de ser es asignarles valor desde el exterior de la clase.
Las propiedades estáticas solo pueden modificar variables estáticas y al igual que la variables su valor es compartido por todas las instancias de esa clase.
Las propiedades dinámicas son las que habitualmente usamos al definir un objeto. En una clse se definen de la siguiente forma:
PROPERTY Enabled AS Boolean ---> definir la propiedad
PRIVATE $Activo AS Boolean ---> definir una variable para mis propios usos y privada
FUNCTION Enabled_Read() AS Boolean ---> función que lee el valor de la propiedad
RETURN $Activo
END
SUB Enabled_Write(bEnabled AS Boolean) ---> función que cambia el valor de la propiedad
$Activo = not $Activo
Actualizar
END
PRIVATE $Activo AS Boolean ---> definir una variable para mis propios usos y privada
FUNCTION Enabled_Read() AS Boolean ---> función que lee el valor de la propiedad
RETURN $Activo
END
SUB Enabled_Write(bEnabled AS Boolean) ---> función que cambia el valor de la propiedad
$Activo = not $Activo
Actualizar
END
De manera que si yo quiero crear un objeto que tenga la propiedad enabled tendré que poner en su clase un código como el anterior. Actualizar es una rutina privada que cambia colores y comportamientos del objeto según el valor de la variable Activo.
Métodos
En un objeto no solo hay variables y propiedades. También hay métodos. Un método es una función asociada a un objeto.
Los métodos pueden ser públicos o privados.
Por ejemplo la rutina anterior a la que llamé 'Actualizar' podría ser un método que cambie un conjunto de variables y parámetros y modifiquen el comportamiento del objeto. Ese método por tanto debería ser privado puesto que su labor es puramente interna. Sin embargo existen los métodos públicos que realizan acciones solicitadas desde el exterior de la clase.
Los métodos como funciones que son pueden devolver valores y pueden tener parámetros algunos de ellos opcionales como cualquier otra función.
Los métodos estáticos solo pueden acceder a variables estáticas.
En gambas 2 solo es posible pasar valor por valor. En gambas 3 por lo visto será posible pasar valores por referencia mediante la palabra clave ByRef.
Métodos especiales
Hay una serie de métodos especiales (nativos) que se pueden incluir en una clase.
_new ---> el método se ejecuta al hacer un NEW y se suele usar para inicializar variables.
_init ---> el método se ejecuta al iniciar la clase la primera vez, esto es al cargarse en memoria
_exit ---> al descargarse de memoria. Es por tanto opuesto a _init
_free ---> se ejecuta al destruir el objeto. Es por tanto opuesto a _new
_get ---> se ejecuta cuando al objeto se le pasan parámetros
Por ejemplo Valor=Gridview[fila,columna] ejecutará el método _get con los parámetros fila y columna.
_put ---> el opuesto a _get. Lo que hace es escribir los valores
Por ejemplo Gridview[fila,columna] ejecutará _put con los parámetros fila y columna
_next ---> devuelve el siguiente item en la enumeración cuando estamos en un un bucle for each
Ejemplo de uso
Pongamos que yo deseo una clase que me sirva para conectar a un determinado sitio.
Yo podría poner en esa clase a la que llamo COMUNICA lo siguiente
Con lo que únicamente al hacer en mi código
Y solo con ello al usar el new se habrá ejecutado el método _new y habrá creado un socket y lo habrá conectado.
Bucle FOR EACH
El bucle for each enumera los distintos items que se encuentran dentro de una colección
Si el método _next está definido como estático entonces el bucle no deberá tener claúsula IN
for each item
print item.text
next
[/code]
Las enumeraciones
Este tema no lo tengo nada claro. Lo menciono aquí para que no se me olvide ponerlo cuando lo entienda bien.
Eventos
En un objeto no solo hay propiedades y métodos. También hay eventos.
Los eventos son METODOS PUBLICOS que se ejecutan cuando se produce un determinado caso (por ejemplo la pulsación de una tecla).
Esta rutina estará en su OBSERVADOR o en el observador de su control padre.
La clase observer
En general especificamos el manejador al crear una nueva instancia. Si no se especifica el observador será el propio objeto definido. Si se especifica (con la claúsula AS entonces el manejador de eventos estará en el objeto padre y se ejecutarán los eventos públicos allí especificados.
Dim T=new textbox as manejador_padre
Sin embargo se puede asociar y disociar un objeto a un determinado manejador
objeto.attach --> asociar un objeto a un manejador
objeto.detach --> disociar un objeto de un manejador
objeto.detach --> disociar un objeto de un manejador
Para declarar un evento se utiliza la claúsula EVENT
El nombre del evento será el nombre del manejador luego un guion y luego el nombre del evento. Si no hay código para un determinado evento este no se ejecuta.
El evento se asigna al instanciar.
Para ejecutar un evento se utiliza el método raise
raise evento
Y puede ocurrir que el evento devuelva un resultado
y para cancelarlo se utiliza stop event dentro del código del evento.
Un objeto puede ser bloqueado o desbloqueado. Si está bloqueado no se dispara ningún evento