Objetos en Visual Basic

¿Cómo sentirse un poco Objeto y saber manejarse?

 

Fecha: 01/Feb/98
por Guillermo "guille" Som
Publicado originalmente en Algoritmo en la edición de Octubre'97


Bien, parece ser que aún hay gente que le sigue teniendo miedo a esto de los objetos. Y no las culpo, realmente pasé mi propio "calvario" antes de empezar a entender cómo funcionan estas cosas, aún me queda mucho que aprender, pero la intención, como siempre, es compartir lo que ya sé e intentar que lo aprendas de forma fácil... por supuesto deberás poner de tu parte para poder conseguir el objetivo.

Como te decía antes, cuando empecé a usar "seriamente" el VB4, antes lo había usado casi de la misma forma que las versiones anteriores... aunque mi intención siempre ha sido intentar usar lo nuevo que ofrece cada una de las versiones de Visual Basic, al menos si las entiendo. Hay cosas que son más fáciles de asimilar que otras, (creo que a todos nos ocurre), puede que lo que para unos es fácil para otros no lo sea tanto... La cuestión es que yo soy "mu cerrao de mollera", "mu torpe" o cualquier "mu..." que se te ocurra; y es más, para que una cosa me "entre" en la mollera, (cabeza), tiene que estar muy bien explicada o tener ejemplos que me saquen de mis dudas...

Pues nada de eso me he encontrado cuando quise "atacar" el tema de los objetos... lo reconozco: soy "mu" torpe y no puedo hacer nada para cambiarlo... salvo tirarme horas y horas intentando comprender lo que a otros seguramente entenderían antes de ponerse a leerlo siquiera... Por suerte, (mal de muchos consuelo de tontos), hay otra gente que están en mi misma situación e incluso, si se puede, en condiciones más precarias, en cuanto a la programación, no por nada, sino porque hayan empezado hace poco... Yo llevo desde hace 14 años con esto del Basic y aún no se mucho... Pero ni me acomplejo, ni me importa... El que sepa más, mejor "pa" él. Y los que seamos más torpes, incluso podríamos crear un club... Siempre me enrollo más de lo necesario con mis tonterías, pero como son mías...

Si has hecho algo con el Visual, me imagino que si no ha sido así, pronto lo harás, al menos habrás visto algún listado, imagen o aplicación hecha con VB. Pues ya has vistos algunos objetos. Los más puristas en esto de los objetos, (léase programadores de C++, Delphi, etc.) dirán que ni por asomo el VB trabaja con objetos... pero esas discusiones se las dejo a los más entendidos y para sitios en los que "guste" ver esas cosas, dónde uno pueda rebatirle a otro si es así o no... la cuestión, al menos para nosotros los pobres mortales que nos toca "bregar" con el VB, es que un formulario de Visual Basic, un TextBox, un Picture, un... prácticamente cualquiera de los componentes de la barra de herramientas de Visual Basic, en un objeto.

Estos tienen sus propiedades, eventos y algunos de ellos hasta métodos. Realmente la "filosofía" de los objetos es esa, ser entidades "medio" independientes que contienen "casi" todo lo que necesitan para subsistir. El uso de "medio" y "casi" es porque normalmente los objetos necesitan de otros objetos para hacer cosas útiles... ¿de que nos sirve un Form si no tiene nada dentro? o ¿un TextBox si no puede estar en un Form para que tenga su utilidad o al menos que podamos verlo?

En teoría los objetos deberían ser un "todo", es decir no necesitar a nadie más para poder sobrevivir, pero en la práctica no suele ser así... aunque se puede vivir con esta falta de "perfección" y de hecho vamos a aprender a vivir y a programar de esa forma. Vamos a usar objetos que se relacionen con otros objetos ya que su utilidad es esa. También veremos objetos que en sí mismos serán independientes y nos podremos valer de ellos para realizar tareas o al menos para facilitarnos la vida a la hora de hacer cosas y permitir que nos sirvan para posteriores ocasiones. Esa es realmente la razón de ser de los objetos: la reusabilidad.

Y no pienses que me estoy contradiciendo, tal vez te esté liando/embrollando un poco, eso sí.

 

 

Objetivo de los objetos: Encapsular

Los objetos se suelen comparar o decir que son como cápsulas con cosas dentro, por eso lo de encapsulamiento: estos trozos de código tienen dentro de sí mismos, o al menos deberían tener, sus propios datos (propiedades) y su propio código (métodos) y la forma de comunicarse con el mundo exterior es precisamente con las propiedades y métodos que "muestren" a ese mundo exterior.

Habrá otros datos y código que use de forma interna, pero de eso los demás objetos de la aplicación ni se enterarán y ahí es donde radica la "gracia" de los objetos: sólo mostrarán al mundo externo lo que el mundo externo necesita saber de ellos.

Cuando usamos un TextBox, sabemos que podemos escribir en él y que podemos cambiar el aspecto que tiene y algunas otras cosas más... todo el código necesario para que actúe como actúa está dentro, (encapsulado), y cuando accedemos al contenido del texto escrito simplemente usamos una de las propiedades que ha puesto a nuestra disposición para que nos enteremos de su contenido, ¿que más nos da lo que ese objeto haga internamente? Pues así son o deberían ser todos los objetos. Habrá ocasiones en las cuales los objetos no serán del todo independientes y necesitarán de otros objetos para funcionar, pero lo que sí ocurrirá siempre, es que para acceder a cualquier dato que contenga, éste deberá estar "expuesto" por el objeto, en otras palabras: que el objeto nos permita usar lo que contiene.

 

¿Cómo crear nuestros propios objetos?

Este es el quid de la cuestión, ¿de qué nos sirve trabajar con objetos si no podemos crear los nuestros propios...? Tal vez no debería plantearlo así, ya que durante tres versiones de VB hemos estado trabajando con objetos (o cuasi objetos) sin poder crear los nuestros propios. Pero a partir de la cuarta versión se nos brindó la oportunidad de ser "creadores" de objetos y con la quinta ya podemos hacer muchas más cosas con ellos. Con la próxima versión del VB no sé que más tendremos a nuestra disposición, pero eso lo dejaremos para el año que viene o el otro... cuando esté disponible ya veremos lo que nos depara. Por ahora vamos a enfocarnos a usar lo que tenemos.

Nota: Para seguir esta serie de entregas sobre los objetos, necesitarás como mínimo el VB4, algunos de los ejemplos que tengo pensados no podrán usarse con esa versión, (intentaré en la medida de lo posible que sean casos concretos), por tanto deberías tener como mínimo el VB5CCE, (Visual Basic 5 Control Creation Edition), éste es gratuito y lo puedes bajar del sitio de Microsoft o de los muchos CDs que hay por ahí en el mercado.

La cuestión es que ahora tenemos la oportunidad de crear un objeto: por medio de las clases. Para crear un nuevo objeto sólo tendremos que insertar un nuevo módulo de clase, (que tienen la extensión CLS). Realmente con hacer sólo esto no tenemos un objeto creado, sólo tenemos el medio de poder crearlo. Ya que de nada sirve un objeto si no tiene ni hace nada... creo que en la vida real hay mucho de esto... sobre todo de la "clase" política.

Vamos a verlo de forma práctica:

 

Nuestro primer objeto

El primero objeto con el que vamos a "bregar" será uno "super simple", sólo tendrá una propiedad (datos) y nos servirá para otras ocasiones. Lo que aprendamos con la creación de éste nos servirá de base para los demás objetos "simples" que hagamos.

¿Que quiero decir con objeto simple? Pues precisamente eso: un objeto que servirá de base para que lo usemos con otro un poco más "trabajado".

En esta ocasión el objeto tendrá una propiedad: Contenido que será del tipo cadena de caracteres, es decir podremos almacenar en ella cualquier cosa que se pueda asignar a un string.

Seguramente te preguntarás. ¿no sería más fácil trabajar directamente con una variable de ese tipo?

La respuesta sería: no, si lo que quieres es trabajar con objetos. Realmente un objeto que sólo tenga una propiedad y nada más, no es demasiado útil, pero según la utilidad que queramos darle o el contexto en el que lo usemos, lo será. Más adelante crearemos objetos "básicos" con más propiedades e incluso con métodos. Pero ahora vamos a ver lo que se puede hacer y lo mejor es verlo de forma simple.

 

Manos a la obra: Nuestro primer objeto

Vamos a la tarea, que llevo un buen rato escribiendo "teoría" y aún no hay mucha "práctica".

Crea un nuevo proyecto en inserta un nuevo módulo de clase (class module). Escribe lo siguiente en el módulo recién creado:

 

 

El Option Explicit, seguramente ya estaría en el código, con ésta instrucción le estamos indicando que necesitaremos declarar todas nuestras variables (práctica que deberías usar siempre) y que declaramos una variable/propiedad pública, es decir: visible por los demás objetos de nuestra aplicación, y que es del tipo String (cadena de caracteres). Pulsa F4 y te mostrará la ventana de propiedades, escribe en la propiedad Name: cNombre. Ya tenemos un objeto creado que se llamará cNombre y que tiene una propiedad pública llamada Contenido. Por supuesto a esta propiedad podrías darle cualquier nombre, lo que debes saber es que está disponible para ser usada en cualquier parte de nuestra aplicación.

 

¿Cómo usar nuestros objetos?

A diferencia de los controles del VB, los cuales podemos insertar en cualquier formulario, los objetos que creemos mediante los módulos de clases, no podemos usarlo así tan directamente. Tendremos que usarlos como si de una variable se tratara. Y se declaran "casi" de la misma forma:

 

Dim miNombre As cNombre

 

Aquí nos topamos con uno de los "problemas" que tiene esto del manejo de los objetos. Las variables así declaradas simplemente son "referencias" a un objeto.

¿Que significa esto? A un programador de C/C++ podríamos decirle que acabamos de crear un "puntero" a un objeto del tipo cNombre; a uno de VB también se lo podemos decir, pero seguramente le sonaría a chino, (perdón a los chinos que lean esto), por regla general no sabremos de que estamos hablando... (se oyen carcajadas de fondo... sí, son nuestros amigos los de C).

La cuestión es que al crear una variable que haga referencia a un objeto, simplemente se está creando eso: una referencia, un apuntador, un link (usando términos de navegación por Internet), no estamos creando realmente el objeto... por tanto si no lo creamos no podemos usarlo.

¿Qué utilidad tiene entonces crear esto? La misma que tiene crear una variable:

 

Dim unaCadena As String

 

Estamos preparando el programa para que pueda manejar ese tipo de dato. Aunque no es lo mismo. Ya que una variable "normal" podemos usarla de forma inmediata:

 

unaCadena = "cualquier cosa"

 

Mientras que esto no podríamos hacerlo tan "inmediatamente", aunque sea correcto: miNombre.Contenido = "otra cosa cualquiera"

Antes de entrar en detalles, fíjate en la forma de asignar el valor, ya estarás acostumbrado a ver esta forma de hacer las cosas con los objetos, por ejemplo para cambiar el ancho de un TextBox usaríamos la propiedad Width de esta forma: Text1.Width = 1215

El punto (".") se usa para acceder a las propiedades e incluso a los métodos de los objetos. Entonces, si está bien, ¿cual es el problema?. Que hemos declarado un puntero a un objeto cNombre y un puntero no es más que una referencia a una dirección de memoria en la que debe encontrase un objeto del tipo referenciado.

Sé que esto no es fácil de digerir, pero voy a insistir un poco ya que lo vas necesitar.

 

Poder asignar datos a nuestros objetos

Cuando creamos una variable y le asignamos un valor, este valor se guarda en la memoria. En el VB4, al declarar una variable de cadena (string), realmente estamos creando un puntero a un dato NULL, útil por ejemplo para algunas funciones del API. No es lo mismo una cadena NULA que una cadena vacía. Cuando le asignamos un valor a esa variable, el valor NULL desaparece y se guarda el valor que acabamos de asignarle, esto, por desgracia, no ocurre con los objetos. Antes de poder asignar un valor a un objeto o usar cualquiera de los métodos que tiene, tendremos que indicarle al Visual Basic que lo cree. Para hacer esto se usa NEW.

En el ejemplo anterior, si queremos usar el objeto miNombre, tendremos que hacer lo siguiente:

 

Set miNombre = New cNombre

 

A partir de este momento podremos usarlo al 100%.

¿Qué es lo que acabamos de hacer? En este momento es cuando le hemos dicho que cree el objeto.

 

Objetivo: Destruir un objeto

Para destruir un objeto/clase, tendremos que asignarle Nothing, realmente no se le asigna Nothing, sino que se hace que apunte a Nothing... ¿?¿? (con saber que de esta forma es como se destruye, no te calientes más la cabeza)

 

Set miNombre = Nothing

 

Todos los módulos de clases, tienen unos eventos predeterminados: Initialize y Terminate Éstos se producen cuando la clase se crea y se destruye. El evento Initialize se ejecuta en cuanto usamos New Objet y Terminate cuando lo destruimos.

 

Buenas normas de conducta con los objetos

La forma que acabamos de ver de crear un objeto es la más recomendable. El porqué es que así sólo reservamos espacio real cuando vamos a usar el objeto. Me explico: Veamos otras formas de declarar/asignar variables de objetos:

 

Dim miNombre As Object
Set miNombre = New cNombre

 

Esta sería la forma de crear un objeto del que no sabemos que clase será. En nuestro caso, es un desperdicio de código (interno del VB) y recursos (no demasiados) que no es necesario. Cuando se usa una variable declarada As Object, el Visual Basic no sabe, hasta que se está ejecutando, de que clase será y reserva unas líneas (ocultas) de código para poder hacer su trabajo cuando esté ejecutándose el programa.

 

Dim miNombre As New cNombre

 

De esta forma, al mismo tiempo que declaramos la clase, le indicamos al VB que en cuanto ejecute el módulo en el que se encuentra la declaración, cree el objeto. Aunque ese objeto nunca se use, se creará en memoria y ahí estará hasta que se destruya... ¿Desperdicio de recursos? Más bien sí.

Pero tanto esta última forma como la primera, es la más rápida y menos consumidora de código interno y recursos o tiempo que el Visual necesita para crear objetos.

Esto es por la sencilla razón que ya le estamos indicando cómo va a ser ese objeto y por tanto él sabe cómo es y cuanto necesitará para albergarlo... por supuesto, esto sólo se puede hacer con objetos que actualmente hay en las referencias o en nuestro proyecto.

 

¿Qué método usar para declarar variables de objetos?

Si sabemos el tipo de antemano, usaremos el primer método:

 

Dim miNombre As cNombre

 

Cuando queramos usarlo, sólo debemos asignarlo mediante SET y ya estará disponible.

Habrá ocasiones, la mayoría, en que se necesite usar el NEW junto con la declaración, un caso es para usar colecciones, ya que no se comporta de igual forma. La razón de este "extraño" comportamiento, al menos en forma práctica, la teórica te la dejo a ti, para que profundices con los manuales del Visual Basic, es que al usarlo sin NEW sólo tenemos una copia "fija" de esa variable. Por otro lado, con NEW obtendremos una nueva copia después de destruir la copia anterior. Esto lo verás prácticamente en el código de ejemplo para probar todo esto.

 

Creación de un objeto que contiene a otro objeto

Ahora vamos a ver cómo usar nuestro objeto/clase desde otro objeto. En este caso será una simulación de una colección de objetos cNombre. ¿Una colección? Es una serie de objetos contenidos en una variable. Realmente no es algo tan simple, pero así es cómo te recomiendo que lo veas. Ahora, con esta nueva clase, verás cómo funciona.

 

Una colección de objetos cNombre

En el proyecto en el que has incluido la clase cNombre, inserta un nuevo módulo de clase, pulsa [F4] y en la propiedad Nombre escribe cNombres, sitúate en el código y escribe lo siguiente:

 

 

Esta no es la forma correcta de usar una clase/colección, pero servirá para empezar a tomarle el "gustillo" a esto de las clases.

¿Por qué no es la forma correcta? Entre otras cosas, porque no es necesaria... no necesitamos crear una clase para hacer esto. Por otro lado, esta función lo único que hace es devolver la colección privada y desde fuera de la clase es dónde se maneja el contenido de la colección, esta no es una de las "buenas" normas de programación con objetos.

Pero como acabo de indicar, es para ver de una forma simple, cómo manejar objetos en nuestra aplicación.

 

Usar estas clases en nuestra aplicación

Ahora vamos a añadir un poco de "actividad" a ese formulario que el Visual creó en el nuevo proyecto. Para poder usar estas clases en nuestro programa, tendremos que declararlas. Abre el panel de código del Form1 y escribe esto en la parte de las declaraciones:

 

'Esta clase/colección estará visible en todo éste módulo
Dim variosNombres As cNombres

 

Selecciona de la lista desplegable de la izquierda el objeto Form y saldrá automáticamente el evento Form_Load, escribe esto otro:

 

 

Fíjate en la declaración de cNombre, en esta ocasión, es necesario usarla así, ya que vamos a interactuar con ella y si no la declaramos As New, cada vez que necesitemos usar una copia nueva, tendremos que asignarle el valor New. Dentro del bucle se asigna Nothing, para "eliminar" el contenido de la memoria, pero como la hemos creado con New, sigue disponible para poder asignarle un nuevo valor.

Prueba a declararla sin New y verás lo que ocurre: que sólo existirá una copia de la variable, por tanto todo lo que se asigne a la colección apuntará al mismo sitio... y estará repetido 10 veces, pero no habrá diez nombres distintos.

Este es el código que habría que usar para que funcione correctamente:

 

 

Para poder manipular el contenido de la colección de variosNombres podemos hacer algo como esto:

 

 

Al hacer clic (pulsar) sobre el form, se mostrarán los nombres en la ventana de Depuración. Realmente, como habrás comprobado, variosNombres no es más que una variable objeto/clase y no una colección. La colección es lo que devuelve la función (método) Nombres.

En un próximo artículo, veremos cómo crear clases de colecciones "a prueba de bombas" (o casi) y otras no tan a pruebas de bombas, pero sí un poco más sofisticadas.

Hasta entonces, un saludo.

 

Nos vemos.
Guillermo


Pulsa aquí para bajarte los listados de ejemplo (objetos1_codigo.zip 1.43 KB)
Pulsa en este link, si quieres bajarte esta página con todos los gráficos (objetos1.zip 31.1 KB)


la Luna del Guille o... el Guille que está en la Luna... tanto monta...