You are on page 1of 328

Índice

Introduccion a la Programacion .NET………………………………………………...-5-

Módulo 1 .................................................................................................- 6 -

Programación y diseño de Algoritmos ....................................................- 6 -


Uso de las computadoras. Ventajas .......................................................... - 7 -
¿A que se denomina programación?.......................................................... - 7 -
¿A qué se denomina lenguaje de programación? ........................................ - 7 -
¿A qué se denomina un programa? ........................................................... - 8 -
Desarrollo de un programa. Etapas ........................................................... - 8 -
 Análisis del problema ....................................................................... - 9 -
 Estudio del problema ....................................................................... - 9 -
Algoritmos........................................................................................... - 10 -
Diagramas de flujo ............................................................................... - 11 -
Operadores e identificadores en los diagramas de flujo ............................. - 15 -
Pseudocódigo....................................................................................... - 20 -
Diagramas de Nassi-Schneiderman ......................................................... - 22 -

Módulo 2 ............................................................................................... - 24 -

Implementación de programas en la plataforma .NET .......................... - 24 -


Implementación de programas ............................................................... - 25 -
Tipos de lenguajes de programación ....................................................... - 25 -
Modelos de programación ...................................................................... - 26 -
Cómo seleccionar el lenguaje de programación mas adecuado ................... - 30 -
El archivo ejecutable y sus procesos de creación ...................................... - 30 -
Interfaces de usuario ............................................................................ - 31 -
Las herramientas para la creación de programas ...................................... - 32 -
El SDK de .NET Framework: las herramientas de desarrollo ....................... - 33 -
Practica 1.- .......................................................................................... - 35 -
El compilador de VB.NET ....................................................................... - 35 -
El entorno de desarrollo integrado (IDE) de Visual Studio .NET .................. - 38 -
Proyectos en Visual Studio .NET ............................................................. - 38 -
Creación de un proyecto ....................................................................... - 38 -
El editor de código fuente ...................................................................... - 39 -
El código del programa ......................................................................... - 40 -
El explorador de soluciones ................................................................... - 42 -
La estructura de archivos del proyecto .................................................... - 42 -
Sistema de ayuda................................................................................. - 43 -

Módulo 3 ............................................................................................... - 46 -

Elementos básicos del lenguaje ............................................................ - 46 -


Componentes de un lenguaje de programación. ....................................... - 47 -
Estructura de un programa ................................................................... - 50 -
Ubicación del código en el programa ....................................................... - 51 -
Comentarios ........................................................................................ - 52 -
Indentación del código .......................................................................... - 52 -
Manejo de la consola del sistema ........................................................... - 54 -
Practica 2: Visualizar información en la consola ........................................ - 55 -
Practica 3: Obtener información de la consola .......................................... - 58 -
Variables ............................................................................................. - 59 -
Practica 4: Valores iníciales ................................................................... - 65 -
Avisos IDE sobre errores en el código ..................................................... - 66 -
Grabación del código modificado ............................................................ - 66 -
Constantes .......................................................................................... - 66 -

Módulo 4 ............................................................................................... - 69 -

Estructuras de control .......................................................................... - 69 -


Selección ............................................................................................ - 70 -
If...End If ............................................................................................ - 70 -
Decisión simple en una sola línea ........................................................... - 71 -
Decisión doble ..................................................................................... - 72 -
Decisión doble en una línea ................................................................... - 72 -
Decisión múltiple .................................................................................. - 73 -
Función IIf() ........................................................................................ - 74 -
Select Case...End Select ........................................................................ - 74 -
Repetición ........................................................................................... - 76 -
While...End While ................................................................................. - 76 -
Do...Loop ............................................................................................ - 77 -
For ...Next ........................................................................................... - 79 -
For Each...Next .................................................................................... - 80 -
Anidación de estructuras de control ........................................................ - 81 -
Construcciones derivadas de las estructuras de control ............................. - 83 -
Bifurcaciones incondicionales con Goto .................................................... - 85 -
Laboratorio 1 ....................................................................................... - 87 -

Módulo 5 ............................................................................................... - 88 -

Procedimientos ..................................................................................... - 88 -
División de una línea de código .............................................................. - 89 -
Escritura de varias sentencias en una sola línea ....................................... - 89 -
Procedimientos .................................................................................... - 89 -
Sintaxis de un procedimiento Sub .......................................................... - 90 -
Llamada a un procedimiento Sub ........................................................... - 91 -
Sintaxis de un procedimiento Function .................................................... - 92 -
Llamada a un procedimiento Function ..................................................... - 93 -
Paso de parámetros a procedimientos ..................................................... - 94 -
Protocolo de llamada o firma de un procedimiento .................................... - 94 -
Tipo de dato de un parámetro ................................................................ - 94 -
Modos de paso de parámetros a un procedimiento. .................................. - 95 -
Lista desplegable “Nombre de método”, en el editor de código ................. - 105 -
Laboratorio 2 ..................................................................................... - 107 -

Módulo 6 ............................................................................................. - 108 -

Introducción a los arrays. Operadores ................................................ - 108 -


Depuración del código de ejecución ...................................................... - 109 -
Arrays............................................................................................... - 110 -
Operadores ....................................................................................... - 115 -
Operadores abreviados de asignación ................................................... - 119 -
Operadores de comparación ................................................................ - 122 -
Comparación de cadenas ..................................................................... - 122 -
Comparación de cadenas en base a un patrón. El operador Like ............... - 124 -

-2-
Comparación de objetos. El operador Is ................................................ - 127 -
Operadores lógicos y a nivel de bit ....................................................... - 128 -
Uso de paréntesis para mejorar la legibilidad de expresiones ................... - 130 -
Prioridad de operadores ...................................................................... - 134 -
Uso de paréntesis para alterar la prioridad de operadores ....................... - 135 -
Laboratorio 3 ..................................................................................... - 136 -

Módulo 7 ............................................................................................. - 137 -

Organización y ámbito de los elementos del lenguaje ........................ - 137 -


Archivos y módulos de código en un programa ....................................... - 138 -
Añadir un nuevo módulo (y archivo) a un proyecto ................................. - 139 -
Crear un nuevo módulo dentro de un fichero existente ............................ - 140 -
Cambiar el nombre de un fichero de código ........................................... - 141 -
Añadir al proyecto un fichero de código existente ................................... - 142 -
Lista desplegable “Nombre de clase”, en el editor de código. ................... - 143 -
Excluir y eliminar ficheros de código del proyecto ................................... - 144 -
Reglas de ámbito ............................................................................... - 145 -
Ámbito de procedimientos ................................................................... - 145 -
Ámbito de variables ............................................................................ - 148 -
Periodo de vida o duración de las variables ............................................ - 152 -
Variable Static ................................................................................... - 152 -
Convenciones de notación ................................................................... - 154 -
Variables ........................................................................................... - 154 -
Constantes ........................................................................................ - 155 -
Laboratorio 4 ..................................................................................... - 156 -

Fundamentos POO………………………..……………………………………………..-157-

Módulo 1 ............................................................................................. - 158 -

Introducción a la programación Orientada a Objetos ......................... - 158 -


Abstracción ....................................................................................... - 159 -
Tipos de abstracciones: es-un y tiene-un [9] ......................................... - 161 -
Buscando el nivel de abstracción correcto [9] ........................................ - 161 -
Modelo .............................................................................................. - 162 -
Modelado del mundo real .................................................................... - 162 -
Modelos OO ....................................................................................... - 164 -
Reseña Histórica [9] ........................................................................... - 165 -
Paradigma ......................................................................................... - 168 -
El Paradigma Orientado a Objetos ........................................................ - 170 -
Programas Orientados a Objetos .......................................................... - 172 -

Módulo 2 ............................................................................................. - 173 -

Elementos básicos de la Programación Orientada a Objetos ............... - 173 -


Características ................................................................................... - 175 -
Estado interno/estructura interna ......................................................... - 178 -
OTROS EJERCICIOS ............................................................................ - 186 -

Módulo 3 ............................................................................................. - 230 -

-3-
UML Básico ......................................................................................... - 230 -
Diagrama de Secuencia ....................................................................... - 238 -
Diagramas de Interacción .................................................................... - 260 -
Diagramas de Comunicación ................................................................ - 260 -
Diagrama de Clases ............................................................................ - 261 -
Estructura de una clase: ..................................................................... - 262 -
Descripción de las propiedades: ........................................................... - 264 -
Descripción de las propiedades de una operación: .................................. - 267 -
Descripción de las restricciones: ........................................................... - 280 -

Módulo 4 ............................................................................................. - 292 -

Sub clasificación y Herencia ............................................................... - 292 -


Subclasificación.................................................................................. - 293 -
Ejemplo de una jerarquía de clases ...................................................... - 296 -
Restricciones en el diseño ................................................................... - 297 -
Solución propuesta del diseño .............................................................. - 298 -
Herencia ........................................................................................... - 303 -
Herencia de comportamiento ............................................................... - 304 -
Ejercicio – Cuenta Bancaria ................................................................. - 305 -
Method lookup ................................................................................... - 307 -
Mensajes abstractos ........................................................................... - 309 -
Clase abstracta .................................................................................. - 311 -

Aplocación POO………………………………………….……………………………...-313-

Módulo 1 ............................................................................................. - 314 -

Programación orientada a objetos (OOP) ........................................... - 314 -


Creación de clases en VB.NET .............................................................. - 315 -
Organización de clases en uno o varios ficheros de código ....................... - 316 -
Código de clase y código cliente ........................................................... - 316 -
Reglas de ámbito generales para las clases ........................................... - 316 -
Instanciación de objetos...................................................................... - 317 -
Miembros de la clase. ......................................................................... - 317 -
Ventajas en el uso de propiedades ....................................................... - 320 -
Encapsulación a través de propiedades ................................................. - 320 -
Propiedades de sólo lectura o sólo escritura ........................................... - 322 -
Propiedades virtuales .......................................................................... - 324 -
Nombres de propiedad más naturales ................................................... - 325 -
Propiedades predeterminadas .............................................................. - 326 -

-4-
-5-
Módulo 1

Programación y diseño de
Algoritmos

-6-
Uso de las computadoras. Ventajas
Todas aquellas personas que hayan tenido acceso a una computadora, habrán
podido comprobar las ventajas que estas máquinas otorgan en el calculo de
complejas operaciones numéricas, a una gran velocidad y de forma efectiva.
Para que una computadora pueda realizar operaciones y resolver problemas
necesita, además de los componentes físicos, el elemento lógico que permite
realizar dichas tareas, este es el programa, que al ser ejecutado por la
computadora, lleva a cabo las operaciones correspondientes, y proporcionando el
resultado esperado, a una velocidad infinitamente elevada que si la hubiésemos
hecho de forma manual.
La creación de un programa para una computadora no es una tarea al azar,
requiere un adiestramiento en una disciplina que es la programación, y en sus
componentes informáticos, que son los lenguajes de programación los cuales nos
permitirán su diseño y creación.
La descripción de las técnicas de programación, más específicamente de Visual
Basic .Net (que denotaremos como Visual Basic a lo largo del curso), son los
objetivos perseguidos en este texto, que la finalidad es mostrar al lector las
distintas etapas de la creación de una aplicación informática, del inicio al
apasionante mundo de la programación.

¿A que se denomina programación?


Se llama programación a la rama de la tecnología de la informática, que esta
encargada del diseño y la escritura de las sentencias que una computadora debe
ejecutar para completar una operación o la resolución de un problema.
Se le denomina proceso al conjunto de operaciones que realiza una computadora
para proporcionar un determinado resultado, se le denomina al conjunto de varias
operaciones para realizar tareas comunes, formando de esta manera una única
entidad, llamada programa.
Por ejemplo, un proceso podría ser la suma de varios importes que componen las
líneas de una factura, otro proceso sería el cálculo de los impuestos a aplicar sobre
el importe de dicha factura, o la obtención de los datos del cliente al que
enviaremos la factura, si todos estos procesos y otros los uniésemos, se obtendría
un programa sobre facturación.
Si por otro lado tenemos un programa de rutas que calcule la distancia de los
vehículos de una empresa de transportes, se podría adicionar al programa anterior,
aunque la lógica no tendría sentido, por lo que este y otros programas relacionados
con la logística de una empresa de transportes, debería de ser ubicada en un
programa diferente. Y de este modo, conseguir un conjunto de programas mejor
organizados, y enfocados a resolver tareas concretas, con un mayor rendimiento al
ser ejecutados.

¿A qué se denomina lenguaje de programación?


Este es la principal herramienta de un programador para la creación de un
programa. El lenguaje de programación se compone de un conjunto mas o menos
extenso de palabras claves y símbolos que forman la denominada sintaxis del

-7-
lenguaje, y con una serie de normas y reglas para le uso correcto de tales palabras
reservadas y símbolos.

¿A qué se denomina un programa?


Una aplicación (como la llamaremos también) o un programa, como lo describimos
en una definición anterior, es un conjunto de instrucciones escritas en un lenguaje
de programación, que pueden desarrollar múltiples tareas, normalmente
desarrolladas aunque sin que esto sea obligatorio, y que nos permiten resolver uno
o más problemas. Se le denomina código fuente a las instrucciones de código que
forman parte del programa.
Para crear un programa, como ya lo indicamos anteriormente, debemos conocer los
elementos del lenguaje que emplearemos y sus diferentes normas de utilización. En
este caso, en el lenguaje de Visual Basic .Net dispone de ciertas normas y
palabras claves como ser Dim e Integer para declarar variables o los signos = o +
para asignar valores o realizar operaciones (posteriormente desarrollaremos y
explicaremos todos estos conceptos). Para poder crear una variable y realizar una
tarea con ella, no es suficiente con saber cuáles son las palabras claves y símbolos
que utilizaremos, sino también debemos saber cómo utilizar estos elementos. Como
veremos en el código fuente 1, que muestra una incorrecta manera de asignar una
variable, y la otra correcta.
'incorrecto
Integer MiDato Dim
MiDato(+543 = 750)

'correcto
Dim MiDato As Integer
MiDato = 543 + 750
Código fuente 1.1

Si desarrollamos el código, el primero producirá un error, y el segundo correrá sin


problemas ya que se atiene a las normas escrituras del código de lenguaje

Desarrollo de un programa. Etapas


En el proceso de creación de un programa, no existen normas absolutas, ya que
como se dijo anteriormente, la programación es una actividad de creación, puesto
que intervienen por un lado los requisitos del problema a afrontar, y por el otro las
capacidades de la resolución del lenguaje, por supuesto la capacidad inventiva del
programador para resolver dicho problema.
Pero si podemos establecer unas pautas generales, se le denomina ciclo de
desarrollo del programa, los cuales se puede dividir en dos grandes etapas, cada
una a su vez está compuesta de una serie de pasos.
Mostraremos a continuación los puntos que constituyen este proceso.
 Análisis del problema
o Estudio del problema
o Desarrollo del algoritmo
o Comprobación de algoritmo
 Implementación del programa

-8-
o Escritura del programa en base a los resultados obtenidos del
algoritmo
o Ejecución del programa
o Depuración del programa
o Documentación del programa
A continuación iremos desarrollando una descripción más detallada de los puntos
más importantes de este esquema.

Análisis del problema


Consiste en investigar el problema que se nos presenta para su resolución, y para
ello, desarrollar los procesos necesarios. Luego de estudiar el problema, se debe
desarrollar un algoritmo que lo solvente satisfactoriamente, y la realización de
diversas comprobaciones para comprobar su correcto funcionamiento.
A continuación se describirá los principales puntos a desarrollar durante la fase de
análisis del problema.

Estudio del problema


Como primer paso para el desarrollo de un programa, debemos estudiar
cuidadosamente el problema planteado, e identificar por un lado la información que
se dispone para su resolución, y por el otro, el resultado que queremos obtener.
Los datos disponibles se denominan información de entrada, mientras que al
resultado se denomina información de salida. Daremos un ejemplo
A una empresa desarrolladora de software se encarga el desarrollo de un programa,
dicha empresa cobra la hora de programación 90 pesos, empleando 45 horas para
la realización del programa. Al importe total de horas trabajadas se le aplicara un
impuesto del 21%. Se debe averiguar el importe total a pagar, antes y después del
impuesto, y el importe que significa el impuesto aplicado.
La información que tenemos tras el anunciado sería la siguiente:
 Entrada
o Importe/Hora : 90 pesos
o Horas trabajadas: 45
o Impuesto a aplicar: 21%
 Salida
o Total antes del Impuesto: 4050 pesos
o Impuesto: 850.50 pesos
o Total después del impuesto: 4900.50 pesos
Es muy importante para resolver el problema, disponer de la suficiente información,
ya que sin ella, no podremos obtener los datos que constituirán el resultado
planteado.
Suponiendo que tenemos este otro problema:
“Una oficina compra cartuchos para sus impresoras. Debemos obtener el total a
pagar y el porcentaje de impuesto correspondiente”.

-9-
En este caso no podemos resolver el problema, porque después de analizarlo, falta
la información de entrada como el número de cartuchos comprados, importe por
cartucho y el porcentaje de impuestos que aplicaremos, por lo que resulta
imposible obtener los datos de salida.

Algoritmos
Podemos definir a los algoritmos como el conjunto de acciones a realizar para
resolver un determinado problema.
El modo de afrontar la creación de un problema, pasa por descomponer el problema
planteado en problemas más pequeños y fáciles de resolver independientemente.
Una vez que se resolvieron los problemas independientes, se unirán todos,
obteniendo de ésta forma el correspondiente algoritmo.
El proceso indicado por un algoritmo debe ser claro y tener sus pasos bien
definidos, de forma que si realizamos dicho proceso varias veces, empleando
siempre los mismos valores en el algoritmo, debemos obtener el mismo resultado.
De igual manera, en el algoritmo deben distinguirse las siguientes fases: entrada,
proceso y salida.
Para comenzar a familiarizarnos con el diseño y escritura de algoritmos pongamos
el siguiente ejemplo: desarrollar el algoritmo para escuchar un CD de música. El
código fuente 1.2 muestra los pasos a seguir para confeccionar este algoritmo.
Inicio
Tomar un CD
Introducir en el reproductor
Pulsar el botón comenzar
Escuchar la música
Fin

Código fuente 1.2

Observemos cómo los datos de entrada sería el CD a reproducir, el proceso estaría


representado por los pasos dados por el reproductor para ponerlo en
funcionamiento, mientras que la salida sería la música reproducida que
escucharíamos.
Cuando finalicemos la escritura de algoritmo, es muy conveniente realizar la
ejecución de prueba para el mismo, empleando datos reales como comprobar que
el resultado es el adecuado. En el caso que obtengamos resultados no esperados,
o bien, consideremos que es posible optimizar el proceso de ejecución del
algoritmo, modificaremos las partes que consideremos necesarias para mejorarlo, a
este proceso se lo llama depuración o refinamiento.
Tomando este concepto de depuración, y aplicándolo al anterior algoritmo de
escuchara un CD podríamos refinar el proceso añadiendo los elementos adicionales
que se muestran en el código fuente 1.3

Inicio
Tomar un CD
Pulsar el botón de encendido del reproductor
Abrir la bandeja del reproductor
Introducir el CD en el reproductor

- 10 -
Cerrar la bandeja
Ajustar el volumen
Pulsar el botón de comienzo
Escuchar la música
Fin
Código fuente 1.3

De ésta manera tenemos en cuenta otros factores como el hecho de que el


reproductor pueda estar apagado o el volumen no sea el adecuado.
Una vez de que hemos realizado el análisis del algoritmo, necesitamos un elemento
que nos permita representarlo. Si bien no existe una técnica única para la
representación de algoritmos, disponemos de algunas que, dadas sus
características, nos facilitan dicha tarea, por lo que son mayormente utilizadas.
Entre los medios para la creación de algoritmos, tenemos los diagramas de flujo, el
pseudocódigo, y los diagramas de Nassi-Scheneiderman.

Diagramas de flujo
Un diagrama de flujo consiste en una representación gráfica, basada en símbolos,
de los pasos que debe realizar un algoritmo. Estos símbolos pueden clasificarse de
mayor a menor importancia en:

 Básicos
Terminador. Indica el inicio o fin de un algoritmo, o bien una pausa. Ver figura 1.1

Figura 1.1 Terminador

Datos. Contiene información de entrada o salida, que será utilizada por el algoritmo
para obtener un resultado. Ver figura 1.2

Figura 1.2 Datos

Proceso. Indica una o más operaciones a realizar durante la ejecución del


algoritmo. Ver figura 1.3

Figura 1.3 Proceso

Decisión. Contiene una operación que da como resultado un valor lógico, en función
de la cual, el flujo del algoritmo se bifurcará en una determinada dirección. Ver
figura 1.4

- 11 -
Figura 1.4 Decisión

Dirección. Indica el camino seguido por el flujo del algoritmo. También suelen
utilizarse líneas simples para la conexión de los símbolos en el diagrama. Ver figura
1.5

Figura 1.5 Dirección

 Principales
Decisión múltiple. Variante de símbolos de decisión, en la que el resultado de la
operación puede ser uno de varios posibles, en lugar del simple verdadero o falso
de la decisión sencilla. Ver figura 1.6

Figura 1.6 Decisión múltiple

Conectores. Unen dos puntos de un diagrama. El círculo indica conexión dentro de


la misma página, y el conector de dirección entre páginas diferentes del diagrama.
Ver figura 1.7

Figura 1.7. Conectores

Rutina. Indica una llamada a un procedimiento que es externo al algoritmo actual.


Una vez procesado dicho procedimiento, el flujo del proceso volverá a éste punto y
continuará con el siguiente paso del algoritmo. Ver figura 1.8

Figura 1.8 Rutinas

- 12 -
 Complementarios
Teclado. Indica una acción de entrada de datos en el algoritmo. Ver figura 1.9

Figura 1.9 Teclado

Pantalla. Indica una acción de salida de datos en el algoritmo. Ver figura 1.10

Figura 1.10. Pantalla

Impresora. Indica una acción de salida de datos en el algoritmo. Ver figura 1.11

Figura 1.11. Impresora

En el proceso de diseño de un diagrama de flujo, se indicarán las operaciones


mediante el símbolo correspondiente, introduciendo dentro del símbolo, si es
necesario, o este lo requiere, una nota con operaciones que va a realizarse.
El algoritmo no sirve única y exclusivamente para ser aplicado en la resolución de
problemas informáticos, es posible emplear algoritmos para resolver los mas
variados tipos de problemas, incluso tareas simples.
Veremos un ejemplo de esta situación, mostraremos un diagrama con el algoritmo
de un problema tan natural como abrir una puerta con llave. Ver figura 1.12
Anteriormente hemos mencionado la depuración, como la técnica que nos permite
corregir o mejorar el proceso desarrollado por un algoritmo o programa, dicho
sistema puede ser aplicado a este algoritmo que acabamos de presentar en forma
de optimización. El anterior ejemplo sólo contempla la posibilidad de una llave para
abrir una puerta, pero normalmente, suele ocurrir que tenemos varias llaves, entre
las que hemos de elegir la correcta. Teniendo éste aspecto en cuenta, depuraremos
el anterior algoritmo tal y como se muestra en la figura 1.13 de manera que nos
servirá para introducir un elemento de decisión.

- 13 -
Figura 1.12 Diagrama de flujo para el algoritmo de abrir una puerta con llave.

- 14 -
Figura 1.13. Diagrama de flujo para el algoritmo de apertura, incluyendo depuración.

Operadores e identificadores en los diagramas de flujo


Dentro de los elementos de un diagrama de flujo, es frecuente la necesidad de
realizar operaciones para obtener diversos resultados. En función de la acción o
partícula de acción a representar, emplearemos un conjunto de símbolos en mayor
o menor medida generalizados, de los cuales pasamos a describir los más comunes.
Cuando necesitemos indicar una operación aritmética, emplearemos los siguientes
símbolos:
+ Suma
- Resta
* Multiplicación
/ División
\ División entera
^ Potenciación
Para establecer una comparación utilizaremos los siguientes símbolos

- 15 -
> Mayor que
>= Mayor o igual que
< Menor que
<= Menor o igual que
= Igual que

Al realizar una operación, el resultado necesitamos guardarlo en algún sitio; para


ello necesitamos de los llamados identificadores, que son elementos que
representan un valor utilizado a lo largo del algoritmo. El valor contenido en un
identificador puede variar según las operaciones que realicemos con el mismo. A un
identificador le daremos un nombre cualquiera, siendo recomen dable que guarde
cierta relación con el valor que contiene. En el próximo ejemplo se utilizarán
identificadores de modo que el lector pueda comprobar cómo se lleva a cabo su uso
El símbolo igual (=), además de para una comparación, se utiliza también para
asignar el resultado de una operación a un identificador, situando el identificador al
que asignaremos el valor a la izquierda del símbolo, y la operación a la derecha.
En el caso de necesitar representar una entrada o salida de datos, podemos usar
las palabras, Lectura y Escritura, seguida de los identificadores a los que se
asignará, o de los que se obtendrá un valor.
En el siguiente ejemplo, representaremos un algoritmo mediante un diagrama de
flujo, enfocado al siguiente problema: calcular el importe de una factura emitida
por una empresa que vende cartuchos de impresora. Cada cartucho tiene un precio
de 36 pesos, y el usuario debe introducir la cantidad de cartuchos vendidos, y
calcular el total, mostrándolo al final. Este algoritmo nos servirá además para
comprobar la representación de las entradas y salidas de información en un
diagrama. Ver figura 1.14

- 16 -
Figura 1.14 Diagrama de flujo con el algoritmo para calcular el importe de cartuchos de impresora

Si suponemos ahora que en el anterior algoritmo hemos olvidado realizar el cálculo


del impuesto a aplicar sobre el importe de los cartuchos. Para solucionar este
inconveniente realizaremos un proceso de depuración sobre dicho algoritmo,
obteniendo una nueva versión, representada en el diagrama de la figura 1.15.
Los algoritmos representados hasta el momento, se basan en un proceso simple de
toma de datos, cálculo de operaciones, y muestra de resultados. Pero una de las
ventajas de la programación consiste en repetir, un número determinado de veces,
un mismo proceso, dentro de una estructura repetitiva llamada bucle.
En las operaciones a realizar dentro de una estructura repetitiva, podemos definir
un identificador que actúe como contador, que controle el número de veces que
llevamos ejecutada la estructura, para saber en qué momento debemos finalizar su
ejecución y continuar con el resto del proceso.
Una particularidad realizadas con las estructuras repetitivas, consiste en agrupar un
valor en un identificador, en cada paso o ejecución de la estructura. Para ello

- 17 -
debemos hacer algo tan sencillo como poner dicho identificador a un acumulador,
además de en la parte izquierda de la asignación, también en la parte de la
derecha.
El algoritmo que desarrollamos a continuación, muestra un ejemplo de los
elementos que acabamos de mencionar, vamos a definir un bucle controlado por
contador, que tiene un identificador con el nombre Pasos el cuál estaremos
ejecutando mientras dicho contador no sea 10, en cada paso del bucle, el usuario
debe introducir un dato paso que se depositará en el identificador Valor, dicho dato
se almacenará en el identificador Resultado. Cuando el contador haya alcanzado el
valor adecuado, se finalizará la ejecución del bucle, escribiendo el resultado del
acumulador. Ver figura1.15

Figura 1.15. Diagrama con algoritmo para calcular el importe de cartuchos de impresora e impuesto

- 18 -
Figura 1.16. Diagrama de algoritmo con bucle, contador y acumulador

Como ejemplo integrador de los aspectos vistos hasta el momento, el siguiente


caso muestra la creación de un algoritmo algo más complejo y completo. El
problema que desarrollaremos se basa en un programa de venta de artículos, cada
cliente puede comprar un número de artículos diferente por lo que el usuario del
programa debe ir introduciendo el precio del artículo; una vez hecho esto, se
comprobará el precio del artículo, y si sobrepasa el importe de 30, se aplicará un
descuento del 2%. En el caso de que el importe sea menor, se le otorgará al cliente
un punto de bonificación sobre el artículo para la próxima compra. Cuando se haya
procesado todos los artículos, deberemos obtener el importe total de la compra y la
cantidad de puntos de bonificación, finalizando de ésta manera el algoritmo. El
diagrama de flujo correspondiente quedaría como muestra la figura 1.17

- 19 -
Figura 1.17. Diagrama de flujo del algoritmo de compra de artículos

Pseudocódigo
El sistema de representación mediante diagramas de flujo, si bien es un medio
gráfico y fácil de comprender, presenta el inconveniente de la lentitud en su
proceso de creación, y dificultad de mantenimiento ya que un cambio de
planteamiento en un programa largo, puede significar el rediseño de gran parte del
mismo.
Como solución a éste problema, se hace necesaria una técnica de diseño de
algoritmos, que permita una creación más ágil del mismo, mediante un lenguaje
sencillo de escribir y mantener. La respuesta la encontramos en el pseudocódigo.
Este consiste en una forma de expresar el desarrollo de un algoritmo, empleando
palabras de nuestro lenguaje cotidiano, junto con símbolos y palabras clave
genéricas de la mayoría de lenguajes de programación, es decir, un lenguaje que
se encuentra a medio camino, entre el lenguaje de programación y el lenguaje
común.

- 20 -
No hay un conjunto de normas establecidas o sintaxis para la escritura de
pseudocódigo, existen una serie de recomendaciones para el desarrollo del
algoritmo mediante esta técnica quedando el resto en manos de cada programador,
que según vea éste programador, las necesidades y experiencia.
Partiendo de lo anterior, cuando en pseudocódigo necesitemos realizar cálculos
matemáticos o comparación entre elementos, emplearemos los operadores
explicados en el anterior apartado que dedicamos a los diagramas de flujo, que la
finalidad es la misma.
En las indicaciones de principio, fin de algoritmo, lectura y escritura de datos,
usaremos también las mismas palabras clave que empleamos en los diagramas de
flujo.
Para estructuras repetitivas o bloques de instrucciones que se ejecuten basados en
una condición, podemos utilizar las siguientes palabras: Si...FinSi, Para....Siguiente,
Mientras...FinMientras, Seleccionar Caso...FinCasos.
Como medio de facilitar la legibilidad de las líneas del algoritmo, indentamos
aquellas que formen parte de un bloque o escritura.
Si debemos escribir comentarios en las operaciones del algoritmo, podríamos
emplear dos barras invertidas //, comilla ', llaves {}, etc.
Comencemos con un ejemplo sencillo de pseudocódigo, basado en un problema
anteriormente comentado, sobre la apertura de una puerta después de elegir la
llave correcta; el algoritmo quedaría de la siguiente manera, como se muestra en el
código fuente 4
Apertura

Inicio
Elegir una llave
Si podemos introducir la llave en el cerrojo
Abrir la puerta
FinSi
Fin
Código fuente 1.4

A continuación pasaremos a otros dos ejemplos que realizamos anteriormente para


un diagrama; de esta forma podemos establecer las comparaciones necesarias
entre una y otra técnica. El pseudocódigo a escribir será para el algoritmo de
compra de cartuchos de impresora, que incluye cálculos de impuestos. Ver código
fuente 5
CompraCartuchos

Inicio
Lectura Cartuchos
ImporteCartuchos= Cartuchos * 12
Impuesto = ImporteCartuchos *.21
TotalFac =ImporteCartuchos + impuesto
Escritura ImporteCartuchos, Impuesto, TotalFac
Fin
Código Fuente 1.5

Finalmente, convertimos a pseudocódigo el diagrama del ejemplo sobre el proceso


de compra de artículos. Ver código de fuente 1.6

- 21 -
CompraArtículos

Inicio
Mientras haya artículos
Lectura Precio
Si Precio > 30
Descuento = Precio * 0.02
Precio = Precio - Descuento
Sino
PuntosBonific = PuntosBonific + 1
FinSi
TotalCompra = TotalCompra + Precio
FinMientras
Escritura TotalCompra, PuntosBonific
Fin
Código Fuente 1.6

Diagramas de Nassi-Schneiderman
Este tipo de diagramas, también denominados N-S, se basa en la representación de
los pasos del algoritmo mediante recuadros adyacentes, eliminando los símbolos de
flechas y líneas de conexión. Al mismo estilo de los diagramas de flujo, podemos
situar una o varias acciones en un mismo recuadro
En el caso más simple, una ejecución de varias instrucciones sin ningún tipo de
condición o desvío del programa, como en el ejemplo de apertura de llave sin
selección, un diagrama de este tipo para dicho algoritmo quedaría como se muestra
en la figura 1.18

Figura 1.18 Diagramas N-S para representar el algoritmo de Apertura con llave

El algoritmo de apertura con llave, pero en ésta ocasión haremos un refinamiento


para hacer la selección de la llave, lo representamos en la figura 1.19

- 22 -
Figura 1.19 Figura19. Diagrama N-S para algoritmo de apertura con selección de llave

En los diagramas N-S, como podemos observaren el siguiente ejemplo, los bloques
de instrucciones que están a un nivel mayor de profundidad, y que en pseudocódigo
deberíamos indentar, se representan en recuadros interiores al cuadro principal del
diagrama. En la figura 1.20, se muestra cómo quedaría el algoritmo de compra de
artículos en un diagrama de éste tipo, eliminamos la condición de que el artículo
tenga descuento o bonificación para no recargarlo demasiado.

Figura 1.20. Diagramas N-S para algoritmo de compra de artículos

- 23 -
Módulo 2

Implementación de
programas en la plataforma
.NET

- 24 -
Implementación de programas
Completada la fase de análisis, y obteniendo el correspondiente algoritmo mediante
algunas de las técnicas descritas en el tema anterior, la etapa de implementación
se trata de trasladar a la computadora el resultado del análisis del problema.
Para introducir en la computadora las instrucciones del algoritmo, deberemos
utilizar un lenguaje de programación con él crearemos un programa que tenga las
sentencias a ejecutar. Al finalizar la escritura de programa, procederemos a su
compilación, para obtener un archivo ejecutable con las instrucciones en un
formato denominado código binario, la computadora comprende éste tipo de código
para ser ejecutado.
En los siguientes apartados se tratarán los aspectos del proceso de implementación
en lo que respecta a los lenguajes de programación, tipos y técnicas; el proceso de
creación del ejecutable, una breve descripción de la plataforma .Net FrameWork,
como entorno de ejecución de aplicaciones; Visual Basic .Net como el lenguaje que
elegimos, su instalación, entorno de desarrollo, y la confección de un sencillo
programa de prueba.

Tipos de lenguajes de programación


Antes de proceder a escribir el código del programa, debemos elegir el lenguaje de
programación que mejor se adapte a nuestras necesidades. En función del tipo de
problema a resolver, los lenguajes se clasifican como describiremos a continuación.

 Lenguajes de máquinas
Se trata de lenguajes que son comprendidos directamente por la computadora en la
que se ejecuta el programa. Su dependencia por lo tanto, con respecto al hardware
de la computadora en la que funcionan es total, por lo que su ejecución es más
veloz que cualquier otro tipo de lenguaje que podamos utilizar.
Luego de la anterior explicación, y ya que este tipo de código es el único que
entiende la computadora de modo directo, ¿no resultaría mejor programar siempre
en el lenguaje máquina?
Como respuesta, y a pesar de la mencionada ventaja, podemos decir que existen
inconvenientes muy importantes: la vinculación del lenguaje máquina con el
hardware del equipo, hace que un programa no pueda ser transportable a otro tipo
de arquitecturas de procesadores, por lo que debemos rescribir el programa, si
necesitamos que sea ejecutado en una máquina con diferente arquitectura que para
la que originalmente fue diseñado.
Por otro lado, la escritura de un programa máquina es una labor lenta y compleja,
en la que el programador no dispone de herramientas de soporte que le ayuden en
su tarea.

 Lenguajes de bajo nivel


En este tipo de lenguajes, al igual que sucede en los lenguajes máquina, existe una
gran dependencia con el hardware del equipo en el que se va a ejecutar. No
obstante son algo más fáciles de escribir, quedando su complejidad en un punto
intermedio entre el lenguaje máquina y uno de alto nivel; no es tan complicado
como en el primero, pero existe una mayor curva de aprendizaje que en el

- 25 -
segundo, debido a que se necesita saber el tipo de máquina en que se va a ejecutar
el programa.
Otra característica que tiene es que el código escrito no es directamente ejecutable
por la computadora, sino que debe pasar por un traductor de código fuente a
código binario denominado compilador. El ejemplo más destacable para éste caso
es el Ensamblador.

 Lenguajes de alto nivel


Aportan tipos de datos y estructuras de control entre dos elementos. Igualmente
disponen de una sintaxis más natural, y un amplio conjunto de funciones internas,
que ayudan a los programadores en diversas situaciones, así como un numero
determinado de utilidades y asistentes que ahorran tiempo y trabajo a la persona
que programa. Visual Basic .Net es uno de los ejemplos de este tipo de lenguajes.

Modelos de programación
Un modelo de programación consiste en la técnica empleada para escribir el código
del programa, de forma que consigamos la mayor efectividad y optimización al
ejecutarlo. El desarrollo de las herramientas informáticas ha posibilitado una
progresiva evolución de las técnicas de programación, con la consiguiente mejora
que ello supone, tanto a la hora de la escritura como de la ejecución de un
programa. A continuación se realiza una descripción de los modelos de
programación que existen

 Programación lineal
Este es el modelo más tradicional, en este momento se encuentra ya en desuso. El
código se organiza linealmente, y ejecuta desde la primera línea hasta la última, sin
disponer de ningún tipo de estructuración o bifurcación. El código fuente 2.1
muestra un esquema de éste tipo de programación.
Instrucción1
Instrucción2
Instrucción3
.
.
.
InstrucciónFinal
Código fuente 2.1

Con éste modelo, el inconveniente de programación, radica en que si dentro de un


algoritmo hay un proceso que necesita repetirse un número determinado de veces,
se tendrá que repetir la escritura de código correspondiente a este proceso las
veces que sean necesarias.
Como ejemplo podríamos dar un proceso que necesita abrir un archivo que
contiene los datos de facturas, y totalizar varias, calculando además, el impuesto a
añadir al total. Mediante programación lineal, el pseudo código de este proceso
quedaría como muestra el código fuente 2.2

Inicio
Abrir archivo datos facturas

Obtener Factura1
Obtener TipoImpuesto

- 26 -
Sumar LineasFactura
Calcular TotalFactura

Obtener Factura2
Obtener TipoImpuesto
Sumar LineasFactura

Obtener Factura3
Obtener TipoImpuesto
Sumar LineasFactura
Calcular TotalFactura
Fin
Código fuente 2.2

Vemos como hay tres líneas que se repiten, lo cuál es el elemento negativo en esta
técnica de `programación, ya que obliga a escribir una mayor cantidad de código y
el mantenimiento del mismo se hace más dificultoso.

 Programación procedural
Para Solventar los problemas de la programación lineal apareció la programación
procedural, que se basa en tomar el programa y dividirlo en partes lógicas con
entidad propia, denominadas procedimientos o rutinas de código.
Cada procedimiento se ocupa de resolver una tarea específica, de modo que
partiendo de un procedimiento inicial o de nivel superior, se llamará a otro
procedimiento para que ejecute un determinado trabajo, y al finalizar, se devolverá
el control o flujo de la ejecución al procedimiento que hizo la llamada. Veremos en
el esquema de la figura 2.1

Figura 2.1. Esquema de ejecución del código de programación procedural

- 27 -
Mediante esta técnica, el ejemplo de cálculo de facturas que vimos en el apartado
anterior puede enfocarse de un modo mucho más optimizado, ya que sólo
necesitaremos escribir el código del proceso que realiza la totalización y el cálculo
de impuestos una sola vez, situarlo en un procedimiento, y llamarlo las veces que
haga falta. La figura 2.2 muestra el esquema de ejecución del código de dicho
ejemplo.
Dentro de la programación procedural se utiliza también el concepto de módulo,
para hacer referencia una entidad contenedora de procedimientos. Esto quiere decir
que podemos usar los módulos para agrupar funcionalmente o por tipos de proceso,
los procedimientos que forman parte de un programa.
Por ejemplo, si en un programa tenemos procedimientos que se encargan del
mantenimiento de clientes y otros que realizan la gestión de facturas, podemos
crear un módulo para cada categoría de procedimiento y de ésta manera, realizar
una mejor organización del código de aplicación. Véase esquema de la figura 2.3
Inicio
Procedimiento Principal
Abrir archivo datos facturas

Obtener Factura1
Calcular Factura

Obtener Factura2
Calcular Factura

Obtener Factura3
Calcular Factura
Fin Procedimiento

Procedimiento CalcularFactura
Obtener TipoImpuesto
Sumar LíneasFactura
Calcular TotalFactura
Fin Procedimiento
Fin
Figura2.2. Ejemplo de código fuente utilizando el modelo de programación procedural

Figura 2.3. Organización de procedimientos dentro de módulos

 Programación estructurada

- 28 -
Complementando a la programación procedural aparece la programación
estructurada, consiste en un modelo de programación que utiliza un conjunto de
estructuras de control, que significan la estructura del código y disminuyen el
número de errores del programa.
La programación estructurada esta basada también en el uso de procedimientos y
módulos de código, pero también, dentro del código de un procedimiento, se
utilizarán determinadas estructuras proporcionadas por el lenguaje, que facilitarán
la codificación de los procesos.
Plantearemos el siguiente ejemplo para poder comprender mejor ésta técnica: se
requiere diseñar un proceso dentro de un procedimiento, que permita introducir un
número de facturas y las imprima, pero sólo deberá imprimirlas si el número es
menor o igual a 500.
Con las técnicas de programación anteriores, no se dispone un elemento que nos
permita determinar el número de facturas, para sí saber si se imprimen o no. Sin
embargo, mediante la programación estructurada, se puede utilizar una estructura
de decisión, que en pseudocódigo se llama If...EndIf, que realiza la mencionada
verificación, y proceda con la impresión si todo está bien. El código fuente 2.3
muestra el algoritmo para éste problema.
Inicio
Modulo Principal
Procedimiento ImprimeFac
Leer NumFactura
If NumFactura <= 500
Imprimir
End If
Fin Procedimiento
Fin Modulo
Fin
Código fuente 2.3

Cuando abordemos los elementos del lenguaje, se tratará ampliamente todos los
tipos de estructuras, por ahora, éste ejemplo sirve para que nos formemos una
idea de cómo mediante la programación estructurada, combinamos todos los
elementos que vimos hasta el momento: módulos, procedimiento y estructuras de
control, para escribir el código de nuestro programa.

 Programación Orientada a Objetos (OOP)


El modelo de programación orientada a objetos (Object Oriented Programing) se
trata de una evolución de la programación estructurada, que se basa en focalizar el
desarrollo a través de los elementos encontrados en un proceso. No en abordar el
problema desde el mismo proceso.
Esto quiere decir que ante un problema como el de mantenimientos de datos de los
clientes de una empresa, la programación estructurada aborda en primer lugar los
procesos a desarrollar: alta, modificación, baja, etc. La programación OOP por el
contrario, comienza su análisis por el elemento sobre el que van a actuar los
procesos: el objeto Cliente.
Por ello, en vez de hacer simples llamadas a procedimientos como sucede en la
programación estructurada, empleando técnicas OOP, primeramente creamos el

- 29 -
objeto en el que trabajaremos, a través de éste mismo se canalizarán todas las
llamadas a sus procedimientos, y si fuese necesario, manipular su información.
En los siguientes temas, analizaremos en profundidad, las principales
características de la programación orientada a objetos, puesto que se trata de un
gran avance en lo que a técnica de programación se refiere.

Cómo seleccionar el lenguaje de programación mas


adecuado
Existen muchos lenguajes de programación: Visual Basic .Net, C# .Net, Visual
C++, Java, Pascal, etc. Debido a ello, cabria la necesidad de preguntarse "puesto
que debemos usar un lenguaje comprensible para el ordenador al desarrollar el
programa, ¿no sería más fácil que existiera un único lenguaje con el que poder
desarrollar todos los programas?, ¿Por qué existe tal gama de lenguajes de
programación?".
Para dar respuesta podemos establecer una similitud entre varios oficios que
utilicen herramientas manuales. Cada uno de éstos oficios realiza una tarea
concreta a resolver, y para ello, el trabajador emplea un conjunto de herramientas
especializadas que le ayudan en la mencionada tarea.
Aplicaremos el mismo caso al desarrollo de programas. No resulta igual crear un
programa para realizar la facturación de una empresa, que tener que efectuar una
serie de operaciones directamente relacionadas con los componentes físicos del
equipo, o hacer cálculos científicos avanzados. Es por ello que encontramos un
lenguaje especializado en algunas de ésta áreas, gestión, matemático, hardware,
etc. Y será ese el lenguaje que debemos emplear, puesto que estará dotado de un
conjunto de un conjunto de utilidades que ayudarán al programador en los aspectos
que debe resolver.

El archivo ejecutable y sus procesos de creación


En el lenguaje de programación que hayamos elegido, una vez escrito el programa
a partir del algoritmo, se necesita tener el archivo ejecutable correspondiente.
El archivo ejecutable es aquél que necesita el ordenador para hacer funcionar el
programa, o dicho de otro modo, es la representación física de nuestro algoritmo.
Un ejecutable es un archivo por lo general con extensión EXE, que luego de una
serie de pasos obtenemos, y que describimos a grandes rasgos:

 Compilación. Lo que hace es convertir el código escrito por el


programador al llamado código objeto. Dicho código es el estado en el que
se encuentra el programa en el punto previo a la fase de obtención del
ejecutable definitivo. Según la herramienta de programación que utilicemos,
el código objeto se almacenará en forma de archivo, o será pasado
directamente a la siguiente fase de creación del ejecutable. El compilador se
emplea para la transformación del código fuente al código objeto, que es un
programa o utilidad encargada de esta labor. Veamos la
Figura 2.4

- 30 -
Código Código
Compilación
fuente objeto

Figura 2.4. Proceso de compilación del código del programa

 Enlace. Aquí se toman, por un lado, el código objeto generado por el


compilador, y por el otro, el código de rutinas de uso general que necesita el
lenguaje de programación, que por lo general se encuentra organizado en
librerías o bibliotecas de código. Todo esto, por medio de un programa o
utilidad denominado enlazador, se une para obtener el ejecutable final, un
archivo con extensión .EXE. Ver figura 2.5.

Figura 2.5. Proceso de enlace del código objeto y librerías para obtener el ejecutable

Interfaces de usuario
La interfaz de usuario es el aspecto que un programa muestra, y el modo que se
conecta con el usuario que lo ejecuta. Los tipos de interfaz de usuario que veremos
a lo largo del texto son:
 Consola. La interfaz de usuario de consola consiste en una ventana de tipo
MS-DOS o modo comando, mediante el cual, el usuario introduce las
instrucciones en el indicador de comandos del sistema. La creación de
programas de tipo consola es sencilla y rápida, debido a que el objetivo
principal de este texto es el aprendizaje de los diferentes aspectos del

- 31 -
lenguaje, la mayoría de los ejemplos realizados se harán utilizando la
consola.
 Formularios Windows. Este tipo de interfaz está basado en el entorno de
ventanas del sistema operativo Windows, permitiéndonos crear aplicaciones
basadas en formularios o ventanas, con todas las características típicas de
este tipo de programas.

Las herramientas para la creación de programas


Remontándonos a los tiempos de las aplicaciones en modo texto, bajo MS-DOS, con
los lenguajes y herramientas de programación disponibles en aquella época, los
pasos para la creación de un ejecutable descritos en un apartado anterior, deberían
ser realizados por el programador de forma manual, puesto que todos los
elementos para la creación del programa estaban separados. Disponíamos por un
lado, de un programa que consistía en un editor de código fuente, por otro, el
compilador, enlazador, librerías de utilidades, etc.
Pero la llegada y evolución de los entornos de desarrollo integrados (IDE,
Integrated Development Environment), que incorpora en una sola aplicación todos
los elementos necesarios para el desarrollo de programas, estas tareas se han
automatizado de tal manera, que el programador sólo necesita escribir el código del
programa, puesto que los pasos de compilación, enlazado y generación del
ejecutable las realiza internamente el propio entorno.
Asombrosamente, la aparición de la tecnología .Net, proporciona al programador, si
es que éste lo desea, una forma de trabajo de la manera antigua, disponiendo
también de un sofisticado entorno de desarrollo, que será seguramente, el medio
de desarrollo más habitual.
Podemos optar por cualquiera de los dos modos de trabajo al programar con Visual
Basic .Net: ya sea por utilidades separadas, ejecutadas en una ventana MS-DOS o
Windows, o también empleando Visual Basic .Net (VS.NET, como lo llamaremos a lo
largo del manual), el IDE o herramienta de desarrollo de la plataforma.

.NET Framework: el entorno de ejecución


La plataforma .NET Framework, en la que se basa el paradigma de .NET, consiste
en una plataforma multiplataforma y multilenguaje.
De forma rápida, podemos decir que, la arquitectura de .NET Framework ha sido
diseñada de modo abierto, de forma que la plataforma pueda ser ejecutada en
diferentes sistemas operativos. El entorno de ejecución de .NET se sitúa como una
capa intermedia entre el hardware y el software de la máquina, actuando de
traductor, lo que hace posible dicha integración. Ver figura 26.

- 32 -
.N ET
Framework
Windows

.NET .NET
Framework Aplicación Framework
Otros S.O. Linux

.NET
Framework
Macintosh

Figura 2.6. La plataforma .NET se sitúa como intermediario entre aplicación y sistema operativo.

De entre todas las cualidades y características, podemos destacar el hecho de que


una aplicación creada bajo .NET Framework, puede ejecutarse en diferentes
equipos, con distintas arquitecturas, sin que necesitemos recopilación, siempre y
cuando, en dichas máquinas esté instalado el entorno de ejecución .NET.
También podemos destacar, que una aplicación puede estar compuesta varias de
piezas o elementos de código, que se denominan ensamblados o assemblies, que
pudieron haber sido codificados, cada ensamblado, en un lenguaje distinto, siempre
que éstos lenguajes sean compatibles con las especificaciones de la plataforma
.NET.

El SDK de .NET Framework: las herramientas de


desarrollo
El núcleo de .NET Framework consta de un conjunto de ejecutables y librerías de
enlace dinámico, que sirven como soporte al desarrollo de programas escritos para
esta plataforma. Este paquete de elementos constituye lo que se denomina Kit de
desarrollo de software o SDK (Software Development Kit) para la plataforma .NET.
El SDK es un paquete que se distribuye de forma libre y gratuita, se lo puede
obtener en los sitios de descarga que Microsoft tiene habilitado para dicho motivo.
Primeramente, el SDK es lo único que necesita instalar el programador para
desarrollar aplicaciones que funcionen en la plataforma .NET, puesto que a parte de
las herramientas de desarrollo y librerías, se instala también la propia plataforma,

- 33 -
pero, la incomodidad de trabajar con múltiples herramientas de forma separada,
hará que en la mayoría de los casos, elijamos la programación usando el entorno
de desarrollo de aplicaciones de .NET: Visual Studio .NET
Visual Studio .NET es un avanzado IDE para el desarrollo de programas basados en
.NET Framework, que hace un uso de forma transparente de todas las utilidades del
SDK de .NET, y de esta manera, liberando al programador, de la necesidad de tener
que usar y configurar manualmente todo el conjunto de aplicaciones del SDK.
Dichas ventajas, sin embargo, tienen un precio, puesto que mientras el SDK es un
paquete gratuito, Visual Studio .NET es un producto comercial, por que se debe
pagar la licencia de uso.

- 34 -
Practica 1.-
Hola mundo, desde Visual Basic .NET
Un programador, al tener enfrente a un nuevo lenguaje, lo que acostumbra a hacer
es una de las primeras pruebas para realizar un pequeño programa que muestre,
mediante la interfaz de usuario correspondiente, el mensaje de "Hola mundo".
Fieles a la tradición, y puesto que le programador puede dar sus primeros pasos en
este nuevo mundo de la programación, escribiremos el primer programa usando el
lenguaje Visual Basic .NET

El compilador de VB.NET
Como se comentó antes, una vez escrito el código fuente de nuestro programa, se
debe utilizar una herramienta llamada compilador, la que tomará nuestro código y
lo transformará a código objeto o directamente ejecutable.
En esta primera prueba, crearemos la aplicación de un modo artesanal, utilizando el
Bloc de notas como editor de código, y el compilador del lenguaje en una ventana
MS- DOS. De esta manera, el lector se irá formando una idea del proceso que debe
seguir, y que Visual Basic .NET lleva a cabo de forma automática. Posteriormente,
se verá este mismo ejemplo pero ya desarrollado desde el IDE.
En el Bloc de notas escribiremos las sentencias mostradas en código fuente 2.4.
Imports System
Module General
Public Sub Main()
Console.WriteLine("HolaMundo")
End Sub
End Module
Código fuente 2.4

Podemos decir, describiendo el código a grandes rasgos, que las primeras líneas
establecen una referencia a una librería de la plataforma .NET Framework, que
contiene elementos del lenguaje necesarios para que el programa sea ejecutado.
A continuación, entre las sentencias Module...End Module se define un módulo de
código, con el nombre General, el cuál se trata de un contenedor de rutinas de
código, y dentro de éste módulo, precisamente, se escribirá un procedimiento entre
las sentencias Sub...End Sub, con el nombre de Main( ), en el que se hará uso del
objeto Console, llamando a su método WriteLine(), al que se pasa una cadena de
caracteres con el texto a mostrar. Este texto será mostrado en una ventana MS-
DOS o de consola, como también será denominado en éste manual.
Si no es comprendido el código de éste ejemplo, no se debe preocupar, se irá
viendo progresivamente todos los elementos que componen un programa, hasta
comprender todos los detalles; por ahora, sólo basta con escribir el ejemplo y
guardarlo en un archivo con el nombre de Saludo.VB, aunque esto no es
obligatorio, puesto que se puede utilizar la extensión que el programador elija.
Necesitamos luego, desde una ventana en modo comando o sesión MS-DOS,
ejecutar el compilador de Visual Basic .NET para que creemos a continuación el
ejecutable de nuestro ejemplo.

- 35 -
El compilador del lenguaje es un archivo con el nombre VBC.EXE (Visual Basic
Compiler), que se ejecutará , pasándole como parámetro el archivo con el código
fuente a compilar.
Para que evitemos la tediosa tarea de localizar la ruta en la que se encuentra el
archivo VBC.EXE, al instalar VS.NET se agrega un elemento entre el conjunto de
opciones de ésta herramienta, que se trata de un acceso directo a una ventana MS-
DOS, en la ya se encuentran definidas las rutas hacia todas las herramientas
necesarias, que se requerirá usar para desarrollar aplicaciones en .NET Framework.
Para abrir esta ventana, se debe seleccionar la ruta del sistema de menús
siguiente: Inicio + Programas + Microsoft Visual Studio .NET 7.0 + Visual Studio
.NET Tools + Visual Studio .NET Command Prompt.
Una vez abierta esta ventana MS-DOS, tecleando VBC.EXE y pulsando Enter,
aparecerá una lista con las opciones del compilador de VB.NET. Ver figura 2.9

Figura 2.9 Ventana MS-DOS con las ventanas del compilador del lenguaje VB.NET

Mostramos algunas de las principales opciones del compilador en la tabla 2.2, pero
en éste ejemplo sencillo, no será necesario el uso de ninguna opción.
Opción Descripción
/out:<archivo> Nombre del archivo de salida (tomando del primer archivo fuente, si no
se especifica lo contrario)
/target:exe Constituye un ejecutable de consola. Esta es la opción por defecto (
forma corta: /t:exe)
/target:winexe Constituye un ejecutable windows ( forma corta: /t:winexe)
/target:library Constituye una librería ( forma corta: /t:library)
/target:module Constituye un módulo que puede añadirse a otro ensamblado (forma
corta: t:/module)
/reference:<lista_archivos> Referencia a metadatos de los ensamblados/archivos especificados
(forma corta: /r)
/define:<lista_símbolos> Define símbolos de compilación condicional ( forma corta: /d)
/optionexplicit[+|-] se requiere la declaración explícita de las variables

- 36 -
/optionstrict[+|-] Exige una semántica de lenguaje estricta
/rootnamespace:<nombre> Especifica el espacio de nombres de la raíz para todos los tipos de
declaraciones
/optioncompare:binary Especifica comparaciones de cadenas de estilo binario. Activado de
forma predeterminada
/optioncompare:text Especifica comparaciones de cadenas de estilo binario.
/main:<class> especifica la clase o módulo que contiene Sub Main. También puede ser
una clase que hereda de System.Windows.Forms.Form (forma corta: /m)
Tabla 2.2 Opciones del compilador del lenguaje VB.NET

Para compilar nuestro primer programa, debemos situarnos en el directorio en el


que hayamos guardado nuestro archivo con el código fuente del ejemplo, y teclear
en el indicador de comandos de esta ventana, la instrucción del código fuente 2.5.
VBC Saludo.VB
Código fuente 2.5.

Aquí ejecutamos el compilador VBC.EXE (no es necesario especificar la extensión


del compilador), luego pasamos el nombre del archivo con el código fuente a
compilar, en éste caso SALUDO.VB. Aquí obtenemos un nuevo archivo SALUDO.EXE
que es el ejecutable de nuestro programa. Al teclear SALUDO en el indicador de
comandos de la ventana, y pulsar Enter, el programa será ejecutado. Como
resultado de ésta ejecución es la visualización del mensaje en la ventana de la
consola, con el que se finaliza el proceso de creación de nuestro primer programa
en VB.NET. Ver figura 2.10

Figura 2.10 Ejecución del programa Hola Mundo, en la ventana MS-DOS

- 37 -
El entorno de desarrollo integrado (IDE) de Visual Studio
.NET
Como ya se dijo anteriormente, el IDE es una aplicación que agrupa un gran
número de utilidades, tales como editores, asistentes, ayudas, etc. de manera que
todo lo que el programador necesita para realizar su trabajo, lo encuentre reunido
en un sólo producto, de esta manera facilitando la creación de programas para un
determinado lenguaje.
De eso se trata el trabajo del IDE de Visual Studio .NET

Figura 2.11 Entorno de desarrollo de Visual Studio .NET

Proyectos en Visual Studio .NET


Debemos crear un proyecto para desarrollar un programa desde el IDE de VS .NET,
que se trata de un contenedor de todos los elementos que forman parte de una
aplicación de .NET: archivos de código, recursos, imágenes, etc.

Creación de un proyecto
Lo que debemos hacer para crear un nuevo proyecto es: situarnos en la página de
inicio del IDE, pulsamos el botón Nuevo Proyecto. También podemos hacerlo a
través de la opción del menú del propio IDE que es la siguiente: Archivo + Nuevo +
Proyecto, lo que dará como resultado la ventana Nuevo proyecto.

- 38 -
Debemos tener en cuenta que .NET Framework es una plataforma para el desarrollo
de programas de varios tipos de lenguajes de programación: Visual Basic .NET,
Visual C# .NET, Visual C++ .NET, J#, y varios otros que están en proceso de
desarrollo, para cumplir con las especificaciones del entorno de ejecución de .NET.
Por consiguiente, en la ventana de creación de proyectos de VS .NET, se debe
elegir en primer lugar, en el panel izquierdo, el lenguaje en el que se escribirá el
programa, y en el panel derecho a continuación, el tipo de proyecto a desarrollar,
de la lista de plantillas disponibles.
Es a partir de ahora que en todos los programas que se desarrollará, y hasta que
no se indique lo contrario, que al crear un proyecto en VS .NET, se seleccionará
como tipo de proyecto: Proyectos de Visual Basic, y como plantilla: Aplicaciones de
consola, como se muestra en la figura 2.12

Figura 2.12 Ventana para la creación de un nuevo proyecto en el IDE

En esta fase de la creación del proyecto, es también necesario darle un nombre al


mismo, y también seleccionar un directorio del equipo en el que se crearán los
archivos que compondrán el programa. Dejaremos como nombre el que hay por
defecto: ConsoleApplication1. Completados estos pasos, pulsaremos el botón
Aceptar, lo que creará un nuevo proyecto con interfaz de consola.

El editor de código fuente


Cuando se crea un nuevo proyecto de consola, también se crea un archivo de
código fuente llamado Module.VB, el cuál contiene un módulo de código (Module), y
un procedimiento o rutina de código vacía (Sub) con el nombre Main(). En la
ventana principal del IDE se puede observar que, hasta ahora ocupada por la
página de inicio, se añade una nueva pestaña en la que se mostrará el editor de
código fuente con el código generado de forma automática por el IDE; dicha
ventana será nuestro principal elemento de trabajo de aquí en adelante, puesto que
en ella se escribirá las sentencias que formarán parte de nuestro trabajo. Ver figura
2.13

- 39 -
Figura 2.13. Código generado por el IDE al crear un nuevo proyecto de consola.

El código del programa


Se ve de forma clara que, del código base que ha generado VS.NET, el
procedimiento Main( ) representa al procedimiento principal o punto de ingreso al
programa, porque es la primera rutina que se ejecutará cuando iniciemos el
programa desde el IDE o invoquemos al archivo ejecutable físico.
A continuación, debemos situarnos sobre la ventana del editor de código y añadir
dentro del procedimiento Main( ) el mensaje que visualizaremos en la consola,
como hicimos en el ejemplo anterior, cuando creamos el programa con el
compilador en modo comando.
Aquí no será necesaria la instrucción Imports System que vimos en el ejemplo
anterior, puesto que al trabajar con el IDE lo incluye internamente. Para ejecutar el
ejemplo, lo haremos utilizando la opción de menú del IDE Depurar + Iniciar
Depuración. Ver el código fuente 2.6.
Module General
Public Sub Main()
Console.WriteLine("HolaMundo")
End Sub
End Module

Código fuente 2.6.

Sin embargo, en este caso, el resultado no es el indicado, puesto que al ejecutar el


programa desde VS.NET, es el propio IDE quien se encarga de abrir una ventana de
consola y mostrar el mensaje, pero a continuación, se cierra la ventana, sin darnos
tiempo para comprobar el texto visualizado. Esto es porque no se ha establecido
ningún tipo de parada en la ejecución.
La solución a éste problema se la puede obtener por dos medios: el más simple
consiste en depurar por medio de la opción del menú Depurar + Iniciar sin depurar,

- 40 -
que agrega una pausa antes de finalizar la ejecución, dando lugar así a la
visualización de la ventana de la consola. Ver figura 2.14.

Figura 2.14. Ejecución del programa Hola mundo con parada

La otra manera es ejecutando el método Read( )de objeto Console, luego de


mostrar el mensaje en la ventana. El código fuente 2.7 muestra otra vez el ejemplo
con éste pequeño cambio.
Module Module1

Sub Main()
Console.WriteLine("Hola Mundo")
Console.Read()

End Sub

End Module
Código fuente 2.7.

La línea Console.Read( ) obliga al programa a realizar una parada en su ejecución,


poniendo el mismo a la espera de que el usuario pulse una tecla en la ventana de
consola. Al pulsar Enter, continuaremos con la ejecución del programa luego de la
mencionada instrucción, y como no existen más líneas de código para ejecutar,
finalizará.
Ahora, para ejecutar el programa desde el IDE, podemos usar la opción del menú
Depurar + Iniciar. En la figura 2.15 se verá nuestra versión de Hola mundo en
ejecución.

- 41 -
Figura 2.15. Ejecución del programa Hola mundo, creado desde VB.NET

El explorador de soluciones
Una solución en VS.NET es un componente del IDE el cuál hace de contenedor de
proyectos. Por defecto, al crear un proyecto, se crea también una solución que lo
contiene, que tiene el mismo nombre del proyecto; tenemos la opción de añadir
más proyectos a la solución o dejarla como solución de proyecto único.
Vemos de manera organizada en la ventana del IDE Explorador de soluciones, a la
solución actualmente abierta, con los proyectos que contiene, y a su vez, los
elementos que componen cada proyecto, principalmente, el archivo MODULE1.VB,
puesto que el resto no es necesario cambiarlos. La figura 2.16 muestra esta
ventana con los elementos del programa que estamos escribiendo.

Figura 2.16. Explorador de soluciones del IDE.

La estructura de archivos del proyecto


Al momento de crear un proyecto utilizando VS.NET, se genera de manera
automática en disco, partiendo de la ruta especificada en la ventana de creación del
proyecto, una estructura de directorios que contiene los archivos que forman parte
del proyecto. La figura 2.17 muestra la estructura que corresponde al programa del
ejemplo que escribimos.

- 42 -
Figura 2.17. Estructura de archivos de un proyecto escrito en VB.NET

Si hacemos cambios en la ventana del editor de código, se deben guardar en su


archivo de código asociado pulsando CTRL+S o, si se modificó diferentes
elementos, y se requiere grabar todos los cambios a la vez, se selecciona la opción
del menú del IDE Generar + Generar.
Un proyecto VB.NET está compuesto por un conjunto de archivos de distintos tipos,
algunos de éstos relacionaremos a continuación:
VB. Código fuente escrito en lenguaje Visual Basic.
VBPROJ. Proyecto de VB. El cual contiene todos los elementos que forman parte de
un proyecto: archivo de código, referencias, etc.
SLN. Solución. La solución es el medio que usa VS.NET para agrupar varios
proyectos escritos en el mismo o en diferentes lenguajes de los que integran la
plataforma .NET.
VBPROJ.USER. Información sobre las opciones del usuario del proyecto.
EXE. Aplicación ejecutable.
PDB. Información sobre depuración de la aplicación.
Al escribir un programa con VS.NET, en el directorio bin del proyecto que genera el
archivo ejecutable, contiene nuestra aplicación, y que por el momento, es lo único
que necesitamos para ejecutar el programa en cualquier otra computadora, que por
supuesto, también tenga instalada la plataforma .NET Framework. Esto nos evitará
problemas de instalación y nos ahorrará tiempo en su distribución.
Para abrir un proyecto dentro del IDE, lo más rápido es hacer doble Clic sobre el
archivo de proyecto o solución; con esto abriremos VS.NET y cargará el proyecto-
solución en el IDE, con lo que ya se podrá comenzar a trabajar.
Si ya está abierto el IDE, podemos usar la opción del menú Archivo + Abrir +
Proyecto, o Archivo + Abrir solución. De cualquiera de las dos maneras se abrirá un
cuadro de diálogo para seleccionar el proyecto o solución a cargar en el IDE para su
edición

Sistema de ayuda
El MSDN (Microsoft Developer Network), es la documentación de ayuda de la
plataforma Microsoft .NET y está accesible en cualquier momento desde el propio
VB.NET
Éste es un sistema de ayuda contextual, lo que significa que si requerimos la ayuda
desde cualquier lugar del IDE que nos encontremos, se intentará buscar un
documento en la ayuda relacionado con el lugar en el que nos encontramos
situados.

- 43 -
Como ejemplo podemos decir, si estamos en la ventana del editor de código, y el
cursor está sobre la palabra clave Sub, al pulsar F1 para requerir la ayuda, se
abrirá una nueva pestaña en la ventana principal del IDE, que corresponde a la
ayuda, la cuál nos mostrará la documentación que existe sobre dicho elemento del
código, como vemos el la figura 2.18.
En caso que no exista información para el elemento que se ha solicitado ayuda, se
puede situar el cursor sobre la pestaña desplegable Ayuda dinámica, que se
encuentra en uno de los laterales del IDE.
Esta pestaña se abrirá en el momento que nos situemos sobre ella y que a través
de los botones de su barra de herramientas, se puede efectuar diferentes tipos de
búsqueda en la documentación del MSDN, a través de un índice por palabra o por
combinación de palabras. Ver figura 2.19.

Figura 2.18. Ayuda de Visual Studio .NET

- 44 -
Figura 2.19. Ventana de ayuda dinámica de Visual Studio .NET

- 45 -
Módulo 3

Elementos básicos del


lenguaje

- 46 -
Componentes de un lenguaje de programación.
Los lenguajes de programación están compuestos de varios elementos que son
usados para escribir las instrucciones y expresiones que tiene un programa. A parte
de dichos elementos, existen varias reglas para construir expresiones, las que están
encargadas de decidir si alguna de las líneas de código está bien escrita, de manera
que la ejecución del programa sea de manera correcta. Este conjunto de normas y
reglas establecidas para que la escritura sea correcta, se denomina también
sintaxis.
En este manual explicaremos los conceptos y aspectos elementales de la
programación, para que puedan ser aplicados a la mayoría de los lenguajes,
poniendo a Visual Studio .NET como el lenguaje de programación modelo. Serán
examinadas también las características particulares de Visual Basic .NET, que lo
ayudarán a elegir a este lenguaje como herramienta de trabajo, para obtener un
mayor partido de ella.
Mostraremos ahora, de forma esquemática, los elementos que la mayoría de los
lenguajes tienen, los cuales comentaremos ampliamente durante todo el texto.
Datos
 Simples
- Numérico
- Caracter
- Fecha
- Lógico
 Compuestos
 Establecidos por el programador
Identificadores
 Variables
 Constantes
 Rutinas de procedimientos
Palabras Reservadas
 Comandos (Instrucciones o sentencias)
 Funciones propias del lenguaje
 Objetos propios del lenguaje
Operadores
 Aritméticos
 Relacionales
 Lógicos
Expresiones
Estructuras de control
 Selección
 Repetición
- Contadores
- Acumuladores
- Interruptores

Datos
Para denominar a los datos podemos decir que es la información que usa un
programa para poder realizar operaciones. Dependiendo de la información que

- 47 -
contenga, los datos se clasifican en simples, compuestos y establecidos por el
programador.

 Simples
Es el que está formado por una sola unidad de información, que dependiendo del
contenido de dicha información, los datos simples se subdividen en los siguientes
tipos: numérico, caracter, fecha y lógico.
- Numéricos
Este tipo de dato contiene un número, el cuál puede ser entero (es decir, sin parte
decimal) o real (con parte decimal).
El código fuente 3.1 muestra algunos ejemplos de los números enteros, el código
fuente 15 muestra ejemplos de números reales
10
350
520
-75
Código fuente 3.1

El código fuente 3.2 muestra algunos ejemplos de números reales


4.75
240.64
-35.55
Código fuente 3.2

Es importante mencionar que debido a la naturaleza de las computadoras, debemos


tener en cuenta que, para representar un número real en un programa, como
observamos antes, debemos usar como separador decimal el punto y no la coma.
- Caracter
El que es de tipo caracter, está formado por un único elemento, pudiendo ser
cualquier letra, símbolo o número, teniendo en cuenta que los números que son
representados como caracteres no pueden ser utilizados para realizar operaciones
aritméticas.
Para representar datos de este tipo en un programa, debemos usar los llamados
delimitadores, entre los que se encierra el caracter correspondiente, en la mayoría
de los lenguajes de programación, suelen ser las comillas simples o dobles, como
se observa en el código fuente 3.3
“b”
“?”
“54”
“*”
Código fuente 3.3

Al desarrollar programas, es muy frecuente agrupar varios datos de este tipo, así
llegando a formar lo que en programación se denomina como cadena de caracteres.
Resulta algo confuso lo último, puesto que una cadena es un dato compuesto y no
simple, pero en determinados lenguajes como VB .NET por ejemplo, es permitido
tratar a las cadenas como datos simples y no compuestos. El código fuente 3.4
muestra algunos ejemplos de lo mencionado.

- 48 -
“el reloj marca las siete”
“debemos apagar el monitor antes de salir”
“el monto de la factura es $ 450”
Código fuente 3.4

- Fecha
Las fechas también son tratadas como una unidad de información por el lenguaje,
puesto que aunque se puedan combinar números, letras y símbolos para ser
representados, de forma interna, se almacenan con un valor numérico (Long o
entero largo)
Los delimitadores usados para las fechas son los símbolos: numeral (#), o las
comillas dobles ("). Dependiendo del delimitador que usemos para encerrar una
fecha, debemos tener en cuenta que se debe especificar en primer lugar el mes o el
día de dicha fecha. Vemos el código fuente 3.5.
Fecha: 10 Agosto 2002
#8/10/2002#  primero el mes
“10/08/2002”  primero el día
Código fuente 3.5

- Lógico
Este representa uno de dos valores posibles: Verdadero o Falso, que en Visual Basic
.NET se indican como True o False respectivamente.

 Compuestos
Un dato compuesto está formado, por varios datos de tipo simple. Como se
mencionó antes, una cadena es un dato compuesto (por datos simples de tipo
caracter), aunque en algunos lenguajes se traten como simples

 Establecidos por el programador


Es esta categoría están la estructura (Structure), que se trata de un tipo especial
de dato compuesto de varios de los tipos de que existen en el lenguaje; también
está el tipo enumerado (Enum), que es una lista de valores numéricos a los que
asociamos un descriptor lineal. Estos dos tipos nos permiten hacer la combinación
de tipos de datos de manera más compleja que los de tipo compuesto.
Ambos tipos de datos, es decir, los compuestos y los establecidos por el
programador, trataremos más adelante y con mayor profundidad, puesto que antes
es recomendable conocer algunos aspectos del lenguaje previamente, antes de
profundizar en lo anterior mencionado.

Identificadores
Un identificador es tan sólo un nombre que el programador asigna a ciertos
elementos del programa, como ser: variables, constantes, rutinas de código, etc.
Son asignados para poderlos reconocer durante el desarrollo del mismo.
Este nombre debe comenzar por una letra y no puede ser igual que una palabra
reservada del lenguaje, tampoco contener caracteres especiales como operadores
aritméticos, relacionales, etc.
Se puede usar cualquiera de nuestra elección, pero es recomendable que el nombre
del identificador esté relacionado con su contenido, de manera que durante la

- 49 -
revisión del código del programa, sepamos de forma rápida lo que contiene tan sólo
viendo el nombre.

Palabras reservadas
Las palabras reservadas son todas aquellas que forman parte del lenguaje de
programación, por ejemplo, instrucciones, estructuras de código, las funciones
propias del lenguaje, objetos, etc. A éste tipo de palabras no se la puede usar como
identificadores, puesto que son usadas internamente por el lenguaje.
Algunos ejemplos de palabras reservadas son: Dim, Sub, Function, Integer, For,
Public.

Estructura de un programa
Como explicamos antes, en el tema que describimos a la primera aplicación de
VB.NET, los elementos mínimos que debe tener toda aplicación escrita en éste
lenguaje, (por lo general, todos los lenguajes) es un módulo de código, y un
procedimiento de inicio o entrada al programa, en VB.NET tiene el nombre de Main(
), todo esto contenido en un archivo de código con extensión .VB.
Veremos en un diagrama, la estructura en niveles de un programa. Ver figura 3.1.
Si el programa que ejecutaremos es de tamaño pequeño, el procedimiento de
entrada del mismo, irá a contener todo el código necesario, Esto no es muy
frecuente sin embargo, por lo general los programas tienen una cantidad de código
considerable, que nos obliga a separarlo en diferentes rutinas. Es por ello que el
procedimiento Main( ) contiene por lo general, código para inicializar valores en el
programa, y hacer llamadas a otros procedimientos entre los que se encuentra
repartido el resto del código.
Puesto que los siguientes ejemplos que son mostrados en el manual estarán
basados en programas simples, por ahora sólo necesitamos usar el procedimiento
Main( ).

- 50 -
Figura 3.1. Estructura en niveles de los elementos de un programa en VB.NET

Ubicación del código en el programa


El código de un programa está ubicado en rutinas de código o procedimientos, en
los que escribiremos las instrucciones que sean necesarias para resolver un
determinado problema. Obviamente, dependiendo de la complejidad del problema,
y de la cantidad de situaciones a resolver, un programa tendrá un número
determinado de procedimientos.
A los procedimientos los trataremos con más profundidad en próximos temas, por
ahora tan sólo se debe saber que para declarar un procedimiento se tiene que usar
la palabra clave Sub, y a continuación el nombre del procedimiento, luego
escribiendo las instrucciones que son necesarias y para finalizar dicho
procedimiento usar la palabra reservada End Sub, como se muestra en el código
fuente 3.6
Sub Calcular()
Instrucción1
Instrucción2
Instrucción3
Instrucción4
Instrucción5
.....
.....
.....
Instrucción
End Sub
Código fuente 3.6

Al crear una aplicación VB.NET de tipo consola usando VS.NET, es el propio IDE
quien se encarga de crear por nosotros la estructura básica del programa, es decir,

- 51 -
crea un archivo de código conteniendo un módulo que tiene el procedimiento de
entrada, solamente falta el código del programador.
Los elementos que componen una aplicación, todos son organizados por VS.NET
bajo en concepto del proyecto. Un concepto reúne los archivos de código de la
aplicación, recursos, referencias globales de la plataforma .NET, etc. Se sugiere que
el lector consulte el tema dedicado a la implementación de programas en .NET,
para obtener una descripción general de los mencionados tipos de archivo.
Para las siguientes pruebas, creamos desde el IDE un nuevo proyecto de tipo
consola.

Comentarios
Es bueno incluir comentarios aclaratorios en el transcurso del código, éstos sirven
como documentación posterior cuando se revise el código para corregir posibles
errores, o porque se tenga que ampliar el programa.
En VB.NET se usa el caracter de comilla simple ( ' ) para poder escribir notas dentro
del programa. Una vez incluida la comilla simple, todo lo siguiente, será tenido en
cuenta como comentario y no como instrucciones ejecutables. Ver código fuente
3.7.
Module Module1
Sub Main()
' comenzaremos a ver el código
instrucción1()
instrucción2()' este comentario va a continuación de una línea
' esta es la última instrucción
instrucción3()
End Sub
End Module
Código fuente 3.7.
Indentación del código
Llamada también sangría, ésta es una técnica para escribir el código del programa,
y consiste en poner las líneas del código a diferentes niveles de profundidad o
tabulación, de manera que sea fácil la lectura al ser revisado.
Cuando creamos una aplicación con VS.NET, comprobamos como el propio editor de
código fuente indenta el código según lo que escribimos, siendo una práctica muy
ligada a la estructura de control, puesto que permite ver rápidamente las
instrucciones que estas estructuras contienen, y situarnos en las líneas necesarias,
éste tipo de escritura lo veremos próximamente.
Mostramos en el código fuente 3.8 unas líneas en pseudocódigo que contienen
estructuras y código dentro de las estructuras, de manera que puede comprobar el
lector manera de realizar la tabulación.

Inicio
„ Líneas con indentación al mismo nivel
Instrucción1
Instrucción2

„ Inicio de la estructura
EstructuraA <Expresión>

- 52 -
„ Líneas indentadas a un nivel de profundidad
InstrucciónA1
InstrucciónA2

„ Inicio estructura anidada


EstructuraB <Expresión>
„ Líneas indentadas a segundo nivel de profundidad
InstrucciónB1
InstrucciónB2
FinEstructuraB

„ según salimos de las estructuras


se vuelve a subir niveles de indentación
InstrucciónA3
InstrucciónA4
Fin EstructuraA

Instrucción3
Instrucción4

Fin

Código fuente 3.8

Cuando se quiera indentar una lía simple, debemos situarnos en el comienzo de la


misma y pulsar TAB, para quitar la tabulación pulsaremos TAB + MAYÚS.
Como se comentó antes, el entorno de desarrollo de VS.NET indenta por defecto y
de manera automática el código según lo vamos escribiendo.
Si se desea variar algún aspecto a este comportamiento del editor de código, se
debe configurar las características de indentación
Establecidas en el IDE seleccionando la opción del menú Herramientas + Opciones,
luego se selecciona la carpeta Editor de texto + Basic, ésta contendrá la
configuración para el editor de texto correspondiente a cada lenguaje.
Si hacemos Clic en el elemento Tabulaciones se mostrarán las propiedades de
indentado, las cuales se pueden modificar para ser adaptadas a nuestras
preferencias. Vemos la figura 3.2.

Figura 3.2. Propiedades de indentado en el IDE de Visual Studio .NET

- 53 -
Manejo de la consola del sistema
Antes de pasar a trabajar con los elementos del lenguaje daremos unos breves
apuntes sobre el manejo del objeto Console, el cuál representa a una ventana MS-
DOS, símbolo del sistema, o consola, como será llamado principalmente en este
manual.
En el capítulo anterior, ya tuvimos un primer contacto con la consola, al realizar
nuestro primer programa, el conocido Hola Mundo. Pero, en éste apartado daremos
unas indicaciones básicas de uso, puesto que la consola será el elemento principal
que usaremos para mostrar y obtener datos por pantalla. Por su simplicidad de uso
y rapidez de ejecución, la consola se convierte en el elemento ideal para realizar
pruebas, y en nuestro caso, mostrar ejemplos.
Aunque la consola es un objeto, no se mostrará aquí ni describiremos en qué
consiste los objetos ni su uso con detenimiento, es recomendable que el lector de
los temas específicos sobre programación orientada a objetos en el manual.
También, los conceptos sobre variables, parámetros, concatenación, y otros
aspectos del lenguaje que son usados en estos ejemplos introductorios a la consola,
se explicarán más adelante, en los apartados que corresponden a los elementos del
lenguaje.

- 54 -
Practica 2: Visualizar información en la consola
Para escribir texto se llamará al método Write( ) o WriteLine( ) del objeto Console.
Como parámetros de estos métodos, es decir, entre los paréntesis que los
acompañaran, se situarán la información que se desea mostrar: una cadena,
variable, o expresión. Veamos el ejemplo en el código fuente 3.9.
Module Module1
Sub Main()
Dim UnValor As String
UnValor = "algo más de texto"

' esta cadena va en una línea


Console.WriteLine("Hola Mundo")

' ahora mostramos una variable


Console.WriteLine(UnValor)

' Las siguientes cadenas se ponen juntas


Console.Write("Coche")
Console.Write("Tren")

' Aqui añadimos una línea en blanco


Console.WriteLine()
End Sub
End Module
Código fuente 3.9

La diferencia entre Write() y WriteLine() consiste en que mediante el primero, todas


las llamadas que se haga a este método escriben el texto seguido, en tanto que el
último lo hace en líneas separadas. En la figura 3.3 se ve el resultado del ejemplo
anterior.

Figura 3.3. Escritura de texto con el objeto Console

Al escribir un texto en la consola, lo que se desea es combinar una cadena de


caracteres con el contenido de una variable, se puede optar por dos técnicas.

- 55 -
Por un lado, se puede concatenar o lo que es igual unir la cadena a la variable
mediante el operador de concatenación del lenguaje (&) Ver código fuente 3,10
Module Module1
Sub Main()
Dim UnValor As Integer
UnValor = "al parque"
Console.WriteLine("Vamos de paseo " & UnValor)
End Sub
End Module
Código fuente 3.10

El resultado se ve en la figura 3.4

Figura 3.4. Concatenar valores al mostrarlos en la consola.

La otra manera es usar parámetros sustituibles, indicando en la cadena los lugares


en los que se desea incluir el contenido de las variables que se necesitan.
Por ejemplo, suponiendo que en la cadena “Como están, voy a un coche”, se desea
insertar los valores “conducir” y “gris”, que están situados en variables, de manera
que la cadena resultante sea “Como están, voy a conducir un coche gris”.
Para resolver este problema, en la cadena debemos incluir unos marcadores que
indican que en este punto lo que se hará es sustituir el marcador por una variable,
y además el número de orden de la variable, tal como se situará al llamar al
método WriteLine(). Los marcadores son los símbolos de llaves usando de una
manera similar a la siguiente: {0}

Al llamar a WriteLine() se sabe que se le pasa como parámetro el valor a mostrar,


pero se puede pasar más parámetros separados por comas, como pueden ser
variables; estos parámetros serán usados para sustituirse en la cadena pasada
como primer parámetro. La figura 3.5 muestra un esquema del uso de este
método.

- 56 -
Resultado: Como están, voy a conducir un coche gris

Figura 3.5. Esquema de parámetros sustituibles al usar el objeto Console

Lo que se comprueba es que a continuación de la cadena pasada en WriteLine(), la


primera variable será sustituida por el marcador {0}, la siguiente en {1}, así
sucesivamente.

- 57 -
Practica 3: Obtener información de la consola
Para tomar el texto tecleado en el indicador de comandos de la ventana de la
consola disponemos del método ReadLine(), que lo que hace es devolver una
cadena que se puede pasar a una variable para su tratamiento posterior. En el
ejemplo del código fuente 3.11 se ve cómo actúa.
Module Module1
Sub Main()
Dim UnValor As String
Console.WriteLine("Escribir algo aqui")
UnValor = Console.ReadLine()

Console.WriteLine("Escribimos el siguiente texto")


Console.WriteLine(UnValor)
End Sub
End Module

Código fuente 3.11

La figura 3.6 muestra el resultado

Figura 3.6 Obtención de texto escrito en la consola.

- 58 -
Variables
Una variable es aquél elemento dentro de un programa que su labor es guardar un
valor, éste valor podrá cambiar durante el funcionamiento del programa (es por ello
que recibe el nombre de variable). El contenido de la variable no es más que una
posición en la memoria del ordenador que almacena el valor, y debido a que la
memoria es un medio de almacenamiento no permanente, cuando finaliza el
programa, el valor se pierde, por lo que se puede deducir que el uso de la variable
se limita al tiempo de ejecución del programa. Para manejar y asignar nombre a
una variable, se emplea un identificador.

Declaración
La declaración de una variable es el proceso por el cuál creamos e inicializamos una
variable en el programa.
Para declarar una variable usaremos la palabra clave Dim, seguida del identificador
o nombre que se da a dicha variable. Ver código fuente 3.12
Module Module1
Sub Main()
Dim MiValor
End Sub
End Module

Código fuente 3.12

Denominación
Como se comentó en el apartado de identificadores, el nombre que se puede
asignar a una variable deben seguir ciertas reglas; deben comenzar por letra, no
puede ser una palabra reservada, no incluir caracteres especiales del lenguaje. En
código fuente 3.13 muestra algunos ejemplos de declaraciones
Sub Main()
' declaraciones correctas
DimB()
Dim Hola
Dim ABCD
Dim NuevoValor
Dim Es_otro
' declaraciones incorrectas
Dim 7Nuevo
Dim Avan-zar
Dim End „ este es incorrecto
Dim Va-bien
End Sub
Código fuente 3.13

Como se puede comprobar en este código fuente, y se explicó anteriormente, se


incluyen comentarios en el código usando la comilla simple („), seguida del
comentario correspondiente.

Lugar de declaración

- 59 -
Se puede declarar variables en muy diversos lugares del código. El punto donde se
declara una variable será determinante a la hora del ámbito o accesibilidad a esa
variable desde otros puntos del programa. Por el momento, y ciñéndonos a la
declaración de variables en la cabecera o inicio del procedimiento, para dar mayor
claridad al mismo. Luego de la declaración, se escribe el resto de las instrucciones
del procedimiento.

Tipificación
La tipificación de una variable es la operación por la cuál, al declarar una variable,
se especifican la clase de valores o tipo de datos se podrá almacenar en dicha
variable.
En VB.NET se usa la palabra clave As seguida del nombre del tipo de datos, para
establecer el tipo de una variable. Ver código fuente 3.14
Sub Main()
Dim Valor As String ' cadena de caracteres
Dim Cuenta As Integer ' numérico entero
Dim FhActual As Date ' fecha
End Sub

Código fuente 3.14

La tabla 3.1 muestra la relación de tipos de datos disponibles en el lenguaje


Tipo de dato Tipo Tamaño de Rango de valores
en VB.NET correspondiente en ocupación
el entorno de .NET en
Framework memoria
Boolean System.Boolean 1 byte True o False (Verdadero o Falso)
Byte System.Byte 1 byte 0 a 255 (sin signo)
Char System.Char 2 bytes 0 a 65535 (sin signo)
Date System.DateTime 8 bytes 1 de Enero de 1 a 31 de Diciembre de
9999
Decimal System.Decimal 12 bytes +/-
79.228.162.514.264.337.593.543.950.335
sin punto decimal; +/-
7,9228162514264337593543950335 con
28 posiciones a la derecha del signo
decimal; el número mas pequeño distinto
de cero es
0,000000000000000000000000001

Double System.Double 8 bytes -1,7976931348623E308 a -


(Punto 4,9406564584124E-324 para valores
flotante con negativos; 4,9406564584124E-324 a
precisión 1,7976931348623E308 para valores
doble) positivos

Integer System.Int32 4 bytes -2,147,483,648 a 2,147,483,647


Long System.Int64 8 bytes -9,223,372,036,854,775,808 a
(entero 9,223,372,036,854,775,807
largo)

- 60 -
Short System.int16 2 bytes -32,768 a 32,767
Single System.Single 4 bytes -3,402823E38 a -1,401298E-45 para
(Punto valores negativos; 1,,401298E-45 a
flotante con 3,402823E38 para valores positivos
precisión
simple)
Object System.Object 4 bytes Cualquier tipo
String System.String 10 bytes Desde 0 a unos 2,000 millones de
(cadena de +(2* caracteres Unicote
longitud longitud de
variable) la cadena)
Estructura Hereda de Suma de Cada miembro de la estructura tiene un
(tipo de System.Value Type los intervalo de valores determinados por su
dato tamaños tipo de datos e independiente de los
definido por de los intervalos correspondientes a los demás
el usuario) miembros miembros
de la
estructura
Tabla 3.1 Tipos de datos en VB.NET

Cuando declaramos una variable y no indicamos el tipo, por defecto tomará el de


Object, que corresponde al tipo de datos genérico en el entorno de ejecución de
.NET.Framework, y que admite cualquier valor.
Según la información que acabamos de ver, si cuando declaramos una variable de
tipo Byte e intentamos asignarle el valor 5899 se producirá un error, puesto que no
se encuentra en el intervalo de valores permitidos para esa variable. Esto puede
hacer que el lector se pregunte "¿Porque entonces no usar siempre Object y poder
usar cualquier valor?", O tal vez ""¿Para qué necesitamos asignar tipo a las
variables?".
La razón de tipificar las variables es que cuando hacemos una declaración, el
entorno de .NET debe reservar un espacio en la memoria para los valores que
pueda tomar la variable, como se puede observar en la tabla anterior, no requiere
el mismo espacio en memoria una variable Byte que una Date. Además, si
declaramos todas las variables como Object, los gastos de recursos del sistema
serán mayores que si establecemos el tipo adecuado para cada una, puesto que
como .NET Framework no sabe el valor que pueda tomar en cada momento la
variable, debe realizar un trabajo extra de adecuación, consumiendo una mayor
cantidad de recursos.
La tipificación correcta de las variables, dará lugar a un mejor aprovechamiento de
las cualidades del sistema y en un código más veloz en ejecución. Es así que
cuantos más programas se realizan optimizando en este sentido, que el sistema
operativo gana en rendimiento beneficiándose el conjunto de aplicaciones que estén
en ejecución.
VS.NET dispone de una ayuda al asignar el tipo a una variable, esta nos muestra la
lista de tipos disponibles para así poder seleccionar uno de ellos, sin tener que
escribir el nombre. Cuando terminamos de escribir la palabra As, aparece dicha
lista, en la que se pulsa las primera letras del tipo a buscar, se irá situando en los
que más se asemeje. Cuando encontramos, presionamos Enter o Tab para tomarlo.
Ver figura 3.7

- 61 -
Figura 3.7

Declaración múltiple en línea


En el caso en que se tenga que declarar más de una variable del mismo tipo,
podemos declararlas todas en una sola línea, separando cada una con una coma, e
indicando junto a la variable el tipo de dato que irá a tener; o bien, especificando el
tipo de dato al final de la lista de variables, todas ellas tendrán el mismo tipo de
dato. Ver código fuente 3.15
Dim Nombre As String, Cadena As Integer, MiFecha As Date
Dim Importe, Total, Precisión As Integer

Código fuente 3.15

Asignación de un valor
Para asignar un valor a una variable, usaremos el operador de asignación: el signo
igual ( = ), situando a su izquierda la variable a asignar y a la derecha, el valor que
tomará. Ver código fuente 3.16
Dim Cuentas As Integer
Cuentas = 7852
Código fuente 3.16

Según el tipo de dato de la variable, puede ser necesario el uso de delimitadores


para encerrar el valor que se irá a asignar.
Tipos Numéricos. Las variables de tipos de datos numéricos no necesitan
delimitadores, se asigna directamente el número correspondiente. Si se requiere
especificar decimales, usaremos el punto (.) Como caracter separador para los
decimales.
Cadena de caracteres. Aquí es necesario encerrar la cadena entre comillas dobles
( “”).

- 62 -
Tipo carácter simple. Al asignar a una variable de tipo de dato Char, es necesario
encerrarlo entre comillas dobles como se hace con una cadena de caracteres,
situando además la letra c junto al caracter fuera de las comillas, aunque esto
último no es necesario. Ver ejemplo en el código fuente 3.17
Dim Letra As Char
Letra = "H"c
Letra = "H" 'no es necesario el uso de c junto al carácter a asignar

Código fuente 3.17.

Fechas. Cuando asignamos una fecha a una variable de este tipo, se puede
encerrar el valor de la variable entre signo de numerales ( # ) o comillas dobles ( "
), el formato de fecha que usemos dependerá del delimitador. Al usar el signo de
numerales, la fecha tendrá el formato Mes/Día/Año; en tanto que si usamos
comillas dobles el formato será Día/Mes/Año.
Las fechas además pueden contener información horaria que se especifica
Hora:Minutos:Segundos Franja horaria. En caso de no indicar la franja horaria
(AM/PM) y si estamos usando el numeral como separador, el entorno insertará
automáticamente la franja horaria correspondiente.
Tipos lógicos. Las variables de este tipo sólo pueden contener el valor True
(Verdadero) o False (Falso).
Además de asignar valores como se vio anteriormente, podemos asignar el
contenido de una variable a otra, el resultado de una expresión a una variable,
como se verá mas adelante en el capítulo dedicado a operadores. El código fuente
3.18 muestra los ejemplos de asignación a variables, que luego se verá en la
consola.
Module Module1
Sub Main()
Dim ImporteFac As Integer
Dim Precio As Double
Dim Valor As String
Dim Letra As Char
Dim FhActual As Date
Dim FhNueva As Date
Dim FhCompletaUno As Date
Dim FhCompletaDos As Date
Dim FhHora As Date
Dim Correcto As Boolean
ImporteFac = 875
Precio = 50.75
Valor = "mesa"
Letra = "A"c
FhActual = #5/20/2002# 'mes/dia/año
FhNueva = "25/10/2002" 'dia/mes/año
FhCompletaUno = #10/18/2002 9:30:00 AM#
FhCompletaDos = "7/11/2002 14:22:00"
FhHora = #5:40:00 PM#
Dim NuevaCadena As String
NuevaCadena = Valor 'asignar una variable a otra
Correcto = True
'mostrar variables en la consola

- 63 -
Console.WriteLine("Variable ImporteFac: {0}", ImporteFac)
Console.WriteLine("Variable Precio: {0}", Precio)
Console.WriteLine("Variable Valor: {0}", Valor)
Console.WriteLine("Variable Letra: {0}", Letra)
Console.WriteLine("Variable FhActual: {0}", FhActual)
Console.WriteLine("Variable FhNueva: {0}", FhNueva)
Console.WriteLine("Variable FhCompletaUno: {0}",
FhCompletaUno)
Console.WriteLine("Variable FhCompletaDos: {0}",
FhCompletaDos)
Console.WriteLine("Variable FhHora: {0}", FhHora)
Console.WriteLine("Variable NuevaCadena: {0}", NuevaCadena)
Console.WriteLine("Variable Correcto: {0}", Correcto)
Console.ReadLine()
End Sub
End Module
Código fuente 3.18.

Algo importante también que se puede decir aquí es que podemos declarar una
variable y asignarle el valor en la misma línea de código, como se ve en el código
fuente 3.19.
Dim Valor As String = "computadora"
Dim ImporteFac As Integer = 532
Código fuente 3.19.

Valor inicial
Toda variable declarada, toma un valor inicial por defecto, si no asignamos un valor
en el momento en que se declara la variable. Mostramos algunos valores de inicio
en función del tipo de dato que tenga la variable.
Numérico. Cero ( 0 )
Cadena de caracteres. Cadena vacía ( "" )
Fecha. 01/01/0001 0:00:00
Lógico. False
Objeto. Valor nulo (Nothing)

- 64 -
Practica 4: Valores iníciales
El código fuente 3.20 muestra un ejemplo de valores iniciales.
Sub Main()
Dim ImporteFac As Integer
Dim Valor As String
Dim FhActual As Date
Dim FhNueva As Date
Dim ValorLogico As Boolean
Dim UnObjeto As Object

'mostrar variables en la consola


Console.WriteLine("Variable ImporteFac: {0}", ImporteFac)
Console.WriteLine("Variable Valor: {0}", Valor)
Console.WriteLine("Variable FhActual: {0}", FhActual)
Console.WriteLine("Variable FhNueva: {0}", FhNueva)
Console.WriteLine("Variable ValorLogico: {0}", ValorLogico)
Console.WriteLine("Variable UnObjeto: {0}", UnObjeto)
Console.ReadLine()
End Sub
Código fuente 3.20.

Se debe tener en cuenta al ejecutar estas líneas, que en los casos de las variables
de tipo de dato cadena y objeto no se mostrará nada, puesto que se considera que
están inicializadas pero vacías.
Al contrario, podemos también inicializar una variable que ya tiene valor, la palabra
clave Nothing, esto hará que la variable pase a tener el valor por defecto inicial. Ver
código fuente 3.21.
Sub Main()
Dim Valor As String
Dim FhActual As Date
Dim ValorLogico As Boolean

'asignar valor a variables


Valor = "mesa"
FhActual = "10 / 8 / 2002"
ValorLogico = True

'inicializar variables
Valor = Nothing
FhActual = Nothing
ValorLogico = Nothing

'mostrar variables en la consola


Console.WriteLine("Variable Valor: {0}", Valor)
Console.WriteLine("Variable FhActual: {0}", FhActual)
Console.WriteLine("Variable ValorLogico: {0}", ValorLogico)
Console.ReadLine()
End Sub
Código fuente 3.21

- 65 -
Avisos IDE sobre errores en el código
Cuando se declara una variable con un nombre incorrecto, o si se produce algún
otro tipo de errores en la escritura del código, el propio IDE se encarga de darnos el
aviso de que existe un problema subrayando el fragmento de código conflictivo y
mostrando una viñeta informativa al situar sobre dicho código el cursor. Ver código
fuente 3.27

Código fuente 3.27

Estos avisos son de gran ayuda, puesto que dan lugar al programador a observar
problemas en la escritura del código, incluso antes de ejecutar el programa.
Hay muchos avisos y de diversa naturaleza, se debe tomar en cuenta que la tónica
general consiste en que el código problemático quedará subrayado por el IDE
hasta que no se modifique la línea señalada y se la escriba correctamente.

Grabación del código modificado


Cuando se edita el código fuente del programa, es conveniente cada cierto tiempo,
cuanto más frecuente mejor, grabar a disco el archivo o los archivos de código
modificado. Para ello se elige la opción de menú del IDE Archivo + guardar
NombreArchivo o la combinación de teclas [CONTROL + S] el acostumbrarse a ello
nos puede evitar serios dolores de cabeza en caso de un apagón imprevisto del
equipo cuando estamos en pleno trabajo y no se guardó el programa.

Constantes
Igualmente que las variables, una constante es un elemento del lenguaje que
guarda un valor, pero que en este caso, y como su nombre lo indica, este valor
permanecerá a lo largo de la ejecución del programa, no pudiendo ser modificada.
Para declarar una constante, se debe usar la palabra clave Const, debiendo al
mismo tiempo establecer el tipo de dato y asignarle un valor. Ver código fuente
3.28
Sub Main()
Const Color As String = "Azul"
Const ValorMoneda As Double = 465.75
End Sub
Código fuente 3.28

La tipificación de una constante se rige, al igual que las variables, por la


configuración que tengamos establecida para la instrucción Option Strict.
Si se intenta asignar un valor a una constante luego de la asignación inicial, el IDE
nos subrayara la línea con un aviso de error de escritura, y se producirá igualmente
un error si intentamos ejecutar el programa. Ver figura 3.10

- 66 -
Figura 3.10

La ventaja del uso de constantes reside en que podemos tener un valor asociado a
una constante a lo largo de nuestro código para diversas operaciones. Si por
cualquier circunstancia, dicho valor debe cambiarse, solamente se tendría que
hacer en el lugar donde se declaro la constante.
Suponiendo que se realiza un programa en el que se realiza una venta de productos
y que se confeccionan facturas. A ambas situaciones debemos aplicar un descuento
sobre el total resultante. Ver código fuente 3.29
Sub Main()
' venta de productos
Dim Importe As Double
Dim TotalVenta As Double
Console.WriteLine("Introducir importe de la venta")
Importe = Console.ReadLine()

' aplicar descuento sobre la venta


TotalVenta = Importe – 100
Console.WriteLine("El Importe de la venta es: {0}",
TotalVenta)
Console.WriteLine()
' .........
' .........
' .........

' factura de mercaderías


Dim PrecioArt As Double
Dim TotalFactura As Double
Console.WriteLine("Introducir el precio del artículo")
PrecioArt = Console.ReadLine()

' aplicar descuento a la factura


TotalFactura = PrecioArt – 100
Console.WriteLine("El total de la factura es: {0}",
TotalFactura)
Console.WriteLine()
' .........
' .........
Console.ReadLine()
End Sub
Código fuente 3.29

En el anterior ejemplo, realizaremos el descuento usando directamente el valor a


descontar. Si en un momento dado, se necesita cambiar el valor de dicho
descuento, tendríamos que recorrer todo el código e ir cambiando en aquellos
lugares donde se realice esta operación.

- 67 -
Empleando una constante para el descuento, y usando dicha constante para todos
aquellos puntos del código donde necesitemos aplicar un descuento, cuando se
deba modificar un descuento, solamente se necesitará hacerlo en la línea que se
declaró la constante. Ver código fuente 3.30
Sub Main()
' crear constante para calcular descuento
Const DESCUENTO As Integer = 100

' venta de productos


Dim Importe As Double
Dim TotalVenta As Double
Console.WriteLine("Introducir importe de la venta")
Importe = Console.ReadLine()

' aplicar descuento sobre la venta, prestar atención al uso


de la constante
TotalVenta = Importe - DESCUENTO
Console.WriteLine("El importe de la venta es: {0}",
TotalVenta)
Console.WriteLine()
'........
'........
'........

' facturas de mercaderías


Dim PrecioArt As Double
Dim TotalFactura As Double
Console.WriteLine("Introducir precio del artículo")
PrecioArt = Console.ReadLine()

' aplicar descuento a la factura, prestar atención al uso de


la constante
TotalFactura = PrecioArt - DESCUENTO
Console.WriteLine("El Total de la factura es: {0}",
TotalFactura)
'........
'........
'........
Console.ReadLine()
End Sub

Código fuente 3.30

- 68 -
Módulo 4

Estructuras de control

- 69 -
Las estructuras de control junto a los procedimientos, componen los dos elementos
que ponen las bases de la programación estructurada.
Las estructuras de control contienen bloques de código que serán ejecutados en
función del resultado que se obtiene a partir de la evaluación de una expresión
asociada a la estructura. Este proceso de redirección del flujo del programa hacia
un determinado bloque de código, es denominado también bifurcación.
Dependiendo del modo de ejecución del código que contiene, las estructuras de
control son divididas en los siguientes tipos: selección y repetición.

Selección
Denominadas también de decisión, las estructuras de selección, permiten ejecutar
un bloque de código entre varios disponibles, dependiendo del resultado de una
expresión que se encuentra en la cabecera de la estructura.

If...End If
En función al tipo de decisión a resolverse, la sintaxis de esta estructura puede ser
aplicada de distintas maneras.
Decisión simple
La sintaxis de decisión simple se muestra en el código fuente 4.1
If Expresión Then
„código
„.......
„.......
End If
Código fuente 4.1

Si la evaluación de Expresión devuelve como resultado True, se ejecutarán las


líneas o el bloque de código comprendido entre If y End If. Si por el contrario la
evaluación de Expresión da como resultado False, la ejecución se desviará hacia la
primera línea de código que haya después de End If. Veremos en el código fuente
4.2 un ejemplo.
Module Module4
Sub Main()
Dim Valor As Integer

Console.WriteLine("Introducir un número")
Valor = Console.ReadLine

If Valor = 5 Then
Console.WriteLine("Estamos dentro de la estructura If," & _
" puesto que su expresión devuelve Verdadero")
End If
Console.ReadLine()
End Sub
End Module
Código fuente 4.2

Como se pudo comprobar, no es necesario especificar en la expresión que el


resultado de la misma sea Verdadero para poder ejecutar el código de la estructura
de control. En el código fuente 4.3, ambas formas de escribir la expresión son

- 70 -
iguales, si bien la primera es más simple e igualmente comprensible, con la
segunda la evaluación resulta ser más explícita en el código del programa, la
decisión de usar una u otra manera de escribir la expresión queda a gusto y estilo
de la persona que está programando, puesto que el resultado será igual de ambas
maneras.
If Precio = 25 Then
„....
If (Precio = 25) = True Then
„....
Código fuente 4.3

Poniéndonos ahora en el caso contrario, ¿cómo conseguir que se ejecute el código


que contiene la estructura de control cuando la expresión a evaluar devuelva Falso?
También en esta situación disponemos de dos maneras de hacer las cosas, el uso
de una u otra depende del estilo y gusto del programador. Se puede indicar de
manera explícita que la estructura se ejecute cuando el valor que devuelve la
expresión sea False o bien usar el operador Not. Ambas estructuras If...End If
Del código fuente 4.4 dará el mismo resultado.
If Not (Precio = 25) Then
Console.WriteLine("El contenido de la variable es diferente de 25 ")
End If

If (Precio = 25) = False Then


Console.WriteLine("La variable resultado es distinta de 25")
End If
Código fuente 4.4

Decisión simple en una sola línea


En el caso de que sólo haya que ejecutar una instrucción simple cuando se cumple
la expresión de la estructura, se puede omitir la palabra clave End If, escribiendo la
sentencia a ejecutar, en la misma línea de la declaración de la estructura If,
precisamente a continuación de la palabra Then, en este caso, la sintaxis se
simplifica, como el código fuente 4.5 lo muestra.
If Expresión Then Instrucción
Código fuente 4.5

Veremos ahora un ejemplo en el código fuente 4.6


Module Module4
Sub Main()
Dim Resultado As Integer
Dim Valor As Integer
Console.WriteLine("Introducir un número")
Valor = Console.ReadLine

If Valor = 35 Then Resultado = Valor + 25

Console.WriteLine("La variable Resultado contiene: {0}",


Resultado)
Console.ReadLine()
End Sub
End Module

- 71 -
Código fuente 4.6

Como se pudo comprobar, la sentencia que hay a continuación de Then solamente


de ejecutará cuando la variable Precio contenga 25

Decisión doble
A parte de ejecutar un bloque de código cuando la expresión sea Verdadera, se
puede también ejecutar código cuando la expresión da como resultado Falso. En
este caso se añadirá a la estructura la palabra clave Else. Ver código fuente 4.7
If Expresión Then
„.... código cuando expresión es Verdadero
„....
„....
Else
„.... código cuando Expresión es Falso
„....
„....
código fuente 4.7

veremos un ejemplo en el código fuente 4.8


Sub Main()
Dim Resultado As Integer
Dim Valor As Integer
Console.WriteLine("Introducir un número")
Valor = Console.ReadLine

If Valor = 35 Then
Resultado = Valor + 25
Else
Resultado = 999
End If

Console.WriteLine("La variable Resultado contiene: {0}",


Resultado)
Console.ReadLine()
End Sub
código fuente 4.8

En este ejemplo, cuando Precio contenga 25, se ejecutará el código que hay a
continuación de If, pero cuando Precio contenga un número diferente, se ejecutará
a continuación de Else. La ejecución de cualquier caso, continuará después, a partir
de la siguiente línea que haya a partir de la palabra clave End If.

Decisión doble en una línea


Como ocurre con la decisión simple, si para calcular cada resultado de la expresión,
tan sólo es necesario ejecutar una instrucción, se puede escribir todo el código en
una sola línea. Ver la sintaxis en el código fuente 4.9
If Expresion Then InstrucciónVerdadero Else InstrucciónFalso
Código fuente 4.9

Un ejemplo del uso de la decisión doble en una sola línea, lo tenemos en el código
fuente 4.10

- 72 -
Sub Main()
Dim Resultado As Integer
Dim Valor As Integer
Console.WriteLine("Introducir un número")
Valor = Console.ReadLine

If Valor = 35 Then
Resultado = Valor + 25
Else
Resultado = 999
End If

Console.WriteLine("La variable Resultado contiene: {0}",


Resultado)
Console.ReadLine()
End Sub

Código fuente 4.10

Por un lado, la ejecución de la estructura If en una sola línea es útil para algunos
códigos cortos, por el otro, se hace más difícil de leer cuando se trata de código que
tiene varias instrucciones. Por ello es recomendable el uso de esta estructura de
control en su formato If...End If

Decisión múltiple
Si se da el caso de que la expresión principal da como resultado Falso, puede ser
útil agregarle expresiones adicionales, usando la palabra ElseIf, con un bloque de
código respectivo. En el caso de que ninguna de ellas se cumplan, se puede agregar
un Else, para que se ejecute un bloque de código por defecto, para que la ejecución
tenga un resultado. Ver la sintaxis en el código fuente 4.11
If ExpresiónA Then
„ código cuando ExpresiónA es Verdadero
„ .....
ElseIf ExpresiónB Then
„ código cuando ExpresiónB es Verdadero
„ ....
[ElseÏf ExpresiónN Then]
„ código cuando ExpresiónN es Verdadero
„ ....
[Else]
„ código cuando ninguna expresión devuelve Verdadero
„ ....
End If
Código fuente 4.11

En el código fuente 4.12 veremos un ejemplo para este tipo de estructura


Sub Main()
Dim Resultado As Integer
Dim Valor As Integer
Console.WriteLine("Introducir un número")
Valor = Console.ReadLine

If Valor = 35 Then
Resultado = Valor + 25
ElseIf Valor > 100 Then

- 73 -
Resultado = Valor + 200
ElseIf Valor < 1 Then
Resultado = -21
Else
Resultado = 999
End If
Console.WriteLine("La variable Resultado contiene {0}",
Resultado)
Console.ReadLine()
End Sub
Código fuente 4.12

En el ejemplo, si la primera expresión es Verdadero, se ejecutará el código situado


a partir de If. Pero, si la expresión devuelve Falso, irá comprobando sucesivamente
las expresiones de cada uno de los ElseIf existentes. Si alguno de los ElseIf
devuelve Verdadero, se ejecutará el código que hay a partir del mismo. Si se da el
caso de que ninguna de las expresiones se cumpla, se ejecutará el código que hay
a partir de Else en el caso de que este se haya definido.

Función IIf()
Esta función realiza el mismo trabajo básicamente que la estructura If...End If, pero
a través de un uso distinto. Ver código fuente 4.13 que es la sintaxis de dicha
estructura.
IIf(Expresión, RetornoVerdadero, RetornoFalso)
Código fuente 4.13

La forma de funcionar de IIf() es pasándole una expresión a evaluar en el primer


parámetro. Si el resultado de ésta evaluación es Verdadero, devolverá lo que
hayamos situado en el párrafo RetornoVerdadero, pero si el resultado de la
expresión resulta ser Falso, devolverá el parámetro RetornoFalso. El código fuente
4.14 muestra un ejemplo de ésta función.
Sub Main()
Dim Valor As Integer
Dim Resultado As String

Console.WriteLine("Introducir el valor que se quiere buscar")


Valor = Console.ReadLine() 'escribir un número

'comprobar el contenido de la variable


Resultado = IIf(Valor = 700, "Un Éxito", "Un Fracaso")
Console.WriteLine("El resultado de la búsqueda fué {0}",
Resultado)
Console.ReadLine()
End Sub
Código fuente 4.14
Select Case...End Select
Esta estructura trata de una evolución de la estructura If...End If de decisión
múltiple, su trabajo se trata de evaluar una expresión y comparar el resultado con
una lista de expresiones de cada uno de los casos proporcionados. El código fuente
4.15 muestra la sintaxis.
Select Case Expresión

- 74 -
Case ListaExpresionesA
„ código si se cumple ListaExpresionesA
„ ....

[Case ListaExpresionesB]
„ código si se cumple ListaExpresionesB
„ ....
[Case ListaExpresionesN]
„ código si se cumple ListaExpresionesN
„ ....

[Case Else]
„ código si no se cumple ninguna ListaExpresiones
„ ....
End Select
Código fuente 4.15

La lista de expresiones que está asociada a cada Case en esta estructura estará
separada por comas y podrá tener alguno de los siguientes formatos:
Expresión
ExpresiónMenor To ExpresionMayor
Is OperadorComparación Expresión
Luego de evaluar la expresión de la estructura, si se encuentra alguna coincidencia
con alguno de los Case, se ejecuta el bloque de código situado entre dicho Case y el
siguiente. Si se da el caso de que no haya ninguna coincidencia, se puede de forma
opcional ejecutar un bloque por defecto, usando la palabra Case Else. Finalizada la
estructura, la ejecución continuará después de End Select
Veremos a continuación en el código fuente 4.16 un ejemplo de uso de la
estructura.
Sub Main()
Dim Valor As Integer
Console.WriteLine("Introducir un número")
Valor = Console.ReadLine()
Select Case Valor
Case 15
Console.WriteLine("El valor es 15")
Case 150, 300
Console.WriteLine("El valor es 150 ó 300")
Case 5000 To 7000
Console.WriteLine("El valor esta en el rango de 5000 a
7000")
Case Is < 10
Console.WriteLine("El valor es es menor que 10")
Case Else
Console.WriteLine("El valor es {0}, y no cumple ningún
caso", Valor)
End Select
Console.ReadLine()
End Sub
Código fuente 4.16

Si se da el caso de que luego de evaluar la expresión, existe más un Case cuya lista
de expresiones se cumpla, se ejecutará el que esté situado en primer lugar. En el

- 75 -
ejemplo anterior, cuando la variable Precio contiene 5, se cumplen dos casos. Ver
código fuente 4.17
Case 5
Console.WriteLine("El precio es 5")
' ....
' ....
Case Is < 10
Console.WriteLine("El precio es menor a 10")
Código fuente 4.17

Sin embargo, solamente se ejecuta el código del primer Case.


Por otro lado, la lista de expresiones puede ser una combinación de distintos
formatos disponibles. Ver código fuente 4.18
Case 12 To 15, 4, 7, Is > 20
Código fuente 4.18
Repetición
También llamadas bucles, las estructuras de repetición, ejecutan un bloque de
código de manera repetitiva en tanto que se cumpla una condición asociada a la
estructura. Iteración es la denominación de cada una de las ocasiones en que se
ejecuta el código contenido en estas estructuras.

While...End While
Dentro de las estructuras de repetición es la más sencilla, ejecuta las líneas de
código que contiene, en tanto la expresión situada junto a While devuelva
Verdadero. En el código fuente 4.19
While Expresión
„ código
„ ....
End While
Código fuente 4.19

Daremos un ejemplo de este tipo de estructura en el código fuente 4.20


Module Module4
Sub Main()
Dim Valor As Integer
Dim Contador As Integer

Console.WriteLine("Mostrar en la consola todos los números


desde 1 hasta el introducido")

While Contador < Valor


Console.Write("_" & Contador)
Contador += 1
End While

Console.ReadLine()
End Sub
End Module
Código fuente 4.20

- 76 -
Do...Loop
En esta estructura se ejecuta un conjunto de líneas de código, en función del valor
devuelto por una expresión, que a modo de condición, puede ser situada al inicio o
final de la estructura.
También es posible no usar la expresión de evaluación al inicio o final, en este caso
se debe introducir alguna condición en el interior de la estructura, para forzar la
salida del bucle y de esta manera evitar un bucle infinito. Con la expresión Exit Do
podemos forzar la salida del bucle, esta expresión se la puede emplear tantas veces
como sea necesario.
A continuación se muestra las variantes que existen.
Condición al inicio de la estructura
La sintaxis se la muestra en el código fuente 4.21
Do While | Until Expresión
„ código
„ ....
[Exit Do]
„ código
„ ....
Loop
Código fuente 4.21

La diferencia entre usar While o Until es que empleando While, el código del bucle
se ejecutará en tanto la expresión devuelva Verdadero. En el caso de Until, el
código se ejecutará mientras que la expresión devuelva Falso. Veremos un ejemplo
en el código fuente 4.22
Module Module4
Sub Main()
Dim Valor As Integer
Dim Palabra As String

' bucle con While


Do While Valor <> 300
Console.WriteLine("Introducir un número")
Valor = Console.ReadLine
Loop
' bucle con Until
Do Until Palabra = "buque"
Console.WriteLine("Introducir una palabra")
Palabra = Console.ReadLine
Loop

End Sub
End Module
Código fuente 4.22

Código al final de la estructura


La diferencia de éste caso con el otro, consiste en que el contenido de la estructura
se ejecuta por lo menos una vez. El código fuente 4.23 muestra la sintaxis.

- 77 -
Do
„ código
„ ....
„ [Exit Do]
„ ....
Loop While | Until Expresión
Código fuente 4.23

Veremos algunos ejemplos en el código fuente 4.24


Module Module4
Sub Main()
Dim Valor As Integer
Dim Palabra As String

' bucle con While


Do
Console.WriteLine("Introducir un número")
Valor = Console.ReadLine()
Loop While Valor <> 300

' bucle con Until


Do
Console.WriteLine("Introducir una palabra")
Palabra = Console.ReadLine
Loop Until Palabra <> "buque"
End Sub
End Module
Código fuente 4.24

Sin condición
Este modo es el más simple de la estructura de repetición, sin tener condición al
inicio o final. Pero también es el modo más peligroso, porque si no se incluye un
control dentro del código, se corre el riesgo de caer en un bucle infinito.
Estableceremos una condición de salida mediante una estructura If dentro del
bucle, que compruebe el contenido de la variable, y fuerza la salida cuando tenga
un valor superior a cierto número. Ver código fuente 4.25
Module Module4
Sub Main()
Dim Valor As Integer
Do
Console.WriteLine("Introducir un número")
Valor = Console.ReadLine()

'comprobar y salir del bucle si fuera necesario


If Valor > 500 Then
Exit Do
End If
Loop

End Sub
End Module
Código fuente 4.25

- 78 -
For ...Next
En esta estructura se ejecuta un bloque de código, un determinado número de
veces, que está establecido por un rango de valores y controlado por un contador.
En el código fuente 4.26 veremos la sintaxis de esta estructura.
For Contador = Inicio To Fin [Step incremento]
„ código
„ ....
[Exit For]
„ código
„...
„ código
[Exit For]
„código
„ ....
„Next
código fuente 4.26

El elemento contador se inicializa con un valor y el código existente entre For y


Next se ejecuta una serie de veces, hasta que el valor de Contador sea igual a Fin.
Por defecto, el incremento de Contador va de uno en uno, pero puede ser
modificado usando el modificador Step, mediante él podemos establecer el número
en el que se realizarán los incrementos. Con Step también realizamos decrementos,
usando un número negativo.
Si se desea realizar una salida de la ejecución de esta estructura antes de
completar el número de iteraciones demarcadas, se puede usar la instrucción Exit
for.
El código fuente 4.27 muestra distintos ejemplos de uso de este tipo del bucle.
Module Module4
Sub Main()
Dim Contador As Integer
Dim Final As Integer

' recorrido simple del bucle


Console.WriteLine("Bucle For normal")
For Contador = 1 To 10
Console.WriteLine("Variable Contador: {0}", Contador)
Next
Console.WriteLine()

' recorrer el bucle especificando un incremento


Console.WriteLine("Bucle For con incremento")
Console.WriteLine("Introducir el número de ejecuciones para el
bucle")
Final = Console.ReadLine()
For Contador = 1 To Final Step 3
Console.WriteLine("Variable Contador: {0}", Contador)
Next

Console.WriteLine()

'recorrer el bucle especificando un decremento


Console.WriteLine("Bucle For con decremento")

- 79 -
For Contador = 30 To 5 Step -6
Console.WriteLine("Variable Contador: {0}", Contador)
Next
Console.WriteLine()
' este bucle no se ejecutará, porque es mayor
' el valor del contador que el valor final,
' y ni haber establecido un decremento
For Contador = 22 To 4
Console.WriteLine("Variable Contador: {0}", Contador)
Next
' recorrer el bucle y salir antes de completar
' todas las iteraciones
Console.WriteLine("Bucle For con salida antes de completar")
For Contador = 1 To 15
Console.WriteLine("Variable Contador: {0}", Contador)
If Contador = 10 Then
Exit For
End If
Next

Console.ReadLine()
End Sub
End Module
Código fuente 4.27

Hay un truco para optimizar y acelerar la ejecución en un bucle como éste tipo, y
es que se debe usar como contador una variable de tipo Integer, en vez de usar,
Short, Long, Double, Decimal, etc. Puesto que los tipo Integer se actualizan más
rápidamente que los otros tipos numéricos, por supuesto que la diferencia sólo es
apreciable en bucles que realizan miles de iteraciones que contengan muchas
instrucciones. Ver código fuente 4.28
Dim ContRapido As Integer
Dim ContLento As Decimal
' este bucle será más rápido que el siguiente
For ContRapido = 1 To 10000
' código
Next

For ContLento = 1 To 10000


' código
Next
Código fuente 4.28

For Each...Next
Es una variante de la estructura For...Next, lo que esta estructura hace es ejecutar
un bloque de código por cada uno de los elementos existentes en un array.
Mostramos en el código fuente 4.29 su sintaxis
For Each Elemento In ColecArray
„ código
„ ....
[Exit For]
„ código
„ ....

- 80 -
Next
Código fuente 4.29

En el código fuente 4.30 veremos un ejemplo de ésta estructura de control.


Module Module4
Sub Main()
' crear un array y rellenarlo con valores
Dim lsColores() As String = {"Verde", "Rojo", "Naranja",
"Marrón", "Violeta"}
Dim lsColor As String

'en cada iteración se obtiene un elemento


'del array lsColores, y se guarda en la variable lsColor
For Each lsColor In lsColores
Console.WriteLine(lsColor)
Next
Console.ReadLine()
End Sub
End Module
Código fuente 4.30

Anidación de estructuras de control


Este técnica consiste en incluir una estructura de control dentro de otra ya
existente. La estructura interior o anidada puede ser del mismo o diferente tipo que
la estructura contenedora o exterior. Es posible también anidar más de una
estructura, a varios niveles de profundad. Veremos varios ejemplos de anidación de
estructuras de control en los siguientes apartados.
Anidación de estructuras de selección
El código fuente 4.31 muestra un ejemplo de dos estructuras If...End If
Module Module4
Sub Main()
' dos estructuras If anidadas
Dim ValorEntrada As Integer
Dim Nombre As String

Console.WriteLine("Introducir un número")
ValorEntrada = Console.ReadLine()

'estructura externa
If ValorEntrada = 10 Then
Console.WriteLine("Introducir un nombre")
Nombre = Console.ReadLine()

' estructura interna


If Nombre = "Anna" Then
Console.WriteLine("Llegaste al interior")
End If
End If
Console.ReadLine()
End Sub

- 81 -
End Module
Código fuente 4.31

Anidación de estructuras de repetición


El código fuente 4.32 muestra un ejemplo de dos estructuras For...Next
Module Module4
Sub Main()
' dos estructuras If anidadas
Dim ValorEntrada As Integer
Dim Nombre As String

Console.WriteLine("Introducir un número")
ValorEntrada = Console.ReadLine()

'estructura externa
If ValorEntrada = 10 Then
Console.WriteLine("Introducir un nombre")
Nombre = Console.ReadLine()

' estructura interna


If Nombre = "Anna" Then
Console.WriteLine("Llegaste al interior")
End If
End If
Console.ReadLine()
End Sub
End Module
Código fuente 4.32

Anidación de estructuras de diferente tipo y a varios niveles


En este ejemplo, lo que se hará es la combinación de estructuras anidadas de
diferentes tipos y varios niveles de profundidad.
Realizaremos a partir de un array, un proceso que se repetirá tantas veces como
cadenas existen en él. En cada uno de los procesos se dará tres oportunidades de
introducción de cadena por consola. Si ésta cadena es igual al elemento del array
que corresponde al número de iteración que se hace actualmente sobre el bucle
For, lo que hará es mostrar un mensaje y salir a la siguiente iteración de For. Ver
código fuente 4.33
Module Module4
Sub Main()
Dim Nombres() As String = {"Anna", "Pablo", "Fernando",
"Elena", "Pedro", "Luis"}
Dim Repeticiones As Integer
Dim Nombre As String
Dim valor As Integer

For Repeticiones = 0 To 6
Console.WriteLine("Captura de nombre, interno {0}",
Repeticiones + 1)
valor = 1
Do While valor <= 3

- 82 -
Console.WriteLine("Introducir un nombre")
Nombre = Console.ReadLine()

If Nombre = Nombres(Repeticiones) Then


Console.WriteLine("Nombre correcto")
Exit Do
End If
valor += 1
Loop
Next
End Sub
End Module

Código fuente 4.33

Anidación incorrecta en estructuras


Al escribir estructuras de control anidadas, lo que debemos tomar en cuenta es que
parte de una estructura de nivel interior no se encuentre fuera de la estructura de
control exterior, puesto que ello llevaría a un error de sintaxis. Ver código figura
4.1

Figura 4.1 Esquema de anidación incorrecta de estructuras de control

Construcciones derivadas de las estructuras de control


El carácter de iteración o bifurcación de las estructuras de control, lo que hace es
permitir la creación de las construcciones de código que se repetirán un
determinado número de veces, para llevar el control de las ejecuciones de un
bloque de código y acumulación de valores. Por lo general los nombres más
conocidos son para este tipo de construcciones son: contadores, acumuladores,
interruptores.
Contadores
El contador es una variable, que como su nombre lo indica, consiste en realizar un
cálculo de las iteraciones realizadas dentro del bucle. En el código fuente 4.34
vemos un ejemplo.
Module Module4

- 83 -
Sub Main()
Dim Contador As Integer
Dim Nombre As String
Console.WriteLine("Introducir un nombre")
Do While Nombre <> "Daniela"
Contador += 1
Console.WriteLine("Valor del contador: {0}", Contador)
Nombre = Console.ReadLine()
Loop
Console.WriteLine("El bucle se ejecutó {0} veces", Contador)
Console.ReadLine()

End Sub
End Module
Código fuente 4.34

Acumuladores
Un acumulador es la variable que va almacenando dentro de un bucle el resultado
de una suma efectuada a cada iteración del mismo, veremos un ejemplo en el
código fuente 4.35
Module Module4
Sub Main()
Dim Contador As Integer
Dim Acumulador As Integer
Dim Cantidad As Integer

For Contador = 1 To 5
Console.WriteLine("Introducir una cantidad numérica")
Cantidad = Console.ReadLine()
Acumulador += Cantidad
Console.WriteLine("El acumulador contiene un valor de
{0}", Acumulador)

Next
Console.ReadLine()
End Sub
End Module
Código fuente 4.35

Interruptores
Llamado también switch, un interruptor es una variable que consiste en tomar
solamente dos estados: conectado y desconectado, de manera que en función del
estado en que se encuentre, determinará el bloque de código a seguir. Veremos un
ejemplo en el código fuente 4.36
Module Module4
Sub Main()
Dim Valores() As Integer = {55, 30, 75, 150, 1200, 10, 1}
Dim Interruptor As Integer
Dim Contador As Integer
Dim Cantidad1 As Integer
Dim Cantidad2 As Integer

' inicializar el estado del interruptor

- 84 -
Interruptor = 1

For Contador = 0 To UBound(Valores)


' según el estado del interruptor
' acumular el valor de la posición actual
' del array en una u otra variable
If Interruptor = 1 Then
Cantidad1 += Valores(Contador)
Else
Cantidad2 += Valores(Contador)
End If
' cambiar el estado del interruptor
If Interruptor = 1 Then
Interruptor = 0
Else
Interruptor = 1
End If
Next
End Sub
End Module
Código fuente 4.36

En el ejemplo anterior, el cambio de estado del interruptor se puede simplificar en


gran medida por medio del uso del operador Not en el código fuente 4.37 se verá el
fragmento de código del anterior ejemplo en el que se cambia de estado pero por
medio de esta técnica
„ cambiar el estado del interruptor
interruptor = Not Interruptor
código fuente 4.37

Bifurcaciones incondicionales con Goto


Como sucede con las estructuras de control del lenguaje, la instrucción Goto realiza
una bifurcación en el flujo de ejecución del programa
Hay una diferencia con las otras estructuras de control, y es que el Goto realiza una
bifurcación de manera incondicional, mientras que las otras permiten una
alternativa para realizar o no las oportunas bifurcaciones. Es por ello que se dice
que la estructura Goto realiza un salto no estructurado en la ejecución del
programa. Es decir, esta bifurcación rompe con todo tipo de programación
estructurada.
Lo que hace Goto es un salto hacia lo que se denomina etiqueta de código, que
consiste en un bloque de líneas encabezadas por un identificador y dos puntos. La
etiqueta de código debe situarse al final del procedimiento en el que vayan a
situarse, para realizar una ejecución hacia una de ellas, se debe escribir dicha
etiqueta en el procedimiento y usar el Goto con la sintaxis del código fuente 4.38
Goto NombreEtiqueta
Código fuente 4.37

En el ejemplo del código fuente 4.38 podemos ver que para ejecutar un bloque de
código lo situamos en una etiqueta, y por medio del Goto se realiza una bifurcación
a la misma, pero el problema está en que después de ejecutarse el Goto de la
etiqueta, no vuelve al flujo de la ejecución de donde se llamó al Goto (en

- 85 -
programación estructurada es lo que sucede), sino que continúa con la ejecución
hasta el final, por ello perdemos toda la estructuración en el programa.
Module Module4
Public Sub Main()
Dim Nombre As String
Dim Ciudad As String
Dim Dato As String

Console.WriteLine("Introducir un nombre")
Nombre = Console.ReadLine()

'ahora el código dará un salto con Goto a la etiqueta


MostrarMayúsculas
GoTo MostrarMayúsculas
' estas líneas no se ejecutarán
Ciudad = "Tierra del Fuego"
Dato = Nombre & " " & Ciudad
Console.WriteLine("Los valores unidados dan: {0}", Dato)

MostrarMayúsculas:
' en esta etiqueta de código se muestra el valor
' de la variable en mayúsculas
Console.WriteLine("El nombre en mayúsculas es: {0}",
UCase(Nombre))
Console.ReadLine()
End Sub
End Module
Código fuente 4.38

Como conclusión, se deduce que el uso del Goto para ejecutar bloques de código
dentro de un procedimiento, es una práctica totalmente desaconsejable, por la
pérdida de estructuración de código y complejidad en el mantenimiento del
programa que producen. Se recomienda al lector un detallada estudio del mismo,
puesto que con toda seguridad, se dispondrá de una alternativa estructurada de
escribir su algoritmo, que evite el uso de la estructura Goto.

- 86 -
Laboratorio 1
Ejercicio 1.
Escriba un programa que solicite al usuario que introduzca dos números,
tome los dos números del usuario, e imprima la suma, el producto, la diferencia, el
cociente y el módulo del número.

Ejercicio 2
Escriba un programa que imprima un recuadro, un oval, una flecha y un diamante
como sigue. Utlice solo asteriscos (*) y el método Console.WriteLine para dibujarlos
en pantalla.

******* * * *
* * * * * * **
* * * * * * * *
* * * * ****** * *
******* * * * * *
* * * **
* * *

Ejercicio 3
Escriba un programa que solicite al usuario que escriba dos enteros, tome los
números del usuario y a continuación imprima el número mayor seguido por las
palabras “es mayor”. Si los números son iguales que imprima el mensaje “Estos
números son iguales”. Utilice sólo la forma de una selección del enunciado If

Ejercicio 4
Escriba un programa que escriba 5 enteros y a continuación determine e imprima
cuáles son es el mayor y el menor del grupo. Utilice las técnicas de programación
aprendidas en este capitulo

Ejercicio 5
Escriba un programa que lea un número e imprima si es par o impar

Ejercicio 6
Escriba un programa que lea dos enteros y determine e imprima si el primero es un
múltiplo del segundo

Ejercicio 7
Escriba un programa que entre un número de cinco digitos, separe el número en
sus dígitos individuales e imprima los digitos separados unos de otros mediante tres
espacios. Por ejemplo, si el usuario escribe 42339 el programa debería imprimir
4 2 3 3 9

- 87 -
Módulo 5

Procedimientos

- 88 -
División de una línea de código
Si tenemos en nuestro programa líneas de código muy largas, que nos obligan a
desplazarnos hacia un lateral de la ventana del editor de código para poder leerlas,
podemos dividir ese tipo de línea lógica de código en varias líneas físicas, situando
el carácter de guión bajo (_) en el punto de la línea de código que queremos
continuar, lo que se debe tener en cuenta es que siempre debe haber un espacio en
blanco antes y después del guión, así la división es efectiva.
En el código fuente 5.1 vemos dos líneas exactamente iguales, la primera está en
una sola línea de código, en cambio la segunda está dividida en dos líneas, ambas
cumplen el mismo objetivo.
Dim Resultado As Boolean
'una sola línea lógica de código
Resultado = ((30 + 5) * 5 > 100) And (52 > 200 / (2 + 5))
'varias líneas físicas, pero internamente el compilador
'reconoce una solo línea lógica
Resultado = ((30 + 5) * 5 > 100) And _
(52 > 200 / _
(2 + 5))
Código fuente 5.1

Escritura de varias sentencias en una sola línea


En éste apartado, lo que haremos es lo contrario al anterior apartado. El lenguaje
nos permite escribir en una misma línea física, varias sentencias separadas por el
carácter de dos puntos (:), esto en condiciones normales, se escribirían en líneas
separadas. Ver código fuente 5.2
Module Module5
Sub Main()
Dim Valor As Integer, Nombre As String, Resultado As Boolean
' en la siguiente línea hay tres sentencias que por lo general
' se escriben en líneas separadas
Valor = 50 : Nombre = "Anna" : Resultado = 82 <> 325
Console.WriteLine("Contenido de variables: {0} - {1} – {2}", _
Valor, Nombre, Resultado)
Console.ReadLine()
End Sub
End Module
Código fuente 5.2

Es posible que en algunas situaciones, esta característica podría ser aplicada a


nuestro código, pero hace que sea más complicado de leer, le resta claridad a
nuestra aplicación, es por ello que es recomendable no hacer uso de ella a no ser
que sea muy necesario.

Procedimientos
El código ejecutable de una aplicación va ubicado en rutinas de código o
procedimientos. El concepto de un procedimiento es el siguiente:
Un procedimiento es un elemento del lenguaje compuesto de un conjunto de líneas
de código a éstas se las denomina, cuerpo del procedimiento. El inicio y fin del
procedimiento, se establece mediante palabras reservadas del lenguaje, se le

- 89 -
asocia un identificador, lo que servirá para como su nombre lo dice, identificarlo
entre el resto de procedimientos creados en nuestra aplicación. También se le
puede enviar información adicional en forma de parámetros, con ello, el resultado
de la ejecución del procedimiento variará dependiendo de los valores que se pasen
en cada llamada.
En VB.NET tenemos los siguientes tipos de procedimientos:
Sub. Es el procedimiento que realiza un conjunto de operaciones, éstas
operaciones no devuelven un valor al punto de llamada. Durante todo el manual
nos referiremos a las rutinas de tipo Sub con el nombre genérico de procedimiento.
Function. Es el procedimiento que realiza un conjunto de operaciones, y devuelve
un valor llamado valor de retorno al punto de código al punto que realizó la
llamada. Durante el resto del manual nos referiremos a los procedimientos de tipo
function con el nombre genérico de función.
Property. Este procedimiento se usa para las tareas de acceso y asignación de
valores a las propiedades de un objeto. Mas adelante, en los temas que se refieren
a la programación orientada a objetos, los veremos con mas detenimiento y en
forma más profunda.

Sintaxis de un procedimiento Sub


El formato para la escritura de un procedimiento Sub se muestra en el código
fuente 5.3.
[Ámbito] Sub NombreProcedimeinto [(ListaParámentros)]
[CódigoEjecutable]
[Exit Sub / Return]
[CódigoEjecutable]
End Sub
Código fuente 5.3

Desglosando cada uno de los elementos que intervienen en éste tipo de rutina
tenemos:
Ámbito. Este elemento define el modo en que se podrá acceder o llamar al
procedimiento desde otro punto de la aplicación. El ámbito de los elementos del
lenguaje se verá en otro apartado.
Sub...End Sub. Éstas palabras claves significan el inicio y final del procedimiento
respectivamente. Al hacer una llamada al procedimiento, el compilador entenderá
que se debe ejecutar el código comprendido entre éstas dos palabras clave.
NombreProcedimiento. Este identificador lo usamos para reconocer y llamar al
procedimiento.
ListaParámetros. Ésta es la lista de identificadores están separados por comas,
encerrados entre paréntesis, que representan la información que recibe el
procedimiento desde el código llamador. Dentro del cuerpo del procedimiento, estos
identificadores o parámetros se usan igual que variables.
Return. Esta palabra clave da lugar a salir de la ejecución del procedimiento sin
haber llegado a su fin. Se usa en tantos lugares como sean necesarios dentro del
procedimiento. Es recomendable usar Return en lugar de Exit Sub, ya que podemos

- 90 -
emplear Return para salir de cualquier tipo de procedimiento, con ello se unifica la
escritura del código.
Exit Sub. Esta palabra clave, al igual que en el punto anterior, permite salir de la
ejecución del procedimiento sin haber finalizado, pudiendo de igual manera, situarla
en los lugares y cuantos sean necesarios en el procedimiento.
Mostramos el modo más sencillo de crear un procedimiento en el código fuente 5.4.
Éste procedimiento lo escribiremos en la aplicación de consola con la que estamos
realizando pruebas a continuación del Main()
Sub Prueba()
Console.WriteLine("Estamos en el procedimiento de prueba")
End Sub
Código fuente 5.4

Llamada a un procedimiento Sub


Para realizar lo que se denomina llamada o ejecución de un procedimiento Sub,
debemos escribir su nombre en un punto del programa. En el siguiente código
fuente mostraremos el código completo del módulo de nuestra aplicación de
consola. Como es habitual, la ejecución del programa comienza Main() dentro del
cual se realiza la llamada al procedimiento Prueba(). Ver código fuente 5.5
Module Module5
Sub Main()
Console.WriteLine("Estamos en el procedimiento Main")

' llamada a un procedimiento


Prueba()

Console.ReadLine()
End Sub

Sub Prueba()
Console.WriteLine("Estamos en el procedimiento Prueba")
End Sub
End Module
Código fuente 5.5

Cuando se hace la llamada a un procedimiento Sub, el uso de los paréntesis es


opcional, al margen de sí pasamos o no parámetros. Pero, es muy recomendable
especificar dichos paréntesis, ya que aportan una gran claridad a nuestro código,
de forma que al leerlo, nos demos cuenta enseguida de los puntos donde hacemos
una llamada a una rutina de código. Por ello, el IDE sitúa de manera automática los
paréntesis de forma que si no les especificamos explícitamente, estarán allí.
Es importante mencionar que no es posible situar la llamada a un procedimiento
Sub como parte de una expresión, ya que como lo dijimos antes, el procedimiento
Sub no devuelve valor, y, situarla como expresión, provocaría un error de
compilación. Ver figura 5.1

- 91 -
Figura 5.1. No es posible hacer una llamada a un procedimiento Sub en una expresión

Sintaxis de un procedimiento Function


En el código fuente 5.6 veremos el formato para la escritura de un procedimiento
Function.
[Ámbito] Function NombreFunción [(ListaParámetros)] As TipoDato
[Código ejecutable]
[Return Valor]
[NombreFunción = Valor]
[Exit Function]
[CódigoEjecutable]
End Function
Código fuente 5.6

Desglosando cada uno de los elementos que contiene ésta rutina tenemos:
Ámbito. Éste define el modo en el que accederemos o llamaremos al procedimiento
desde otro punto de la aplicación. El ámbito de los elementos del lenguaje será
visto en próximos apartados.
Function... End Function. Ésta palabra clave indica el inicio y final de la función
respectivamente. El compilador ejecuta el código comprendido entre éstas dos
líneas al hacer la llamada a la función.
NombreFunción. Es el identificador que se usa para reconocer y llamar a la
función. También usamos su nombre para darle el valor que será devuelto al código
en el modo NombreFunction = Valor, podemos situar ésta expresión de devolución
en tantos lugares como sea necesario dentro de la función.
TipoDato. Es el tipo de dato del que devuelve como resultado de la ejecución de la
función.
ListaParámetros. Es la lista de identificadores, están separados por comas, y
encerrados entre paréntesis. Éstos representan la información que recibe la función
desde el código llamador. Son usadas igual que variables dentro del cuerpo del
procedimiento.
Return. Lo que hace esta palabra clave es permitir salir de la función sin haber
llegado al final, y al mismo tiempo devolviendo un valor al código que hizo la
llamada. Podemos usarla dentro de la función en tantos lugares como se requiera.
Exit Function. Es una palabra clave y permite salir de la función sin haber
terminado. Se la puede usar dentro de la función en tantos lugares como sean
necesarios.

- 92 -
El código fuente 5.7 muestra un simple ejemplo de procedimiento Function, en el
que se pide al usuario que escriba un número que es devuelto como resultado de la
función.
Function Calcular() As Integer
Dim MiValor As Integer

Console.WriteLine("Introducir un número de 1 a 100")


MiValor = Console.ReadLine()

Return MiValor

' podemos usar esta sintaxis para devolver el valor


' de retorno de la función:
' Calcular = MiValor
End Function
Código fuente 5.7

Si se da caso de devolver el valor de retorno de una función usando el mismo


nombre, tenemos el problema de que si en determinado momento debemos
cambiar el nombre de la función, también debemos cambiar todos los puntos de la
rutina donde se devolvió el valor. Por ello, es recomendable el uso de Return para
devolver el valor, porque si tenemos que cambiar el nombre de la función, no será
necesario modificar en los puntos en que se devuelve el valor de este tipo de
procedimiento.

Llamada a un procedimiento Function


Para ejecutar un procedimiento Function o hacer una llamada a dicho
procedimiento, debemos escribir su nombre en un punto del programa así como
hacemos con el procedimiento Sub, es en este aspecto donde ambos tipos de
procedimientos son iguales.
Los puntos donde se marca la diferencia son los siguientes:
Un procedimiento Function devuelve un valor, por lo tanto, si queremos obtenerlo,
lo que hacemos es asignar la llamada a la función a una variable. Por el contrario,
los procedimientos Sub no pueden devolver un valor.
Precisamente por que el procedimiento Function tiene la capacidad de devolver un
valor, podemos situar la llamada a una función dentro de una expresión, lo que da
nuestro código mayor flexibilidad. En tanto que los procedimientos Sub no pueden
formar parte de expresiones.
En el código fuente 5.8 vemos varios ejemplos de llamadas a la función Calcular(),
según el modo en que manipularemos su valor de retorno.
Module Module5
Sub Main()
Dim Resultado As Integer
Dim NuevoValor As Integer

' llamada a una función sin guardar el valor de retorno,


' por ello, este valor se pierde
Calcular()

- 93 -
' llamada a una función obteniendo el valor de retorno
' asignando el valor a una variable
Resultado = Calcular()
Console.WriteLine("La variable Resultado contiene: {0}",
Resultado)

' llamada a una función como parte de una expresión


NuevoValor = 2750 + Calcular() * 2
Console.WriteLine("La variable NuevoValor contiene : {0}",
NuevoValor)

Console.ReadLine()
End Sub

Function Calcular() As Integer


Dim MiValor As Integer

Console.WriteLine("Introducir un número de 1 a 100")


MiValor = Console.ReadLine

Return MiValor

' se puede también usar esta sintaxis para


' devolver el valor de retorno de la función
' Calcular = MiValor
End Function
End Module

Código fuente 5.8

Paso de parámetros a procedimientos


El parámetro es un valor que es pasado a un procedimiento. Éste valor puede ser
variable, una constante, o una expresión. Los procedimientos pueden recibir
parámetros en forma se lista de variables separada por comas. Ver código fuente
5.9 para ver la sintaxis del paso de parámetros.
[Optional][ByVal / ByRef] [ParamArray] NombreParametro As TipoDato
código fuente 5.9

Las reglas sobre paso de parámetros descritas en los siguientes apartados, son
válidas tanto para procedimientos como para funciones, a excepción de aquellos
lugares donde se indique lo contrario.

Protocolo de llamada o firma de un procedimiento


A la lista de parámetros de un procedimiento se le llama protocolo de llamada o
firma (signature) del procedimiento. Este tipo de concepto lo veremos mas
detenidamente en el apartado dedicado a la sobrecarga de procedimientos.

Tipo de dato de un parámetro


Así como hacemos al declarar una variable, al declarar un parámetro lo que se debe
hacer es especificar el tipo de dato que el parámetro contendrá. Esto puede o no
ser obligado, en función del modificador establecido en la instrucción Option Strict

- 94 -
Ver en el código fuente 5.10 que se añadió un parámetro de tipo String al
procedimiento Prueba(). Cuando se llame desde otro procedimiento a Prueba(), al
pasar desde el código llamador a una cadena de caracteres, ya sea de forma literal
o en una variable, el contenido de dicha cadena se traspasará a la variable que está
en la lista de parámetros del procedimiento, que luego visualizaremos en la
consola. El código fuente es la modificación del código fuente anterior.
Module Module5
Sub Main()
Dim Nombre As String

Nombre = "Anna"
Prueba(Nombre)

Prueba("Esto es una prueba")


Console.ReadLine()

End Sub
Sub Prueba(ByVal ValorMostrar As String)
Console.WriteLine("El valor del parámetro pasado es {0}",
ValorMostrar)
End Sub
End Module
Código fuente 5.10

Modos de paso de parámetros a un procedimiento.


En Visual Studio .NET existen dos modos de pasar parámetros a un procedimiento
por valor y por referencia, este aspecto del lenguaje está relacionado con la forma
en que el contenido de los parámetros es gestionado internamente en la memoria.
Esto nos permite, alterar el valor del parámetro en el código que realizó la llamada,
según el tipo de paso empleado.
Paso por valor (ByVal)
Al pasar un parámetro por valor a un procedimiento, la variable que contiene el
parámetro puede ser modificada dentro del procedimiento, sin que estos cambios
afecten al valor original en el código llamador. En este caso, en el procedimiento
situamos la palabra clave ByVal antes del nombre del parámetro. Ver código fuente
5.11
Module Module5
Sub Main()
Dim Nombre As String

Nombre = "Anna"

' se hace el llamado a un procedimiento y


' se pasa una variable por valor
Prueba(Nombre)

' la variable que se pasó al parámetro,


' al volver aquí no fué cambiada, puesto que
' fué pasada por valor, sigue conteniendo "Anna"

- 95 -
Console.WriteLine("El valor de la variable dentro del Main():
{0}", Nombre)
Console.ReadLine()
End Sub
Sub Prueba(ByVal ValorMostrar As String)
' se modificará el valor del parámetro,
' este cambio no afecta a la variable Nombre
ValorMostrar = "Margarita"
Console.WriteLine("Valor del parámetro dentro de Prueba()",
ValorMostrar)
Console.ReadLine()

End Sub
End Module
Código fuente 5.11

En el código fuente anterior, a nivel de gestión interna en memoria de los


parámetros, ocurre lo siguiente: al realizar la llamada al procedimiento y pasar el
parámetro, el entorno detecta que se trata de un parámetro pasado por valor, y
crea una nueva variable en memoria a la cual manipularemos dentro del
procedimiento. La representación gráfica de éste proceso está en la figura 5.2

Figura 5.2. Esquema de gestión interna de variables en el paso por valor

En el entorno de .NET Framework, por defecto, son pasados por valor. Esto se
puede comprobar de una manera muy sencilla: si al declarar un parámetro no se
especifica el tipo de paso, el IDE de forma automática situará junto al parámetro, la
palabra clave ByVal.
Es recomendable en tanto sea posible, el paso de parámetros por valor, puesto que
ayuda a obtener un código más optimizado y contribuye a mejorar la
encapsulación.
Paso por referencia (ByRef)

- 96 -
Si al pasar un parámetro por referencia a un procedimiento, se modifica dentro del
procedimiento la variable que contiene el parámetro, éstos cambios en este caso sí
afectan al código llamador, lo que debe hacer entonces es situar en el
procedimiento, la palabra clave ByRef antes del nombre del parámetro. Si se
cambia el código fuente anterior, y se hace que en este caso, el parámetro sea
pasado por referencia y se observa, los resultados son los siguientes. Ver código
fuente 5.12
Module Module5
Sub Main()
Dim Nombre As String

Nombre = "Anna"
Console.WriteLine("Valor de la variable antes de llamar a
Prueba(): {0}", Nombre)

'se llamará a un procedimiento


' y se le pasará una variable por referencia
Prueba(Nombre)

' el cambio realizado al parámetro en el procedimiento


' afectó a la variable Nombre, que aquí contiene
' el mismo valor que se asignó en el procedimiento
Console.WriteLine("El valor de la variable dentro del Main():
{0}", Nombre)
Console.ReadLine()
End Sub
Sub Prueba(ByRef ValorMostrar As String)
' modificamos el valor del parámetro
ValorMostrar = "Margarita"
Console.WriteLine("Valor del parámetro dentro de Prueba()",
ValorMostrar)
End Sub
End Module
Código fuente 5.12

A nivel de gestión interna de memoria en los parámetros ocurre lo siguiente:


cuando se realiza la llamada al procedimiento y se pasa el parámetro, el entorno
detecta que es un parámetro pasado por referencia, y tanto la variable del código
llamador como la del procedimiento llamado, usan la misma dirección de memoria o
referencia hacia los datos, por lo tanto, los cambios realizados en un procedimiento
afectarán también al otro. En la figura 5.3 se ve la representación gráfica de éste
proceso.

- 97 -
Figura 5.3

Paso de parámetros por posición y por nombre


Cuando se llama a un procedimiento con parámetros, éstos de deben pasar en el
mismo orden en que se los está especificando en la declaración del procedimiento,
a esto se le denomina el paso de parámetros por posición.
Hay otro modo de paso de parámetros en el cuál no se está obligado a situarlos en
el mismo orden que indica la declaración, a esto se lo denomina paso de
parámetros por nombre. Aquí debemos situar en la llamada al procedimiento el
nombre del parámetro, seguido de dos puntos e igual (:=) y finalmente el valor a
pasar.
Veremos algunos ejemplos de ambos tipos de paso de parámetros en el código
fuente 5.13
Module Module5
Sub Main()
Dim Provincia As String
Dim Importe As Integer
Dim DiaHoy As Date
'------------------
Provincia = "Córdoba"
Importe = 2750
DiaHoy = #10/8/2002#

'paso de parámetros por posición


Prueba(Provincia, Importe, DiaHoy)

'------------------

- 98 -
Provincia = "Buenos Aires"
Importe = 450
DiaHoy = #6/1/2002#

' paso de parámetros por nombre


Prueba(Cantidad:=Importe, Fecha:=DiaHoy, Ciudad:=Provincia)

Console.ReadLine()
End Sub

Sub Prueba(ByVal Ciudad As String, ByVal Cantidad As Integer,


ByVal Fecha As Date)
Console.WriteLine("Valores de los parámetros")
Console.WriteLine("Ciudad: {0} - Cantidad: {1} - Fecha: {2}",
Ciudad, Cantidad, Fecha)

End Sub
End Module

código fuente 5.13

ambos tipos de llamada a un procedimiento pueden ser mezclados, teniendo en


cuenta que en los parámetros que no usemos el paso por nombre, deben ir
situados en la posición correcta. El código fuente 5.14 muestra un ejemplo de una
variación del código anterior.
Prueba (Localidad, Fecha := DíaHoy, Cantidad := Importe)

Código fuente 5.14

Parámetros opcionales
El parámetro opcional es aquél que no es necesario hacer la llamada a un
procedimiento.
Para señalar que un parámetro es opcional en la declaración de un procedimiento,
se debe usar la palabra clave Optional y a continuación la especificación del
parámetro, y por último, la asignación de un valor por defecto para el parámetro.
También se debe tener en cuenta que, a partir del primer parámetro opcional en la
lista de un procedimiento, todos los parámetros siguientes a ese, deben ser
opcionales.
A continuación, crearemos una función en la que declararemos a un parámetro
opcional. Luego se harán dos llamadas a dicho procedimiento, pasando y omitiendo
el parámetro opcional, respectivamente en cada llamada. Ver código fuente 5.15
Module Module5
Sub Main()
Dim Provincia As String
Dim Importe As Integer
Dim Resultado As Integer
'------------------
Provincia = "Córdoba"
Importe = 2750

'paso de todos los parámetros al procedimiento


Resultado = Calcular(Provincia, Importe)

- 99 -
Console.WriteLine("Primera llamada, valor devuelto: {0}",
Resultado)

'------------------
Provincia = "Buenos Aires"

' paso sólo del primer parámetro al procedimiento


' esto hará que se use el valor por defecto
' del parámetro opcional
Resultado = Calcular(Provincia)
Console.WriteLine("Segunda llamada, valor devuelto: {0}",
Resultado)

Console.ReadLine()
End Sub

Function Calcular(ByVal Ciudad As String, Optional ByVal Cantidad


As Integer = 1250) As Integer
Console.WriteLine("Valores de los parámetros")
Console.WriteLine("Ciudad: {0} - Cantidad: {1}", Ciudad,
Cantidad)

Return Cantidad + 100

End Function
End Module
Código fuente 5.15

Arrays de parámetros.
Si en la lista de parámetros de procedimientos usamos la palabra clave ParamArray
junto al nombre del último parámetro de la lista, dicho parámetro entonces es
considerado un array, por lo tanto, al hacer la llamada al procedimiento, podemos
pasarle un numero variable de valores que se manejarán a través del de array. Ver
código fuente 5.16
Module Module5
Sub Main()
Dim Valor As Integer
Dim Ciudad As String
Dim Nombre As String

Valor = 2307
Ciudad = "Mendoza"
Nombre = "Fernando"

' en la llamada al procedimiento Prueba()


' todos los valores que se pasen a continuación
' del primer parámetro serán depositados
' en el array de parámetros
Prueba(Valor, Ciudad, "mesa", Nombre)

Console.ReadLine()
End Sub
' el parámetro MasDatos del procedimiento es un array

- 100 -
' del parámetro variables
Sub Prueba(ByVal Importe As Integer, ByVal ParamArray MasDatos()
As String)
Dim Contador As Integer

' mostrar el primer parámetro


Console.WriteLine("Parámetro Importe: {0}", Importe)
Console.ReadLine()

' el resto de parámetros del procedimiento


' están en el array, se los obtiene recorriéndolo con (una)
estructura For...Next
Console.WriteLine("Contenido del array de parámetros
MasDatos():")
For Contador = 0 To UBound(MasDatos)
Console.WriteLine("Elemento: {0} - Valor: {1}", Contador,
MasDatos(Contador))
Next
End Sub
End Module

Código fuente 5.16

La ventaja que tenemos al usar ParamArray es que podemos pasarle una cantidad
variable de parámetros al procedimiento en cada llamada. La única restricción es
que debemos usarlo como último parámetro de la lista del procedimiento.
Sobrecarga de procedimientos
Vimos que el uso de parámetros opcionales es un medio para ahorrar al
programador el paso de los mismos en situaciones en las que realmente no son
necesarias, pero resulta una solución tanto artificiosa, puesto que en vez de facilitar
la escritura, la complica más.
VB.NET aporta una nueva técnica al lenguaje, esta permite obviar el uso de
parámetros opcionales, en lugar de ello, le da una solución más elegante y flexible;
son los procedimientos sobrecargados
Daremos un ejemplo antes de explicar lo que es un procedimiento sobrecargado.
Se necesita mostrar los datos de un empleado de dos maneras, en función del
modo de consulta. Por un lado visualizaríamos su nombre, domicilio y localidad; y
por el otro, su edad, DNI y fecha de ingreso a la empresa.
Con lo que vimos hasta el momento, podría resolverse el problema escribiendo el
procedimiento con parámetros opcionales, y según se pase un valor u otro, mostrar
la información correspondiente.
En el código fuente 5.17 se muestra el modo de resolver el problema.
Module Module5
Sub Main()
' mostrar datos del empleado
' en función del nombre
VerDatosEmpleado("Leonardo")

- 101 -
' mostrar datos del empleado
' en función de la edad
VerDatosEmpleado(, 28)

Console.WriteLine()
End Sub
Sub VerDatosEmpleado(Optional ByVal Nombre As String = "X",
Optional ByVal edad _
As Integer = 5555)
If Nombre <> "X" Then
Console.WriteLine("Nomre del empleado, {0}", Nombre)
Console.WriteLine("Domicilio: Alcina 456")
Console.WriteLine("Localidad: Capital Federal")
End If

If edad <> 999 Then


Console.Write("Edad del empleado: {0}", edad)
Console.Write("DNI:93945677")
Console.Write("Fecha de alta en la empresa: 10/4/1997")
End If

Console.ReadLine()
End Sub

End Module

Código fuente 5.17

Como vimos en el anterior código, el uso de parámetros opcionales resulta


engorroso, puesto que nos obliga a comprobar qué valor fue pasado y en
consecuencia, mostrar los datos correspondientes. Además añadimos un
inconveniente, y es que se puede pasar los dos parámetros a la vez, con lo que se
mostrarían todos los datos, cuando lo que se desea en realidad es visualizar un
grupo u otro en cada llamada.
Un aproximación de la solución del problema sería escribir dos procedimientos
diferentes, y llamar a uno u otro según los datos que necesitemos. Ver código
fuente 5.18

Module Module5
Sub Main()
'mostrar datos del empleado según nombre
VerEmpleadoNombre("Pedro")

'mostrar datos del empleado según la edad


VerEmpleadoNum(28)

Console.ReadLine()
End Sub

Public Sub VerEmpleadoNombre(ByVal Nombre As String)


Console.WriteLine("Datos empleado por nombre")
Console.WriteLine("Nombre del empleado: {0}", Nombre)

- 102 -
Console.WriteLine("Domicilio: Monroe 456")
Console.WriteLine("Localidad: Capital Federal")
Console.WriteLine()
End Sub

Public Sub VerEmpleadoNum(ByVal Edad As Integer)


Console.WriteLine("Datos empleado por edad")
Console.WriteLine("Edad del empleado: {0}", Edad)
Console.WriteLine("DNI: 23568974")
Console.WriteLine("Fecha de alta en la empresa: 10/4/1997")
Console.WriteLine()
End Sub
End Module
Código fuente 5.18

Pero con esta solución debemos saber varios nombres de procedimientos, con lo
que tampoco simplifica mucho el código.
Sería ideal disponer de un único nombre de procedimiento y que este fuera los
suficientemente inteligente como para mostrar los datos adecuados en cada caso,
bueno pues, ésta característica es implementada en VB.NET a través de la
sobrecarga de procedimientos.
El concepto de sobrecarga de procedimiento se refiere a lo siguiente: es una técnica
que consiste en crear varias versiones de un mismo procedimiento, se distinguen
entre sí mediante la lista de parámetros o protocolo de llamada del procedimiento.
La declaración del procedimiento sobrecargado debe comenzar con la palabra clave
Overloads. Podemos usar procedimientos tanto Sub como Function al realizar la
sobrecarga, por lo tanto, es posible que una de las implementaciones no tenga lista
de parámetros. En el código fuente 5.19 veremos un ejemplo de sobrecarga.
Overloads Sub Datos()
„ código del procedimiento
„ …………..
„ …………..
End Sub

Overloads Sub Datos(Lista de ParámetrosA)


„ Código del procedimiento
„ …………..
„ …………..
End Sub

Overloads Sub Datos(Lista de ParámetrosB) As Tipo de DatoRetorno


„ Código del procedimiento
„ …………..
„ …………..

End Function

Código fuente 5.19

Vemos que en el ejemplo anterior, cuando llamemos al procedimiento Datos(), el


entorno de .NET Framework, en función de si pasamos o no parámetros al
procedimiento, y de cómo sean esos parámetros ejecutará la versión adecuada del
procedimiento.

- 103 -
Puesto que el protocolo o firma del procedimiento es el elemento que emplea .NET
Framework para diferenciar cada una de sus versiones o implementaciones, las
listas de parámetros de cada versión deben ser diferentes al menos en uno de los
siguientes aspectos:
Número de parámetros
Orden de los parámetros
Tipo de dato de los parámetros
Por lo tanto, no es posible crear dos procedimientos sobrecargados que sólo se
diferencien en los nombres de los parámetros, por los modificadores de ámbito
(Public, Private, etc.), o por el tipo de dato de retorno en el caso de un
procedimiento Function.
Luego de que se vio las normas y restricciones aplicables a los procedimientos
sobrecargados, veremos en el código fuente 5.20 la solución al problema planteado
al comienzo de este apartado empleando esta técnica.
Module Module5
Sub Main()
Dim Días As Integer
'mostrar datos del empleado según nombre
VerEmpleadoNombre("Pedro")

'mostrar datos del empleado según la edad


Días = VerEmpleadoNum(28)
Console.WriteLine("Días libres del empleado: {0}", Días)
Console.WriteLine()

' mostrar salario según las horas trabajadas


verEmpleado(25, 80)

Console.ReadLine()
End Sub

Public Sub VerEmpleadoNombre(ByVal Nombre As String)


Console.WriteLine("Datos empleado por nombre")
Console.WriteLine("Nombre del empleado: {0}", Nombre)
Console.WriteLine("Domicilio: Monroe 456")
Console.WriteLine("Localidad: Capital Federal")
Console.WriteLine()
End Sub
Overloads Function VerEmpleadoNum(ByVal Edad As Integer) As
Integer
Dim DiasLibres As Integer
Console.WriteLine("Datos empleado por edad")
Console.WriteLine("Edad del empleado: {0}", Edad)
Console.WriteLine("DNI: 23568974")
Console.WriteLine("Fecha de alta en la empresa: 10/4/1997")
Console.WriteLine()

DiasLibres = 5
Return DiasLibres
End Function

- 104 -
Overloads Sub VerEmpleado(ByVal PrecioHora As Integer, ByVal
HorasTrabajadas As Long)
Dim Salario As Long

Salario = PrecioHora * HorasTrabajadas


Console.WriteLine("Salario según horas: {0}", Salario)
Console.WriteLine()
End Sub
End Module

Código fuente 5.20

Como vemos en el código anterior, se creó tres versiones de sobrecargas del


procedimiento VerEmpleado(). En una se muestra los datos del empleado según el
nombre; en otra mostramos también otro conjunto de datos según la edad, y al ser
una función, devolvemos el número de días libres del empleado; y por último en
una tercera implementación, calculamos el salario según el precio por hora y las
horas trabajadas que pasamos al protocolo de llamada. Por lo tanto, desde el
Main() siempre llamamos al procedimiento VerEmpleado().

Lista desplegable “Nombre de método”, en el editor de


código
La lista desplegable Nombre de método, ubicada en la parte superior derecha del
editor de código, tiene dos finalidades principales. A continuación se muestra una
descripción general.
Mostrar el nombre del procedimiento sobre el que actualmente trabajamos.
Esta es útil sobre todo en procedimientos con muchas líneas de código en las que
no se tiene en todo momento visible la declaración del procedimiento.
Cambiar a otro procedimiento del módulo de código. Al abrir la lista
desplegable y hacer clic sobre algunos de los nombres de procedimiento que se
muestran, nos situaremos al inicio de dicho procedimiento. Este es un medio más
rápido para desplazarnos entre los procedimientos, a tener que recorrer toda la
ventana del editor de código.
En el ejemplo de la figura 5.4, estamos situados en el procedimiento Main(), y al
abrir esta lista de procedimientos, podemos cambiar de manera sencilla a cualquier
otro de los que se creó.

- 105 -
Figura 5.4. Lista Nombre de método, en el editor de código del IDE

El motivo de usar el término método en lugar de procedimiento para esta lista, se


debe a que como se verá en el tema sobre objetos, todo lo que se hará
habitualmente en nuestra labor de programación, será crear clases, objetos,
métodos, propiedades, etc. Por esto, la terminología empleada en general se
aproxima más a la técnica de programación con objetos que a la programación
estructurada.

- 106 -
Laboratorio 2
Ejercicio 1
Escriba un programa que sume una secuencia de enteros. Suponga que el primer
entero leído con Read() especifica el número de valores que faltan de introducir. Su
programa deberá leer un valor cada vez que Read() sea ejecutado. Una secuencia
típica pudiera ser
5 100 200 300 400 500
Donde 5 indica que los 5 valores subsiguientes deberán ser sumados
Ejercicio 2
Escriba un programa que calcule e imprima el promedio de todos los valores que
preceden a 9999. Una secuencia típica de entrada pudiera ser
10 11 7 9 9999
Indicando que debe calcularse el promedio de todos los valores que preceden a
9999
Ejercicio 3
Escriba un programa que localice el más pequeño de varios enteros. Suponga que
el primer valor leido especifica el número de valores que restan
Ejercicio 4
Escriba un programa que calcule e imprima la suma de los enteros pares del 2 al 30
Ejercicio 5
La función factorial se utiliza con frecuencia en problemas de probabilidad. El
factorial de un entero positivo n (escrito n! Y dicho como “factorial de n”) es igual
al producto de los enteros positivos del 1 hasta n. Escriba un programa que evalue
los factoriales de los enteros del 1 al 5. Imprima el resultado como tabular
Ejercicio 6
Escriba un programa que imprima los siguientes patrones por separado, uno debajo
del siguiente. Utilice ciclos for para generar los patrones. Todos los asteriscos (*),
deberán ser impresos por un solo enunciado Write de la forma Write(“*”) ( Esto
hace que los asteriscos se impriman uno al lado del otro)

- 107 -
Módulo 6

Introducción a los arrays.


Operadores

- 108 -
Depuración del código de ejecución
Hasta el momento, para comprobar el resultado de los ejemplos realizados, se usó
la salida de consola. Pero, esto no es suficiente información para el programador a
la hora de desarrollar una aplicación.
El lenguaje o entorno de programación proporciona al programador utilidades que
le permiten comprobar cómo se ejecuta el código de aplicación línea por línea,
información sobre el contenido de las variables, expresiones, puntos de interrupción
en la ejecución, etc. Al conjunto de todas estas técnicas o utilidades que debe
aportar el lenguaje se le llama depurador.
Visual Studio .Net aporta un depurador muy completo, en este capitulo se mostrará
algunas de las funcionalidades básicas, dejaremos para temas posteriores el
estudio completo de ésta herramienta.
Puesto que algunas características del depurador y de otros elementos se realizan
por medio de combinaciones del teclado, es bueno configurar el IDE al perfil del
programador más adecuado, o con el que nos encontremos más cómodos.
Un depurador nos permite ingresar dentro del código de nuestro programa durante
la ejecución de este, para que observemos lo que pasa: ejecutar línea a línea el
programa, observar el valor de las variables, etc. Todos estos aspectos que son
fundamentales para el seguimiento de errores y fallos en la lógica de aplicación.
El depurador que dispone VS.NET es excelente. A continuación describiremos sus
elementos más básicos, para que el lector pueda hacer un seguimiento mas preciso
en cuanto a lo que sucede durante la ejecución de la aplicación.
Si deseamos ejecutar el programa en modo de depuración pulsar F8, o seleccionar
del menú Depurar + Ir a instrucciones. Ambas instrucciones iniciarán el programa
dentro del contexto del depurador, detiene la ejecución en la primera línea de
código, destacada en color amarillo. Ésta línea es la que está a punto de ejecutarse,
para ejecutarla y pasar nuevamente a la siguiente línea de código, pulsar
nuevamente F8, y así sucesivamente hasta llegar a la ultima línea de código, donde
el depurador finalizará la ejecución.
Observamos de forma inmediata el valor de una variable simplemente situando el
cursor de mouse sobre ella, lo que mostrará el contenido en una viñeta informativa.
Ver figura 6.3.

Figura 6.3. Visualizando el contenido de una variable durante la depuración

- 109 -
Podemos además ver con detalle el valor que van adquiriendo las variables a lo
largo de la ejecución, abriendo la ventana Locales del depurador por medio del
menú Depurar + Ventanas + Locales o por la combinación de teclas CTRL. + ALT +
V, L. Ver figura 6.4.

Figura 6.4. Ventanas locales del depurador.

Para continuar la ejecución normal del programa, en cualquier momento se puede


pulsar F5 y saldrá del modo depurador.

Arrays
En capítulos anteriores se indicó en la descripción general de los componentes del
lenguaje que un array es un tipo de dato compuesto formado por un conjunto de
elementos del mismo tipo de dato al que se le asigna un identificador para poder
reconocerlo en el código del programa. Es llamado también matriz o vector, auque
en el manual emplearemos el término genérico array. A cada elemento del array se
accede mediante un índice, que indica el número de posición que ocupa el elemento
dentro del array.
Para representarlo gráficamente, podríamos hacerlo mediante un conjunto de
casillas, en cada una de las cuales se encontraría un elemento del array. Cada
casilla tendría un número (índice) que identificaría de forma única su posición. Ver
figura 6.5.

Figura 6.5. Representación gráfica de un array.

En éste capítulo, se realizará una introducción a los arrays y su uso de forma


básica. Porque los tipos de datos pueden ser tratados a mismo tiempo como
objetos en el lenguaje VB.NET, al llegar a la programación orientada a objetos
cubriremos los aspectos avanzados sobre arrays

Declaración
Al declarar un array se hace de la misma manera que si declarásemos una variable
normal, con la diferencia que se usan los paréntesis junto al nombre de la variable
para indicar que se trata de un array, y de forma opcional, dentro de los

- 110 -
paréntesis, indicamos el número de elementos que el array contendrá inicialmente.
Es posible también asignar valores a los elementos en momento de la declaración.
Se debe tomar en cuenta a la hora de establecer el número de elementos, que el
primer índice de un array es el cero, por lo que al ser creado, el número verdadero
de elementos en un array será especificado en la declaración más uno.
La figura 6.6 muestra un esquema de la declaración de un array.

En el código fuente 6.1 se verá unos ejemplos de creación de arrays


Module Module6
Sub Main()
' array sin elementos
Dim Colores() As String

' array con 4 elementos vacíos: de 0 a 3


Dim Nombres(3) As String

' array con 3 elementos, cuyos valores asignamos


' en el momento de la declaración del array
Dim Frutas() As String = {"Uva", "Durazno", "Banana"}
End Sub
End Module
Código fuente 6.1

Figura 6.6. declaración de un array

Todos los valores son del mismo tipo de dato cuando se declara un array, si se
necesitase que dichos datos sean de tipos diferentes, se debe declarar al array
como tipo Object, puesto que al ser éste un tipo de dato genérico en el entorno de
.NET, esto permitirá asignar valores de distintos tipos al array.

Asignación y obtención de valores


Para asignar y obtener valores de los elementos de un array, se actúa igual que
para una variable normal, pero empleando el índice entre paréntesis junto al

- 111 -
nombre de la variable, para indicar la posición que de desea manipular. Ver código
fuente 6.2
Module Module6
Sub Main()
' array con 4 elementos: de 0 a 3
Dim Nombres(3) As String

'asignar valores al array


Nombres(0) = "Anna"
Nombres(1) = "Margarita"
Nombres(2) = "Pablo"
Nombres(3) = "Fernando"

' obtener valores de un array


Dim ValorA As String
Dim ValorB As String

ValorA = Nombres(1) ' Margarita


ValorB = Nombres(3) ' Fernando

' mostrar los valores obtenidos de array


Console.WriteLine("Variables: Valor A --> {0}, ValorB -->
{1}", ValorA, ValorB)
Console.ReadLine()
End Sub
End Module
Código fuente 6.2

Modificación de tamaño
En función de sí la cantidad de elementos de un array puede ser cambiada, los
arrays se clasifican de la siguiente manera
Estáticos. Son los arrays que tienen un tamaño fijo y no pueden ser modificados.
Dinámicos. Son los arrays cuya cantidad de elementos puede ser ampliada o
reducida. En VB.NET todos los arrays son de tipo dinámico.
Para modificar el número de elementos de un array o su tamaño, se emplea la
instrucción ReDim, seguida del array a modificar y el nuevo tamaño. En el código
fuente 45, se modifica el tamaño de un array, agregándole dos elementos.
' array con 4 elementos: de 0 a 3
Dim Nombres(3) As String

' asignar valores al array


Nombres(0) = "Anna"
Nombres(0) = "Gabriela"
Nombres(0) = "Fernando"
Nombres(0) = "Margarita"

'ampliamos el array con 6 elementos: de 0 a 5


ReDim Nombres(5)
Código fuente 6.3.

- 112 -
ReDim no toma el array existente y modifica su número de elementos, sino que
internamente crea un nuevo array con el número de elementos indicado, por lo que
los valores del array previo, se pierden.
Para resolver este problema, se debe usar junto a ReDim, la palabra clave
Preserve. Con esto, los valores existentes en el array a modificar son conservados.
Ver código fuente 6.4
' ampliamos el array con 6 elementos: 0 a 5
' y los valores de los elementos que hubiera, son conservados
ReDim Preserve Nombres(5
Código fuente 6.4

Recorrer un array
Para recorrer todos los elementos de un array, se emplea la estructura de control
For...Next, la que ejecuta un bloque de código un determinado número de veces, y
la función del lenguaje UBound(), que devuelve el número correspondiente al índice
superior del array pasado como parámetro. Ver código fuente 6.5.
Module Module6
Sub Main()
' crear un array y rellenarlo con valores
Dim Nombres(3) As String

Nombres(0) = "Anna"
Nombres(1) = "Margarita"
Nombres(2) = "Pablo"
Nombres(3) = "Fernando"

' recorrer el array y mostrar el contenido


' de cada uno de sus elementos
Dim Contador As Integer
For Contador = 0 To UBound(Nombres)
Console.WriteLine("Posición del array: {0}, valor: {1}",
Contador, Nombres(Contador))
Next

Console.ReadLine()
End Sub

End Module

Código fuente 6.5

Arrays multidimensionales
Según el modo en que se organizan los valores en sus elementos, los arrays se
clasifican de la siguiente manera:
Unidimensionales. Son aquellos arrays que tienen una sola lista de valores, que
se denomina dimensión. Hasta el momento se trabajó con éste tipo de array.
Multidimensionales. Consiste en un array que dispone de más de una lista de
valores o dimensión.

- 113 -
Los arrays multidimensionales se representan en forma de tabla, con filas y
columnas, como se muestra en la figura 6.7.

Figura 6.7 Representación gráfica de un array multidimensional.

Como terminamos de ver en el esquema de la figura, el primer número de la


declaración del array: 2, indica la cantidad de dimensiones que tiene el array, y el
segundo: 3, indica la cantidad de elementos que tendrá cada dimensión, puesto
que los arrays comienzan por cero, en este ejemplo se crea un array de tres
dimensiones, y cada una de éstas dimensiones tiene cuatro elementos. El código
fuente 6.6 muestra la forma de declarar y asignar valores a un array
multidimensional de éstas características.
Dim Artículos(2, 3) As String
Artículos(0, 0) = "cama"
Artículos(0, 1) = "mesa"
Artículos(0, 2) = "silla"
Artículos(0, 3) = "monitor"
Artículos(1, 0) = "teclado"
Artículos(1, 1) = "impresora"
Artículos(1, 2) = "cocina"
Artículos(1, 3) = "discos"
Artículos(2, 0) = "coche"
Artículos(2, 1) = "barco"
Artículos(2, 2) = "bicicleta"
Artículos(2, 3) = "tren"
Código fuente 6.6

Para recorrer los elementos de un array multidimensional se usan los bucles


For...Next o For Each...Next.
La diferencia entre usar una u otra técnica para manejar al contenido del array,
reside en que con la estructura For...Next tenemos un mayor control de los
elementos a manejar, en tanto que con For Each...Next, al implementar
internamente el proceso, irá tomando las primeras posiciones de cada una de las
dimensiones del array, después las segundas, y así sucesivamente.
Aplicando For...Next usaremos la función UBound() ya comentada anteriormente,
con la diferencia de que al emplearla para arrays multidimensionales, debemos
pasarle en el segundo parámetro, el número de dimensión del array del que se
extraerán valores. Veremos un ejemplo en el código fuente 6.7

- 114 -
Module Module6

Sub Main()
Dim Artículos(2, 3) As String
Dim Contador1 As Integer
Dim Contador2 As Integer
Artículos(0, 0) = "cama"
Artículos(0, 1) = "mesa"
Artículos(0, 2) = "cocina"
Artículos(0, 3) = "monitor"
Artículos(1, 0) = "teclado"
Artículos(1, 1) = "impresora"
Artículos(1, 2) = "impresora"
Artículos(1, 3) = "discos"
Artículos(2, 0) = "coche"
Artículos(2, 1) = "barco"
Artículos(2, 2) = "bicicleta"
Artículos(2, 3) = "tren"

For Contador1 = 0 To UBound(Artículos, 1)


Console.WriteLine("dimensión actual del array: {0}",
Contador1)
For Contador2 = 0 To UBound(Artículos, 2)
Console.WriteLine("------Valor del elemento: {0}",
Artículos(Contador1, Contador2))
Next
Next

End Sub

End Module
Código fuente 6.7

Operadores
Son aquellos elementos del lenguaje que nos permiten combinar variables,
constantes, valores literales, instrucciones, etc., para obtener un valor numérico,
lógico, de cadena, etc., como resultado.
La combinación de operadores con variables, instrucciones, etc., se llama
expresión, en tanto que a los elementos integrantes de una expresión y que no son
operadores, se lo denomina operandos.
En función de la complejidad de la operación a realizar, o del tipo de operador que
usamos, una expresión puede ser manipulada a su vez como un operando dentro
de otra expresión de mayor nivel.
Los operadores se clasifican en las categorías detalladas a continuación según el
tipo de expresión a construir.

Operadores aritméticos
Efectúan el conjunto habitual de operaciones matemáticas.

- 115 -
Potenciación: ^
Eleva un número a determinada potencia. Debemos situar el número base a la
izquierda del este operador, mientras que el exponente lo situamos a la derecha.
Podemos realizar varias potenciaciones al mismo tiempo y utilizar números
negativos. El valor devuelto será del tipo Double. Ver código fuente 6.8
Dim Resultado As Double

Resultado = 12 ^ 5 ' devuelve 248832


Resultado = 2 ^ 3 ^ 7 ' devuelve 2097152
Resultado = (-4) ^ 2
Código fuente 6.8

Multiplicación: *
Multiplica dos números. En caso de que uno de los operandos sea un valor nulo, se
usará como cero. Ver código fuente 6.9
Dim Resultado As Double
Dim DatosSinValor As Integer
Dim Indefinido As Object

Resultado = 25 * 15 ' devuelve: 375

' la variable DatosSinValor no fue asignada,


' por lo que contiene cero
Resultado = 25 * DatosSinValor ' devuelve: 0

'la variable Indefinido no fue asignada


' por lo que contiene Nothing
Resultado = 25 * Indefinido ' devuelve: 0

Resultado = 23.78 * 6.89 ' devuelve: 163.8442

Código fuente 6.9

División real: /
Divide dos números, devolviendo un resultado con precisión decimal. Ver código
fuente 6.10
Dim Resultado As Double

Resultado = 50 / 3 ' devuelve: 16.66666667


Resultado = 250 / 4 ' Devuelve 62.5
Código fuente 6.10

Por norma general, el número devuelto será de tipo Double. Sin embargo, si uno de
los operandos es de tipo Single, el resultado será de tipo Single. También, si los dos
operandos son del tipo de dato Decimal, el resultado también será Decimal.

División entera:\
Divide dos números devolviendo como resultado un valor numérico entero. Ver
código fuente 6.11

- 116 -
Dim Resultado As Integer

Resultado = 50 \ 3 ' devuelve: 16


Resultado = 250 \ 4 ' devuelve: 62
Código fuente 6.11

Resto: Mod
Divide dos números y devuelve el módulo o resto de la división. Ver código fuente
6.12
Dim Resultado As Double

Resultado = 10 Mod 3 ' devuelve: 1


Resultado = 100 Mod 27 ' devuelve: 19
Resultado = 38 Mod 4 ' devuelve : 2
Código fuente 6.12

Suma : +
En función del tipo de dato de los operandos, dicho operador realiza una suma de
números o una concatenación de cadena de caracteres. Puede haber un error
dependiendo del tipo de dato del operando, y la configuración de Option Strict. El
código fuente 6.13 muestra algunos ejemplos de sumas y concatenaciones, con la
instrucción Option Strict Off.
Module Module6
Sub Main()
Dim Resultado As Double
Dim Cadena As String
Dim Valor As Integer
Dim Nombre As String
Dim CadenaResultado As String

' suma de números


Resultado = 12 + 7 'devuelve: 19
Resultado = 450 + 130 ' devuelve: 580

' concatenación de cadenas


Cadena = "buenos días" + "amigos" ' devuelve: "buenos días
amigos"

' suma de variables


Cadena = "15"
Valor = 20
CadenaResultado = Cadena + Valor ' devuelve "35"

' operaciones incorrectas


Valor = 25
Nombre = "Eduardo"

CadenaResultado = Valor + Nombre ' error


Resultado = Valor + Nombre ' error
End Sub
End Module

- 117 -
Código fuente 6.13

Si a continuación cambiamos la configuración a Option Strict On, la siguiente


operación que se ejecutaba con Option Strict Off, ahora provocará un error. Ver
código fuente 6.14
' suma de variables
Cadena = "15"
Valor = 20
CadenaResultado = Cadena + Valor ' error
Código fuente 6.14

Para solucionar este problema, debemos convertir, explícitamente, todos los


operandos, al mismo tipo de datos. Observemos que en esta situación, no se
realiza una suma sino una concatenación. Ver código fuente 6.15

' suma de variables


Cadena = "15"
Valor = 20
CadenaResultado = Cadena + CStr(Valor) devuelve: “1520”

Código fuente 6.15

A pesar de que el operador + permite concatenar tipos String, es recomendable el


uso del operador específico de concatenación &, que se verá más adelante.

Resta: -
Efectúa una resta entre dos números, o cambia el signo de un número (de positivo
a negativo, o viceversa), ver código fuente 6.16
Module Module6
Sub Main()
Dim Resultado As Double
Dim Valor As Integer
Dim OtroValor As Integer

'resta de números
Resultado = 100 - 75

' cambiar el signo de un número


Valor = -50

' volver a cambiara el signo de un número


' estaba en negativo, con el cambio vuelve
' a ser positivo
OtroValor = -Valor

End Sub
End Module

Código fuente 6.16

- 118 -
Operadores de concatenación: &, +
Estos operadores permiten unir dos o más cadenas de caracteres para así formar
una única cadena. Es recomendable el uso de & para facilitar la legibilidad del
código y evitar ambigüedades. El uso de + es más fácil de confundirlo, puesto que
en muchas situaciones no se sabrá a primera vista si se está realizando una suma o
una concatenación. Ver código fuente 6.17
Module Module6
Sub Main()
Dim CadResultado As String
Dim Nombre As String

CadResultado = "esto es" & " una prueba"


Console.WriteLine("Variable CadResultado: {0}", CadResultado)

Nombre = "Gabriela"
CadResultado = Nombre & " Sabatini"
Console.WriteLine("Variable CadResutado: {0}", CadResultado)
Console.ReadLine()

End Sub
End Module

Código fuente 6.17

Operadores abreviados de asignación


Estos operadores simplifican la escritura de expresiones, facilitando la creación del
código. El resultado aplicando operadores abreviados en una expresión, es el
mismo que si utilizamos la sintaxis normal, pero con un pequeño ahorro de código.
Al probar éste tipo de ejemplos, probar por separado la sintaxis normal, y luego la
abreviada, para así evitar resultados inesperados.

Potencia: ^=
Para elevar un número a una potencia podemos usar la sintaxis normal o
abreviada. Ver código fuente 6.18

Dim Valor As Integer


Dim Resultado As Double

Valor = 3
Resultado = 2

' sintaxis normal


Resultado = Resultado ^ Valor ' devuelve: 8

'sintaxis abreviada
Resultado ^= Valor 'devuelve: 8
Código fuente 6.18

- 119 -
Multiplicación: *=
Para multiplicar dos números podemos usar la sintaxis normal o abreviada. Ver
código fuente 6.19
Dim Valor As Integer
Dim Resultado As Double
Valor = 7
Resultado = 12
'sintaxis normal
Resultado = Resultado * Valor ' devuelve: 84
' sintaxis abreviada
Resultado *= Valor ' devuelve: 84

Código fuente 6.19

División real: /=
Para dividir dos números, y obtener un resultado con precisión decimal, podemos
usar la sintaxis normal o la abreviada. Ver código fuente 6.20
Dim Valor As Integer
Dim Resultado As Double
Valor = 5
Resultado = 182
'sintaxis normal
Resultado = Resultado / Valor ' devuelve: 36.4
' sintaxis abreviada
Resultado /= Valor ' devuelve: 36.4

Código fuente 6.20

División entera: \=
Para dividir dos números con un resultado entero, podemos usar la sintaxis normal
o la abreviada. Ver código fuente 6.21
Dim Valor As Integer
Dim Resultado As Double
Valor = 5
Resultado = 182
'sintaxis normal
Resultado = Resultado \ Valor ' devuelve: 36
' sintaxis abreviada
Resultado \= Valor ' devuelve: 36

Código fuente 6.21

- 120 -
Suma: +=
Podemos sumar números o concatenar cadenas usando la sintaxis normal o
abreviada. Ver código fuente 6.22
Dim Valor As Integer
Dim Resultado As Double
Dim CadenaA As String
Dim CadenaB As String

'sintaxis normal
Resultado = Resultado + Valor ' devuelve: 269

'sintaxis abreviada
Resultado += Valor ' devuelve: 269

'con cadenas de caracteres


CadenaA = "Diferentes números"
CadenaB = "754"
CadenaB += CadenaA ' devuelve “754 Diferentes números”
Código fuente 6.22

Resta: -=
Podemos restar números usando la sintaxis normal o la abreviada. Ver código
fuente 6.23
Dim Valor As Integer
Dim Resultado As Integer
Valor = 85
Resultado = 500
' sintaxis normal
Resultado = Resultado - Valor ' devuelve: 715
'sintaxis reducida
Resultado -= Valor ' devuelve: 715
' devuelve “754 Diferentes números”
Código fuente 6.23

Concatenación: &=
Para concatenar cadenas, podemos emplear la sintaxis normal o la abreviada. Ver
código fuente 6.24
Dim PrimeraCad As String
Dim SegundaCad As String
PrimeraCad = "Aquí está"
SegundaCad = " una prueba"

' sintaxis normal


PrimeraCad = PrimeraCad & SegundaCad ' devuelve “Aquí está
una prueba”
Código fuente 6.24

- 121 -
Operadores de comparación
Estos operadores permiten comprobar el nivel de igualdad o diferencia existente
entre los operandos de una expresión. El resultado obtenido será un valor lógico,
True (Verdadero) o False (Falso). La tabla 6.1

Operador El resultado es verdadero cuando El resultado es falso cuando


< Menor que ExpresiónA < ExpresiónB ExpresiónA >= ExpresiónB
<= Menor o igual que ExpresiónA <= ExpresiónB ExpresiónA > ExpresiónB
> Mayor que ExpresiónA > ExpresiónB ExpresiónA <= ExpresiónB
>= Mayor o igual que ExpresiónA <= ExpresiónB ExpresiónA < ExpresiónB
= Igual que ExpresiónA = ExpresiónB ExpresiónA <> ExpresiónB
<> Distinto de ExpresiónA <> ExpresiónB ExpresiónA = ExpresiónB
Tabla 6.1. Operadores de comparación

El código fuente 6.25 permite ver algunas expresiones de comparación usando


números.
Dim Resultado As Bolean
Resultado = 10 < 45 ' devuelve: True
Resultado = 7 <= 7 ' devuelve: True
Resultado = 78 > 98 ' devuelve: False
Resultado = 45 >= 68 ' devuelve: False
Resultado = 150 = 450 ' devuelve False
Resultado = 7 <> 45 ' devuelve True

Código fuente 6.25

Comparación de cadenas
Los operadores de comparación antes descritos se pueden usar también para
comparar cadenas de caracteres. La instrucción Option Compare, junto a sus
modificadores Binary/Text, nos permite definir el modo en el que se realizarán las
comparaciones entre expresiones que contengan cadenas.
Option Compare Binary. Las comparaciones se realizan sobre la base de los
valores binarios internos de los caracteres. Esta es la opción por defecto.
Option Compare Text. Las comparaciones se realizan sobre la base de los valores
textuales de los caracteres.
Podemos configurar Option Compare a nivel proyecto y de fichero de código. En el
caso de configurar a nivel proyecto, debemos abrir la ventana proyecto y en su
apartado Generar, establecer el valor correspondiente en la lista desplegable. Ver
figura 6.8

- 122 -
Figura 6.8. Configuración de Option Compare

Cuando configuremos a nivel de fichero de código, escribiremos ésta instrucción en


la cabecera del fichero con el modificador oportuno. Para mayor información se
sugiere consultar el capítulo sobre declaración obligatoria de variables, para tener
mayor detalles sobre el acceso a esta ventana de propiedades del proyecto.
El código fuente 6.26 tiene un ejemplo de comparación de cadenas usando Option
Compare Binary.
Module Module6
Sub Main()
Dim Resultado As Boolean
Resultado = "A" = "a" 'devuelve: False
Resultado = "M" < "Z" 'devuelve: True
Resultado = "M" > "m" 'devuelve: False
Resultado = "F" <> "f" 'devuelve: True
End Sub
End Module
Código fuente 6.26

El motivo de que la comparación “A” con “a” devuelva falso, o de que “M” no sea
mayor que “m” es porque los que se comparan son los valores binarios, o códigos
que sirven para representar a cada carácter. Por ejemplo, el código de “M” es 77 y
de “m” es 109, por lo que al ser éste último mayor, la comparación da como
resultado False.
En cambio, si cambiamos la configuración de Option Compare a Text y realizamos
las mismas comparaciones, en algunos casos obtendremos resultados distintos. Ver
código fuente 6.27
Module Module6
Sub Main()
Dim Resultado As Boolean

Resultado = "A" = "a" 'devuelve: True


Resultado = "M" < "Z" 'devuelve: True
Resultado = "M" > "m" 'devuelve: False
Resultado = "F" <> "f" 'devuelve: False
End Sub

- 123 -
End Module
Código fuente 6.27

En este tipo de comparación, “A” y “a” sí son iguales, puesto a que se comparan
sus valores como texto y no como códigos internos usados para representar los
caracteres. También, devuelve Falso en la expresión que comprueba si “F” con “f”
son diferentes, puesto que bajo éste concepto de configuración, ambos caracteres
se consideran iguales.

La función Asc()
Cuando se realizan comparaciones entre cadenas basadas en los niveles binarios de
los caracteres, es útil en ocasiones conocer el código de dichos caracteres. Para
conocer cuál es el código que corresponde a un determinado carácter, el lenguaje
nos proporciona la función Asc().
Esta función recibe como parámetro una cadena y devuelve un valor numérico de
tipo Integer, con el código correspondiente al primer carácter de la cadena. El
código fuente 6.28 muestra algunos ejemplos
Dim CodigoCar As Integer
CodigoCar = Asc("A") 'devuelve: 65
CodigoCar = Asc("a") 'devuelve: 97
CodigoCar = Asc("M") 'devuelve: 77
CodigoCar = Asc("F") 'devuelve: 70
CodigoCar = Asc("f") 'devuelve: 102
CodigoCar = Asc("hola") 'devuelve: 104
Código fuente 6.28

La función Chr()
Nos encontramos en la situación inversa a la descripción del subtítulo anterior, es
decir, tenemos el código de un carácter y lo que deseamos saber es a qué carácter
corresponde, la función Chr() recibe un parámetro como número y devuelve el
carácter al que pertenece como un dato de tipo Char, aunque también podemos
asignar el resultado a una variable de tipo String. Ver código fuente 6.29
Dim MiCaracter As Char
Dim MiCadena As String

MiCaracter = Chr(65) ' devuelve: “A”


MiCaracter = Chr(70) ' devuelve: “F”
MiCadena = Chr(77) ' devuelve: “M”
MiCadena = Chr(102) ' devuelve: “f”
Código fuente 6.29

Comparación de cadenas en base a un patrón. El operador


Like
El operador Like permite realizar una comparación entre cadenas, en base a un
patrón establecido en una de éstas cadenas. Ver código fuente 6.30 que es el
formato de uso.
Resultado = Cadena Like Patrón

Código fuente 6.30

- 124 -
Resultado. Valor lógico con el resultado de la comparación. Si resultado es
verdadero, indica que hay una coincidencia de Cadena con Patrón.
Cadena. Cadena de caracteres que se compara con el patrón de coincidencia
Patrón. Cadena de caracteres donde se especifican los caracteres especiales que
sirven de patrón de coincidencia respecto al valor de Cadena. La Tabla 6.2 nos da
referencia a los caracteres y convenciones de uso establecidas por el lenguaje para
el uso de patrones de comparación.

Carácter del patrón Coincidencia en la cadena a buscar


? Cualquier único carácter
* Varios caracteres o ninguno
# Cualquier único número
Cualquier único carácter que se encuentre
[ListaCaracteres] en la lista
Cualquier único carácter que no se
[!ListaCaracteres] encuentre en la lista

Tabla 6.2. caracteres patrón del operador Like

Algo importante a tomar en cuenta es que los resultados obtenidos en expresiones


que utilicen el operador Like, estarán condicionadas por la configuración establecida
mediante Option Compare. Se sugiere revisar el apartado sobre comparación de
cadenas donde se describe ésta instrucción.
Cuando usemos los corchetes para establecer una lista de caracteres a comparar,
debemos emplear el guión ( - ) como separador de rangos. Si lo que se necesita es
que alguno de los caracteres patrón esté entre los que vamos a buscar, debemos
encerrarlo entre corchetes. El código fuente 6.31 muestra algunos ejemplos de uso
del operador.
Module Module6
Sub Main()
' ejemplos con el operador Like
Dim Resultado As Boolean

'-------------------------------

' patron ?

' devuelve True – el patrón coincide con la cadena


Resultado = "HOLA" Like "HO?A"

' devuelve True – el patrón coincide con la cadena


' al hacer sustitución de dos caracteres
Resultado = "MONITOR" Like "MO?ITO"

' Devuelve False – el patrón no coincide con la cadena


' al hacer la sustitución de un carácter
Resultado = "ROEDOR" Like "R?DEO"

'-------------------------------

' patrón *

- 125 -
' devuelve True – El patrón coincide con la cadena
' al hacer la sustitución de varios caracteres con
' con espacio en blanco a ambos lados
Resultado = "La gran llanura" Like "La * llanura"

' devuelve True – El patrón coincide con la cadena


' al hacer la sustitución de dos grupos de caracteres
Resultado = "La gran llanura" Like "La *llanura"

' devuelve False – El patrón no coincide con la cadena


' al hacer la sustitución de un grupo de caracteres
' puesto que en el patrón falta una palabra que si
' se halla en la cadena
Resultado = "La gran llanura" Like "La llanu*"

'-------------------------------

' patrón #

' devuelve True – el patrón coincide con la cadena


' al hacer la sustitución de dos números
Resultado = "Ganó 128 millones" Like "Ganó ##8 millones"

' devuelve False – el patrón no coincide con la cadena


' puesto que al hacer
' al hacer la sustitución de dos números
Resultado = "Ganó 128 millones" Like "Ganó ##8 millones"

' devuelve False – El patrón no coincide con la cadena,


' ya que en el patrón se utilizan caracteres de sustitución
' de dígitos incorrectamente
Resultado = "Ganó 128 millones" Like "Ganó 128 ##llones"

'-------------------------------

' patrón [Lista]


' devuelve True – El carácter de la cadena se encuentra
' dentro del rango en la lista del patrón
Resultado = "H" Like "[A-M]"

' devuelve False – El carácter de la cadena no se encuentra


' dentro del rango en la lista del patrón
Resultado = "h" Like "[A-M]"

' devuelve True – El carácter de la cadena no se encuentra


' dentro del rango en la lista del patrón
Resultado = "D" Like "[¡P-W]"

' devuelve False – El carácter de la cadena no se encuentra


' dentro del rango en la lista del patrón
Resultado = "R" Like "[¡P-W]"

'-------------------------------

- 126 -
' combinación de varios caracteres patrón

' devuelve True – Todas las sustituciones del patrón son


correctas
Resultado = "Faltan 48 horas para llegar a destino" Like _
"Fal* ## * para ll[a-g]gar ? des*"

'devuelve False – Las sustituciones de caracteres numéricos


son incorrectas
Resultado = "Faltan 48 horas para llegar a destino" Like _
"Fal## * para ll[a-g]gar ? des*"

'-------------------------------

' comparación utilizando caracteres patrón


' dentro de la expresión

' devuelve True – El carácter de cierre de interrogación


' se sustituye correctamente al encerrarse entre corchetes
Resultado = "¿Llegó Ana?, bienvenida" Like "¿Ll*Ana[?],
bienvenida"

'-------------------------------

'comparación de dos cadenas vacías

'devuelve True
Resultado = "" Like ""

End Sub
End Module
Código fuente 6.31

Comparación de objetos. El operador Is


Este operador permite comparar si dos variables que contienen objetos apuntan o
no a la misma referencia o instancia del objeto. En capítulos posteriores veremos
los conceptos básicos sobre objetos, es recomendable consultar temas dedicados a
la programación orientada a objetos.
El código fuente 6.32 muestra el formato de uso para este operador.
Resultado = ObjetoA Is ObjetoB
Código fuente 6.32

Para probar este operador podemos crear una aplicación de tipo Windows y añadir
un módulo en el que escribiríamos un procedimiento Main(). Luego de configurar el
procedimiento para que se inicie en por éste procedimiento, escribiremos las líneas
que se muestran en el código fuente 6.33
' declarar dos variables que
' contendrán objetos de la clase Form
Dim VentanaUno As Form
Dim VentanaDos As Form

- 127 -
Dim Resultado As Boolean

' crear dos instancias de la clase Form


' asignando cada uno de los objetos
' a las variables
VentanaUno = New Form()
VentanaDos = New Form()

' la expresión de comparación con Is devuelve


' False puesto que las variables tienen referencias
' a objetos diferentes, así sean de la misma clase
Resultado = VentanaUno Is VentanaDos
Código fuente 6.33

Se pudo comprobar que, al comparar las variables del anterior código fuente Is, el
resultado es False, puesto que ambos objetos son instancias diferentes, aunque
pertenezcan a la misma clase: Form. La creación de formularios la abordaremos en
temas posteriores.
En cambio, si creamos una única instancia de un objeto y la asignamos las dos
variables, el resultado será muy distinto. Aquí el operador devolverá True puesto
que ambas variables contienen el mismo objeto. Ver código fuente 6.34
Public Sub Main()
' declarar dos variables que
' contendrán objetos de la clase Form
Dim VentanaUno As Form
Dim VentanaDos As Form

Dim Resultado As Boolean

' crear una única instancia de la clase Form,


' el objeto resultante se asigna a una variable
VentanaUno = New Form()

' luego, el mismo objeto que se encuentra ya


' en una variable, se asigna a otra variable

VentanaDos = VentanaUno
' ambas variables contienen una referencia
' al mismo objeto, por lo que la expresión
' de comparación is devuelve True
Resultado = VentanaUno Is VentanaDos
End Sub
Código fuente 6.34

Operadores lógicos y a nivel de bit


Los operadores lógicos devuelven un valor de tipo Bolean (True o False), en base a
una condición establecida entre los operandos de la expresión. En las expresiones
que impliquen el uso de los operadores lógicos, es normal que los operandos sean a
su vez expresiones, en el código fuente 6.35 veremos el formato de uso para éstos
operadores, para luego ver algunos ejemplos.
Resultado = ExpresiónA OperadorLógico ExpresiónB
Código fuente 6.35

- 128 -
Cuando los operandos que forman parte de las expresiones son numéricos, la
evaluación de la expresión se hace a nivel de bit, lo que quiere decir que,
comparando los bits de las posiciones equivalentes de ambos números y
obteniendo igualmente, un valor numérico como resultado.

And
Este operador, a nivel lógico, realiza una conjunción entre dos expresiones. La tabla
6.3 muestra los distintos resultados obtenidos con el uso de dicho operador en
función de los valores que tengan sus expresiones.

Cuando la ExpresiónA Y la ExpresiónB


El resultado es
devuelve devuelve

True True True


True False False
False True False
False False False

Tabla 6.3. Tabla de valores lógicos del operando And.

El código fuente 6.36 muestra algunos ejemplos a nivel lógico con éste operador
Dim Resultado As Boolean
Resultado = 58 > 20 And "H" = "H" 'devuelve: True
Resultado = "H" = "H" And 720 < 150 'devuelve: False
Resultado = 8 <> 8 And 62 < 115 'devuelve: False
Resultado = "W" = "b" And "Q" = "R" 'devuelve: False
Código fuente 6.36

A nivel de bit, And realiza las operaciones mostradas en la tabla 6.4

Cuando el bit de la Y el bit de la El valor del bit


ExpresiónA es ExpresiónB es resultante es
0 0 0
0 1 0
1 0 0
1 1 1

Tabla 6.4. Tabla de valores a nivel bit del operador And

El código fuente 6.37 muestra algunos ejemplos a nivel de bit con este operador
Dim Resultado As Integer
Resultado = 25 And 8 ' devuelve: 8
Resultado = 6 And 45 ' devuelve: 4
Código fuente 6.37

- 129 -
Uso de paréntesis para mejorar la legibilidad de
expresiones
Los ejemplos a nivel lógico del apartado anterior, si bien se ejecutan
correctamente, pueden llegar a ser un tanto confusos a la hora de leer, puesto que
al tratarse de una operación lógica, cada operando es a su vez una expresión.
Para facilitar la lectura y comprensión en expresiones sobre todo lógicas, lo que se
puede hacer es encerrar cada operando-expresión entre paréntesis. Ver código
fuente 6.38
Dim Resultado As Boolean
Resultado = (58 > 20) And ("H" = "H") ' devuelve True
Resultado = ("H" = "H") And (720 < 150) ' devuelve False
Resultado = (8 <> 8) And (62 < 115) ' devuelve False
Resultado = ("W" > "b") And ("Q" = "R") ' devuelve False
Código fuente 6.38

Como se puede comprobar al ejecutar el programa, el resultado es el mismo que si


no usásemos paréntesis, pero la claridad al leer estas líneas de código es mucho
mayor.

Not
A nivel lógico, este operador realiza una negación entre dos expresiones. Su
formato es apenas diferente del resto de los operadores lógicos, como vemos en el
código fuente 6.39.
Resultado = Not Expresion

Código fuente 6.39

La tabla 6.5 muestra los resultados obtenidos con el uso de este operador en
función de su expresión.

Cuando la
Expresión El resultado
devuelve es
True False
False True

Tabla 6.5 Tabla de valores lógicos del operador Not

El código fuente 6.40 muestra algunos ejemplos a nivel lógico con este operador
Dim Operación As Boolean
Dim Resultado As Boolean
Operación = 100 > 60
Resultado = Not Operación ' devuelve: „False
Resultado = Not (28 > 50) ' devuelve: „True
Código fuente 6.40

A nivel de bit, Not realiza las operaciones mostradas en la tabla 6.6

- 130 -
Cuando el bit de
la Expresión El resultado
devuelve es
0 1
1 0

Tabla 6.6 Tabla de valores a nivel de bit del operador

El código fuente 6.41 muestra algunos ejemplos a nivel de bit con este operador.
Dim Resultado As Integer
Resultado = Not 16 'devuelve: -17
Resultado = Not 4 'devuelve: -5
Código fuente 6.41

Or
A nivel lógico, lo que éste operador hace es una disyunción entre dos expresiones.
La tabla 6.7 muestra los distintos resultados obtenidos con el uso de éste operador
en función de los valores que tengan sus expresiones.

Cuando la ExpresiónA Y la ExpresiónB


El resultado es
devuelve devuelve

True True True


True False True
False True True
False False False

Tabla 6.7. Tabla de valores lógicos del operador Or

El Código fuente 6.42 muestra algunos ejemplos a nivel lógico con este operador.
Dim Resultado As Boolean
Resultado = (45 > 15) Or ("b" = "b") ' devuelve: True
Resultado = ("J" = "J") Or (720 < 150) ' devuelve: True
Resultado = (15 <> 15) Or (48 < 140) ' devuelve: True
Resultado = (32 > 85) Or ("a" = "A") ' devuelve: True
Código fuente 6.42

A nivel de bit, Or realiza las operaciones mostradas en la tabla 6.8

Cuando el bit de la Y el bit de la El valor del bit


ExpresiónA es ExpresiónB es resultante es
0 0 0
0 1 1
1 0 1
1 1 1

Tabla 6.8 Tabla de valores a nivel de bit con este operador

El código fuente 6.43 muestra algunos ejemplos a nivel de bit con este operador
Dim Resultado As Integer

- 131 -
Resultado = 15 Or 8 „devuelve: 15
Resultado = 6 Or 45 „devuelve: 47
Código fuente 6.43

Xor
A nivel lógico, la tarea de éste operador es la de excluir entre dos expresiones. La
tabla 6.9 muestra los resultados luego de usar éste operador en función de los
valores que tengan sus expresiones.

Cuando la ExpresiónA Y la ExpresiónB


El resultado es
devuelve devuelve

True True False


True False True
False True True
False False False

Tabla 6.9 Tabla de valores lógicos del operador Xor

El código fuente 6.44 muestra algunos ejemplos con dicho operador a nivel lógico.
Dim Resultado As Boolean
Resultado = (72 > 45) Xor ("A" = "A") ' devuelve: False
Resultado = ("i" > "b") Xor (315 > 100) ' devuelve: True
Resultado = (10 <> 10) Xor (420 > 545) ' devuelve: True
Resultado = ("R" > "d") Xor ("K" = "m") ' devuelve: False
Código fuente 6.44

A nivel de bit, Xor realiza las operaciones mostradas en la tabla 6.10

Cuando el bit de la Y el bit de la El valor del bit


ExpresiónA es ExpresiónB es resultante es
0 0 0
0 1 1
1 0 1
1 1 0

Tabla 6.10. Tabla de valores a nivel bit del operador Xor

El código fuente 6.45 muestra algunos ejemplos a nivel bit


Dim Resultado As Integer
Resultado = 15 Xor 8 ' devuelve: 7
Resultado = 6 Xor 45 ' devuelve 43
Código fuente 6.45

- 132 -
And Also
El sentido de este operador es el de realizar un cortocircuito entre dos expresiones,
en esta operación, en cuanto la primera expresión devuelva falso, el resto no será
evaluado porque ya no tiene importancia y devolverá falso como resultado final.
La tabla 6.11 muestra los diferente resultados, si se usa este operador, en función
de los valores que tengan sus expresiones.

Cuando la ExpresiónA Y la ExpresiónB


El resultado es
devuelve devuelve
True True True
True False False
False No se evalúa False

Tabla 6.11. Tabla de valores lógicos del operador And Also

El código fuente 6.46 muestra algunos ejemplos con este operador


Dim Resultado As Boolean
Resultado = (47 < 92) AndAlso ("R" = "R") ' devuelve True
Resultado = ("E" <> "P") AndAlso (14 > 63) ' devuelve False
Resultado = (23 = 55) AndAlso (72 > 46) ' devuelve False
Código fuente 6.46

OrElse
Al igual que el operador AndAlso, este operador realiza una disyunción lógica de
tipo cortocircuito entre dos expresiones. Y, en este tipo de operador, en cuanto la
primera expresión es evaluada verdadera, la siguiente ya no tiene importancia el
valor, dando como resultado final, verdadero.
La tabla 6.12 muestra los distintos resultados con el uso de este operador, en
función de los valores que tengan sus expresiones.

Cuando la ExpresiónA Y la ExpresiónB


El resultado es
devuelve devuelve
True No se evalúa True
False True True
False False False

Tabla 6.12. Tabla de valores lógicos del operador OrElse

El código fuente 6.47 muestra algunos ejemplos con este operador.


Dim Resultado As Boolean
Resultado = (26 > 19) OrElse ("R" <> "R") ' devuelve True
Resultado = ("g" = "h") OrElse (42 < 85) ' devuelve True
Resultado = (23 = 55) OrElse (72 < 46) ' devuelve False
Código fuente 6.47

- 133 -
Prioridad de operadores
La prioridad de operaciones se da cuando en una misma línea de código existen
varias operaciones, éstas se deben resolver en un orden predeterminado. Dicha
prioridad es aplicada tanto entre los operadores de un mismo grupo como entre los
distintos grupos de operadores.

Prioridad entre operadores del mismo grupo


La tabla 6.13 muestra a los operadores aritméticos que se ajustan a la prioridad
indicada.

Prioridad de operadores aritméticos


Potenciación ( ^ )
Negación ( - )
Multiplicación y división real ( *, / )
División Entera ( \ )
Resto de división ( Mod )
Suma y resta ( +, - )

Tabla 6.13. Prioridad de operadores aritméticos

Como se ve en la tabla, el operador de mayor prioridad es el de potenciación, los


de menor son la de suma y resta. Cuando se trata de operadores de igual prioridad
como ser multiplicación y división, se resolverán en el orden de aparición, es decir
de izquierda a derecha. Ver código fuente 6.48
Dim Resultado As Long
Resultado = 5 + 8 ^ 2 * 4 'devuelve: 261
Código fuente 6.48

Los operadores de comparación todos tienen la misma prioridad, se resuelven en el


orden de aparición dentro de la expresión.
En la tabla 6.14 se ve cómo los operadores lógicos se ajustan a la prioridad
indicada.

Prioridad de operadores lógicos


Negación ( Not )
Conjunción ( And, AndAlso)
Disyunción ( Or, OrElse, Xor )

Tabla 6.14 Prioridad de operadores lógicos

En el ejemplo del código fuente 6.49 la operación da como resultado True puesto
que el operador Not invierte la segunda expresión a True, y por consiguiente se
evalúa como True.
Dim Resultado As Boolean
Resultado = 35 < 80 And Not 52 = 28 'devuelve: True
Código fuente 6.49

- 134 -
Prioridad entre operadores de distintos grupos.
Cuando una expresión contenga operadores de distintos grupos, éstos se
resolverán en el orden marcado por la tabla 6.15
Prioridad entre operadores
entre distintos grupos
Aritméticos
Concatenación
Comparación
Lógicos

Tabla 6.15 Prioridad entre grupos de operadores

El código fuente 6.50 muestra un ejemplo de expresión en el que interviene


operadores de diferentes tipos
Dim Resultado As Boolean
Resultado = 30 + 5 * 5 > 100 And 52 > 10 ' devuelve: False
Código fuente 6.50

Uso de paréntesis para alterar la prioridad de operadores


Si fuera necesario, podemos alterar el orden natural de prioridades entre
operadores, usando paréntesis, encerrando entre ellos los elementos que se desea
que sean resueltos en primer lugar dentro de una expresión. Con ello, se resolverán
en primer lugar las operaciones que se encuentran en los paréntesis más inferiores,
finalizando por los paréntesis exteriores. Por supuesto que dentro del paréntesis se
debe tener en cuenta el orden natural de prioridad que se explicó anteriormente.
El resultado del código fuente 6.50 en condiciones normales, daría False como
resultado. Pero, por el uso de paréntesis, la prioridad predeterminada, cambia,
obteniendo finalmente True.
Dim Resultado As Boolean
Resultado = ((35 + 5) * 5 > 100) And (52 > 200 / (2 + 5))
'devuelve: True

Código fuente 6.50

- 135 -
Laboratorio 3

Ejercicio 1
Utilice la estructura de repetición For Next para inicializar los elementos de un array
entero de diez elementos, e imprima el arreglo en formato tabular
Inicialice con números pares
Inicialice con números impares
Inicialice con múltiplos de tres

Ejercicio 2
A cuarenta alumnos se les preguntó el nivel de calidad de los alimentos de la
cafetería para alumnos en una escala de 1 a 10 (1 significa terrible y 10 significa
excelente). Coloque las cuarenta respuestas en una arreglo entero y resuma los
resultados de la encuesta.
Realice el Histograma (utilice nuevamente asteriscos (*) para realizar el grafico)

Ejercicio 3
Utilice un array de una dimensión para resolver el siguiente problema. Una empresa
le paga a su personal de ventas en base a comisión. Los vendedores reciben $200
por semana más 9% de sus ventas brutas de dicha semana. Por ejemplo un
vendedor que vende $3000 en ventas brutas en una semana recibe $200 mas 9%
de 3000, o sea un total de $470. Escriba un programa que determine cuantos de
los vendedores ganaron salarios en cada uno de los rangos siguientes (suponiendo
que el salario de cada vendedor se trunca a una cantidad entera)

1.$200 - $299
2.$300 - $399
3.$400 - $499
4.$500 - $599
......
9. $1000 o superior

Ejercicio 4
Escriba un programa que simule el tirar dos dados. El programa deberá utilizar una
función que genere numero aleatorios para tirar el primer dado, y despues volver a
utilizarla para tirar el segundo dado. La suma de los dos valores debera ser
calculada. Nota: en vista de que cada dado puede mostrar un valor entero de 1 a 6
entonces la suma de los dos valores variará desde 2 hasta 12, siendo 7 la suma
más frecuente y 2 y 12 las menos frecuentes. Su programa debera tirar 36000
veces los dos dados. Utilice un arreglo de una dimensión para llevar cuenta del
número de veces que aparece cada suma posible. Imprima los resultados en un
formato tabular. Tambien determine si los totales son razonables, es decir, existen
seis formas de llegar a un 7, por lo que aproximadamente una sexta parte de todas
las tiradas deberán ser 7

- 136 -
Módulo 7

Organización y ámbito de los


elementos del lenguaje

- 137 -
Archivos y módulos de código en un programa
Cuando trabajamos con la plataforma .NET Framework tenemos una gran
flexibilidad para el orden del código de nuestra aplicación, que se deben organizar
en contenedores físicos y lógicos de código.
Se llama contenedor físico al archivo con extensión .VB, éstos archivos son los que
la plataforma reconoce como archivo con código VB.NET. Se puede tener uno o
varios dentro de un proyecto.
Dicho de la forma más sencilla, un contenedor lógico, es aquél elemento en el
entorno de .NET que nos permite escribir en su interior declaraciones y
procedimientos, que serán accesibles desde otros elementos dentro del proyecto
actual, o también desde otros proyectos, en función de su ámbito o accesibilidad.
El entorno de Framework .NET, dispone de varios tipos de contenedores lógicos,
como ser, los módulos, clases, interfases, estructuras, etc. Hay tipos de
contenedores lógicos especiales, son los espacios de nombres (namespaces), su
misión es albergar al resto de los contenedores lógicos, algo así como meta
contenedor. La estructura básica de un contenedor lógico se muestra en la figura
7.1
Por defecto, la configuración para VS.NET, establece que cada vez que se añade un
nuevo módulo o clase a un proyecto, se crea un archivo con extensión VB, que
contiene el mencionado módulo o clase. El nombre que usamos el mismo para el
archivo y para el módulo o clase, sin embargo, podemos incluir varios contenedores
lógicos de igual o diferente tipo dentro del mismo archivo de código. Ver código
figura 7.2

Contenedor lógico
Módulo, Clase, etc.

Declaración 1
Declaración 2
Zona de declaraciones

Declaración n

Sub NombreB

End Sub

Function NombreC()
Zona de procedimientos …
End Function

Function NombreD()

End Function

Figura 7.1 Estructura de un contenedor lógico de código

- 138 -
Figura 7.2. Esquema de organización del código en un proyecto VB.NET

A continuación se describe las operaciones básicas que se debe realizar, para añadir
un nuevo módulo de código a un proyecto, quitarlo, o agregar otros que ya existen.
Esto también es válido en el momento de manejar clases en los temas dedicados a
la programación orientada a objetos.

Añadir un nuevo módulo (y archivo) a un proyecto


Para añadir un nuevo módulo debemos seleccionar en el IDE de VS.NET la opción
de menú Proyecto + Agregar módulo. Con esto abriremos la caja de dialogo
Agregar nuevo elemento, en la que de manera automática aparecerá un nombre
para el módulo, que asigna el IDE. Se puede emplear este nombre o cambiarlo. Ver
figura 7.3

- 139 -
Figura 7.3 Agregar un nuevo módulo al proyecto

Cuando se pulsa Abrir, se creará un nuevo fichero con el nombre que se indicó en la
caja de diálogo y la extensión .VB, que contendrá un nuevo módulo con el mismo
nombre, dentro de éste ya se puede empezar a escribir código. Ver figura 7.4
Figura 7.4. Modulo recién creado

Crear un nuevo módulo dentro de un fichero existente


El crear un nuevo módulo dentro de un fichero que ya existe, es aún más sencillo,
puesto que en esta situación tan sólo se debe escribir la declaración del módulo
dentro del fichero de código, usando las palabras clave Module...End Module,
conjuntamente con el nombre que asignaremos al módulo. Veamos la sintaxis en el
código fuente 7.1
Module NombreModulo
' código
' ....
End Module
Código fuente 7.1

Es importante tener en cuenta que no es posible anidar módulos, es decir, no se


puede declarar un módulo dentro de la declaración de un módulo que ya existe. Ver
código fuente 7.2
Module NombreModulo
' esto no es válido, producirá un error
Module NombreNuevo
End Module
End Module
Código fuente 7.2

A continuación veremos un ejemplo. En el apartado anterior se creó un nuevo


módulo con el nombre Module2, se crea al mismo tiempo, un nuevo fichero de
código con el nombre Module2.VB. Pues bien, para añadir otro módulo dentro de

- 140 -
este fichero al que le pondremos el nombre Cuentas, solamente se podrá declarar
el nuevo módulo ya sea antes o después del existente. Ver figura 7.5

Figura 7.5. Inclusión de un nuevo módulo dentro de archivo de código.

Con este ejemplo lo que se intenta demostrar es que los módulos de código son
totalmente independientes del archivo físico que los contiene, por esta razón, varios
módulos pueden escribirse dentro del mismo archivo.

Cambiar el nombre de un fichero de código


Si no se desea que el nombre de un fichero de código sea igual a alguno de los
módulos que contiene, se debe abrir la ventana Explorador de soluciones, hacer clic
derecho sobre el nombre del fichero de código y elegir la opción, cambiar nombre.
Esto permitirá dar un nuevo nombre al fichero .VB que contiene el código. Ver
figura 7.6

- 141 -
Figura 7.6 Cambiar el nombre de un fichero de código

Añadir al proyecto un fichero de código existente


Si tenemos código de otro proyecto, y se necesita usar en el proyecto actual, o
bien, se escribió código usando un editor diferente del proporcionado por VS.NET,
se puede añadir al proyecto usando la opción del menú Proyecto + Agregar
elemento existente. Se observará que es necesario que el código escrito esté en un
fichero con extensión .VB
Daremos un ejemplo, se usó el bloc de notas para escribir un módulo que contiene
un procedimiento, y se guardó en un fichero con el nombre de MiCodigo.VB. Al usar
la opción antes mencionada, se abrirá una caja de diálogo, con la que se navegará
por las carpetas del equipo para localizar el fichero, al pulsar el botón Abrir, se
añadirá este fichero al proyecto. Ver figura 7.7

- 142 -
Figura 7.7. Agregar un fichero de código existente al proyecto

Lista desplegable “Nombre de clase”, en el editor de


código.
La lista desplegable, nombre de clase, que está en la parte superior izquierda en el
editor de código, tiene dos finalidades principales que se describe a continuación.
Mostrar el nombre del módulo sobre lo que actualmente se trabaja. Esta
información es útil cuando se está escribiendo código en un fichero que tiene varios
módulos, de manera que siempre se puede saber sobre qué módulo estamos
posicionados.
Cambiar a otro módulo dentro del mismo fichero de código. Esta operación
se la realiza en dos pasos. Primero se debe abrir la lista desplegable y seleccionar
el nombre del módulo al que se cambiará. Por último, abrir la lista nombre del
método, y elegir uno de los procedimientos del módulo sobre el que nos
posicionamos, entonces, el editor de código cambiará a dicho procedimiento.
La figura 7.8 muestra una imagen de la lista de módulos.

- 143 -
Figura 7.8 Lista Nombre de clase, en el editor de código del IDE

Hay una motivo para el uso del término clase de módulo para esta lista, y es que,
como se verá en los temas sobre programación con objetos, todo lo que más
adelante se hará en la labor de programación será crear clases, objetos, métodos,
propiedades, etc. Es por ello que se emplea la terminología generalmente a las
técnicas de programación con objetos a la de la programación estructurada.

Excluir y eliminar ficheros de código del proyecto


Si no se desea que un determinado fichero (con el módulo o módulos que incluye)
siga en el proyecto, se puede separarlo abriendo la ventana Explorador de
soluciones, y hacer clic derecho sobre el nombre del procedimiento, elegir la opción
del menú Proyecto + Excluir de proyecto. Esto quita el fichero del proyecto pero no
lo elimina físicamente. Ver figura 7.9

- 144 -
Figura 7.9 Excluir un fichero del proyecto

Si lo que en realidad se desea eliminar físicamente el fichero de código, se debe


realizar la operación antes descrita, pero en este caso, seleccionar del menú
contextual, la operación Eliminar.

Reglas de ámbito
Como concepto de ámbito o accesibilidad de un elemento declarado en el código, se
puede decir que es, la capacidad que tenemos para usar éste elemento desde
cualquier punto del código, sea este desde el interior del propio programa, o desde
un proyecto externo, compilado como librería de clase (archivo. DDL)
Las reglas de ámbito son aplicadas por un lado a procedimientos y variables, viendo
al lenguaje desde el punto de vista de la programación estructurada, y por otro,
también son aplicadas a métodos y propiedades, visto el mismo desde el punto de
vista de la programación orientada a objetos.
En este capítulo se realizará una revisión de las cuestiones de ámbito aplicadas a
procedimientos y variables, se dejará el ámbito de métodos y propiedades para los
temas que son sobre programación orientada a objetos.

Ámbito de procedimientos

- 145 -
Consiste en la capacidad de poder hacer la llamada a procedimientos desde un
punto determinado del programa, esto en función del nivel de acceso definido para
dicho procedimiento cuando se lo declara.
La especificación del ámbito de un procedimiento se hará por medio de una palabra
clave o modificador de ámbito, se debe anteponer al tipo de procedimiento (Sub o
Function) dentro de la declaración. El código fuente 7.3 muestra su sintaxis
ModificadorÁmbito Sub l Function NombreProcedimiento ([ListaParámetros])
Código fuente 7.3

A continuación veremos los ámbitos de procedimientos disponibles


Público
Este tipo de procedimiento puede ser llamado desde cualquier punto del módulo en
el que se declaró, o desde cualquier módulo del proyecto. En este caso la palabra
clave que se usa como modificador de ámbito es Public
En el código fuente 7.4 existen dos módulos General y Cálculos, que contienen los
procedimientos Main() y Totales() respectivamente. Desde el procedimiento Main()
se puede perfectamente llamar al procedimiento Totales() puesto que al haber sido
declarado como Public, es accesible desde otro módulo.
Module General
Public Sub Main()
Console.WriteLine("Estamos en el módulo General, procedimiento
Main")

' llamar al procedimiento totales() que está en otro módulo


Totales(400)
Console.ReadLine()
End Sub
End Module
Module Cálculos
Public Sub Totales(ByVal Importe As Integer)
Dim Resultado As Integer
Console.WriteLine("Estamos en el módulo Cálculos,
procedimiento Totales")
Resultado = Importe + 1000
Console.WriteLine("El total obtenido es: {0}", Resultado)
End Sub
End Module
Código fuente 7.4

El modificador de ámbito de procedimientos por defecto es Public, lo que significa


que si no lo usamos, cuando se crea un procedimiento, será público por defecto.
Se puede escribir varios procedimientos con el mismo nombre y ámbito público en
distintos módulos. Si ocurre esto, cuando se llame al procedimiento, por defecto se
ejecutará el que esté más próximo desde el módulo que fue llamado. Si lo que se
necesita es ejecutar el procedimiento que se encuentra en otro módulo, se debe
hacer la llamada usando la sintaxis descrita en el código fuente 7.5
NombreModulo.NombreProcedimiento()
Código fuente 7.5

Veremos un ejemplo en el código fuente 7.6

- 146 -
Module General
Public Sub Main()
Console.WriteLine("Estamos en el módulo General, procedimiento
Main")

' llamar al procedimiento totales() que está en otro módulo


Totales(400)
Console.ReadLine()

End Sub

End Module
Module Cálculos

Public Sub Totales(ByVal Importe As Integer)


Dim Resultado As Integer
Console.WriteLine("Estamos en el módulo Cálculos,
procedimiento Totales")
Resultado = Importe + 1000
Console.WriteLine("El total obtenido es: {0}", Resultado)

End Sub
End Module
Código fuente 7.6

Privado
Cuando un procedimiento tiene un ámbito privado, sólo puede ser llamado desde el
propio módulo en que ha sido declarado. Usa como modificador de ámbito la
palabra clave Private. En el código fuente 7.7 veremos un ejemplo
Module General

Public Sub Main()


' podemos ejecutar el procedimiento Totales()
' puesto que tiene ámbito público
Totales(400)

Dim MiNumero As Integer


'error, la función ObtenerNumero tiene ámbito privado,
' dentro del módulo Cálculos,
' por lo que no es accesible desde este módulo
MiNumero = ObtenerNumero()

Console.ReadLine()
End Sub
End Module

Module Calculos

Public Sub Totales(ByVal Importe As Integer)


Dim Resultado As Integer
Console.WriteLine("Estamos en el módulo Cálculos,
procedimiento Totales")

' se puede llamar desde aquí a la función ObtenerNumero

- 147 -
' puesto que estamos en el mismo módulo
Resultado = Importe + ObtenerNúmero()
Console.WriteLine("El total obtenido es: {0}", Resultado)
End Sub

Private Function ObtenerNumero() As Integer


Console.WriteLine("Estamos en el módulo Cálculos," & _
" procedimiento ObtenerNumero")
Return 18
End Function
End Module
Código fuente 7.7

En el anterior código fuente, observamos que desde Main() no se puede llamar a la


función ObtenerNúmero(), puesto que dicha función tiene como ámbito Private y
reside en un módulo diferente.
Pero sí se puede llamar desde el procedimiento Totales(), puesto que en este caso,
la llamada se hace dentro del mismo módulo de código.

Ámbito de variables
Éste tipo de ámbito consiste en tener la capacidad de acceso que se tiene sobre una
variable, de manera que se puede obtener su valor, así como asignarlo. Para
determinar el nivel de accesibilidad, intervienen, además de los modificadores de
ámbito, el lugar o nivel de emplazamiento de la variable dentro del código.
En cuanto a los modificadores de ámbito, se dispone de las mismas palabras clave
que para los procedimientos Public y Private, el código fuente muestra la sintaxis de
uso 7.8
ModificadorÁmbito [Dim] NombreVariable As TipoDato
Código fuente 7.8

En función del punto de código en el que sea declarada una variable, podremos
omitir el uso de la palabra clave Dim para realizar dicha declaración.
Pasamos a describir los diferentes tipos de ámbito para variables, en función del
lugar de declaración.
Ámbito a nivel de procedimiento
Cuando una variable se declara dentro del cuerpo de un procedimiento se dice que
tiene un ámbito local o a nivel de procedimiento, y no puede ser accedida por otro
código que no sea el de dicho procedimiento. Ver código fuente 7.9
Module General
Sub Main()
' se declara una variable que tiene ámbito
' a nivel de este procedimiento
Dim Nombre As String

Nombre = "Hola"

Console.WriteLine("Introducir un valor")
Nombre &= " " & Console.ReadLine()
End Sub
Public Sub Manipular()

- 148 -
' si se intenta desde este procedimiento
' acceder a la variable Nombre del
' procedimiento Main(), se produce un error
Nombre = "nuevo valor"
End Sub
End Module
Código fuente 7.9

Como se puede ver en el ejemplo anterior, la variable Nombre puede ser


manipulada dentro del procedimiento Main(), si se desea acceder a ella desde otro
procedimiento, da como resultado un error.
Ámbito a nivel de bloque
Al declarar una variable dentro de una estructura de control, tiene ámbito local a
nivel de bloque, siendo accesible solamente dentro del bloque que está contenido
en la estructura. Ver código fuente 7.10
Module Modulo7
Public Sub Main()
' variables con ámbito a nivel de procedimiento
Dim MiNumero As Integer
Dim Total As Integer

Console.WriteLine("Introduzca un número")
MiNumero = Console.ReadLine()

If MiNumero > 0 Then


' variable con un ámbito a nivel de bloque
' solamente es accesible dentro de esta estructura If
Dim Calculo As Integer
Console.WriteLine("Introduzca otro número para sumar")
Calculo = Console.ReadLine()

MiNumero += Calculo
End If

Console.WriteLine("El resultado total es: {0}", MiNumero)

' error, la variable Calculo no es accesible desde aquí


Total = 250 + Calculo

Console.ReadLine()
End Sub
End Module
Código fuente 7.10

Debemos declarar en este punto que el ámbito dentro de un bloque se entiende


como la parte de la estructura que fue declarada la variable. Por ejemplo, si en una
estructura If...End If con Else, si se declara una variable a continuación de If, esta
variable no será accesible desde el bloque de código que hay a partir de Else. Ver
código fuente 7.11
If MiNumero > 0 Then
' variable con un ámbito a nivel de bloque
' solamente es accesible dentro de esta estructura If
Dim Calculo As Integer

- 149 -
'..............
Else
' la variable Calculo no es accesible desde aquí
'..............
End If
Código fuente 7.11

Ámbito a nivel de módulo


Al declarar una variable en la zona de declaraciones de un módulo, es decir, fuera
de cualquier procedimiento, pero dentro de las palabras clave Module...End Module,
y usando como palabra clave Dim o Private, ésta variable tiene un ámbito a nivel de
módulo.
Pero tanto Dim como Private, son válidas para declarar variables a nivel de módulo,
es recomendable el uso de Private, de esta manera se facilita la lectura de código,
reservando las declaraciones con Dim para las variables de ámbito de
procedimiento, y las declaraciones con Private para el ámbito de módulo.
En el ejemplo del código fuente 7.12, se declara la variable Nombre dentro del
módulo, pero fuera de cualquiera de sus procedimientos, esto hace que sea
accesible desde cualquiera de dichos procedimientos, pero no así desde otro
procedimiento que esté en otro módulo.
Module General

' Dim Nombre As String < --- esta declaración vale perfectamente

Private Nombre As String ' .... pero es recomendable declarar con


Private

Public Sub Main()

Console.WriteLine("Procedimiento Main()")
Console.WriteLine("Asignar valor a la variable")
Nombre = Console.ReadLine

Console.WriteLine("El valor de la variable en Main() es {0}",


Nombre)
Manipular()
MostrarValor()

Console.ReadLine()
End Sub

Public Sub Manipular()


Console.WriteLine("Procedimiento Manipular()")
Console.WriteLine("Asignar valor a la variable")
Nombre = Console.ReadLine()

Console.WriteLine("El valor de la variable en Manipular() es:


{0}", Nombre)
End Sub

End Module

- 150 -
Module Calculos
Public Sub MostrarValor()
' error, no se puede acceder desde este módulo
' al a variable Nombre, que está declarada Private
' en el módulo General
Console.WriteLine("Procedimiento MostrarValor()")
Nombre = "Cristian"
Console.WriteLine("Valor de la variable Nombre: {0}", Nombre)
End Sub
End Module
Código fuente 7.12

Para comprobar el valor de estas variables a través del depurador, debemos usar la
ventana Automático, que se puede abrir con el menú Depurar + Ventanas
Automático o la combinación de teclas [CTRL. + ALT + V, A]. Ver código fuente
7.10

Figura 7.10. Ventana Automático, del Depurador

Ámbito a nivel de proyecto


Una variable se dice que tiene ámbito a nivel de proyecto, si está declarada en la
zona de declaraciones de un módulo usando la palabra clave Public, esto significa
que, es accesible por cualquier procedimiento de cualquier módulo que se
encuentre dentro del proyecto.
Si se toma como ejemplo el código fuente anterior se declara como Public la
variable Nombre, en este caso sí se puede manipular desde cualquier punto de la
aplicación. Ver código fuente 7.13
Module General
' esta variable será accesible
' desde cualquier punto del proyecto
Public Nombre As String

Public Sub Main()

Console.WriteLine("Procedimiento Main()")
Console.WriteLine("Asignar valor a la variable")
Nombre = Console.ReadLine()

Console.WriteLine("El valor de la variable en Main() es {0}",


Nombre)
Manipular()
MostrarValor()

- 151 -
Console.ReadLine()
End Sub

Public Sub Manipular()


Console.WriteLine("Procedimiento Manipular()")
Console.WriteLine("Asignar valor a la variable")
Nombre = Console.ReadLine()

Console.WriteLine("El valor de la variable en Manipular() es:


{0}", Nombre)
End Sub

End Module

Module Calculos
Public Sub MostrarValor()
' al haber declarado la variable Nombre
' como Público en el módulo General, podemos acceder a ella
' desde un módulo distinto al que se declaró
Console.WriteLine("Procedimiento MostrarValor()")
Nombre = "Cristian"
Console.WriteLine("Valor de la variable Nombre: {0}", Nombre)
End Sub
End Module
Código fuente 7.13

Periodo de vida o duración de las variables


Se dice que el periodo de vida de una variable es el tiempo durante el cuál la
variable está activa, ocupando el espacio de memoria que le fue asignado en el
entorno de aplicación de .NET Framework y disponible para ser usada. Depende del
ámbito el período de vida de una variable, de manera que se puede clasificar de la
siguiente forma:
Ámbito de bloque. El tiempo de vida de este tipo de variables está desde
el momento en que son declaradas dentro del bloque hasta que éste finaliza.
Ámbito de procedimiento. El periodo de vida de éstas está comprendido
desde el momento en que son declaradas y hasta que la ejecución del
procedimiento termina.
Ámbito a nivel de módulo y proyecto. En este caso, el período de vida de
las variables, va desde el inicio de la ejecución de la aplicación y hasta que
ésta termina.

Variable Static
Éstas variables se diferencian de las demás por el hecho de que conservan su valor
luego de finalizar el procedimiento en él fueron declaradas. Se deben declarar
usando la palabra clave Static, y opcionalmente se puede omitir la palabra clave
Dim. El código fuente 7.14 muestra su sintaxis.
Static [Dim] Importe As Integer
Código fuente 7.14

- 152 -
Si se declara una variable normal dentro de un procedimiento, cada vez que se
llama al procedimiento, ésta variable será inicializada. En el código fuente 7.15
veremos un ejemplo donde en cada llamada al procedimiento, se inicializa la
variable y se le suma un número, por ello, la variable siempre muestra el mismo
valor en la consola.
Module Modulo7
Public Sub Main()
Verificar("Primera") ' en esta llamada se muestra 7
Verificar("Segunda") ' en esta llamada se muestra 7
Verificar("Tercera") ' en esta llamada se muestra 7
Console.ReadLine()
End Sub
Public Sub Verificar(ByVal OrdenLlamada As String)
' cada vez que este procedimiento se ejecuta
' la variable Importe se inicializa a 5
Dim Importe As Integer = 5
Importe += 2
Console.WriteLine("{0} llamada al procedimiento, la variable
contiene {1}", _
OrdenLlamada, Importe)
End Sub
End Module
Código fuente 7.15

Pero si cambiamos el modo de declaración de la variable Importe, y se le añade


Static, en este caso, la primera vez que se ejecuta el procedimiento, se inicializa
esta variable con el valor de 5, pero al terminar la ejecución, la variable no se
destruye, al contrario, en la siguiente ejecución conserva el valor, que se puede ir
incrementando en cada llamada. Ver código fuente 7.16
Module Modulo7
Public Sub Main()
Verificar("Primera") ' en esta llamada se muestra 7
Verificar("Segunda") ' en esta llamada se muestra 9
Verificar("Tercera") ' en esta llamada se muestra 11
Console.ReadLine()
End Sub
Public Sub Verificar(ByVal OrdenLlamada As String)
' declarar variable con el modificador Static,
' en la primera llamada toma el valor inicial de 5
' las siguientes llamadas no ejecutarán esta línea

Static Dim Importe As Integer = 5

Importe += 2
Console.WriteLine("{0} llamada al procedimiento, la variable
contiene {1}", _
OrdenLlamada, Importe)
End Sub
End Module
Código fuente 7.16

Por lo tanto, las variables Static, tienen un periodo de vida que dura todo el tiempo
de ejecución del programa, en tanto que su ámbito es a nivel de procedimiento o
bloque, puesto que también pueden crearse dentro de una estructura de control.

- 153 -
Convenciones de notación
Se dice que son convenciones de notación a una serie de normas no oficiales a la
hora de declarar identificadores en el código, que facilitan su implementación y
mantenimiento.
Tal vez esto no sea necesario inicialmente, tampoco la herramienta de
programación obliga a ello, en la práctica queda demostrado que una cantidad de
normas cuando se está escribiendo el código, redunda en una mayor velocidad de
desarrollo y facilita el mantenimiento de la aplicación. Siendo esto útil, no
solamente en grupos de trabajo, también está el grupo de programadores
independientes.
A continuación se describirá una serie de normas de codificación para las variables
y constantes, que no son obligatorios a la hora de escribir el código de programa,
pero si el afán es concienciar al programador de la necesidad que se desea seguir,
se forma que si desea compartir con otros programadores, o cuando se tenga que
revisar una aplicación desarrollada anteriormente, se emplee el menor tiempo
posible, para descifrar lo que ésas variables significaban en el contexto del
procedimiento.

Variables
El formato que se emplea para la notación de variables se basa en usar un carácter
para indicar el ámbito de la variable, a continuación uno o dos caracteres para
especificar el tipo de dato, finalmente el resto del nombre que adquiere la variable,
que lleva por nombre cuerpo de la variable. Ver código fuente 7.17
<Ámbito><TipoDato><Cuerpo>
Código fuente 7.17

La tabla 7.1 muestra los diferentes valores para ámbito

Carácter Ámbito que define

L
local
M Módulo (privado)
P Proyecto (público)
Tabla 7.1. Carácter para indicar el ámbito en los nombres de variables

La tabla 7.2 muestra los valores para el tipo de dato

Carácter Tipo de dato que


define
B Boolean
By Byte
C Char
Ct Date
Dc Decimal
Db Double
I Integer
L Long
Sh Short
Sg Single

- 154 -
O Object
S String

Tabla 7.2 Caracteres para indicar el tipo de dato en los nombres de las variables

Para el cuerpo de la variable se usa WordMixing, consiste en una técnica en la cual


empleamos, si es necesario, varias palabras juntas para describir mejor el
contenido de la variable. En el ejemplo del código fuente 7.18
„ variable local de tipo integer
liCodAcceso
„variable a nivel de módulo de tipo string
msNombreUsuario

„ variable a nivel de proyecto de tipo fecha


pdtDiaAlta

Código fuente 7.18

En el caso de objetos creados por el programador, usaremos como prefijo para el


tipo de dato, el carácter “o”, o bien tres caracteres indicativos de la clase. Ver
código fuente 7.19
`variable local cuyo nombre es un objeto creado por el programador
Dim loEmpleado As Empleado
Dim lempEmpleado As Empleado

Código fuente 7.19


Constantes
Con respecto a las constantes, se seguirá el mismo formato que para las variables
en lo que respecta al ámbito y tipo de dato. Pero el cuerpo de la constante, lo
escribiremos en mayúsculas, separando las distintas palabras usando el carácter
guión bajo (_) en vez de WordMixing. Ver código fuente 7.20
„ constante a nivel de proyecto de tipo integer
piTIPO_IVA
„ constante a nivel de módulo de tipo string
msCOLOR_INICIAL

código fuente 7.20

- 155 -
Laboratorio 4

Ejerccio 1.-
Un jugador tira dos dados. Cada dado tiene seis caras. Las caras contienen 1, 2,
3,4,5 y 6 puntos. Una vez que los dados se hayan detenido, se calcula la suma de
los puntos de los puntos en las dos caras superiores. Si a la primera tirada, la suma
es 7, o bien 11, el jugador gana. Si en la primera tirada la suma es 2, 3, o 12
(conocido como “craps”), el jugador pierde (es decir, la casa “gana”). Si en la
primera tirada la suma es 4, 5, 6, 8, 9, ó 10, entonces dicha suma se convierte en
el “punto” o en la tirada. Para ganar, el jugador deberá continuar tirando los dados
hasta que haga su “tirada”. El jugador perderá si antes de hacer su tirada sale una
tirada de 7

Ejercicio 2.-
Escriba una función que despliegue en el margen izquierdo de la pantalla un
cuadrado sólido de asteriscos, cuyo costado o lado está especificado en el
parámetro entero lado. Por ejemplo si side es 4 la función mostrará
****
****
****
****
Ejercicio 3.-
Un número entero se dice que se trata de un número perfecto si sus factores,
incluyendo a 1 (pero excluyendo en el número mismo), suman igual que el número.
Por ejemplo, 6 es un número perfecto porque 6 = 1+2+3. Escriba una función
perfect que determine si el parámetro number es un número perfecto. Utilice esta
función en un programa que determine e imprima todos los números perfectos
entre 1 y 1000. Imprima los factores de cada número perfecto para confirmar que
el numero de verdad es perfecto.Ponga en acción la potencia de su computadora
para probar números más grandes que 1000

Ejercicio 4.-
Modifique el programa de craps para permitir apuestas. Empaquete como una
función aquella parte del programa que ejecuta un juego de craps. Inicialice la
variable Cuenta a 1000 dólares. Solicite al jugador que introduzca una apuesta.
Utilice un ciclo while para verificar que apuesta es menor o igual a Cuenta y de lo
contrario indiquele al usuario de que vuelva a entrar la apuesta hasta que
introduzca una apuesta valida. Una vez introducido una apuesta valida, ejecute
un juego de craps. Si el jugador gana, aumente Cuenta por la cantidad apuesta e
imprima el número apuesta. Si el jugador pierde, reduzca Cuenta por la cantidad
apuesta, imprima la nueva Cuenta, verifique si Cuenta se ha convertido en cero
si es asi imprima “Lo siento perdio” Conforme progrse el juego, imprima varios
mensajes para crear algo de “conversación” como “Oh te vas a la quiebra” etc.

- 156 -
- 157 -
Módulo 1

Introducción a la
programación Orientada a
Objetos

- 158 -
Abstracción
Probablemente la abstracción sea la herramienta más poderosa con la que cuenta
el hombre para comprender fenómenos complejos del mundo real. En el mundo
real nos enfrentamos día a día con diferentes fenómenos tales como objetos físicos,
eventos, situaciones y procesos.
La abstracción, en este sentido, es el proceso [intencional] de supresión, u
ocultamiento, de detalles respecto de un fenómeno, entidad o concepto, dejando de
lado el resto, de manera de concentrarnos en otros aspectos que nos son más
significativos en un determinado contexto.
Es importante notar que este proceso de abstracción es completamente subjetivo y
dependiente del contexto; diferentes personas pueden atravesar este proceso de
simplificación de diferentes maneras para un mismo fenómeno o entidad,
eliminando diferentes conceptos y, por tanto, llegando a una caracterización
diferente. Por ejemplo, tomando como objeto de análisis el concepto de automóvil,
un observador interesado en la mecánica podría caracterizarlo como un vehículo
con cierto tipo de motor, mientras que otro observador, en un contexto diferente,
podría caracterizar al mismo automóvil como un medio de trasporte, haciendo
énfasis en su capacidad de trasportar personas o cosas. Notar que en este caso,
deja de importar el tipo de motor que tenga (simplificación).
Diferentes niveles de abstracción
Nuestro mundo está conformado por una enorme cantidad de fenómenos y
entidades, imposibles de representar y manejar sin alguna herramienta que nos
permita caracterizarlos de alguna forma práctica.

- 159 -
Una forma de realizar esto es lograr abstraer determinadas características de las
entidades de nuestro dominio, para así modelar un concepto más general que las
abarque. En otras palabras, lo que buscamos es separar efectivamente los objetos
concretos de la idea que queremos representar. Esto, que en principio nos puede
parecer una tarea difícil, es algo que hacemos inconscientemente en el día a día. A
modo de ejemplo, pensemos en la noción de que un objeto se encuentre sobre
otro: si vemos un florero apoyado en una mesa diremos naturalmente que el florero
se encuentra sobre la mesa. Asimismo, podemos decir que un lápiz se encuentra
sobre un escritorio o que el pan se encuentra sobre la mesada. De estos ejemplos
podemos decir que el florero, el lápiz y el pan comparten el concepto de estar sobre
algo. De hecho, una vez que logramos abstraer la idea de estar sobre, no sólo la
podemos extrapolar a otras situaciones sino que podremos hablar en abstracto con
otras personas que comprendan esa noción, sin referirnos a un caso concreto. De
forma similar, podríamos utilizar una pelota, un aro, una rueda, etc., y a partir de
estos objetos explicar lo que significa que un objeto sea redondo. Una vez hecho
esto podemos determinar si una o más entidades pueden ser caracterizadas de esta
manera simplemente por comparación (verificando que el conjunto de propiedades
que define al concepto redondo también son propias de la entidad en cuestión).
Al trabajar con objetos, dos de las más importantes abstracciones con las que
trabajaremos son las nociones es-un y tiene-un:

- 160 -
Tipos de abstracciones: es-un y tiene-un [9]
“Las nociones de dividir en partes y dividir en especializaciones representan las dos
formas de abstracción más importantes usadas en la programación orientada a
objetos. Comúnmente se las conoce como las abstracciones es-un y tiene-un.
La idea de división en partes es la abstracción tiene-un. El significado de este
término es fácil de comprender; un auto „tiene-un‟ motor, „tiene-una‟ transmisión,
etc.
Al concepto de especialización nos referimos como la abstracción es-un.
Nuevamente, el término surge de las sentencias que pueden ser usadas para
ilustrar las relaciones. Utilizando este concepto, una bicicleta „es-un‟ vehículo
rodado, el cual a su vez „es-un‟ medio de transporte...”
Buscando el nivel de abstracción correcto [9]
En las etapas tempranas del desarrollo de software uno de los problemas críticos es
encontrar el nivel de abstracción correcto o adecuado. Un error común es hacer
hincapié en los niveles más bajos, preocupándose por los detalles de
implementación de varios componentes claves, en lugar de esforzarse para
asegurar que la estructura organizativa de alto nivel promueva una clara
separación de responsabilidades (concerns).
El programador (o el equipo de diseño en grandes proyectos) debe tratar de
balancear el nivel de abstracción adecuado en cada momento. Por un lado, uno no
quiere ignorar o tirar a la basura demasiados detalles sobre un problema, pero por
otro lado, tampoco uno debe mantener muchos detalles que al fin de cuentas
opaquen y no nos permitan ver ciertas cuestiones importantes.
En el contexto de la programación OO, la abstracción surge como un proceso de
reconocimiento de similitudes entre fenómenos, conceptos y entidades, y la
decisión de concentrarse en estas similitudes e ignorar las diferencias entre ellos.
De esta manera, logramos identificar conceptos generales (persona, auto, pelota,
etc.) que puedan ser mapeados directamente a construcciones básicas (objetos) en
nuestro paradigma.

- 161 -
Modelo
Un modelo, es una versión simplificada de algún fenómeno o entidad del mundo
real. El modelado, como proceso, está muy ligado a otro concepto muy importante
que vimos anteriormente: el de abstracción. La forma de construir un modelo, ya
sea mental, físico, etc., es a través de un proceso de abstracción (simplificación),
mediante el cual descartamos aquellas características que no nos sean relevantes y
nos concentramos en aquellas que sí nos interesan. Esas características relevantes
son las que terminarán dando forma a nuestro modelo. En dos líneas, acerca de un
modelo podríamos decir:
Es una abstracción utilizada para entender y razonar sobre entidades y fenómenos
del mundo real.
Debe omitir detalles no esenciales y su grado de granularidad debe estar acorde a
sus propósitos.
Modelado del mundo real
Creamos un sinfín de modelos mentales para poder comprender los fenómenos
interesantes y para poder dominarlos. Un modelo es un artefacto creado por un
propósito; no puede estar bien o mal, sólo puede ser más o menos útil en relación
a su objetivo. La elección de los fenómenos y las preguntas que hacemos sobre los
mismos dependen de nuestros intereses, los paradigmas de modelado a los que
estemos acostumbrados y las herramientas que usemos para expresar nuestras
ideas. Si lo que queremos es comunicar de manera precisa nuestras ideas a un
colega, nuestro paradigma de modelado y notación deben ser similares a su
paradigma y notación. Si lo que queremos es comunicarnos con una computadora,
nuestro paradigma de modelado debe ser consistente con el lenguaje de
computación apropiado. A medida que seamos más expertos en un paradigma de

- 162 -
modelado en particular, más difícil será poder realizar preguntas cuyas respuestas
excedan los límites del paradigma.[16]
Como dice Trygve en la referencia anterior, un modelo es creado con un propósito,
y por tanto, podemos inferir que hay una subjetividad implícita agregada por el
observador que crea este modelo, ya que lo hace motivado por un propósito. Es
importante notar que dicho propósito (ya sea propio o inducido) puede ser
completamente diferente al de otro observador. Asimismo, un modelo nuca está
completo, sino que su grado de completitud depende del uso que le demos a dicho
modelo. Las personas creamos modelos justamente para simplificar y generalizar
fenómenos más complejos, con lo cual, en realidad, terminamos ignorando más
detalles de los que incluimos en nuestro modelo.

- 163 -
A pesar de no hacerlo conscientemente, vivimos constantemente utilizando y
creando nuevos modelos de todo tipo para representar los fenómenos de la
naturaleza; los ejemplos abundan y van desde los modelos físicos (utilizados en el
diseño de represas, puentes, puertos y otras construcciones) hasta los modelos
matemáticos (utilizados por ejemplo para realizar simulaciones y optimizaciones
sobre sistemas reales, como en el campo de la hidrología). En astronomía se
utilizan modelos específicos para representar el movimiento de los cuerpos celestes
en el espacio, utilizando elementos de la geometría como son los círculos y las
elipses para representar las órbitas que describen los planetas, junto con otros
modelos matemáticos. Estos modelos permiten a los astrónomos, entre otras cosas,
poder estimar la posición de uno de estos cuerpos celestes en el espacio en un
punto determinado en el tiempo y predecir, por ejemplo, las colisiones entre ellos.
Es importante notar que al realizar este tipo de modelos se dejan de lado muchos
detalles; por ejemplo, los planetas no son esferas perfectas, pero son modelados de
esa forma ya que simplifican determinados cálculos y la imprecisión que introducen
en el resultado final es despreciable.
Los modelos también nos permiten poder realizar simulaciones para evaluar o
estimar cuál será el desempeño del sistema en el mundo real, una vez que sea
llevado a la práctica. Este tipo de técnicas es utilizado en la industria del diseño de
vehículos de alta tecnología (automotriz o aeronáutica) para testear, por ejemplo,
las características aerodinámicas de los prototipos, utilizando maquetas a escala y
simulando el desempeño del vehículo dentro de un túnel de viento.
Modelos OO
La ejecución de un programa se puede ver como un modelo físico simulando el
comportamiento de una parte real o imaginaria del Mundo.

- 164 -
La palabra clave aquí es “físico”. El térmico “modelo físico” es utilizado para
distinguir estos modelos de, por ejemplo, los modelos matemáticos. Parte de la
realidad puede ser explicada utilizando ecuaciones matemáticas: las leyes de
Newton son un ejemplo de esto. Un modelo físico es un modelo construido a partir
de algún material físico como pueden ser los ladrillos Lego. Los elementos del
modelo físico representan fenómenos del dominio de aplicación. Los objetos son
como el material “computarizado” que se utiliza para construir modelos físicos
computarizados. Podemos ver a los objetos como un tipo de ladrillos electrónicos de
Lego.

Reseña Histórica [9]


Comúnmente se piensa que la programación orientada a objetos es un fenómeno
relativamente reciente dentro de la ciencia de la computación. Por el contrario, en
realidad, casi todos los conceptos principales actualmente asociados con los
programas orientados a objetos, tales como objetos, clases y jerarquías de
herencia, fueron desarrollados en los años 60 como parte de un lenguaje llamado
Simula, diseñado por investigadores en el Centro de Computación Noruego
(Norwegian Computing Center). Como el nombre lo indica, Simula fue un lenguaje
inspirado por los problemas involucrados en la simulación de sistemas de la vida
real. Sin embargo, la importancia de estas construcciones, aún para los propios
desarrolladores de Simula, fue reconocida parcialmente [10].
En la década del 70 Alan Kay organizó un equipo de investigación en Xerox PARC
(Palo Alto Research Center o “Centro de Investigación Palo Alto”). Con una gran
presciencia o previsión, Kay predijo la próxima revolución en la computación
personal que se desarrollaría cerca de una década más tarde (ver, por ejemplo, su
artículo de 1977 en Scientific American [11]). Kay estaba interesado en descubrir

- 165 -
un lenguaje de programación que fuera entendible para aquellos profesionales
ajenos a la computación, para la gente común sin ningún tipo de entrenamiento en
el uso de computadoras. Encontró en las nociones de clases y en la computación
como simulación una metáfora que fácilmente podría llegar a ser comprendida por
los usuarios principiantes, como luego demostraría mediante una serie de
experimentos dirigidos en PARC usando a los chicos como programadores. El
lenguaje de programación desarrollado por su equipo fue llamado Smalltalk. Este
lenguaje evolucionó a través de varias revisiones durante la década. Un artículo
muy popular de la revista Byte de 1981 contribuyó para popularizar en gran medida
los conceptos desarrollados por Kay y su equipo en Xerox.
Casi contemporáneo al trabajo de Kay fue otro proyecto llevado a cabo al otro lado
del continente. Bjarne Stroustrup, un investigador de los Laboratorios Bell que
había aprendido Simula mientras completaba su doctorado en la Universidad de
Cambridge en Inglaterra, se encontraba desarrollando una extensión al lenguaje C
que facilitaría la creación de objetos y clases [12]. Esto se transformaría luego en el
lenguaje C++ [13].
Con la difusión de información sobre estos y otros proyectos similares, comenzó un
aumento vertiginoso de la investigación sobre técnicas de programación orientada a
objetos. Al momento de producirse la primera conferencia importante sobre
programación orientada a objetos, en 1986, hubo literalmente docenas de nuevos
lenguajes de programación compitiendo para ser aceptados. Entre estos incluidos
Eiffel [14], Objective-C [15], Actor, Object Pascal, y varios dialectos de Lisp.
En las dos décadas desde la conferencia de OOPSLA en 1986, la programación
orientada a objetos a pasado de ser revolucionaria a ser el movimiento principal, y
en este proceso ha transformado gran parte de la ciencia de la computación.

- 166 -
Simula: Por los años 60, los programadores comprendieron que era necesario
descomponer los sistemas de programación en partes pequeñas más manejables.
La introducción de Simula-67 trajo consigo la primera noción de objetos, las clases,
y una especie de herencia; por lo tanto, Simula es un hito importante en cualquier
debate sobre lenguajes de programación OO. El lenguaje fue diseñado por Ole-
Johan Dahl, Bjørn Myhrhaug y Kristen Nygaard en el Norwegian Computing Center
ubicado en Oslo. La primer versión del lenguaje, Simula-1, fue presentada en 1966.
Los módulos de programación definidos por Simula no se basaron en
procedimientos, sino en objetos físicos tangibles. Simula tuvo una novedosa
manera de plantear los objetos, en donde que cada objeto tiene sus propios datos y
comportamiento.
Smalltalk: Muchos consideran que el primer lenguaje verdaderamente orientado a
objetos fue Smalltalk, desarrollado en el Learning Research Group en Xerox's Palo
Alto Research Center a principios de los 70. En Smalltalk, todo es realmente un
objeto, lo que impone el paradigma OO y hace que sea prácticamente imposible
escribir un programa en Smalltalk que no sea OO.
Smalltalk es en realidad un ambiente de programación interactivo que interpreta
código sobre la marcha (on-the-fly) lo que permite cambiar los parámetros y el
código de un programa mientras el programa está corriendo.
Smalltalk fue el primero en introducir muchos otros conceptos que luego
aparecerían como revolucionarios al ser implementados en otras aplicaciones, como
los buscadores o exploradores (browsers), las ventanas y los menús emergentes
(pop-up menus). El ambiente se basa en una máquina virtual, permitiendo a las
aplicaciones ser migradas entre diferentes plataformas.
C++: Tiene su origen en un proyecto para simular software corriendo en un
sistema distribuido. Este simulador, de hecho escrito en Simula, es donde Bjarne
Stroustrup concibió la idea de combinar algunas de las características de Simula
con la sintaxis de C. El concepto de clase en C++ brindaba el mecanismo de
encapsulamiento, que hoy por hoy es un requisito esencial de cualquier lenguaje
OO.
Aunque C brindó una base sólida para C++, también se convirtió en una carga un
tanto pesada. El hecho de hacer a C++ compatible con su predecesor trajo serios
inconvenientes. Aunque C++ proporciona construcciones OO, también es posible
usar técnicas de programación estructurada. Por este motivo, C++ no es
considerado un lenguaje OO puro, si no un lenguaje híbrido.
Java: Los orígenes de Java se encuentran en un lenguaje que se apodó Oak. Su
creador decidió que basaría su lenguaje en el tan exitoso C++, pero que sólo
incorporaría aquellas características de C++ que parecieran valer la pena. Las
características que eliminó de C++ fueron la herencia múltiple, las conversiones
automáticas de tipos, el uso de punteros, y el esquema de administración de
memoria de C++. Pero el proyecto fue archivado por falta de interés en el
mercado.
Con la llegada de la Web y el surgimiento de los browsers, la gente de Sun
comenzó a atar cabos, y así Oak fue rescatado de la inactividad y renombrado
como Java.
C#: Microsoft respondió a la popularidad de Java produciendo una versión de Java
llamada Visual J++. Sin embargo, Microsoft se decidió por una respuesta más
integral. Usando muchas de las innovaciones que implementaba Java, Microsoft
desarrolló un lenguaje denominado C# que se convirtió en la base para la
plataforma .NET. De igual manera que Java, C# se basó fuertemente en los éxitos
y fracasos de lenguajes anteriores.

- 167 -
Paradigma
Etimológicamente la palabra paradigma deriva del Griego paradigma, que significa
“patrón” o “ejemplo”. Thomas Kuhn [2] asignó a la palabra paradigma [19] el
significado aceptado hoy en día en la comunidad científica, cuando la adoptó para
referirse al conjunto de prácticas que definen a una disciplina científica durante un
período de tiempo en particular. Kuhn define también el término “cambio
paradigmático”[20], como el proceso y el resultado de un cambio en las hipótesis
establecidas por las teorías científicas reinantes. Un “cambio paradigmático” (o
“revolución científica”, como también lo llama Kuhn) se origina cuando los
científicos encuentran anomalías que no pueden ser explicadas mediante el
paradigma aceptado universalmente sobre el cual debe realizarse el progreso
científico. Todos los paradigmas presentan anomalías pero las hay de distinto tipo e
importancia. Cuando ocurre una serie de anomalías significativas contra un
paradigma actual, la disciplina científica entra en un estado de crisis, en el cual se
prueban nuevas ideas, tal vez descartadas previamente. Eventualmente se forma
un nuevo paradigma, que entrará en conflicto con el actual, enfrentando a los
seguidores de cada corriente. De producirse la transición entre el antiguo
paradigma y el nuevo, se dice que ha sucedido una “revolución científica” o “cambio
paradigmático”, según Kuhn.
Floyd, en “The Paradigms of Programming” [18] de 1978 habla sobre cómo influyen
los paradigmas de programación en el suceso de los diseñadores de programas,
sobre cómo deben ser enseñados y cómo deben ser incorporados en los lenguajes
de programación. Afirma que por aquella época existían problemas en cuanto al
inventario de paradigmas de programación disponible, en la manera en que se
enseñaba estos paradigmas y en la manera en que los lenguajes de programación

- 168 -
soportaban o dejaban de soportar los paradigmas de sus correspondientes
comunidades de usuarios. Se refiere al estado de la programación como un estado
de depresión (lo llama “depresión del software”), en comparación con la “crisis del
software” de la década anterior. Basándose en la visión de Kuhn sobre las
revoluciones científicas y en experiencias llevadas a cabo por él y algunos de sus
colegas, concluye que la probabilidad de que se produzca un avance continuo en
programación, requerirá de una invención continua, elaboración y comunicación de
nuevos paradigmas.

Paradigma estructurado [21] [22]: describe la programación en términos del


estado del programa y sentencias que cambian dicho estado. Los programas
estructurados son una secuencia de instrucciones o sentencias que le indican a la
computadora cómo realizar una tarea. Podemos identificar los siguientes tipos de
sentencias básicas sobre las cuales se basa el paradigma: la asignación, la
secuencia, la repetición o iteración y la ramificación condicional. Con estas tres
sentencias se supone que se puede construir cualquier programa dentro del
paradigma estructurado. Dentro del conjunto de lenguajes que soportan el
paradigma estructurado, podemos mencionar: C, PASCAL, ADA, BASIC.

- 169 -
El Paradigma Orientado a Objetos
Hasta el momento hemos dado algunas ideas respecto de qué es un paradigma y
de los distintos paradigmas de programación que encontramos hoy en día. Pero…
¿por qué es importante ésto? En nuestro caso, poder definir el paradigma orientado
a objetos nos va a permitir entender claramente cuáles son las bases sobre las que
vamos a trabajar. En breve, al definir el paradigma OO estaremos explicitando
cuáles son los conceptos básicos con los que trabajaremos y cuáles son las reglas
válidas que nos permitirán manipular dichos conceptos.
Probablemente Alan Kay es quién ha dado la definición más concisa del paradigma
orientado a objetos. En [27] escribe:
…para este momento la mayoría de los principios de Smalltalk se habían plasmado
en seis ideas principales que estaban en consonancia con las premisas iniciales del
diseño del intérprete. Las primeras tres hablan sobre “que significa” ser un objeto –
cómo son vistos y utilizados desde el “exterior”. Estas premisas no requirieron de
ninguna modificación durante los años. Las últimas tres – los objetos vistos desde
adentro – fueron re-pensadas en cada nueva versión de Smalltalk…
Todo es un objeto.
Los objetos se comunican enviando y recibiendo mensajes.
Los objetos tienen su propia memoria (en términos de objetos).
Cada objeto es instancia de una clase (que también debe ser un objeto).
Las clases contienen el comportamiento compartito por sus instancias.
Para evaluar un programa, el control es pasado al primer objeto y el resto es
tratado como envío de mensajes.

- 170 -
- 171 -
Programas Orientados a Objetos
Una vez que hemos sentado el paradigma con el cual vamos a trabajar (o sea, las
“reglas del juego”) es interesante detenernos un momento y analizar que forma
tiene un programa en este paradigma. Al utilizar un paradigma estructurado, un
programa se basa en el diseño de estructuras de datos, los cuales son básicamente
contenedores de información pasivos. Luego, se desarrollan algoritmos que
trabajan sobre dichas estructuras realizando algún tipo de transformación de datos.
Al construir programas orientados a objetos, se deja de pensar en términos de
estructuras de datos pasivas y algoritmos y se piensa en términos de objetos
activos; los objetos son entidades que proveen un comportamiento particular y son
utilizados para modelar el dominio del problema. Bajo esta óptica, nuestro
programa ya no se encuentra dividido entre datos pasivos y algoritmos activos, sino
que es una red de objetos que cooperan (enviándose mensajes) para llevar
determinada tarea a cabo.

- 172 -
Módulo 2

Elementos básicos de la
Programación Orientada a
Objetos

- 173 -
Los objetos son los elementos primarios que utilizaremos para construir programas.
Dichos objetos son básicamente abstracciones de alguna entidad (ya sea tangible o
no) del dominio del problema que estamos atacando. Para resolver un problema
determinado en el paradigma OO sólo tenemos objetos, que se comportan de una
determinada manera (definido por sus mensajes) e interactúan entre ellos
(enviándose de mensajes).
Cada objeto es una construcción caracterizada por: su comportamiento, el cual está
dado por los mensajes a los que puede responder; su estado interno, que,
mediante un conjunto de variables de instancia representa las características
intrínsecas de la entidad; y finalmente su identidad.
El comportamiento que provee puede verse como los servicios que presta y que
determinan su existencia y deben servir para responder preguntas como /¿para qué
quiero a este objeto?/ y /¿qué servicios me puede brindar?/. Por otro lado, como
dijimos antes, el estado interno está representado por variables de instancia que se
utilizan para expresar características del objeto y relaciones de conocimiento con
los otros objetos con que va a colaborar.
Otra de las propiedades importantes de los objetos es el encapsulamiento, que
sostiene que el único que puede manipular el estado interno de un objeto es el
mismo objeto. En otras palabras, un objeto no puede invadir el espacio privado
(estado interno) de otro objeto.
Pero no debemos perder de vista el hecho de que dentro de un sistema coexisten
miles de objetos, lo que conduce a la necesidad de disponer de algún mecanismo
que permita identificarlos unívocamente de modo de poder diferenciarlos. Por este
motivo, los objetos poseen una identidad que, como se presentó anteriormente, es
una propiedad intrínseca de cada objeto y, por tanto, no puede ser modificada por
el programador.

- 174 -
Características
Comportamiento bien determinado. Al diseñar un objeto lo que uno hace es
establecer cuáles son las responsabilidades de dicho objeto. Estas
responsabilidades se materializan en un conjunto de mensajes a los que un objeto
puede responder.
Estado interno. A nivel de implementación los objetos poseen una estructura
interna que se define en términos de variables de instancia. Las variables de
instancia se utilizan para representar aquellas características propias del objeto
(como puede ser el número de una cuenta bancaria) y a los objetos con los que
deberá colaborar a lo largo de su vida.
Identidad. Es una propiedad intrínseca que poseen todos los objetos. La definición
de identidad es la siguiente: Un objeto solo es idéntico a si mismo. Notar que
identidad no es lo mismo que igualdad; dos tazas pueden ser iguales, pero cada
taza solo es idéntica a si misma.
Todo objeto es instancia de una clase. Las clases son el siguiente nivel de
abstracción, sobre el cual entraremos en detalle mas adelante. Como dijimos
anteriormente, un objeto es una abstracción de una entidad de nuestro modelo.
Dado que generalmente nos encontramos con un conjunto de objetos que se
comportan en forma similar, el siguiente paso es encontrar una forma de definir el
comportamiento de todos estos en forma general. Pensemos por ejemplo en las
cuentas bancarias: en un banco habrá miles de cuentas bancarias, las que se
comportarán de la misma forma. Por este motivo, aparece la noción de clase
“cuenta bancaria”, la cual se utiliza para describir el comportamiento de todas sus
ocurrencias (instancias).

- 175 -
Cuando pensamos en los objetos vistos desde afuera lo que nos interesa es qué es
lo que el objeto puede hacer y no cómo lo hace. A continuación veamos un extracto
del libro de Budd [34]:
Supongamos que un individuo, llamado Chris, desea enviarle flores a una amiga
llamada Robin, que vive en otra ciudad. Debido a la distancia, Chris no puede
simplemente recoger las flores y llevárselas a Robin en persona. No obstante, esta
tarea puede resolverse fácilmente. Chris puede simplemente caminar hasta la
florería más cercana, la cual es atendida por un florista llamado Fred. Chris le dirá a
Fred el tipo de flores que desea enviar a Robin, y la dirección donde deben ser
entregadas. Luego Chris tendrá la seguridad de que las flores serán entregadas de
manera expeditiva y automática.
Corriendo el riesgo de volver innecesariamente a algún punto, enfaticemos el hecho
de que el mecanismo que fue usado para resolver el problema, fue encontrar un
agente apropiado (llamado Fred) y enviarle a este un mensaje con la solicitud. Es
responsabilidad de Fred satisfacer esa solicitud. Existe un método (algún algoritmo
o conjunto de operaciones) usado por Fred para hacer esto. Chris no tiene que
preocuparse en saber las particularidad del método que Fred usará para satisfacer
la solicitud, de hecho, a menudo la persona que hace una solicitud no desea saber
lo detalles. Esta información usualmente se encuentra oculta. Una investigación, sin
embargo, podría mostrar el hecho de que Fred envía un mensaje ligeramente
diferente a otro florista en la ciudad donde vive Robin. Ese florista, tal vez tenga un
subordinado que hace los arreglos florales. Este florista entonces le pasa las flores,
junto con otro mensaje a un repartidor, y así sucesivamente. En un principio, el
florista que vive en la ciudad de Robin obtuvo sus flores de un mayorista de flores,
el cual interactuó con los que cultivan las flores, los cuales deben administrar un
equipo de jardineros.

- 176 -
Entonces, nuestra primera observación de la solución orientada a objetos a un
problema, es que la solución a este problema requiere de la ayuda de otros
individuos. Sin su ayuda, el problema no podría ser fácilmente solucionado.
Expresaremos esto de la siguiente manera:
“Un programa orientado a objetos se estructura como una comunidad de agentes
interactuando, llamados objetos. Cada objeto tiene un rol para llevar a cabo. Cada
objeto provee un servicio, o ejecuta una acción, que es usada por otro miembro de
la comunidad.” [34]
En muchos casos el objeto necesitará otros objetos que lo ayuden a llevar a cabo
su tarea. En este caso, al enviar el mensaje, el objeto emisor también le envía un
conjunto de parámetros para que el objeto pueda resolver el pedido. Por ejemplo,
al pedirle al florista que envíe las flores, el objeto emisor (Chris) debe indicarle al
florista el tipo y cantidad de flores que quiere enviar, así como la dirección de
Robin.

- 177 -
Estado interno/estructura interna
El estado interno de un objeto está constituido por un conjunto de variables de
instancia. Dichas variables de instancia acompañan al objeto durante todo su ciclo
de vida.
Una variable de instancia puede hacer referencia a una propiedad intrínseca de la
entidad que representa, o bien a otro objeto con el cual pueda colaborar para llevar
a cabo sus responsabilidades. A lo largo de la vida del objeto, las propiedades y
colaboradores pueden cambiar. Por ejemplo, al depositar $100 en una cuenta
bancaria la variable de instancia saldo cambiará su valor.
Este estado interno es privado del objeto. Es una de las características
fundamentales del paradigma y, como veremos más adelante, resulta crucial para
lograr software escalable. Por definición, las variables de instancia (estructura
interna) de un objeto es privado a éste. El único que puede acceder y manipular
sus v.i. es el propio objeto. Si un objeto externo quiere acceder a una v.i. lo tiene
que hacer por medio del envío de un mensaje. Esto le da la posibilidad al objeto de
decidir qué es lo que quiere publicar.
Identidad
La identidad es una propiedad intrínseca que poseen todos los objetos. Por
definición un objeto solo es idéntico a si mismo. Es importante notar que identidad
no es lo mismo que igualdad; dos sillas pueden ser iguales al punto que, si nos
damos vuelta y las cambian de lugar, no podríamos distinguir cual es cual. A pesar
de esto, cada silla sigue manteniendo su identidad.

- 178 -
La identidad sirve para poder distinguir objetos individuales dentro de un sistema.
Es decir, dentro de un sistema coexisten una cierta cantidad de objetos, por lo que
es necesario poder identificarlos y diferenciarlos entre ellos.
La identidad, a nivel práctico, no tiene mayor importancia para el programador ya
que los lenguajes orientados a objetos proveen un mecanismo por el cual cada
objeto posee un identificador único y, de hecho, casi nunca es posible obtener dicho
identificador. Indirectamente vamos a estar utilizando este concepto cuando
comparemos dos objetos por igualdad, pero este concepto se ampliaran a
continuación.

- 179 -
- 180 -
• Objetos:

• Banco, CuentaBancaria, Cliente.

• Propiedades:

• Depositar, Extraer, Saldo, CerrarCuenta, CrearCuenta, Apellido, DNI,


Nombre.

Como ejercitación adicional, y dependiendo de la compresión del tema hasta el


momento de los cursantes, puede plantearse la idea de agrupar las propiedades en
los objetos que correspondan. La solución deseada es la siguiente:
Banco: CrearCuenta, CerrarCuenta.
Cliente: Apellido, DNI, Nombre.
CuentaBancaria: Extraer, Depositar, Saldo.

- 181 -
• Objetos:

• Computadora, Monitor, Gabinete, Teclado.

• Propiedades:

• modelo, numeroDeSerie, modeloTeclado, modeloMonitor,


modeloGabinete, numeroDeSerieTeclado, numeroDeSerieMonitor,
numeroDeSerieGabinete, temperatura, puertosUSBDisponibles,
puertosUSBEnUso, crearCuenta.

Como ejercitación adicional, y dependiendo de la compresión del tema hasta el


momento de los cursantes, puede plantearse la idea de agrupar las propiedades en
los objetos que correspondan. La solución deseada es la siguiente:
Computadora: modeloTeclado, modeloMonitor, modeloGabinete,
numeroDeSerieTeclado, numeroDeSerieMonitor, numeroDeSerieGabinete,
temperaturaGabinete, puertosUSBDisponibles, puertosUSBEnUso.
Monitor: modelo, numeroDeSerie.
Teclado: modelo, numeroDeSerie.
Gabinete: modelo, numeroDeSerie, temperatura, puertosUSBDisponibles,
puertosUSBEnUso.

- 182 -
Dijimos que el comportamiento de un objeto se define por medio de los mensajes
que éste entiende y que para poder enviarle un mensaje a un objeto, hay que
conocerlo. Hemos visto también que al enviarle un mensaje a un objeto, éste
responde activando el método asociado al mensaje, siempre y cuando éste exista.
También vimos que un mensaje es enviado a un objeto por otro objeto y como
resultado del envío de un mensaje, siempre se retorna un objeto.
El método, es decir la implementación, especifica qué hace el objeto receptor al
recibir el mensaje. El método no contiene otra cosa que una serie de mensajes
enviados a otros objetos (sólo hay objetos y mensajes). Recordemos también que
los métodos son privados al objeto y que los objetos sólo pueden comunicarse
mediante el envío de mensajes. Veamos en qué consiste la ejecución de
comportamiento ante el envío de un mensaje.
Mostrar la importancia de qué mensajes entiende un objeto y no cómo los realiza.
Poder mostrar la modularidad y separación que existe a la hora de programar en
POO.

- 183 -
Por ejemplo, supongamos que contamos con un objeto que representa la torre de
control de un aeropuerto. Si la torre desea avisar al avión LV-YPS que debe
aterrizar, primero debe conocerlo. A su vez, si el avión LV-YPS desea comunicarse
con la torre, también debe conocerla.

- 184 -
Cuando un objeto (emisor) le envía un mensaje a otro objeto (receptor), el objeto
receptor responde activando el método asociado a este mensaje, siempre que el
mensaje recibido forme parte del protocolo del objeto receptor. Volviendo al
ejemplo, cuando la torre envíe el mensaje „aterrizar‟ al avión, éste activará un
método que contendrá el procedimiento de aterrizaje.
Podría suceder que el avión no conozca los procedimientos para aterrizar, es decir,
podría no existir un método que se corresponda con el mensaje „aterrizar‟. ¿Qué
ocurre cuando un objeto no entiende un mensaje recibido? Esto depende del
lenguaje: algunos lenguajes pueden evitar esta situación mediante un sistema de
tipos fuerte que chequee estas situaciones en tiempo de compilación, mientras que
otros brindan una mayor libertad en cuanto al envío de mensajes y responden,
eventualmente, con un error en tiempo de ejecución.

- 185 -
Expendedora de café
El director debe entregar a cada jugador una tarjeta. Para establecer las relaciones
de conocimiento en forma ordenada puede repartir primero las que corresponden a
objetos que no conocen a nadie preguntando el nombre a cada jugador a medida
que le va dando la tarjeta. De esta forma, cuando entregue las tarjetas que tienen
relaciones de conocimiento ya puede pedirle que la llene con el nombre del jugador
que corresponda.
Se debe poner un vaso a disposición del jugador que representa a la máquina
expendedora, pero debe aclararse que el vaso es un objeto al igual que cada
jugador.
El director debe explicar que en las tarjetas se encuentran las instrucciones que
deben seguir al pie de la letra cuando se les pide algo.
El director es quien debe comenzar el juego diciéndole a la máquina expendedora
alguno de los mensajes que ésta entiende.

OTROS EJERCICIOS
Guiar a los alumnos para que digan cómo sería el método “hacer café con n
cucharadas de azúcar” de la máquina expendedora
Intentar iniciar el juego enviándole a la máquina expendedora un mensaje que no
sepa responder, por ejemplo uno que sea de otra clase
Cambiarle la tarjeta al azucarero por una que tiene una implementación distinta,
por ejemplo:
AZUCARERO
“poner n cucharadas de azúcar en este vaso”
Poner n cucharadas de azúcar en el vaso (poner n bollitos de papel en el vaso)
Devolverle el vaso a quien me pidió poner las cucharadas

- 186 -
VENTAJAS
Se ven claramente las interacciones entre los objetos
Se puede aprovechar para dar un anticipo al concepto de polimorfismo (con
respecto al mensaje “preparar uno en este vaso”)
Alienta la interacción entre los alumnos
DESVENTAJAS
No todas las personas se sienten cómodas con este tipo de ejercicios
Puede llegar a perderse la atención de los alumnos en caso de que sea un curso
muy numeroso
No sirve para mostrar mensajes de un objeto a sí mismo

Otro ejemplo de envío de mensajes, usando una versión simplificada del juego de
rol.

- 187 -
- 188 -
Siempre se debe contar con dos objetos para poder resolver el envío de un
mensaje, uno cumpliendo el rol de emisor y otro el de receptor (eventualmente
podría tratarse del mismo objeto cumpliendo los dos roles). El emisor envía un
mensaje al receptor, en este caso el mensaje hacerAlgo. El receptor recibe el
mensaje y busca entre sus métodos aquel que coincida con el nombre del mensaje.
Si encuentra el método correspondiente, procede a ejecutarlo (en este caso el
objeto receptor tiene un método asociado al nombre hacerAlgo). La ejecución del
método la veremos en detalle más adelante, en este caso nos interesará saber que
al finalizar la misma, el objeto receptor deberá retornar un objeto como resultado
del envío del mensaje, devolviendo nuevamente el control al objeto emisor.

¿Cómo es la manera en que se especifica un mensaje? En primer lugar debemos


asignarle un nombre, el mismo debe tener significado en el dominio del problema,
esto es de vital importancia para el futuro entendimiento del sistema. Por otro lado,
debemos indicar cuáles son los posibles objetos, u otro tipo de parámetro,
requeridos para resolver el mensaje.
Cada lenguaje de programación propone una sintaxis particular para indicar el
envío de un mensaje. A lo largo del curso utilizaremos la siguiente sintaxis:
<objeto receptor>.<nombre de mensaje> (<parámetros>);
Por ejemplo, decirle a una cuenta bancaria que deposite $100 se escribe como:
unaCuenta.depositar(100);

- 189 -
Ejemplificar correctamente la diferencia entre método y mensaje.
Mostrar, si es necesario, el #dameCafe(), del ejemplo del juego de rol.

- 190 -
Veamos como ejemplo la implementación del método depositar del objeto caja de
ahorro.
El comentario nos indica de manera concisa en qué consiste la resolución del
comportamiento representado por el método.
En este caso la resolución es muy sencilla: la variable de instancia saldo de la caja
de ahorro se actualiza con el valor del parámetro unMonto.

- 191 -
Este caso es muy similar, salvo que se reciben dos parámetros: el saldo y el nro. de
cuenta. El cajero conoce al banco por medio de la variable de instancia banco, y lo
que hace es delegar en dicho objeto la responsabilidad de buscar la caja de ahorro
que corresponde al nro. de cuenta que viene como parámetro. Luego, una vez
encontrada la caja de ahorro correspondiente, se le envía el mensaje depositar con
el monto como parámetro.

- 192 -
Ahora será necesario especificar el método saldo. El objeto caja de ahorro debe
devolver su saldo actual como respuesta al envío del mensaje saldo, para lo cual
necesitaremos un mecanismo que nos permita indicar cuál es el resultado de
evaluar un método. Para tal fin contamos con una construcción sintáctica especial,
el símbolo flecha hacia arriba. El símbolo va seguido de cualquier objeto e indica
que ese objeto será retornado como resultado de la ejecución del método.
La especificación del método saldo quedaría de esta manera. Simplemente se
indicaría que se debe devolver el colaborador interno saldo, anteponiendo el
símbolo al nombre de la variable de instancia que contiene el valor a retornar.

- 193 -
Forma más visual e intuitiva de los envíos de mensajes en los objetos.

Cambio del objeto titular dentro de la caja de Ahorro

- 194 -
Este caso, en respuesta al mensaje titular(), esperamos obtener el titular de la caja
de ahorro. Por lo tanto, cuando la caja de ahorro recibe el mensaje titular, activa el
método correspondiente y se retorna el objeto persona Juan Pérez.

- 195 -
Realizar el método #extraer(unMonto), utilizando el método #depositar(unMonto)
como ejemplo

- 196 -
Modelar el proceso de extracción de dinero de un cajero automático identificando
las principales entidades participantes y el conjunto de mensajes que los
comunica. Para esto utilizaremos diagramas de secuencia UML.

- 197 -
- 198 -
El ocultamiento de la información es particularmente importante en la
programación orientada a objetos. Los objetos frecuentemente son complejas
estructuras de datos con muchos componentes que no deben ser accedidas por los
clientes. Existen algunas razones para tal encapsulamiento:
- La representación de un objeto está sujeta a cambios. Durante el desarrollo de
una clase puede suceder que un conjunto diferente de variables de instancia resulte
mejor con el propósito de la clase. Si los clientes acceden directamente a las
variables de instancia, éstos deben ser modificados para que queden consistentes
con la nueva representación.
- En contraste con los registros en los programas convencionales, los objetos no
son usados principalmente como contenedores cuyo único objetivo es agrupar
datos elementales. Más bien, las variables de instancia del objeto son utilizadas
para representar el estado del mismo. El objeto en si mismo es una entidad activa
que puede llevar a cabo ciertas operaciones cuando le es requerido. Las variables
de instancia pueden ser consideradas como variables auxiliares que son necesarias
para realizar las operaciones.
- Los objetos frecuentemente poseen otros objetos. La posesión es privada para el
objeto; la relación entre el objeto y los otros objetos que le pertenecen no debe ser
alterada por los clientes.
- Los objetos son accedidos mediante referencias polimórficas. Si un objeto es
accedido a través de una variable v, el objeto referenciado por v puede cambiar
dinámicamente durante la ejecución del programa y no podemos estar seguros si la
variable v siempre hará referencia a un objeto con la misma estructura interna.

- 199 -
El encapsulamiento es una de las características fundamentales del paradigma y es
uno de los puntos clave para que el software escale en forma “suave” y se adapte a
los cambios.
Idealmente, en cualquier sistema, intentamos que el acoplamiento entre las
partes que lo componen sea lo más bajo posible. Esto implica que cada parte sabe
lo mínimo indispensable de las otras partes, lo que implica que los cambios en
alguna de esas partes no impactan (o lo hacen en forma muy leve) en el resto de
las partes del sistema.
En un sistema OO las “partes” básicas son los objetos, por lo que nos gustaría que
los cambios en un objeto impacten lo menos posible en el resto de los objetos que
hacen al sistema. Uno de las formas de lograr esto es por medio de la separación
entre lo que es público de un objeto y lo que es privado.
Desde el punto de vista mas puro del paradigma orientado a objetos un objeto
se define por los servicios que puede brindar (o sea, por los mensajes que
entiende). Luego, lo lógico es que estos mensajes sean la parte pública del objeto.
Por otro lado, la implementación de estos mensajes (los métodos, o sea cómo
resuelve un requerimiento el objeto) no es algo que le importe al emisor del
mensaje, por lo que debe ser privado del objeto que implementa el método. De
forma similar, tampoco tiene porque interesarle al resto de los objetos cuál es la
estructura interna de un determinado objeto ni con qué otros objetos éste tiene que
colaborar para llevar a cabo sus responsabilidades. Todo lo que le importa al objeto
emisor es cuál es el mensaje que tiene que enviar, qué parámetros debe enviar y
cual es la semántica asociada al envío del mensaje.
El hecho de programar en términos del protocolo de un objeto, sin saber nada de
su estructura interna ni de cómo implementa sus métodos, es lo que ayuda a
mantener los cambios acotados, evitando que un cambio en un objeto se propague
por todo el sistema. De aquí la relación que nombramos anteriormente acerca de
los métodos y el encapsulamiento. Justamente es a través de los métodos que el
objeto publica la única manera de interactuar con él. Nada se podrá hacer que no
esté provisto a través del protocolo.

- 200 -
El mismo gráfico que habíamos visto anteriormente lo vemos ahora desde el punto
de vista del encapsulamiento. Vemos que el titular de la caja de ahorro es sólo
conocido por la misma caja de ahorro y la única forma de accederla es a través del
protocolo del objeto. Lo mismo ocurre con el saldo.

- 201 -
Ahora debemos modelar un objeto punto, que represente un punto en el plano,
dando la implementación correspondiente a cada uno de los siguientes mensajes:
getX() “Devuelve la coordenada x del punto”
setX(unNumero) “Cambia la coordenada x del punto por
unNumero”
getY() “Devuelve la coordenada y del punto”
setY(unNumero) “Cambia la coordenada y del punto por
unNumero”
igualA(otroPunto) “Devuelve si el punto es igual a otroPunto”

- 202 -
Mostrar con diagramas de secuencia la interacción entre el pulsador, la vía, la
locomotora. En primera instancia van a modelar el motor con un boolean. Luego el
ejercicio los llevará a que lo modelen con un objeto a parte: Motor

- 203 -
En este punto, el nuevo objeto Motor entenderá los tres mensajes:
#haciaAtrás.
#haciaAdelante.
#apagado.
Mostrar la escalabilidad del objeto agregando más estados posibles de movimiento.

- 204 -
Si pensamos nuevamente en el ejemplo del banco, es evidente que existirán varios
objetos de tipo caja de ahorro, uno por cada caja de ahorro existente en el banco.
Todos estos objetos deberán tener el mismo comportamiento y es de esperar que si
hay algún cambio en el comportamiento de las cajas de ahorro, el mismo se refleje
por igual en todos los objetos de este tipo. Luego, es necesario contar con algún
mecanismo que permita agrupar el comportamiento común a un conjunto de
objetos, de manera que pueda ser reutilizado sin tener que ser especificado
individualmente. Por otro lado, el estado interno de cada caja de ahorro será
diferente (los saldos no serán los mismos por ejemplo) pero todas compartirán la
misma estructura interna (todas conocen su saldo, titular, etc.). Desde el punto de
vista de la reutilización, es así como surge la noción de clase: como una
herramienta que me permite factorizar y reutilizar estructura y comportamiento en
común.

- 205 -
Una clase nos permite describir en un sólo lugar el comportamiento genérico de un
conjunto de objetos. Una vez definido este comportamiento, es posible crear
objetos que lo reutilicen y se comporten de la manera allí descripta. Las clases nos
permiten pensar en un nivel de abstracción más alto. Cuando construimos
programas nos preguntamos constantemente: ¿qué clases de objetos aparecen en
mi sistema?
Una clase entonces puede pensarse como un molde para un tipo específico de
objeto. Molde como medio para definir la forma de los objetos.
Es natural clasificar objetos por determinadas características. En muchos casos
nos encontramos en situaciones en las que un conjunto de objetos se comportan en
forma similar y sólo difieren en sus características básicas o en los objetos con los
que colabora. En estos casos es importante poder abstraer el comportamiento
común de los objetos y especificarlos en forma abstracta, de forma tal de modelar
el concepto subyacente. Como definición de clase se puede tomar la siguiente:
Una clase es una descripción abstracta de un conjunto de objetos.
Las clases describen el formato de los objetos y agrupan comportamiento en
común. Una clase especifica qué forma tendrán sus instancias (sus variables de
instancia) y cómo responderán a los mensajes que se le envíen. De esta forma, una
clase puede ser vista como una descripción de sus instancias y como un repositorio
de comportamiento. Cuando se le envía un mensaje a un objeto, lo que hace el
intérprete es buscar en la clase del objeto receptor un método con el cual
responder al envío del mensaje. De ésta forma, todos los objetos que comparten
una misma clase responden en forma similar al envío de un mensaje.
En el caso de la cuenta bancaria, dado que en un banco habrá miles de cuentas,
lo que hacemos es modelar la noción de cuenta bancaria en una clase. Esta clase
definirá qué variables tendrán sus instancias, así como los mensajes a los que
puede responder. En nuestro caso la clase se llamará CuentaBancaria, especificará
que sus instancias tienen dos variables (saldo y titular) y que pueden responder a
los mensajes saldo(), titular(), depositar(unMonto) y extraer(unMonto).

- 206 -
Sabemos que las clases son las encargadas de describir en forma abstracta a sus
instancias, luego es lógico que si necesitamos crear una nueva instancia se lo
pidamos a la clase. Por ese motivo, la clase tiene la responsabilidad de crear sus
instancias. Volviendo al ejemplo de la cuenta bancaria, para crear una nueva
cuenta bancaria lo que debemos hacer es pedirle a la clase CuentaBancaria que nos
retorne una nueva instancia.
Uno de los problemas más comunes es la confusión entre clases e instancias. Es
importante remarcar que una clase es un molde de estructura y comportamiento,
así como la encargada de crear a sus instancias. Una vez que se crea una instancia,
esta tiene sus propias variables. Por ejemplo, si creamos dos cuentas bancarias,
cada una tendrá su saldo y su titular. Lo único que comparten es que ambas son
instancia de la misma clase, lo que implica que al enviarles un mensaje, el método
que se activará se buscará en la clase CuentaBancaria, que es común a las dos.

- 207 -
Contamos con una clase CajaDeAhorro, que define el comportamiento y la
estructura común a todas sus instancias. Una CajaDeAhorro sabrá
extraer(unMonto) de su saldo, depositar(unMonto) y devolver su saldo actual.
Además deberá colaborar con un objeto que cumplirá el rol de titular de la cuenta.
Podemos ver en el ejemplo dos instancias de CajaDeAhorro, cada una con su propio
estado interno. Eventualmente podrían llegar a compartir el mismo titular de
cuenta (un persona es titular de ambas cuentas) o bien tener el mismo saldo. Las
dos instancias de la clase CajaDeAhorro comparten el mismo comportamiento,
definido en la propia clase.
De ahora en más cuando queramos referirnos a un método de una clase, lo
haremos utilizando la siguiente sintaxis, por convención:
NombreDeClase>>método(parámentro1, …)
Ejemplo:
CajaDeAhorro>>depositar(unMonto)
saldo := saldo + unMonto

- 208 -
Las clases se especifican por medio de un nombre, la estructura interna que
tendrán sus instancias y los mensajes y métodos asociados que definen su
comportamiento. El nombre debe comenzar con mayúscula y no contener espacios.
Las variables de instancia representan el estado o estructura interna de las
instancias de la clase. Por último, se detalla el conjunto de mensajes que entenderá
una instancia de dicha clase, también llamado protocolo

- 209 -
Hasta el momento habíamos visto que un objeto, ante le envío de un mensaje,
buscaba entre sus métodos aquél que correspondiera con el mensaje en cuestión
para proceder con la activación del mismo. Ahora que hemos introducido las clases
como repositorio de comportamiento, la búsqueda del método asociado a un
mensaje ya no será plena responsabilidad de las instancias, sino que este trabajo
será delegado a las clases. En el ejemplo podemos ver cómo el objeto
unaCajaDeAhorro delega la búsqueda del método a su clase (CajaDeAhorro) ante la
recepción del mensaje depositar(unMonto). La clase buscará entre su colección de
métodos aquél que corresponda con el mensaje depositar(unMonto) y se procederá
a ejecutar el método en el contexto del objeto receptor del mensaje
(unaCajaDeAhorro).

- 210 -
Mostrar la necesidad de generar una instancia nueva de la clase Punto, la cual es el
resultado de las operaciones pedidas.

- 211 -
- 212 -
- 213 -
A la hora de programar existen diversas formas de conocimiento. A esta altura es
bueno recordar que, para que un objeto le envíe un mensaje a otro debe conocerlo,
o sea, nombrarlo. Para esto existen diversas formas de conocimiento:
- Variables de instancia.
- Variables temporales.
- Parámetros.
- Seudo-variables.

- 214 -
Son las que más hemos visto hasta el momento. Al definir la clase, se define la
estructura que tendrán sus instancias; esta estructura interna viene dada por un
conjunto de variables de instancia. Las variables de instancia acompañan al objeto
desde su creación hasta que muere.

- 215 -
Se utilizan para nombrar objetos que el objeto receptor necesita para cumplir un
requerimiento. Por ejemplo, para alquilar una película a un cliente, el video club
debe saber qué película y qué cliente. En este caso la película y el cliente son
parámetros que se envían junto con el mensaje alquilar para poder cumplir el
requerimiento.

- 216 -
Para transferir de una cuenta a otra, el banco necesita el monto, y las dos cuentas.

Se definen dentro de un método. Estas variables se utilizan para nombrar objetos


temporalmente. Al finalizar la activación del método dejan de existir.

- 217 -
En este caso, la variable cuenta se utiliza sólo como una referencia auxiliar. No es
necesaria más allá de la activación de este método.

- 218 -
Así como un objeto necesita conocer a otro objeto para enviarle un mensaje, es
necesario que tenga una forma de nombrarse a si mismo para poder enviarse
mensajes. Esto se hace por medio de la seudo-variable this. Se dice que this es una
seudo-variable ya que funciona similar a una variable de instancia, excepto por dos
motivos: no está definida en ninguna clase y no pude ser asignada (¿qué
significaría hacer algo del estilo this := otherObject?). Si bien la denominación this
es la más correcta para esta situación de “autoreferenciamiento”, en el sentido de
que representa al objeto en sí mismo y la palabra concuerda con este hecho,
existen otros lenguajes donde se ha dado una denominación distinta para esta
misma seudo-variable.

- 219 -
En este caso tenemos a un objeto caja de ahorro con un saldo inicial de 400 (de
Juan) y otra con 300 (de Ana). Inicialmente la extracción se hace sobre la caja de
Juan, previo chequeo de ciertas condiciones (por ejemplo que el saldo no quede en
descubierto), para lo cual se utiliza el método sePuedeExtraer(unMonto) con el fin
de realizar esta validación. El objeto caja de ahorro deberá poder mandarse a sí
mismo el mensaje sePuedeExtraer(unMonto) en el contexto de una extracción y en
el caso de resultar positivo el chequeo, procederá a realizar la extracción
actualizando su saldo, en caso contrario se obtendrá un error. Esto queda reflejado
en la especificación del método extraer(unMonto) perteneciente al objeto caja de
ahorro.
En este caso el objeto caja de ahorro hizo las veces de Emisor y Receptor para
un mismo mensaje, pero como al Receptor no le interesa saber quién es el Emisor,
es exactamente lo mismo si el mensaje ha sido enviado por otro objeto o por uno
mismo, no se tratan de manera diferente.
En el segundo caso, el objeto intenta hacer lo mismo con la caja de Ana, pero se
aprecia que la operación falla debido a que no tiene saldo suficiente.

- 220 -
- 221 -
En este ejercicio debemos dar una implementación para un objeto fecha, que
sirva para representar fechas del tipo 21/6/1999, el cual deberá entender los
siguientes mensajes con su correspondiente semántica:
getDia() “Devuelve el número de día de la fecha”
setDia(unNumero) “Cambia el número de día de la fecha por unNumero”
getMes() “Devuelve el número de mes de la fecha”
setMes(unNumero) “Cambia el número de mes de la fecha por
unNumero”
getAño() “Devuelve el número de año de la fecha”
setAño(unNumero) “Cambia el número de año de la fecha por unNumero”
igualA (otraFecha) “Devuelve true si la fecha es igual a otraFecha, false
en caso contrario”
mayorQue() “Devuelve true si la fecha es posterior a otraFecha, false en
caso contrario”
menorQue() “Devuelve true si la fecha es anterior a otraFecha, false en
caso contrario”
mayorOIgualQue() “Devuelve true si la fecha es posterior o igual a
otraFecha, false en caso contrario”
menorOIgualQue() “Devuelve true si la fecha es anterior o igual a
otraFecha, false en caso contrario”
seEncuentraEntre(unaFecha, otraFecha) “Devuelve true si la fecha se
encuentra entre unaFecha y otraFecha, false en caso contrario”

- 222 -
Este ejercicio consiste en modelar un objeto lapso de tiempo que permita
representar un intervalo o lapso de tiempo entre dos fechas. El protocolo a
implementar es el siguiente:
desde() “Devuelve la fecha de inicio del lapso de tiempo”
hasta () “Devuelve la fecha de fin del lapso de tiempo”
desdeHasta(unaFecha, otraFecha) “Cambia la fecha de inicio por
unaFecha y la de fin por otraFecha”
cantidadDeDias() “Devuelve la cantidad de días existentes entre la fecha
de inicio y la de fin”
incluye(unaFecha) “Devuelve true si la fecha unaFecha se encuentra
entre la fecha de inicio y la de fin”
La idea de este ejercicio es mostrar cómo funciona el doble encapsulamiento. Hacer
notar cómo podría cambiar la estructura interna de este objeto y cómo se
resolverían los mismos mensajes si en vez de tener dos fechas como variables
internas se tuviera una fecha desde que comienza el lapso y la cantidad de días en
el cual termina.

- 223 -
- 224 -
- 225 -
- 226 -
Cuando se hace referencia al “desacoplamiento interno” se quiere decir que se
puede seguir agregando funcionalidad sin depender de la estructura interna que
tenga el objeto, sino utilizar el protocolo que implementa para llevar a cabo la
nueva funcionalidad querida.

- 227 -
- 228 -
- 229 -
Módulo 3

UML Básico

- 230 -
Aquí se trata de definir qué es realmente UML.
Tomar y pensar en las tres palabras por separado ayudan a la comprensión del
objetivo de este lenguaje y al por qué de su utilidad:
- Modelado: nos llevará a presentar la visión y concepción de MODELOS.
- Unificado: nos llevará a mencionar qué se unificó en UML
- Lenguaje: nos llevará a explicar que para cerrar esta Unificación de Modelado
era importante consensuar un Lenguaje; especificando su sintaxis y
su semántica, indicando también reglas para conformar modelos gráficos válidos

- 231 -
Se presenta la idea de modelo porque lo que se va a notar, utilizando UML, es
justamente un modelo.
Se presentan características y ventajas de los modelos.

- 232 -
Booch, Rumbaug y Jacobson, son los creadores de UML, llamado inicialmente
Lenguaje de Modelado.
El primer intento de combinar y reemplazar los métodos existentes se dió cuando
Rumbaugh se unió a Booch en Rational Software Corporation en 1994.
Ellos empezaron combinando conceptos de los métodos OMT. La metodología OMT -
Object Modeling Technique - fue creada por James Rumbaugh mientras dirigía un
equipo de investigación en los laboratorios de la Cía. General Electric) y Booch,
obteniendo como resultado una primera propuesta en el año 1995. En ese
momento Jacobson también se unió a Rational y comenzó a trabajar con el dúo
Booch-Rumbaugh.
El Lenguaje Unificado de Modelado fue adoptado en forma unánime por los
miembros de OMG como estándar en noviembre de 1997. Allí OMG asumió la
responsabilidad de futuros desarrollos en el estándar de UML.
Nota:
OMG (Object Management Group) es una organización que promueve estándares
para la industria del software.
Puede ampliar información en: www.omg.org

- 233 -
Notar que hubo muchos otros aportes además de lo propuesto por Rumbaugh,
Booch y Jacobson.
Todas estas contribuciones sumaron riqueza al lenguaje y graficamente se
manifiestan en los diferentes tipos de diagramas que tiene UML.
Mencionar las ventajas buscadas y obtenidas con la unificación de diferentes
enfoques. Algunos de ellos son:
• Reunir los puntos fuertes de cada método

• Idear nuevas mejoras

• Proporcionar estabilidad al mercado

• Eliminar ambigüedad en los usuarios

- 234 -
Es importante mencionar que la mayoría de las personas somos naturalmente
visuales. Eso explica por qué entendemos mejor y más rápidamente un dibujo que
parte de un texto.
Es por ello que en el criterio de unificación de las metodologías de modelado se
concluyó en un lenguaje gráfico visual para la especificación y construcción de
modelos.
Aquí vale la pena detenerse en semántica y sintaxis.
La sintaxis de UML determina la forma de los elementos básicos sintácticos. Por
ejemplo, un rectángulo con una división y nombre es una clase.
La semántica de UML especifica el significado de cada elemento de modelado.
Siguiendo con el ejemplo de la anterior, la semántica de la clase es la de denotar a
un conjunto de objetos, instancias de la misma, que tienen la misma estructura y el
mismo comportamiento.
Las reglas de construcción o reglas de buena formación determinan la forma en que
los elementos pueden combinarse de manera de obtener modelos correctos. Por
ejemplo, que las clases deben tener obligatoriamente un nombre; o que los
nombres de los mensajes de una clase no pueden repetirse.

- 235 -
El Lenguaje Unificado de Modelado se ha convertido en una notación estándar para
el modelado de sistemas con gran cantidad de software.
UML sirve además para el modelado de negocios y sistemas no software [OMG01].
Nota:
Artefacto: es una pieza de información usada o producida por un proceso de
desarrollo de software.

- 236 -
En UML 2.0 se definen una serie de diagramas adicionales a los establecidos en
UML 1.x.
Aquí se presentan todos los diagramas UML para que el asistente tenga una idea
global de lo abarcado por el lenguaje.
El conjunto de diagramas se encuentra organizado en torno a dos categorías:
• Diagramas Estructurales (representados en naranja).

• Diagramas Dinámicos o de Comportamiento (representados en azul).

Diferentes diagramas se utilizan durante diferentes etapas dentro del desarrollo de


software. Se puede asociar como ejemplo alguna etapa con algún diagrama, por
ejemplo, la etapa de Análisis con los diagramas de Casos de Uso, de Actividad y de
Estado.
Los diagramas a presentar a continuación se corresponden con la etapa de Diseño
(hay más diagramas para esta etapa) son los de clases y los diagramas de
secuencia.

- 237 -
Diagrama de Secuencia

El diagrama de secuencias es uno de los diagramas dinámicos que presenta el


estándar UML.
Su objetivo es mostrar cómo un conjunto de objetos realiza una tarea determinada,
destacando el orden en que los mensajes son enviados a través del tiempo.
Se construye sobre dos “ejes cartesianos”: sobre el eje X se grafican los objetos
“vivos” o creados al momento de comenzar la interacción. Sobre el eje Y, se
grafican los mensajes que un objeto envía a otro objeto.

- 238 -
Los elementos de modelado para este diagrama son 2:
• Objetos

• Mensajes

Los frames representan una notación adicional que aporta UML para enriquecer los
diagramas, pero no son elementos de modelado.
El nombre del operador indica el sentido del frame. El rectángulo del mismo debe
abarcar a todos los objetos que participan de la operación.
Algunos operadores para manejar fragmentos de secuencias:
• alt : Indica que el fragmento de diagrama es una
alternativa (permite elegir entre dos o más
fragmentos).

• loop : Indica que el fragmento de diagrama se ejecuta


repetidas veces.

• sd: fragmento de diagrama con nombre.

• ref: referencia a un diagrama o fragmento de


diagrama.

- 239 -
Mencionar que se nota más comúnmente a los objetos como anónimos o sin
nombre, indicando solamente el nombre de la clase de la cual es instancia.
Las diferentes formas en que se puede describir el nombre de un objeto son:
Nombre explícito: nombre del objeto junto al nombre de la clase.
Objetos anónimos: sólo se escribe el nombre de la clase. Cada aparición de un
objeto anónimo se considera distinta de las otras apariciones.
Objetos huérfanos: el nombre del objeto, sin la clase.
Hacer notar que notar una instancia sin clase a la cual pertenezca es válido
sintácticamente en UML pero no es una buena práctica en Objetos (al menos, para
quien está aprendiendo recientemente el paradigma)

- 240 -
La notación para el mensaje siempre es una flecha, pero el tipo de flecha y la punta
varía en función del tipo de mensaje.
Tipos de mensajes:
Mensaje síncrono (o llamada): Si un objeto envía un mensaje sincrónico, esperará
la respuesta a tal mensaje antes de continuar con su trabajo. El originario del
mensaje pierde el control hasta recibir la respuesta.
Mensaje asincrónico: si un objeto envía un mensaje asincrónico, no esperará una
respuesta antes de continuar, continúa activo pudiendo enviar mensajes.
Mensaje directo: el originario no espera respuesta, pero se pasa el control al que
recibe el mensaje, el fin del foco de control devuelve el control)
Mensaje respuesta: no es un mensaje nuevo, sino la respuesta a un mensaje
previo.

- 241 -
Notar que los objetos retornados en este mensaje puede participar también de la
secuencia de mensajes.
Si en un mensaje se devuelve el objeto unaCuenta y luego se quiere actualizar el
saldo de esa cuenta, bastará con agregar el objetos unaCuenta como uno más de
los objetos del diagrama y se le podrán enviar los mensajes necesarios para
interactuar con él.

- 242 -
- 243 -
Cada uno de los objetos participante en un Diagrama de Secuencia se representa
en una columna diferente.
Para cada objeto se dibuja una línea vertical discontinua, llamada línea de vida, que
muestra la existencia de un objeto a lo largo de un cierto período de tiempo.
Caja de Activación: es un rectángulo delgado y estrecho que representa el período
de tiempo durante el cual un objeto ejecuta un método. La parte superior del
rectángulo se alinea con el envío del mensaje; la inferior se alinea o se extiende
más allá de su terminación (y puede marcarse con un mensaje de retorno).

- 244 -
- 245 -
Notar que si bien es sintácticamente válido en UML que cualquier objeto le envíe un
mensaje a cualquier otro, según el paradigma OO deberían estar bien asignadas las
responsabilidades.

- 246 -
- 247 -
- 248 -
- 249 -
Puede resolverse también con el envío de un solo mensaje desde el banco, por
ejemplo, con extraerMantenimiento().

- 250 -
- 251 -
La sintaxis completa de mensaje se utiliza según sea necesario.
Número de secuencia: no suele ser necesario ya que el orden descendente de los
mensajes indica cuál se envía primero y cuál se envía después.
Condición: indica que el mensaje se envía si esta se cumple.
Iteración: indica el envío de un mismo mensaje un cierto número de veces. Puede
indicarse con cardinalidades tales como:
 Número Exacto: 1, 5, 1000

 Cero o Uno: 0..1

 Cero o muchos: *

 Uno o Más: 1..*

 Rango: 5..10

Valor de retorno: es la asignación a una variable que luego puede usarse en la


interacción. Esta variable puede contener un dato simple o un objeto.

- 252 -
El frame es una incorporación de UML 2.
No es un elemento de modelado, sino más bien un soporte sintáctico.
El rectángulo del mismo debe abarcar a todos los objetos que participan de la
operación.
Algunos operadores para manejar fragmentos de secuencias:
• alt : Indica que el fragmento de diagrama es una
alternativa (permite elegir entre dos o más
fragmentos).

• loop : Indica que el fragmento de diagrama se ejecuta


repetidas veces.

• sd: fragmento de diagrama con nombre.

• ref: referencia a un diagrama o fragmento de


diagrama.

Son útiles para indicar la ejecución de un bloque de mensajes

- 253 -
Las guardas sirven para elegir entre un conjunto de opciones dependiendo de una
condición booleana. Ahora, en vez de realizar diferentes Diagramas para los cursos
alternativos, los mismos se manejan dentro de un mismo Diagrama de Secuencia.

- 254 -
El fragmento bucle sirve para indicar una iteración. Es decir, para mostrar que algo
se repite dentro de un mismo Diagrama, la cantidad de veces indicada en el bucle.

- 255 -
- 256 -
- 257 -
- 258 -
- 259 -
Diagramas de Interacción

Diagramas de Comunicación

Un Diagrama de Comunicación muestra los mensajes que se envían los objetos


entre sí. A diferencia del diagrama de Secuencia, hay que indicar cuál es el orden
en que se envían lso mensajes porque ya no hay orden cronológico. La notación y
sintaxis de objetos y mensajes es la misma que para los diagramas de Secuencia.
Se puede convertir un diagrama en otro, ya que semánticamente son equivalentes.
Se usa uno u otro (secuencia o comunicación) según lo que se quiera mostrar en un
diagrama.

- 260 -
Diagrama de Clases

El objetivo de este diagrama es el de representar los objetos del sistema,


especificando la estructura de las clases, sus relaciones y su comportamiento.
Si bien el elemento de modelado que será presentado es la CLASE, también pueden
aparecer en el diagrama de Clases, las INTERFACES.
Aparte de esos dos (y la nota), no hay otro elemento de modelado que pueda
participar de este diagrama.

- 261 -
Una clase es una plantilla que define una colección de conceptos con las mismas
características.

Estructura de una clase:


Cada uno de los compartimientos es opcional, excepto el del nombre.
• Nombre de la clase: en la práctica, los nombres de clase son nombres cortos
o expresiones nominales extraídos del vocabulario del sistema que se está
modelando. El nombre de la clase se escribe con mayúscula, centrado y en
negrita.

• Atributos: un atributo representa alguna propiedad del elemento que se está


modelando

• Operaciones: son los mensajes que los objetos de la clase entienden

• Responsabilidades: es un contrato o una obligación de una clase. Se utiliza


cuando aún no se ha definido completamente el comportamiento de la clase,
en una etapa previa al diseño.

- 262 -
Diferenciar lo sintácticamente correcto de lo semánticamente correcto.
En UML, lo indicado es que el nombre comience con letra mayúscula. Por ej: X o
Clase1.
Según el paradigma OO, el nombre de una clase debe ser lo más representativa
posible del concepto que modela. Por ejemplo: CuentaBancaria,
TarjetaDeClienteVIP
Se muestran dos formas de escribir el nombre de una clase: escribiendo
directamente su nombre y escribiendo su nombre precedido de su ubicación (teatro
es un paquete).

- 263 -
La única condición es que el nombre del atributo debe comenzar con minúsculas.
Los corchetes significan que el elemento es opcional, por lo que sólo el nombre es
obligatorio.
La barra “/” indica que el atributo es derivado. Por ejemplo, la edad de una persona
podría derivarse de su fecha de nacimiento.
El atributo subrayado indica que el atributo es “de clase”. Esto significa que este
atributo es compartido por todas las instancias de la clase (también se lo conoce
como “variable de clase”). Por convención, se indica subrayado.
Descripción de las propiedades:
• changeable: no hay restricciones para modificar el valor del atributo.

• addOnly: para los atributos con multiplicidad mayor de uno (colecciones),


se pueden añadir valores adicionales, pero una vez creado, un valor no
puede ser eliminado o modificado.

• frozen: el valor del atributo no se puede modificar tras inicializar el objeto


(una constante)

A menos que se especifique lo contrario, los atributos siempre son changeable.

- 264 -
UML ofrece una serie de elementos para especificar detalles para los atributos y las
operaciones. Desde fuera de un objeto sólo se puede manipular los datos por medio
de llamadas a operaciones –métodos- del objeto.
Tipos de visibilidad:
Privado: (-) significa que sólo se puede usar en los objetos donde está definido el
atributo u operación.
Protegido: (#) significa que sólo los objetos de las subclases de la clase a la que
pertenece el atributo u operación pueden utilizarlo.
Paquete: ( ) significa que sólo los objetos del paquete en donde está definida la
clase a la que pertenece el atributo u operación pueden utilizarlo.
Público: (+) significa que los objetos pertenecientes a cualquier clase puede utilizar
el atributo u operación.
No existe un valor por defecto para la visibilidad. Si ésta no se indica, está
indefinida.

- 265 -
El nombre del mensaje junto a sus parámetros (incluido el tipo de retorno, si lo
hay) se conoce como signatura de la operación.

- 266 -
Al igual que con los atributos, pueden especificarse mensajes a nivel de clase. Éstas
se indican con el subrayado.
Descripción de las propiedades de una operación:
isQuery: indica que la operación no cambia el valor de ningún atributo. La
operación es una función pura sin efectos laterales.
Hay otras tres propiedades relacionadas con la concurrencia, que tienen que ver
con la manera de que un método que implementa una operación responde a los
múltiples hilos de actividad:
• sequential: (sólo puede llegar una llamada por vez). Los invocadores deben
coordinarse para que en el objeto sólo haya un único flujo al mismo tiempo.

• guarded: (pueden llegar varias llamadas simultáneamente, pero sólo puede


atenderse una por vez).

• concurrent: (pueden entrar múltiples llamadas al método provenientes de


otros tantos hilos y todas ellas se atienden concurrentemente).

- 267 -
Indicar que no es necesario mostrar todos los atributos y mensajes de la clase.
Para organizar mejor las listas largas de atributos y operaciones, se pueden utilizar
estereotipos para anteponer a cada grupo una categoría descriptiva, sin que estas
estén predeterminadas.

- 268 -
Al modelar clases, un buen comienzo consiste en especificar las responsabilidades
de los elementos del vocabulario. Una clase puede tener cualquier número de
responsabilidades, aunque, en la práctica, cada clase bien estructurada tiene al
menos una responsabilidad y a lo sumo unas pocas. Al ir refinando los modelos, se
traducirán esas responsabilidades en el conjunto de atributos y mensajes que mejor
satisfagan las responsabilidades de la clase.

- 269 -
Entre las relaciones que pueden aparecer en un diagrama de Clases, no se
menciona aquí a la Realización.
Una realización es una relaciona una interfaz con la clase que la implementa.

- 270 -
Dada una asociación entre dos clases, se puede navegar desde un objeto de una
clase hasta un objeto de la otra clase, y viceversa.
Es legal que ambos extremos de una asociación estén conectados a la misma clase.
Esto significa que, dado un objeto de la clase, se puede conectar con otros objetos
de la misma clase.
La navegabilidad en las asociaciones es bidireccional.

- 271 -
Rol: cuando una clase participa en una asociación, tiene un rol específico que juega
en la asociación.
Un rol es simplemente la cara que la clase de un extremo de la asociación presenta
a la clase del otro extremo. Se puede nombrar explícitamente el rol que juega una
clase en una asociación.
• Nota: la misma clase puede jugar el mismo o diferentes roles en otras
asociaciones.

Navegabilidad: indica qué objeto conoce a quien. En el caso presentado, un


usuario conoce una clave, pero una clave no conoce a un usuario.
Si se quiere bidireccionalidad puede indicarse indistintamente con una flecha en
cada punta de la asociación o sólo con la asociación, sin flechas en los finales.

- 272 -
Multiplicidad: el “cuántos” se denomina multiplicidad del rol de la asociación, y se
escribe como una expresión que se evalúa a un rango de valores o a un valor
explícito.
Cuando se indica una multiplicidad en un extremo de una asociación, se está
especificando que cada objeto de la clase conoce a tantos objetos como los
indicados en la multiplicidad en este extremo opuesto.
Notar que * indica 0..*

- 273 -
Una asociación entre dos clases representa una relación estructural entre iguales,
es decir, ambas clases están conceptualmente en el mismo nivel, sin ser ninguna
más importante que la otra.
Agregación: sirve para modelar una relación “todo/parte”, en la cual una clase
representa el “todo”, que se compone de otros elementos (las “partes”). Este tipo
de relación se denomina agregación, la cual representa una relación del tipo “tiene-
un”, o sea, un objeto del todo tiene objetos de la parte.
El rombo vacío distingue el “todo” de la “parte”. Esto significa que la agregación
simple no cambia el significado de la navegación a través de la asociación entre el
todo y sus partes, ni liga la existencia del todo y sus partes.

- 274 -
Las partes con multiplicidad no fija, se pueden crear después del elemento
compuesto. Pero una vez creadas, viven y mueren con él.
Notar que una parte siempre se asocia a un todo. NO PUDE PASAR que una parte
(una instancia de Parte) se asocie a más de un todo (una instancia de Todo).
Las palabras que mejor definen a este tipo de asociación son:
-exclusividad
-dependencia

- 275 -
Las composiciones a Punto indican que cualquier instancia de Punto puede estar en
un Polígono o en un Círculo, pero no en ambos. Sin embargo, una instancia de
Estilo puede ser compartida por muchos Polígonos y Círculos. Es más, esto implica
que el borrado de un Polígono provocaría el borrado de sus Puntos asociados, pero
no del Estilo asociado.
Esta restricción (un Punto puede solamente aparecer en un solo Polígono o Círculo
a la vez) no se puede expresar mediante las multiplicidades, únicamente.
Sugerencia: comparar las diferencias entre composición y agregación en el ejemplo
1. Ésta puede estar claramente determinada por el contexto o dominio del
problema a representar

- 276 -
Contexto:
Nombre: Una asociación puede tener un nombre, que se utiliza para describir la
naturaleza de la relación. Para que no haya ambigüedad en su significado, se puede
dar una dirección al nombre por medio de una flecha que apunte en la dirección en
la que se pretende que se lea el nombre.
• Nota: aunque una asociación puede tener un nombre, normalmente no se
necesita incluirlo si se proporcionan explícitamente nombres de rol para la
asociación, excepto si se tiene un modelo con muchas asociaciones y es
necesario referirse a una o distinguir unas de otras. Esto es esencialmente
cierto cuando se tiene más de una asociación entre las mismas clases.

- 277 -
• Muchas veces se omite escribir la multiplicidad en un extremo de la
asociación. En dicho caso se asume que la misma corresponde a “1”.

El modelador puede escribir explícitamente el nombre que juega una clase dentro
de una asociación. Pero si no lo hace, igualmente cada una de las clases juega un
rol en la asociación. Ese rol es el nombre de la clase en letras minúsculas.

- 278 -
La generalización representa a la relación “es-un”: un elemento concreto es-un
elemento más general. La generalización especifica que los objetos hijos se pueden
emplear en cualquier lugar que pueda aparecer el padre, pero no a la inversa. Una
clase hija hereda las propiedades de sus clases padres (atributos, asociaciones y
operaciones). A menudo, no siempre, el hijo añade atributos y operaciones a los
que hereda de sus padres. Una operación de un hijo con la misma signatura que
una operación del padre redefine la operación del padre.
• Nota: Una generalización puede tener un nombre, aunque es raro que se
necesiten los nombres, a menos que se tenga un modelo con muchas
generalizaciones y haya que referirse a ellas o distinguirlas.

En UML, una clase puede tener ninguno, uno o más padres. Una clase sin padres y
uno o más hijos se denomina clase raíz o clase base. Una clase sin hijos se llama
clase hoja. Una clase con un único padre se dice que utiliza herencia simple; una
clase con más de un padre se dice que utiliza herencia múltiple.

- 279 -
Una generalización simple, sin adornos, es suficiente para la mayoría de las
relaciones de herencia que aparecen en el modelado. Pero si se quieren especificar
ciertos matices, UML aporta cuatro restricciones que pueden aplicarse a las
generalizaciones.
Descripción de las restricciones:
• complete: especifica que todos los hijos en la generalización se han
especificado en el modelo (aunque puede que algunos se omitan en el
diagrama) y no se permiten hijos adicionales.

• incomplete: especifica que no se han especificado todos los hijos en la


generalización (incluso aunque se omitan algunos) y que se permiten hijos
adicionales. Es la opción por defecto.

• disjoint: especifica que los objetos del padre no pueden tener más de uno de
los hijos como tipo.

• overlapping: especifica que los objetos del padre pueden tener más de uno
de los hijos como tipo.

Nota: disjoint y overlapping se aplican en el contexto de herencia múltiple.

- 280 -
Las notas permiten agregar comentarios que se pueden utilizar para describir,
clarificar y hacer observaciones sobre cualquier elemento de un modelo.
Se marca por medio de línea punteada al elemento al cual están ligados y por lo
tanto, comentan.
El comentario puede hacerse en lenguaje coloquial o en un lenguaje formal como lo
es OCL.
Gráficamente, una nota se representa como un rectángulo con una esquina
doblada, junto con un comentario (no puede estar sin texto).

- 281 -
- 282 -
Descripción:
Dada una instancia de Clase_A, indicar si la misma conoce instancias de Clase_C

- 283 -
Nota:
UML permite notar las relaciones como atributos o como relaciones de
conocimiento.
En la práctica se utiliza notar al estado de los objetos como atributos y al
conocimiento con otros objetos, como relaciones de asociación o al menos tomar
una misma postura de notación.

- 284 -
Inciso c:
La cardinalidad de la composición debe ser 1.

Inciso d: es como el ejemplo del punto, el círculo y el polígono.

- 285 -
Nota: las clases hijas pueden ocupar el lugar del padre.

- 286 -
- 287 -
Contexto:

- 288 -
- 289 -
Descripción:
Se presenta un ejemplo general de un Diagrama de Clases, modelando parte del
dominio de representaciones artísticas y reserva de entradas.
Notar que la composición indica la carencia de sentido de tener representaciones
sin entradas para el ingreso del público.

- 290 -
- 291 -
Módulo 4

Sub clasificación y Herencia

- 292 -
Subclasificación
Las clases pueden agruparse utilizando la relación de herencia, formándose lo que
se conoce como jerarquía de clases. Intuitivamente, la relación de herencia dicta
una especialización entre una subclase y su superclase; la subclase representa un
concepto más refinado que su superclase.
Veremos más adelante que es importante respetar la relación es-un entre una
clase y su superclase. Bajo este principio, toda instancia de una clase también es-
una instancia de su superclase, en el sentido en que responde al mismo protocolo.

- 293 -
Ejemplo de una subclasificación en el mundo animal.

- 294 -
Ejemplo de la estructura de la subclasificación.

- 295 -
Ejemplo de una jerarquía de clases
Existen dos tipos de cuenta bancaria, las cajas de ahorro y las cuentas corrientes,
las cuales tienen un comportamiento similar: ambas llevan cuenta de su saldo,
permiten realizar depósitos y extracciones.

- 296 -
Restricciones en el diseño
Cada una de las cuentas tiene distintas restricciones en cuanto a las extracciones.
Las cuentas corrientes permiten que el cliente extraiga en descubierto, con un tope
pactado para cada uno, mientras que las cajas de ahorro poseen una cantidad
máxima de extracciones mensuales (que es igual para todos los clientes) y además
no permiten extraer en descubierto.
¿Cómo se puede hacer, entonces, para reutilizar el comportamiento común a los
dos tipos de cuenta? Podemos hacer uso de la subclasificación y herencia para
resolver este problema.

- 297 -
Solución propuesta del diseño
Tanto las cajas de ahorro como las cuentas corrientes son cuentas bancarias. En la
clase CuentaBancaria está el comportamiento común a todas las cuentas
(depositar(), saldo(), titular(), titular(unaPersona)), mientras que las subclases
CajaDeAhorro y CuentaCorriente definen el método extraer(unMonto). Además,
cada una agrega la estructura interna necesaria para resolver el nuevo
comportamiento.

- 298 -
Relación es-un
Cuando creamos una jerarquía de clases, se debe respetar la relación es-un entre
una clase y su superclase. Esto quiere decir que, conceptualmente, toda subclase
es-un de su superclase. Por ejemplo, una caja de ahorro es-una cuenta bancaria.
En forma similar, un empleado de planta permanente es-un empleado. Como
veremos en breve, este concepto es fundamental a la hora de diseñar jerarquías de
clase.
Si bien la herencia es un poderoso mecanismo de reutilización, no debe ser
utilizado indiscriminadamente. Lo que se busca es crear jerarquías en las que se
cumpla la relación es-un. Para obtener este tipo de jerarquías se pueden aplicar dos
metodologías:

Top-down
En la cual se plantea primero el concepto más abstracto en una superclase y luego,
por medio de un proceso de refinación, se crean las subclases.
Bottom-up
En la cual se modelan los conceptos en forma separada y luego, al encontrar
similitudes en el comportamiento de los objetos, se realiza un proceso de
generalización, mediante el cual se crean abstracciones que engloban las clases
previamente modeladas.

- 299 -
La solución esperada es la siguiente:
Vehiculo:
Terrestre:
Moto.
Omnibus.
Acuatico:
Barco.
Buque.
Deporte:
Rugby.
Futbol.
Tenis.
InstrumentoMusical:
Cuerdas:
Guitarra.
Violin.
Vientos:
Tuba.
Trompeta.

- 300 -
No es correcta. Se necesita una relación de composición y no de herencia, dado que
un auto tiene ruedas y tiene un motor, y un motor no es-un auto y una rueda no
es-un auto.

- 301 -
No es correcta. Un Hijo no es-un Padre, una Hija no es-un Padre y un Padre no
es-un Abuelo.

- 302 -
Herencia
Sin importar la metodología que se utilice, el resultado es una jerarquía de clases
en la cual la superclase define un concepto general que determina la esencia de
todas sus subclases. En términos de comportamiento, todos los métodos que
tengan que ver con este concepto general son definidos en la superclase, y cada
subclase puede extenderlos agregando comportamiento específico, o bien agregar
métodos nuevos.
A pesar que el mecanismo de herencia nos permite reutilizar tanto estructura como
comportamiento, existen algunas diferencias entre éstos.

- 303 -
Herencia de comportamiento
- Una subclase hereda todos los métodos definidos en su superclase.
- Una subclase puede redefinir un método heredado, permitiendo alterar la forma
en la que se comportan sus instancias ante el envío de ese mensaje (polimorfismo).
- Una subclase no puede anular un método que esté definido en su superclase.
Notar que eso es el equivalente a redefinir un método para que disparare un error,
lo cual, a pesar de ser posible en la práctica, es conceptualmente incorrecto, ya que
nos pondría nuevamente en problema que una subclase no es-un de su superclase.
Herencia de estructura
- Una subclase hereda todas las variables de instancia definidas en su superclase.
- Una clase no puede redefinir un atributo o colaborador. Esto llevaría a tener que
utilizar dos variables de instancia con el mismo nombre, lo cual sería ambiguo.
- Una subclase no puede anular la herencia de una variable de instancia.
A la hora de subclasificar es importante tener en cuenta que lo importante es
basarnos en el comportamiento y no en la estructura. Si hacemos el foco en los
mensajes a los que debe responder cada clase estaremos seguros de mantener el
principio es-un en nuestras jerarquías.

- 304 -
Ejercicio – Cuenta Bancaria
Debemos dar ahora una implementación para el mensaje extraer: unMonto en cada
una de las subclases de CuentaBancaria. Tenemos que tener en cuenta las
diferencias en el comportamiento entre estas dos clases de cuenta. Por un lado, las
cuentas corrientes permiten que el cliente gire en descubierto (con un tope pactado
con cada cliente), mientras que las cajas de ahorro poseen una cantidad máxima de
extracciones mensuales (para todos los clientes) y no se permite girar en
descubierto.

- 305 -
Una implementación posible para los métodos extraer de CuentaCorriente y
CajaDeAhorro:
CajaDeAhorro:
public void extraer(float unMonto){
if((this.extraccionesRealizadas<this.extraccionesPosibles)&&(unMonto <
this.saldo())){
saldo=saldo-unMonto;
extraccionesRealizadas=extraccionesRealizadas+1;
}
else{
“No puede realizarse la extracción.”
}
}
CuentaCorriente
public void extraer(float unMonto){
if(unMonto<this.saldo()+topeDeExtraccion){
saldo=saldo-unMonto;
}
else{
“No puede realizarse la extracción del monto deseado.”
}
}

- 306 -
Method lookup
Al enviarse un mensaje, el lenguaje debe realizar dos tareas:
1. Determinar cual es la clase del objeto.
2. Buscar el método para responder al envío del mensaje. Este proceso se lleva a
cabo buscando en la clase del objeto receptor del mensaje. En el caso que dicha
clase no tenga definido un método asociado al mensaje enviado, se repite el
proceso comenzando ahora por su superclase. En el caso que se llegue a la clase
raíz (Object) y no se encuentre un método para responder al envío de mensaje, se
genera una excepción.
Al proceso que se lleva a cabo en el paso 2 se lo denomina method lookup y
consiste básicamente en buscar en la cadena de superclases, partiendo de la clase
del objeto receptor, un método para responder al envío de un mensaje.

- 307 -
- 308 -
Mensajes abstractos
En muchos casos, al crear una jerarquía de clases, nos encontramos en una
situación en la que cada subclase debe implementar por completo un determinado
método.
Los mensajes abstractos se utilizan para definir el protocolo de una clase cuando no
se tiene la información suficiente para implementar un método asociado.

- 309 -
- 310 -
Clase abstracta
Una clase abstracta es aquella que contiene al menos un mensaje abstracto. En
teoría las clases abstractas no pueden tener instancias, ya que en el caso de
enviarle un mensaje definido como abstracto, no habría un método con el cual
responder al envío. Al igual que con los mensajes abstractos, la noción de clases
abstractas (y por ende, la posibilidad de crear instancias de clases abstractas)
depende mucho del lenguaje de programación utilizado.
Como mencionamos en la sección anterior, las clases abstractas se utilizan para
especificar el protocolo que deben cumplir todas sus subclases. Al subclasificar de
una clase abstracta, nos encontramos con dos posibilidades:
- Implementar los mensajes abstractos en la subclase. En este caso la subclase es
una clase concreta y por ende puede ser instanciada.
- No implementar los mensajes abstractos en la subclase. En este caso la subclase
también será abstracta.

- 311 -
- 312 -
- 313 -
Módulo 1

Programación orientada a
objetos (OOP)

- 314 -
Creación de clases en VB.NET
Un programador necesitaba desarrollar los procesos de un empleado dentro de una
aplicación de gestión empresarial. Recordar que se planteaba el problema de que
ante el crecimiento del programa, el mantenimiento del código, al enfocarse de
modo procedural, podía volverse una tarea realmente difícil.
Se replantea este diseño, encauzándolo bajo una perspectiva orientada a objeto,
que permita un uso más sencillo del código y mantenimiento también más fácil.
Para lo cual desarrollaremos una clase que contenga todas las operaciones a
realizar por el empleado; en definitiva, crearemos la clase Empleado, cuyo proceso
describiremos a continuación.
En primer lugar se inicializar VS.NET creando un proyecto de tipo consola. Luego
seleccionar el menú Proyecto + Agregar clase, que mostrará la ventana para
agregar nuevos elementos al proyecto. El nombre que se asignó por defecto por el
IDE para la clase será Class1, cambiar este nombre por el de Empleado y pulsar
Abrir. Ver figura 1.3

Figura 1.3 Añadir una clase a un producto

De esta manera se creará un nuevo fichero de código (Empleado.VB), donde se


muestra el editor de código con su contenido. Se observa que la diferencia de una
clase se realiza usando las palabras clave Class...End Class; entre estas palabras
estará escrito el código de la clase. Ver código fuente 1.2
Public Class Empleado
End Class
Código fuente 1.2

- 315 -
Organización de clases en uno o varios ficheros de código
Como se explicó antes en los temas sobre el lenguaje, una clase es uno de los tipos
de contenedor lógico disponible que está dentro del entorno de .NET Framework, y
su organización puede realizarse al igual que los módulos (Module) de código
estándar del entorno, es decir, cada vez que se añade una clase al proyecto usando
el IDE, por defecto se crea un fichero de código por clase.
Pero, también se puede incluir varias clases dentro del mismo fichero de código, o
mezclar clases con módulos y otro tipo de contenedores lógicos, cambiando si fuese
necesario el nombre del dichero, como ya se explicó en los apartados sobre el
leguaje. En el código fuente 1.3 se verá un ejemplo donde se muestra dos clases
creadas dentro del mismo fichero.
' Fichero MisClases.VB
' ==================
Public Class Empleado
' código de la clase
' .....
' .....
End Class

Public Class Factura


' código de la factura
' .....
' .....
End Class
Código fuente 1.3

Código de clase y código cliente


Antes de comenzar a realizar pruebas con las clases que se vaya escribiendo, se
debe explicar dos conceptos referentes a la escritura de código orientado a objetos,
puesto que en función del lugar desde el que sea manipulado, se debe distinguir
entre código de clase y código cliente.
Código de clase. Se trata del código que se escribe para crear la clase, y que se
encuentra entre las palabras clave Class.... End Class.
Código cliente. Éste es el código que hace uso de la clase mediante la acción de
crear o instanciar objetos a partir de la misma. Aquí se englobaría todo el código
que se encuentra fuera de la clase.

Reglas de ámbito generales para las clases


Las normas de ámbito para variables y procedimientos escritos dentro de una clase
son las mismas que las que ya se explicaron en el apartado de la programación a
través de módulos, pero se debe tener en cuenta que en este caso, el ámbito a
nivel de módulo debe ser equiparado con el ámbito a nivel de clase.
Dando un ejemplo, cuando se declara una variable dentro de las palabras clave
Class...End Class, pero fuera de todo procedimiento de la clase, dicha variable
tendrá un ámbito a nivel de clase, ésta es accesible por los procedimientos de la
clase o por todo el código, según se la haya definido privada o pública.

- 316 -
Hay reglas de ámbito específicas para los miembros de una clase que serán
comentadas en un apartado posterior.

Instanciación de objetos
Hasta ahora, la clase Empleado, cuenta con el código mínimo para poder ser usada,
para lo que se debe instanciar objetos a partir de la misma.
Como se explicó en un apartado anterior, el proceso de instanciación consiste en
crear un objeto a partir de las especificaciones de la clase. El modo más común de
trabajar con una instancia de una clase, o lo que es igual, con un objeto, pasa por
asignar este objeto a una variable.
Se instanciará un objeto en el código usando la sintaxis de declaración de variables
junto a la palabra clave New, empleando como tipo de dato el nombre de la clase.
Todo este código se lo puede situar en un módulo dentro del proyecto, ya sea en un
fichero de código aparte o en el mismo fichero donde se está escribiendo la clase.
El código fuente 1.4 muestra las formas disponibles de instanciar un objeto y
asignarlo a una variable.
Module General
Sub Main()
' declarar primero la variable
' y luego instanciar el objeto
Dim loEmpleado1 As Empleado
loEmpleado1 = New Empleado()

' declaración e instanciación simultánea


Dim loEmpleado2 As New Empleado()

' declaración y posterior instanciación en


' la misma línea de código
Dim loEmpleado3 As Empleado = New Empleado()
End Sub
End Module
Código fuente 1.4

Si es cierto que ya es posible crear objetos a partir de la clase, también es cierto


que no es posible hacer grandes cosas con ellos, puesto que la clase se encuentra
vacía de código. Se debe añadir propiedades y métodos para conseguir que los
objetos actúen en la aplicación.

Miembros de la clase.
Los elementos de una clase que contienen sus datos y definen su comportamiento,
es decir, las propiedades y métodos, reciben además el nombre de miembros de la
clase, término que también utilizaremos a partir de ahora.

Definir la información de la clase.


Existen dos formas de almacenar los datos o información en una clase: a través de
campos de clase y de propiedades.

- 317 -
Desde la perspectiva del programador que hace uso de una clase para crear
objetos, la diferencia entre un campo o una propiedad resulta imperceptible; sin
embargo, desde el punto de vista del programador de la clase existen claras
diferencias, concernientes fundamentalmente, a preservar la encapsulación del
código de la clase.
El uso de campos o propiedades para una clase es una cuestión de diseño, no
pudiendo afirmar categóricamente que un tipo de almacenamiento de datos sea
mejor que otro.

Creación de campos para la clase


Un campo de una clase no es otra cosa que una variable, generalmente con ámbito
público, accesible desde el exterior de la clase. El Código fuente 1.5 muestra la
creación de un campo para la clase Empleado.
Public Class Empleado

' se declara un campo en la clase


' para guardar el identificador
' del empleado
Public piIdentificador As Integer
End Class
Código fuente 1.5

Para manipular un campo desde el código cliente, se debe instanciar un objeto, a


continuación de la variable que lo contiene situar un punto (.), Y finalmente el
nombre del campo a manipular. Este modo de operación es común para todos los
miembros de clases, tanto creadas por el programador, como pertenecientes a la
propia plataforma.NET Framework. Ver Código fuente 1.6.
Module General
Sub Main()
Dim loEmpleado As Empleado

' instanciar el objeto


loEmpleado = New Empleado()

' asignar un valor al campo del objeto


loEmpleado.piIdentificador = 75

' mostrar el valor de un campo del objeto


Console.WriteLine("El valor del campo es: {0}",
loEmpleado.piIdentificador)
Console.ReadLine()
End Sub
End Module

Código fuente 1.6

- 318 -
Como habrá observado el lector, al escribir el nombre del objeto y el punto,
aparece una lista con los miembros de la clase accesibles desde el código cliente.
De momento solo se dispone del campo y el método GetType( ), que devuelve un
objeto de la clase Type, conteniendo información sobre el tipo del objeto. Esta lista
ira aumentando progresivamente según añadimos mas propiedades y métodos a la
clase, constituyendo una inestimable ayuda para el programador, que le evita el
tener que recordar los nombres de todos los elementos de la clase, o consultar
continuamente su documentación.

Creación de propiedades para la clase


Una propiedad en la clase se define, por norma general, mediante dos elementos:
una variable de propiedad y un procedimiento de propiedad.
La variable de propiedad, tal y como su nombre lo indica, es una variable con
ámbito privado a nivel de la clase, que se encarga de guardar el valor de la
propiedad. Por su parte el procedimiento de propiedad o Property, es el encargado
de actuar de puente entre el código cliente y la variable de propiedad, realizando
las operaciones de acceso y asignación de valores a dicha variable.
Por lo tanto, para crear la propiedad en nuestra clase, se declarará en primer lugar
una variable Private, y en segundo lugar un procedimiento de tipo Property, que
consta de dos bloques: Get, para devolver el valor de la variable de propiedad; y
Set, para asignárselo. La sintaxis a emplear se muestra en el Código fuente 1.7.
Public Class Empleado
' declarar una variable de propiedad
' para la propiedad Nombre
Private msNombre As String

' declarar el procedimiento Property


' para la propiedad Nombre
Public Property Nombre() As String
' bloque Get para devolver
' el valor de la propiedad
Get
Return msNombre
End Get

' bloque Set para asignar


' valor a la propiedad
Set(ByVal Value As String)
msNombre = Value
End Set
End Property
End Class
Código fuente 1.7

Cuando se declare un procedimiento Property, se debe, al igual que en una función,


tipificarlo, puesto que una de sus labores consiste en devolución de un valor.
Para devolver el valor, en el bloque Get se puede usar la palabra clave Return,
seguida del valor de retorno, o también la sintaxis clásica de asignar el valor al
nombre de la función. Nuestra recomendación es el uso de Retuns por las ventajas
explicadas en los apartados sobre el lenguaje.

- 319 -
En cuanto a la asignación de valor, el bloque Set usa un parámetro con el nombre
Value, que contiene el valor para asignar a la propiedad.
Observe el lector que al declarar un procedimiento de este tipo, el IDE de VS.NET
crea automáticamente lo correspondientes bloques Get y Set, ahorrando ese
trabajo al programador.
A la hora de manipular una propiedad desde el código cliente, y como ya habíamos
apuntados anteriormente, la diferencia no será notoria, como muestra el Código
fuente 1.8 la única forma de hacer más patente el uso del procedimiento Property,
consiste en ejecutar el programa utilizando el depurador; de esta manera se
comprueba como el flujo de la ejecución salta a los bloques Get y Set al manejar la
variable del objeto.

Module General
Sub Main()
Dim loEmpleado As New Empleado()

' asignar valor a una propiedad


loEmpleado.Nombre = "Guillermo"

' mostrar el valor de una propiedad del objeto


Console.WriteLine("El valor de la propiedad Nombre es: {0}", _
loEmpleado.Nombre)
Console.ReadLine()
End Sub
End Module
Código fuente 1.8

Dado que los procedimientos Property no son otra cosa que rutinas de código,
también se les denomina métodos de acceso y asignación en el argot OOP.

Ventajas en el uso de propiedades


Comprobada la facilidad de los campos de clase, el lector se estará preguntando en
estos momentos por que debe utilizar propiedades, si en definitiva, su finalidad es
la misma que los campos: guardar un valor en el objeto.
Existen varias y poderosas razones, por las cuales nos debemos decatar en muchas
ocasiones, hacia el uso de propiedades. En los siguientes apartados haremos una
descripción de ellas.

Encapsulación a través de propiedades


Una de las características de la OOP, la encapsulación, establece que el código de
una clase debe permanecer, siempre que sea posible, protegido de modificaciones
no controladas del exterior (código cliente). Esta clase debe actuar como una
especie de caja negra, que expone un interfaz para su uso, pero que no debe
permitir el acceso a la implementación de dicho interfaz.
Suponiendo que en la ya conocida clase Empleado se necesite crear un elemento
para guardar el sueldo pagado, pero el importe del sueldo deberá estar entre un
rango de valores en función de la categoría del empleado. Si la categoría es 1, el
sueldo estará entre 1 y 200, mientras que si la categoría es 2, el sueldo podrá

- 320 -
llegar hasta 300. si abordamos este problema utilizando campos de clase, puede
ocurrir lo que mostramos en el Código fuente 1.9.
Module General
Sub Main()

Dim loEmpleado As Empleado


loEmpleado = New Empleado()
loEmpleado.psNombre = "Omar"
loEmpleado.piCategoría = 1

' atención, el sueldo para este empleado


' debería estar entre 1 y 200, debido a su categoría
loEmpleado.pdbSueldo = 250
End Sub

End Module

Public Class Empleado


Public psNombre As String
Public piCategoría As Integer
Public pdbSueldo As Double
End Class
Código fuente 1.9

¿Qué está sucediendo aquí?. Fue creado un objeto empleado al que se le dio
categoría 1, sin embargo le estamos asignando un sueldo que no corresponde a su
categoría, pero se nos permite hacerlo sin ningún problema, ya que no existe un
medio de control que nos lo impida.
Afrontando el problema mediante el uso de propiedades, se cuenta con la ventaja
de escribir código de validación en los correspondientes procedimientos Property;
con ello se encapsula el código de la clase, manteniéndolo a salvo de asignaciones
incoherentes. Veamos esta solución en el Código fuente 1.10.
Module General
Sub Main()

Dim loEmpleado As Empleado


loEmpleado = New Empleado()

loEmpleado.psNombre = "Omar"
loEmpleado.Categoria = 1

loEmpleado.Sueldo = 250
Console.WriteLine("Asignación incorrecta")
Console.WriteLine("Empleado {0} - Categoría {1} - Sueldo {2}", _
loEmpleado.psNombre, loEmpleado.Categoria, loEmpleado.Sueldo)

loEmpleado.Sueldo = 175
Console.WriteLine("Asignación correcta")
Console.WriteLine("Empleado {0} - Categoría {1} - Sueldo {2}", _
loEmpleado.psNombre, loEmpleado.Categoria, loEmpleado.Sueldo)

Console.ReadLine()
End Sub

- 321 -
End Module

Public Class Empleado


Public psNombre As String

' variable de propiedad


Private miCategoria As Integer
Private mdbSueldo As Double

' procedimientos de propiedad


Public Property Categoria() As Integer
Get
Return miCategoria
End Get
Set(ByVal Value As Integer)
miCategoria = Value
End Set
End Property

Public Property Sueldo() As Double


Get
Return mdbSueldo
End Get

' cuando se asigna el valor a esta propiedad,


' se ejecuta código de validación en el bloque Set
Set(ByVal Value As Double)
' si la categoría del empleado es 1 ...
If miCategoria = 1 Then
' pero el sueldo supera 200
If Value > 200 Then
' mostrar un mensaje y asignar un cero
Console.WriteLine("La categoría no corresponde con
el sueldo")
mdbSueldo = 0
Else
' si todo está bien, asignar el sueldo
mdbSueldo = Value
End If
End If

End Set
End Property
End Class
Código fuente 1.10

Propiedades de sólo lectura o sólo escritura


Se nos plantea ahora un nuevo caso para la clase Empleado: se debe guardar el
valor del código de cuenta bancaria del empleado en el objeto, pero sin permitir
que dicha información sea accesible desde el código cliente.
Igualmente y en función de los primeros dígitos de la cuenta bancaria, se necesita
mostrar el nombre de la entidad, pero sin permitir al código cliente su modificación,
puesto que esta será siempre una operación que debe calcular el código de la clase.

- 322 -
Utilizando campos de clase no es posible resolver esta situación, puesto que al ser
de ámbito público, permiten tanto la escritura como lectura de sus valores.
Pero si se emplean propiedades, éstas permiten la creación de las denominadas
propiedades de solo lectura, en las que utilizando las palabras clave ReadOnly y
WriteOnly, se consigue que a una determinada propiedad, solo se pueda asignarle o
recuperar su valor.
Debido a esto , en una propiedad ReadOnly no podremos escribir el bloque Set, ya
que no tendría sentido, puesto que no se va a utilizar. Lo mismo se puede aplicar
para una propiedad WriteOnly, solo que en esta, el bloque que no se podrá codificar
será Get.
Igualmente genera un error de compilador, si en el código cliente se intenta asignar
un valor a una propiedad ReadOnly, u obtener un valor de una propiedad
WriteOnly.
Veamos a continuación, en el Código fuente 1.11, un ejemplo de cómo resolver el
problema comentando al comienzo de este apartado.
Module General
Sub Main()
Dim loEmpleado As Empleado
loEmpleado = New Empleado()

loEmpleado.psNombre = "Augusto"

' a esta propiedad solamente se le puede asignar valor,


' si se intenta obtenerlo, se producirá un error
loEmpleado.CuentaBancaria = "222-56-77779995555"

' en esta línea, la propiedad EntidadBancaria sólo


' permite obtener valor, si se intenta asignarle uno
' se producirá un error
Console.WriteLine("La entidad del empleado {0} es {1}", _
loEmpleado.psNombre,
loEmpleado.CuentaBancaria)
Console.ReadLine()
End Sub

End Module
Public Class Empleado
' campo de clase
Public psNombre As String

' variables de propiedad


Private msCtaBancaria As String
Private msEntidad As String

' variables diversas


Private msCodigoEntidad As String

' esta propiedad sólo permite asignar valores,


' por lo que no dispone del bloque Get
Public WriteOnly Property CuentaBancaria() As String
Set(ByVal Value As String)
Select Case Left(Value, 4)

- 323 -
Case "1111"
msEntidad = "Banco Galicia"
Case "2222"
msEntidad = "Banco Francés"
Case "3333"
msEntidad = "Banco Provincia"
Case Else
msEntidad = "entidad sin catalogar"
End Select
End Set
End Property

' esta propiedad sólo permite obtener valores


' por ello no dispone del bloque set
Public ReadOnly Property EntidadBancaria() As String
Get
Return msEntidad
End Get
End Property
End Class

Código fuente 1.11

Propiedades virtuales
Otra de las ventajas del uso de propiedades reside en la posibilidad de definir
propiedades virtuales; es decir, una propiedad que no tenga una correspondencia
directa con una variable de propiedad, ya que podemos crear un procedimiento
Property que no esté obligatoriamente asociado con una variable.
Siguiendo con la clase Empleado, en esta ocasión se creará una propiedad para
almacenar la fecha en la que el empleado fue incorporado a la empresa; esto no
entraña ninguna novedad. Sin embargo, seguidamente se necesita disponer de una
propiedad que permita mostrar el nombre del mes en el que se ha dado de alta al
empleado.
Se puede resolver esta cuestión creando una variable de propiedad, guardando en
ella una cadena con el nombre del mes, pero si se dispone de la fecha de alta, que
ya contiene el mes, nos ahorramos ese trabajo extra creando una propiedad, en
este caso de solo lectura, en la que extraigamos el nombre del mes de la fecha de
alta y lo devolvemos como resultado. Ver como hacerlo en el Código fuente 1.12.
Module General
Sub Main()
Dim loEmpleado As Empleado
loEmpleado = New Empleado()

loEmpleado.psNombre = "Ximena"
loEmpleado.FechaAlta = "12/6/2002"

' mostrar el mes de alta que corresponde


' a una propiedad virtual del objeto
Console.WriteLine("El empleado {0} fué dado de alta en el mes
de {1}", _
loEmpleado.psNombre, loEmpleado.MesAlta)

- 324 -
Console.ReadLine()
End Sub
End Module

Public Class Empleado


' campo de clase
Public psNombre As String

' variables de propiedad


Private mdtFechaAlta As Date

' propiedad para manejar la fecha de alta del empleado


Public Property FechaAlta() As Date
Get
Return mdtFechaAlta
End Get

Set(ByVal Value As Date)


mdtFechaAlta = Value
End Set
End Property

' propiedad virtual en la que se devolverá


' el nombre del mes en el que se dio de alta
' al empleado, usando la variable de otra propiedad
Public ReadOnly Property MesAlta() As String
Get
Return Format(mdtFechaAlta, "MMMM")
End Get
End Property
End Class
Código fuente 1.12

Nombres de propiedad más naturales


Cuando desde código cliente se trabaja con objetos, estos ofrecen habitualmente
nombres de propiedades claros y sin notaciones.
En el caso de la clase Empleado tenemos un inconveniente a este respecto con el
campo de clase correspondiente al nombre del empleado, puesto que en él
utilizamos convenciones de notación para facilitar el mantenimiento del código,
pero por otra parte, se está contribuyendo a dificultar la legibilidad de los miembros
de la clase desde el código cliente.
Es cierto que podemos obviar las convenciones de notación en el código, pero esto,
como ya se comentó en el apartado sobre convenciones de código, pude hacer que
la lectura del programa sea más complicada.
Como se comprobó también en los pasados ejemplos, si se usan propiedades, se
pueden mantener las normas de notación que se establecieron en cuanto en las
variables de la clase, sea cual sea su tipo, y ofrecer al código cliente, nombres mas
naturales a través de los procedimientos Property.

- 325 -
Por lo tanto, si en lugar de utilizar un campo de clase para el nombre del empleado,
se la convierte en una propiedad, se habrá ganado en claridad de cara al
programador usuario de nuestra clase. Ver código fuente 1.13
Module General
Sub Main()
Dim loEmpleado As New Empleado
' al usar un objeto desde código cliente
' siempre es más simple manipular la propiedad
' Nombre, que msNombre, en cuanto a la claridad del
' código se refiere
loEmpleado.Nombre = "Juan Manuel"
End Sub
End Module

Public Class Empleado


' antes se usaba un campo de clase.....
' Public psNombre as String 

' ... pero se lo convierte en una variable de propiedad...


Private msNombre As String
' ... creando su procedimiento de propiedad correspondiente
Public Property Nombre() As String
Get
Return msNombre
End Get
Set(ByVal Value As String)
msNombre = Value
End Set
End Property
End Class
Código fuente 1.13

Propiedades predeterminadas
Una propiedad predeterminada o por defecto, es aquella que permite su
manipulación omitiendo el nombre.
Al declarar una propiedad por defecto, se debe usar la palabra clave Default al
comienzo de la sentencia de declaración, siendo obligatorio además, que dicho
procedimiento de propiedad reciba al menos un parámetro.
La ventaja a la hora de trabajar con una propiedad de este tipo en un objeto, reside
en que no es necesario indicar su nombre, solo es preciso especificar su parámetro.
Debido a la naturaleza de este tipo de propiedad, solo es posible crear una
propiedad predeterminada en cada clase,
Una de las situaciones más idóneas en una clase para crear una propiedad
predeterminada, serian aquellos elementos en los que se tengan que manejar un
conjunto de valores a través de un array, es decir, la variable de propiedad seria el
array que se manipularía a través del correspondiente procedimiento de propiedad.
De esta manera, para asignar y obtener valores de este tipo de propiedad,
tendremos que utilizar el índice del array que internamente la gestiona.

- 326 -
Poniendo como ejemplo, el hecho de que el trabajo desempeñado por el empleado
le supone realizar viajes a diferentes ciudades; para llevar un control de los viajes
realizados, se creará una nueva propiedad, que además será predeterminada. Ver
este ejemplo en el código fuente 1.14

Module General
Sub Main()
Dim loEmpleado As New Empleado()
Dim liContador As Integer

' primero se maneja la propiedad predeterminada


' igual que una normal
loEmpleado.Viajes(0) = "Santa Fe"

' aquí se manipula la propiedad predeterminada


' sin indicar su nombre
loEmpleado(1) = "Carranza"

For liContador = 0 To 1
Console.WriteLine("Visita: {0} - Ciudad: {1}", _
liContador, loEmpleado(liContador))
Next

Console.ReadLine()
End Sub
End Module

Public Class Empleado


' este es el array asociado a la propiedad predeterminada
Private msViajes() As String

' declaración de la propiedad predeterminada


Default Public Property Viajes(ByVal Indice As Integer) As String
Get
' para devolver un valor, se emplea el número de índice
'pasado como parámetro
Return msViajes(Indice)
End Get

Set(ByVal Value As String)


' para asignar un valor a la propiedad,
' se comprueba primero si el array está vacío

' comprobar si el array está vacío,


' al ser el array también un objeto,
' se usa el operador Is
If msViajes Is Nothing Then
ReDim msViajes(0)
Else
' si el array ya contenía valores,
' añadir un nuevo elemento
ReDim Preserve msViajes(UBound(msViajes) + 1)
End If

- 327 -
' asignar el valor del array
msViajes(Indice) = Value
End Set
End Property
End Class
Código fuente 1.14

El uso de propiedades predeterminadas proporciona una cierta comodidad a la hora


de escribir el código, sin embargo, si uno se acostumbra a especificar en todo
momento las propiedades en el código, gana en legibilidad.

- 328 -

You might also like