Lexico
...el poder de lo simple...
Marzo.6.2010

Uso de objetos compuestos

(recuerde: la documentación de la plataforma .NET está en éste sitio)

Hasta ahora hemos mencionado objetos simples, es decir aquellos cuya composición interna es elemental, generalmente formada por la representación de un dato primitivo como una cantidad o unos símbolos textuales. Las operaciones posibles para tales objetos aparecen como si fueras externas a ellos. Éste es digamos el caso excepcional cuando se habla de programación orientada a objetos. Se mantiene en éste paradigma con el propósito de facilitar el diseño de muchas tareas algorítmicas usualmente necesarias para el programador.

Miremos a continuación el caso general de los objetos en programación y su uso.

Los objetos en general están formados internamente por varias entidades o componentes llamadas miembros. Los miembros están descritos en dos maneras posibles: unos significan las características y no son más que datos que reflejan las particularidades y/o el estado en que se encuentra el objeto. Se representan con objetos más pequeños y se conocen en el argot como los atributos del objeto. Los otros son algoritmos, lógica, funcionalidad, métodos, "los mensajes que entiende el objeto", acciones u operaciones posibles definidas y se les denomina los comportamientos del objeto.

La forma de hacer mención a los miembros de un objeto es mediante el operador de manejo llamado cualificador (un punto) que referencia al objeto y su componente en la forma:
                                                        objeto.miembro

Así por ejemplo: si existe ya creado en memoria RAM un objeto llamado robot y el tiene internamente definidos los miembros número_de_ruedas y gire_a_la_derecha, podrá hacerse mención a ellos en la forma:

 robot.número_de_ruedas
 robot.gire_a_la_derecha

Muy probablemente
número_de_ruedas esté definida como una cantidad y gire_a_la_derecha como un algoritmo. La primera referencia (al atributo número_de_ruedas) puede utilizarse tanto para tomar imagen de su contenido como para modificarla con otro dato. La segunda (referencia a un comportamiento) significa que se le ordena al objeto llamado robot ejecutar su algoritmo interno llamado gire_a_la_derecha. Usualmente se dice que se le envió el mensaje gire_a_la_derecha al objeto robot.

Los objetos compuestos, tal como sucede con los objetos simples, han de crearse en la RAM mediante la instrucción de instanciación. Significa que debe conocerse la existencia de un modelo para tal tipo de objetos. En el argot se dice que debe estar ya programada su clase, es decir que alguien ya debe haber programado una descripción detallada del modelo o clase de objetos donde se definen todos los miembros que tendrán los objetos que se construyan con ella. Los objetos entonces tendrán exactamente la composición y los comportamientos definidos en la 
clase utilizada para definirlos. Por ejemplo, si ya existe definida una clase de objetos llamada Móvil, podrían crearse los siguientes dos objetos que denominamos robot y alvaro:

        los objetos robot, alvaro son Móvil

Entre las cerca de 7000 definiciones existentes en la plataforma .NET están programadas las 
clase de objetos Form y Button que definen todo lo que debe tener cualquier ventana o formulario y cualquier botón.  El siguiente ejemplo crea una ventana y dos botones:

        el objeto ventana es una
Form
        los objetos botón1, botón2 son Button

Uno de los métodos programados en la 
clase de objetos Form es Show que permite mostrar la ventana.

En la clase de objetos Form está definido el atributo Controls que es un arreglo destinado a contener los controles que se desee adscribir al formulario. Además tal estructura fue definida con otra clase de objetos que a su vez tiene definido el comportamiento llamado Add (adicionar o agregar). El ejemplo siguiente agregará los dos botones creados a la ventana creada:

        ventana
.Controls.Add(doy botón1)
        ventana.Controls.Add(doy botón2)

Así, agregando los botones, se estará diciendo al sistema operativo Windows que cuando tenga que pintar la ventana recuerde pintar los botones pues han entrado a ser componentes de ella. De lo contrario el programador debería encargarse de mostrarlos cada vez.

Algunos  métodos de un objeto pueden requerir parametros circunstancia en la cual el programador usuario de tal método debe enviar el respectivo mensaje y enviar los argumentos apropiados que cacen con los parámetros definidos. La equiparación ocurre una a una y en el mismo orden. Los argumentos colocados deben ser del mismo tipo o clase de objetos que sus respectivos parámetros y los flujos deben ser complementarios. Si un parámetro fue definido con flujo entra o deme, deberá colocarse su respectivo argumento con flujo sale o doy. Si allá fue definido con flujo sale o doy aquí deberá colocarse uno con flujo entra o deme. Recuérde que un flujo de datos produce destrucción o reemplazo en el objeto receptor y por ello éste deberá ser variable.

El término doy significa que el algoritmo donde está escrito proporciona la información al otro algoritmo que se activa: es decir se establece un flujo de datos haciá allá, de aquí se toma imagen de la información y se lleva a allá. El caso contrario se indica con deme.

Un caso especial de los métodos que persiste desde los albores de la programación en lenguajes de alto nivel por su facilidad para ser utilizades dentro de expresiones son las llamadas funciones. Son métodos con la característica de comportarse como una constante: con solo mencionarlos entregan su valor y éste no hay necesidad de recuperarlo por intermedio de un argumento como es lo usual.

Ejemplos

Diseñar un algoritmo que simule 10 lanzamientos de un dado.

Existe la clase
Random. Uno de sus métodos es Next definido con dos parámetros para establecer el rango cerrado-abierto dentro de los cuales  generará un número seudoaleatorio. Un dado genera valores entre 1 y 6 por lo que debe activarse al algoritmo Next con el rango 1-7:

tarea
{
los objetos númeroGenerado, vez son cantidades
el objeto dado es un Random
copie 0 en vez
mientras vez < 10 haga:
 {
 copie dado.Next(doy 1, doy 7) en númeroGenerado
 muestre númeroGenerado
 copie vez + 1 en vez
 }
}


Uso de modelos o clases existentes en otros archivos

Para usar desde Lexico otros modelos o clases de objetos contenidos en archivos ya compilados (.dll) diferentes a los asumidos automáticamente o en archivos fuente (.lx), puede usarse la instrucción incluya junto con una lista de nombres de archivos encerrados entre dobles comillas y separados por comas.

Por ejemplo, la biblioteca riosur30.dll contiene la clase Graficador en un espacio de nombres EnRiosur30. En ella está definido el método Escriba con tres parámetros: los caracteres que se desean escribir, la vertical y la horizontal donde debe quedar la esquina superior izquierda del primer caracter. Los flujos son entrantes al algoritmo por lo que los datos deben ser proporcionados por el usuario-programador. También está definido el comportamiento Muéstrese sin parámetros para ordenar mostrar todo lo que haya en la gráfica armada:
incluya "riosur30.dll"

tarea
{
el objeto lienzo es un EnRiosur30.Graficador

lienzo.Escriba(doy "riosur30\ncon Lexico\nHecho en Medellín", doy 10, doy 20)
lienzo.Muéstrese

muestre "Hola"
}
Ver descripción de la clase Graficador


Otros ejemplos:

Cómo generar (crear) un archivo plano: Se conoce con éste término a aquellos archivos de texto sin decorados, archivos que contienen solo códigos ASCII tal como los creados por medio de NotePad. Generalmente, sin ser obligatorio, se denominan con un nombre y extensión .txt. En éste ejemplo se llamará informe.txt

Para crear éste tipo de archivos la plataforma .NET posee las clase StreamWriter o escritor de chorro desímbolos que tiene definidos entre sus métodos los siguientes tres:
WriteLine: para escribir símbolos en una línea y al final agregar los códigos no visibles de nueva línea y retorno de carro.
Write: para escribir símbolos en una línea y al final NO agregar los códigos de salto de línea.
Close: para cerrar el archivo.

El siguiente código hace uso de lo dicho para crear el archivo informe.txt que podrá ser visto en la forma usual: abriéndolo con un programa tal como NotePad, WordPad, Word o haciendo sobre él dobleclick en el explorador de archivos. En el ejemplo será lanzado un proceso, es decir se simulará como si el usuario hubiese iniciado (Start) el proceso dando dobleclick sobre él en el explorador.

El detalle más delicado es que una vez armado el archivo debe cerrarse. Si no se hace el archivo quedará con un tamaño de 0 bytes (sin contenido)

tarea
    {
    el objeto archivo es un System.IO.StreamWriter(doy "informe.txt")
    archivo.WriteLine(doy "Informe:")
    archivo.WriteLine(doy "")
    archivo.WriteLine(doy "Esta es la tercera línea")
    archivo.WriteLine(doy "4º línea")
    archivo.WriteLine(doy 5)
    archivo.WriteLine(doy 5+1)
    archivo.Close

    System.Diagnostics.Process.Start(doy "informe.txt", doy "")
    }

En los siguientes ejemplos se crea una solución para ésta situación: Un usuario tiene muchos puntos de un plano cartesiano y una circunferencia. Informe los puntos que caen en el círculo subtendido por ella.

Muchos puntos: no sabemos cuantos, que lo diga él al principio (valor para N) y usamos el modelo cuantitativo
para el control de puntos. Cada punto son dos datos (absisa y ordenada): 2*N + 1 datos

La circunferencia en particular la desconocemos, que la defina él dando centro y radio h, k, r: 3 datos

Por lo tanto se pedirá al usuario que entre  2*N + 4 datos

Ordenaremos a la máquina decidir con base en la ecuación de la circunferencia para seleccionar si cada
punto cae o no en el círculo.

Recuérdese que la igualdad en la ecuación ocurre cuando los valores x, y utilizados forman precisamente
la circunferencia. Si la relación es > estarán fuera y si es < estarán dentro.

5 Soluciones:

1. Se seleccionan puntos, se  informan uno a uno,
2. Se informan en el archivo informe.txt
3. Se informan en el archivo dicho por el usuario,
4. Se informan en el archivo dicho por el usuario mediante un control para diálogo
5. Se informan en el archivo dicho por el usuario mediante un control para diálogo y se lanza el proceso que despliega el archivo


tarea
{
los objetos x, y, i, N, h, k, r son cantidades
entre N, h, k, r
copie 0 en i
mientras i<N haga:
 {
 entre x, y
 es (x-h)^2 + (y-k)^2 <= r^2 ?
    si: muestre x, y

 copie i + 1 en i
 }
}

En vez de mostrar los puntos seleccionados uno a uno podría informarse en un archivo plano (archivo sin
decorados o archivo de texto que llamaremos informe.txt) de manera que el usuario lo abra cuando quiera y con el programa que
quiera para verlos. Para ello la plataforma .NET tiene definida la clase StreamWriter o escritor de
chorros de símbolos y en ella los métodos WriteLine, Write, Close para escribir en una línea y cerrar el archivo.

tarea
{
los objetos x, y, i, N, h, k, r son cantidades
entre N, h, k, r
copie 0 en i
/* el objeto reporte al crearse inscribe ante Windows el nombre de archivo informe.txt */
el objeto reporte es un System.IO.StreamWriter(doy "informe.txt")
mientras i<N haga:
 {
 entre x, y
 es (x-h)^2 + (y-k)^2 <= r^2 ?
    si:    {
    reporte.WriteLine(doy x)
    reporte.WriteLine(doy y)
    }

 copie i + 1 en i
 }
reporte.Close
}

Si se quiere que el nombre del archivo no lo establezcamos nosotros sino el usuario habrá que pedirlo:

tarea
{
los objetos x, y, i, N, h, k, r son cantidades
el objeto nombre_archivo es un caracter
entre  nombre_archivo
entre N, h, k, r
copie 0 en i
el objeto reporte es un System.IO.StreamWriter(doy  nombre_archivo)
mientras i<N haga:
 {
 entre x, y
 es (x-h)^2 + (y-k)^2 <= r^2 ?
    si:    {
    reporte.WriteLine(doy x)
    reporte.WriteLine(doy y)
    }

 copie i + 1 en i
 }
reporte.Close
}

Si se desea el nombre sea aportado por el usuario de la manera usual en las aplicaciones windows
donde sale un control para que seleccione uno ya existente o lo escriba se puede crear un objeto
con la clase SaveFileDialog definida en .NET. Ella tiene definido el atributo FileName donde queda
lo seleccionado por el usuario:

tarea
{
los objetos x, y, i, N, h, k, r son cantidades
el objeto diálogo es un SaveFileDialog
diálogo.ShowDialog

entre N, h, k, r
copie 0 en i
el objeto reporte es un System.IO.StreamWriter(doy  diálogo.FileName)
mientras i<N haga:
 {
 entre x, y
 es (x-h)^2 + (y-k)^2 <= r^2 ?
    si:    {
    reporte.WriteLine(doy x)
    reporte.WriteLine(doy y)
    }

 copie i + 1 en i
 }
reporte.Close
}

Si queremos evitarle al usuario tener que ir al explorador de windows para cliquear
sobre el informe para ser abierto o ejecutar otro programa para ello, podemos usar el
método exclusivo de la clase Process llamado Start con dos argumentos: nombre del proceso
y  parámetros si los tiene. Ésto se llama lanzar un proceso (permite ejecutar otros .exe):


tarea
{
los objetos x, y, i, N, h, k, r son cantidades
el objeto diálogo es un SaveFileDialog
diálogo.ShowDialog

entre N, h, k, r
copie 0 en i
el objeto reporte es un System.IO.StreamWriter(doy  diálogo.FileName)
mientras i<N haga:
 {
 entre x, y
 es (x-h)^2 + (y-k)^2 <= r^2 ?
    si:    {
    reporte.WriteLine(doy x)
    reporte.WriteLine(doy y)
    }

 copie i + 1 en i
 }
reporte.Close
System.Diagnostics.Process.Start(doy diálogo.FileName, doy "")
}

"Profe hize el programa que hicimos en clase y corre pefecto =D
me sorprendio realemente esas funciones son muy buenas Ahora esto si se puso bueno XD
pero resulta que el informe no da de la forma (x,y) si no que da los resultados como un codigo por cada linea
x
y

Como podria cambiarse eso?"


El método WriteLine difiere de Write en que después de escribir agrega los códigos no visibles
(ver una tabla ASCII) 10 y 13 para cambiar de línea (LF o LineFeed) y volver al principio de línea (CR o Carriage Return). Usemos apropiadamente los dos:

tarea
{
los objetos x, y, i, N, h, k, r son cantidades
el objeto diálogo es un SaveFileDialog
diálogo.ShowDialog

entre N, h, k, r
copie 0 en i
el objeto reporte es un System.IO.StreamWriter(doy  diálogo.FileName)
mientras i<N haga:
 {
 entre x, y
 es (x-h)^2 + (y-k)^2 <= r^2 ?
    si:    {
    reporte.Write(doy "(")
    reporte.Write(doy x)
    reporte.Write(doy ", ")
    reporte.Write(doy y)
    reporte.WriteLine(doy ")")
    }

 copie i + 1 en i
 }
reporte.Close
System.Diagnostics.Process.Start(doy diálogo.FileName, doy "")
}


Ejemplo: Cómo hacer sonar un archivo .wav ?

/*
http://msdn.microsoft.com/es-es/library/system.media.soundplayer(VS.80).aspx
Atención: NO disponible en CF
*/


tarea
{
el objeto sonador es un System.Media.SoundPlayer
copie "Explosion.wav" en sonador.SoundLocation

sonador.Play
muestre "Esperando....para terminar"
}

Ejercicios:

1. Simular el recorrido punto a punto de una hormiga borracha.
2. Simular un recorrido oscilatorio de una circunferencia entre los extremos de un segmento de recta.
3. Mostrar una tabla de multiplicar.
4. Dibujar un diagrama de barras (grupo de barras que reflejan proporcionalmente los valores de los datos del usuario).
5. Dibujar un segmento de una curva particular escogida por usted.

 Celecciones de objetos: Grupos de objetos:
 Arreglos rígidos de objetos: Con cantidad predefinida de objetos y cuya reserva de memoria se solicita en un solo bloque para garantizar acceso directo.
 Arreglos flexibles de objetos:  Con cantidad flexible de objetos solicitados en el momento de su necesidad (lo que obliga a su acceso secuencial).