mis tecnicas.pdf
TRANSCRIPT
Técnicas de
Programación
Orientada a
Objetos
Técnica de Programación Orientada a Objetos 2
Presentación…………………………………………………………………………………………..3
Modulo A
Semana 1: Arreglos Lineales y Matrices …………………………………………………...4
Semana 2: Ordenamiento de datos y Búsqueda de Datos…….……………….28
Semana 3: Programación Orientada a Objetos …………………………………40
Semana 4: Manejo de la Clase String ……………………………………………72
Semana 5: Manejo de Archivos ………………………………………………………….....81
Semana 6: Clases Primitivas ………………………………………………………………….99
Semana 7: Métodos propios …………………………………………………………………116
Semana 8: Ejercicios de Aplicación…………………………………………………….…127
Semana 9: Manejo de Capas en una aplicación en escritorio……………………133
Modulo B
Semana 1: Introducción a la Plataforma .NET…………………………………136
Semana 2: Uso de Estructuras de Control…….……………………………….194
Semana 3: Introduccion a la Estructura de Datos(Arreglos)………………….233
Semana 4: Procedimientos y Funciones……………………………………...…239
Semana 5: Funciones de Sistema y Formatos …………………………………..…284
Semana 6: Programacion Orientados a Objetos…………………………………….308
Semana 7: Manejo de Colecciones………………………………………………………350
Semana 8: Manejo de Archivos……………………………………………………………392
Semana 9: Manejo de Streams de Datos y Archivos………………………………412
Bibliografía: ……………………………………………………………………………………………421
Técnica de Programación Orientada a Objetos 3
PRESENTACIÓN
Esta guía didáctica es un material de ayuda institucional, perteneciente a las
especialidades de computación, Ingeniería de Software e Ingeniería de Redes y
Comunicaciones tiene por finalidad proporcionar los conocimientos de la
programación orientada a Objetos a los estudiantes del segundo ciclo de estudios.
La Organización SISE, líder en la enseñanza tecnológica a nivel superior, promueve
la elaboración de materiales educativos, en concordancia a las exigencias de las
tecnologías de estos tiempos, que permiten la creación de nuevas herramientas de
aprendizaje con el objetivo de facilitar el acceso de los estudiantes a la educación en
el marco del desarrollo tecnológico de la informática de las telecomunicaciones.
Esta guía se divide en 2 módulos y cada una de ellas en 9 semanas. Permite conocer
las herramientas indispensables para la elaboración de aplicaciones con el uso de la
técnica O.O. Se inicia con el uso de técnica en manejo de datos en memoria y en el
manejo de capas donde estas técnicas básicas se necesitan para dar solución a una
determinada proposición o problema.
En este proceso el alumno aprenderá instrucciones que le permitirán evaluar
expresiones para luego procesar un conjunto de sentencias. También aprenderá el
manejo de una aplicación a nivel de contenedores.
La implementación y uso de Capas dentro de la aplicación en escritorio permitirán que
el alumno aplique la técnica Orientada a objetos.
Todas estas herramientas darán un soporte solido al alumno para aprender a
programar en cualquier lenguaje Orientada a Objetos(JAVA, .NET, Visual C,etc).
Este material en su primera edición, servirá para ayudar a nuestros estudiantes
SISESINOS.
Técnica de Programación Orientada a Objetos 4
Arreglos
Contenidos
- Concepto de Arreglos :Declaración, asignación e inicialización de memoria a un arreglo - Acceso Secuencial y Aleatorio. Agregar Datos. - Arreglos con uso de Estructuras Condicionales: Uso de Contadores y Acumuladores. - Uso del JList (defaultListModel) - Definición de matrices: Acceso a elementos de una matriz: Asignación de Datos: - Matrices: Definicion,Asignacion, Ingreso. - Uso del JTable(DefatultTableModel), (setElementAt(), getSelectedRow(),
getSelectedColum(), changeSelection(), addRow(),etc).
____________________________________________________________________________
ARREGLOS LINEALES
Un arreglo es una colección de datos del mismo tipo, que se almacenan en posiciones consecutivas de memoria y reciben un nombre común. Para referirse a un determinado elemento de un arreglo se deberá utilizar el nombre del arreglo acompañado de un índice el cual especifica la posición relativa en que se encuentra el elemento.
Los arreglos pueden ser: Unidimensionales (vectores).
Bidimensionales (matrices, tablas).
Multidimensionales (tres dimensiones o más).
Declaración de un arreglo:
<tipo de dato>: nombre_variable [Tamaño]
Técnica de Programación Orientada a Objetos 5
Con esto diremos que se está definiendo un atributo de tipo arreglo y estamos
determinando el tipo de dato y el tamaño de registros.
Ejemplos: entero: Numeros[10]
decimal: talla [5]
caracter nombres [8]
Asignación de datos hacia a un arreglo:
Esta instrucción asigna el valor asociado de la expresión a la posición índice del arreglo nombre_variable. El índice debe ser una expresión del tipo entero en el rango [0, longitud-1].
Ejemplos: Estableciendo Datos a los Arreglos Numero[2]=152 talla[4]=170.5 nombre[6]=”Verónica”
Numero[5]=115 talla[0]=168.52 nombre[3]=”William”
Numero[10]=652 talla[2]=102.62 nombre[1]=”Angie”
Numero[0]=52 talla[1]=85.62 nombre[8]=”Sebastian”
Los datos establecidos en Memoria serian así:
Arreglo Numero
Índice 0 1 2 3 4 5 6 7 8 9 10 Valores 52 0 152 0 0 115 0 0 0 0 652
Arreglo Talla
Índice 0 1 2 3 4 5 Valores 168.52 85.62 102.6 0 170.5 0
Arreglo Nombres
Índice 0 1 2 3 4 5 6 7 8
Valores null Angie null William null null Verónica null Sebastián
nombre_variable[índice] = <expresión del tipo>
Técnica de Programación Orientada a Objetos 6
Nota: las posiciones que no se le asignaron datos quedarían vacios (0) en el caso de ser numero y null en el caso de carácter.
Acceso al contenido de un arreglo:
Para poder acceder al contenido:
a. escribir: Obtener el dato de acuerdo al índice establecido, para ello se deberá mostrar dicho dato, lo cual se podrá utilizar una variable o mostrarlo directamente.Aquí también vale la aclaración de que el índice debe estar dentro del rango de definición del arreglo.
Variable=nombre_Arreglo[índice] escribir (Variable) o escribir (nombre_Arrgelo[indice)
Ejemplo:
X=nombre[1]
escribir(X) el resultado será Angie
_________________________________________________________
escribir (nombre[8]) el resultado será Sebastián
b. Leer: se podrá ingresar datos al arreglo en forma contigua de acuerdo al índice. Es por
ello que se usara a una estructura iterativa que puede ser Mientras(while), Desde (do)
o Repetir(do..while).
Leer(Arreglo[indice])
Nota Para que esta lectura se repita hasta el total de tamaño del arreglo se deberá de
usar a una estructura Iterativa.
Un Ejemplo con él Desde
desde(x=1 hasta 10)
leer(Arreglo[x])
escribir(Arreglo[x])
fin_desde
Técnica de Programación Orientada a Objetos 7
Los pasos para la utilizar un vector:
1. Declarar el vector: Consiste en establecer el nombre, el tamaño y el tipo de los datos
que se van a almacenar en el arreglo ejemplo:
Hay que diferenciar dos términos:
tamaño del vector (T): es el número máximo de elementos que puede contener el
vector.
Numero de elementos(N): que indica cuantos elementos hay almacenados en el
arreglo en determinado momento. Nota N<=T.
T = 10;
decimal :notas[T]
2. Llenar el vector con los datos: Se puede hacer en el momento de la declaración
asignando al vector los valores que necesitamos almacenar.
Ejemplo.
notas[10] = {2.3 , 3.5 , 4.2 , 3.3 , 3.0 , 4.9 , 4.2 , 3.0 , 2.0 , 1.5 };
ó recorriendo el arreglo así dándole nuevos valores:
desde(i = 1 hasta N)
leer( notas[i] )
fin_desde
3. Manipular la información guardada en el vector. Para esto es necesario recorrer dicha
estructura y se puede hacer de la siguiente manera.
desde(i = 1 hasta N)
escribir ( notas[i] )
fin_desde
Tambien se puede leer y a la vez escribir los datos ingresados al arreglo
desde(i = 1 hasta N)
leer( notas[i] )
escribir ( notas[i] )
fin_desde
Operaciones que se pueden realizar con los arreglos
Son las siguientes:
Lectura (llenar el vector)
Escritura (escribir el vector)
Asignación (dar valor a una posición específica)
Actualización (inserción , eliminación, modificación )
Ordenación . (burbuja, inserción directa, selección directa, selle y quicksort).
Técnica de Programación Orientada a Objetos 8
Búsqueda. (secuencial, binaria, hash( por claves) ).
Ejemplos:
1. Crear un Arreglo que permita ingresar 10 Apellidos.
caracter: Apellidos[10]
desde(i =1 hasta 10)
leer(Apellidos[i] )
escribir (Apellidos [i] )
fin_desde
2. Crear un Arreglo que permita ingresar 15 promedios del aula 307 del curso de
fundamentos de programación
decimal: Promedios[15]
desde(i = 1 hasta 15)
leer(Promedios[i] )
escribir (Promedios [i] )
fin_desde
3. Crear un Arreglo que permita ingresar 20 Nombres de Institutos y Zona de
ubicación.
Constante N=20
Carácter: Institutos[N]
Carácter: Zonas[N]
desde(i = 1 hasta N)
leer(Institutos[i] )
leer(Zonas[i] )
escribir(Institutos[i])
escribir (Zonas[i] )
fin_desde
Técnica de Programación Orientada a Objetos 9
4. Crear un Arreglo que ingrese 50 datos numéricos enteros.
Constante N=50
entero: Numeros[N]
desde(i = 1 hasta N)
leer(Numeros[i] )
escribir(Numeros[i])
fin_desde
5. Crear un Arreglo que ingrese 10 promedios y escribir cuantos están aprobados y
cuantos desaprobados.
Constante N=10
decimal: Promedios[N]
desde(i = 1 hasta N)
leer(Promedios[i] )
escribir (Promedios [i] )
si(Promedios[i]>=10.5)
ca=ca+1
sino
cd=cd+1
fin_si
fin_desde
escribir(“Total de Aprobados: “,ca)
escribir(“Total de Desaprobados: “,cd)
Técnica de Programación Orientada a Objetos 10
6. Crear un Arreglo que ingrese 15 Áreas y sus respectitos Sueldos y mostrar cuantos
son del área de “Sistemas”,”Contabilidad”,
Cuantos superan al sueldo mínimo
Cuántos ganan entre 1000 y 2500.
Constante N=15
entero:Sueldo[N]
Carácter:Area[N]
desde(i = 0 hasta N-1)
leer(Sueldo[i] , Area[i] )
escribir (Sueldo[i] , Area[i] )
si(Area[i]=”Sistema”)entonces
cs=cs+1
fin_si
si(Area[i]=”Contabilidad”) entonces
cc=cc+1
fin_si
si(Sueldo[i]>650) entonces
csum=csum+1
fin_si
si(Sueldo[i]>=1000 y Sueldo[i]<=2500) entonces
cr=cr+1
fin_si
fin_desde
escribir(“Total del Área de Sistemas: “,cs)
escribir(“Total del Área de Contabilidad: “,cc)
escribir(“Total de Empleados que ganan más que el sueldo mínimo: “,csum)
escribir(“Total de Empleados que ganan entre 1000 y 2500: “,cr)
Técnica de Programación Orientada a Objetos 11
USO DE ARREGLOS EN JAVA
Una matriz es una estructura que contiene múltiples valores del mismo tipo. La longitud de un array se establece cuando se crea un arreglo (en tiempo de ejecución).
Se pueden declarar en Java Arreglos de cualquier tipo:
Para definir un Arreglo se usa la palabra clave new.
La palabra clave new se usa para crear una instancia de la clase.
Antes de ser instanciada con new no consume memoria, simplemente es una declaración de
tipo. Por ejemplo:
// Solo definir a un identificador como tipo arreglo.
char nombreJugadores [];
int edades[];
// Definir el arreglo con su tamaño especifico
String [ ] nombreJugadores = new String [10];
int [ ] edades = new int [99];
int[] a_Nac= new int[5];
int[] codigo = new int[4];
O se puede crear ya el arreglo con sus valores iníciales:
String nombres[] = { "Veronica","William","Angie","Sebastian"};
Esto que es equivalente a:
String nombres[]= new String[4];
nombres[0] = new String( "Veronica”);
nombres[1] = new String( "William");
nombres[2] = new String( "Angie");
Técnica de Programación Orientada a Objetos 12
nombres[3] = new String( "Sebastián" );
Otro Ejemplo:
String [ ] Coordinadores={“Verónica Escobar”, “Víctor Sánchez”,“Rogelio Tello”,”Carlos Monge”};
O También:
Coordinadores [0] = " Verónica Escobar ";
Coordinadores [1] = " Víctor Sánchez ";
Coordinadores [2] = " Rogelio Tello ";
Coordinadores [3] = "Carlos Monge";
Casos Prácticos
1. Ejemplo ingresando valores aleatorios al arreglo:
private void btnAgregar_actionPerformed(ActionEvent e) {
modLstf.clear();
int Numeros[]=new int[10];
for( int i=0; i < 10; i++ ){
Numeros[i] = (int)(Math.random()*100)+1;
modLstf.addElement((i+1)+".- "+Numeros[i] );
}
}
Se usara el random para
poder establecer números
aleatorios en este caso
será desde 1 al 100.
Técnica de Programación Orientada a Objetos 13
2. Almacenar los votos obtenidos por los 20 candidatos. Estos son ingresados por el usuario.
private void btnAgregar_actionPerformed(ActionEvent e) {
int votos[]=new int[20]; //Declara el Arreglo en forma Local
modLstf.clear(); //Limpia todo el contenido de la lista
for( int i=0; i < 20; i++ ){
votos[i] = Integer.parseInt(JOptionPane.showInputDialog("Ingresar Cantidad de
Votos - "+(i+1)));
modLstf.addElement((i+1)+".- "+votos[i] );
}
}
Técnica de Programación Orientada a Objetos 14
3. Se tiene una lista llamado Amigos: Verónica E., Gelnda D., Victor S., Rogelio T., Waldir C., Eduardo A., Carlos M., Henrry Q., Miguel F., Manue T, Juan C.. Se necesita almacenarlo en un Arreglo y mostrarlo.
private void btnAgregar_actionPerformed(ActionEvent e) {
String Amigos[]={"Verónica E.","Glenda D.","Victor S.","Waldir C.","Rogelio R.",
"Eduardo A.","Carlos M.","Henrry Q.","Miguel F.","Manuel T.","Juan C."};
for( int i=0; i < Amigos.length; i++ ){
modLstf.addElement((i+1)+".- "+Amigos[i] );
}
}
4. Se pide crear una lista que almacene 10 registros: estos datos serán Apellidos, edades y distritos del aula 307.
private void btnAgregar_actionPerformed(ActionEvent e) {
final int t=10;
int edades[]=new int[t];
String apellidos[]=new String[t];
String distritos[]=new String[t];
for( int i=0; i < t; i++ ){
Este método length
devuelve un valor
numérico entero
El length se usa para ver el total de
elementos que tiene el arreglo.
Técnica de Programación Orientada a Objetos 15
apellidos[i] = JOptionPane.showInputDialog("Registro nro. "+(i+1)+"\n"+"Ingresar Apellidos:");
edades[i] = Integer.parseInt(JOptionPane.showInputDialog("Ingresar Edad"));
distritos[i] =JOptionPane.showInputDialog("Ingresar Distrito:");
modLstf.addElement((i+1)+".- "+apellidos[i] );
modLstE.addElement(edades[i]);
ModLstD.addElement(distritos[i]);
}
5. Modificando el programa anterior, también deberá de visualizar cuantos son mayores a 31
o menores e iguales que 31. Cuántos son del distrito de Surco o Chorrillos.
Técnica de Programación Orientada a Objetos 16
public class FrmCAso01 extends JFrame {
final int t=5;
int edades[]=new int[t];
String apellidos[]=new String[t];
String distritos[]=new String[t];
private void btnAgregar_actionPerformed(ActionEvent e) {
for( int i=0; i < t; i++ ){
apellidos[i] = JOptionPane.showInputDialog("Registro nro. "+(i+1)+"\n"+"Ingresar Apellidos:");
edades[i] = Integer.parseInt(JOptionPane.showInputDialog("Ingresar Edades"));
distritos[i] =JOptionPane.showInputDialog("Ingresar Distrito:");
modLstf.addElement((i+1)+".- "+apellidos[i] );
modLstE.addElement(edades[i]);
ModLstD.addElement(distritos[i]);
}
private void btnReporte_actionPerformed(ActionEvent e) {
int cc=0,cmay=0,cme=0;
for( int i=0; i < t; i++ ){
if(distritos[i].equalsIgnoreCase("Surco") | distritos[i].equalsIgnoreCase("Chorrillos"))
cc=cc+1;
if(edades[i]>31)
cmay=cmay+1;
else
cme=cme+1;
}
txtsalida.append("* Total del Distrito de "+"\n"+"Surco o de Chorrillos son: "+cc+"\n");
txtsalida.append("* Total de Mayores de 31 Años son: "+cmay+"\n");
Estos arreglos deben ser
variable Globales debido a
que es llamado en botones
diferentes.
El atributo t es una
constante donde indica el
tamaño de los Arreglos.
Técnica de Programación Orientada a Objetos 17
txtsalida.append("* Total de Menores o iguales a 31 Años son: "+cme+"\n");
}
Técnica de Programación Orientada a Objetos 18
0 1 2
0
1
2
3
0 1 2
0
1
2
3
4
0 1 2 3 4
0
1
ARREGLOS BIDIMENSIONALES
MATRICES
La utilización de matrices constituye actualmente una parte esencial de los lenguajes de programación, ya que la mayoría de los datos se introducen en los ordenadores como tablas organizadas en filas y columnas: hojas de cálculo, bases de datos, Archivos, etc. Se llama matriz de orden m×n a todo conjunto rectangular de elementos Matriz(m)(n) dispuestos en m líneas horizontales (filas) y n verticales (columnas) de la forma:
Definir una matriz
<tipo de dato>: nombre_variable[Filas][Columnas]
Ejemplo:
a) Entero: Numeros[5][3]
Cuando se define este espacio en memoria para las matrices establece este espacio.
b) Caracter: Letras[2][5]
Filas
Columnas
Recordemos que los
Arreglos o Matrices
empiezan desde la
posición cero tanto para
las filas y columnas.
Técnica de Programación Orientada a Objetos 19
Asignación de datos hacia una Matriz:
nombre_variable[índiceFila] [índiceColumna] = <expresión del tipo>
Ejemplos: Estableciendo Datos a una Matriz
Asignar años de nacimiento a la Matriz Numeros.
Numeros[0][1]=1975
Numeros[1][2]=1972
Numeros[3][1]=1999
Numeros[4][2]=2004
Asignar Letras a la Matriz Letras
Letras[0][0]=”V”
Letras[0][1]=”E”
Letras[0][2]=”R”
Letras[0][3]=”O”
Letras[0][4]=”N”
Letras[1][0]=”I”
Letras[1][1]=”C”
Letras[1][2]=”A”
Acceso al contenido de una Matriz:
Para poder acceder al contenido:
a. Escribir: Obtener el dato de acuerdo al índice establecido, para ello se deberá mostrar utilizando una variable o mostrándolo directamente.
Variable=Matriz[índiceFila] [índiceColumna]
Escribir(Variable) o Mostar(Matriz[índiceFila] [índiceColumna])
Ejemplo:
X=Letras[0][3]
Escribir(X) el resultado será O
_________________________________________________________
Escribir(Letras[0][0]) el resultado será V
Técnica de Programación Orientada a Objetos 20
b. Lectura: se podrá ingresar datos al arreglo en forma contigua de acuerdo al índice. Es
por ello que se usara a una estructura iterativa anidad que puede ser Mientras(while),
Desde (for) o Repetir(do..while).
Leer(Matriz[índiceFila] [índiceColumna])
Nota: Para que esta lectura se repita hasta el total de tamaño del arreglo se deberá de
usar a una estructura Iterativa anidada que permitirá realizar el recorrido de filas y de las
columnas o viceversa(Columnas o Filas).
Llenar datos a la matriz:
Ejemplo. Recorriendo la Matriz dándole nuevos valores:
desde(f=1 hasta Filas)
desde(c =1 hasta Columnas)
leer( numeros[f][c] )
fin_desde
fin_desde
4. Manipular la información guardada en la Matriz. Para esto es necesario recorrer dicha
estructura y se puede hacer de la siguiente manera.
desde(f = 1 hasta Filas)
desde(c = 1 hasta Columnas)
escribir( numeros[f][c] )
fin_desde
fin_desde
También se puede leer y a la vez escribir los datos ingresados al arreglo
desde(f =1 hasta Filas)
desde(c =1 hasta Columnas)
leer( numeros[f][c] )
escribir( numeros[f][c] )
fin_desde
fin_desde
Técnica de Programación Orientada a Objetos 21
Operaciones que se pueden realizar con los arreglos Lectura (llenar datos de la matriz)
Escritura (escribir datos de la matriz)
Asignación (dar valor a una posición específica)
Actualización (inserción , eliminación, modificación )
Ejemplos:
En una matriz de dimensiones 5x4 hallar el mayor valor y el menor valor.
Variables
Fi=5
Co=4
Entero: Datos[Fi][Co]
Inicio
mayor=0; menor=1000;
desde(x=0 hasta Fi-1)
desde (y=0 hasta Co-1)
leer(Datos [x] [y])
si (Datos [x] [y]> mayor)
mayor= matriz [x] [y]
si (Datos [x] [y]< menor)
menor= matriz [x] [y]
fin_desde
fin_desde
escribir(mayor, menor)
fin_programa
Técnica de Programación Orientada a Objetos 22
USO DE MATRICES con el control JTABLE
Java posee la capacidad de definir un conjunto de variables del mismo tipo, agrupadas todas ellas bajo un mismo nombre, y distinguiéndolas mediante un índice numérico.
Para definir un arreglo o Matriz en java es como definir una variable o atributo, pero al especificar el tipo lo que hacemos es colocar un par de corchetes [] para indicar que lo que estamos definiendo es un arreglo o Matriz.
Para definir una Matriz se realiza de la siguiente manera:
Tipo_de_Dato variables[ ] [ ] = new Tipo_de_Dato [fila] [columna];
Por ejemplo definición de Matrices:
int numero[][]=new int[5][3];
double sueldos[][]=new double[10][2];
String apellidos[][]=new String[5][4];
boolean estado [][]=new boolean[6][4];
Asignar datos:
numero[0][0]=123;
numero[0][1]=456
Leer datos:
//solo indica el ingreso para esa posición de la matriz
números[0][2]=Integer.parseInt(JOptionPane.showInputDialog(“Ingresar Numero));
En el caso que se desee realizar para toda la matriz deberás de usar a una estructura
anidada para el ingreso. Por ejemplo:
//Definimos el total de filas y columnas
final int filas=5;
final int columnas=3;
int numero[][]=new int[filas][columnas];
for(int y=0;y<filas;++y){
for(int x=0;x<columnas;++x){
numero[y][x]= Integer.parseInt(JOptionPane.showInputDialog(“Ingresar
Numero”));
}
}
Técnica de Programación Orientada a Objetos 23
Uso del JTable
Jtable es una clase que me permite organizar una determinada información en tabla, esta
difiere de una base de datos normal porque al utilizar Jtable tú puedes visualizar esta tabla,
brindándole al usuario organización de información, oportunidades de editar y cambiar el
tamaño de las columna entre otras.
Jtable le da al programador muchas facilidades, pues este posee varias características que
permiten hacer desde tablas con información compleja y muy estructurada hasta tablas con
información sencilla y "básica".
DefaultTableModel
La clase Jtable controla como se presentan los datos, para crear un Jtable habrá pues que crear un DefaultTableModel antes. DefaultTableModel lo que hace es predeterminar ciertas características para el Jtable, es decir que tu puedes poner ciertos parámetros dentro de un DefaultTableModel y así no tener que determinarlos siempre. DefaulTableModel guarda los datos de la tabla para sí mismo, es decir, puede tener la información de la tabla pero estos datos son los visualizados por el computador, es decir, para visualizar una tabla el DEFAULTTABLEMODEL puede tener la información pero sin el Jtable no se puede visualizar para el usuario.
EDITABLE O NO?
Jtable tiene una característica muy llamativa, este permite que el programador pueda decidir que se edita y que no, sin embargo si el programador dentro de su programa o de su DEFAULTTABLEMODEL no tiene determinado este aspecto, Jtable automáticamente hace editable las celdas dentro de la tabla.
LA INFORMACIÓN, Y LAS COLUMNAS?
Jtable te brinda muchas facilidades para poder crear una tabla, y así mismo de llenarla con la información que desees ( números, letras etc...) por lo que sencillamente dentro de una tabla esta automáticamente esta a través de la información debidamente separada - por ""(comillas) o por , (coma) - es capaz de contabilizarlas y al mismo tiempo llenarla con la información que se le dio; es decir el programador solo se debe encargar de poner los títulos de las tablas y así mismo de escribir la información en el mismo orden en que desee que salga de acuerdo con los títulos y Jtable se encargara automáticamente de colocar la información donde se le indico.
UN CHECK BOX?
Para un CellRendered con un DefaultTableModel sencillo, tal vez identificar clases pueda ser algo más complejo que no pueda hacer, pero para uno un poco más avanzado, esto sería muy fácil, y para esto cito el caso de un CHECK BOX(casilla de verificación) el cual es un componente grafico generado por Jtable después de que identifica una información tipo boolean, dándole así la apariencia de un cuadro rellenable, un check box no es más que eso, una opción - que puede ser editable o no.
UN LIST BOX?
En algunas oportunidades, para cierto tipo de información que deseamos que el usuario complete, necesitamos darle a el usuario, cierto tipo de opciones cosa que a través de un List Box tu puedes ofrecer al usuario el tipo de respuestas que tu desees que selecciones, este tipo de organización de información ya no es tan sencillo como declarar una información tipo boolean, toca crear la lista.
Técnica de Programación Orientada a Objetos 24
Creación y enlace de un JTable
Insertar el JTable y definir la clase DefaultTableModel en el public class
por ejemplo:
En el método jbInit establecer el enlace del modal y el total de filas y columnas.
Ejemplo 01:
Crear una Matriz de 5 X 3 y llenar datos numéricos enteros.
Realizar el procedimiento de creación y enlace del Jtable.
private void btnAgregar_actionPerformed(ActionEvent e) {
final int filas=5;
final int columnas=3;
int numero[][]=new int[filas][columnas];
for(int y=0;y<filas;++y){
for(int x=0;x<columnas;++x){
numero[y][x]= Integer.parseInt(JOptionPane.showInputDialog("IngresarNumero"));
modTbDatos.setValueAt(numero[y][x],y,x);
}
}
}
DefaultTableModel modTbDatos=new DefaultTableModel();
jTable1.setModel(modTbDatos);
modTbDatos.setColumnCount(3);
modTbDatos.setRowCount(5);
Técnica de Programación Orientada a Objetos 25
Ejemplo 02:
Escribir los resultados de las tablas de multiplicar hasta el 10.
Realizar el procedimiento de creación y enlace del Jtable.
private void btnAgregar_actionPerformed(ActionEvent e) {
final int MAXT = 11;
int [] [] tabla = new int [MAXT][MAXT];
//Se inicializan los valores de tabla
for (int i = 0; i < MAXT; i++)
for (int j = 0; j < MAXT; j++)
tabla [i][j] = i*j;
//Se imprime tabla
//se muestran los resultados que tenga la matriz
for (int i = 0; i < MAXT; i++) {
for (int j = 0; j < MAXT; j++)
modTbDatos.setValueAt(tabla [i][j],i,j);
}
}
Ejemplo 03:
Crear 2 vectores Apellidos y Edades que almacenen 15 registros y deberán ser
presentados en el JTable por columnas.
private void btnAgregar_actionPerformed(ActionEvent e) {
final int filas=15;
int Edad[]=new int[filas];
String apellidos[]=new String[filas];
for (int i = 0; i < filas; i++){
apellidos[i]=JOptionPane.showInputDialog("Ingresar Apellidos");
Edad[i]=Integer.parseInt(JOptionPane.showInputDialog("Ingresar Edad"));
modTbDatos.setValueAt(apellidos[i],i,0);
Técnica de Programación Orientada a Objetos 26
modTbDatos.setValueAt(Edad[i],i,1);
}
}
Técnica de Programación Orientada a Objetos 27
BALOTARIO DE EJERCICIOS – USANDO VECTORES Y MATRICES
1. Dado un vector de números reales: a) Escriba un método max que nos devuelva el máximo de los valores incluidos en el
vector. b) Escriba un método min que nos devuelva el mínimo de los valores incluidos en el
vector. c) Escriba un método media Aritmética que nos devuelva la media de los valores
incluidos en el vector. d) Dado un vector de números reales, escriba un método que nos devuelva el máximo
y el mínimo de los valores incluidos en el vector. e) Dado un vector, implemente un método que inserte un elemento en una posición
dada del vector. f) Realizar programas que definan un vector de 10 elementos inicializado con valores
enteros cualesquiera, tanto negativos como positivos y hagan lo siguiente:
Mostrar por pantalla el contenido del vector
Mostrar por pantalla el contenido del vector en orden inverso.
Mostrar la suma de los valores del vector
Indicar el máximo y el mínimo de los valores del vector.
Hallar la media aritmética de aquellos valores que sean mayores que 20 y menores que 80.
Indicar cuantos hay pares y si hay alguno primo. 2. Realizar un programa al que se le vayan introduciendo por teclado números enteros. El
programa dispone de dos vectores, uno llamado positivos y otro negativo, ambos de 8 posiciones. Se trata de meter los números introducidos en uno u otro según su signo hasta que se llenen los dos. El programa avisará si se intenta meter un número (positivo o negativo) cuando el vector correspondiente está lleno. Finalmente el programa nos
a) informará de la suma de todos los elementos guardados en los vectores. b) El promedio de lo positivos c) Cuantos números + fueron mayores a 100.
3. Realizar un subprograma llamado llenar_vector_sin_repet igual que llenar_vector_10_elem pero que no introduzca repetidos. Realizar un programa que lo utilice y muestre por pantalla el contenido del vector.
4. Dada una matriz de 10 x 10, mostrar la suma de las filas y columnas a) Que fila obtuvo la suma mayor
b) Que columna obtuvo la suma menor.
c) El numero mayor
d) El promedio de la suma
e) El promedio de la columna.
Técnica de Programación Orientada a Objetos 28
Contenidos
- Definir Ordenamientos de Datos: Método de Burbuja, Método Shell. - Definición de Búsqueda: Tipos Búsqueda de Datos dentro de un Arreglo. - Tipos de Búsquedas: Búsqueda Lineal - Búsqueda Binaria.
____________________________________________________________________________
Algoritmos de Ordenamiento
Ordenar es simplemente colocar información de una manera especial basándonos en un criterio de ordenamiento.
Métodos de ordenamientos. Existen diferentes métodos de ordenamiento entre ellas tenemos por Selección, Inserción, Quick Sort, Burbuja, Shell, etc. Dentro de las cuales hablaremos de los métodos: El hecho de que la información está ordenada, nos sirve para poder encontrarla y accesarla de manera más eficiente ya que de lo contrario se tendría que hacer de manera secuencial. A continuación se describirán 4 grupos de algoritmos para ordenar información:
Algoritmos de inserción:
En este tipo de algoritmo los elementos que van a ser ordenados son considerados uno a la vez. Cada elemento es INSERTADO en la posición apropiada con respecto al resto de los elementos ya ordenados. Entre estos algoritmos se encuentran el de INSERCION DIRECTA, SHELL SORT, INSERCION BINARIA y HASHING.
Algoritmos de intercambio:
En este tipo de algoritmos se toman los elementos de dos en dos, se comparan y se INTERCAMBIAN si no están en el orden adecuado. Este proceso se repite hasta que se ha analizado todo el conjunto de elementos y ya no hay intercambios. Entre estos algoritmos se encuentran el BURBUJA y QUICK SORT.
Técnica de Programación Orientada a Objetos 29
Algoritmos de selección: En este tipo de algoritmos se selecciona o se busca el elemento más pequeño (o más grande) de todo el conjunto de elementos y se coloca en su posición adecuada. Este proceso se repite para el resto de los elementos hasta que todos son analizados. Entre estos algoritmos se encuentra el de SELECCION DIRECTA.
Algoritmos de enumeración: En este tipo de algoritmos cada elemento es comparado contra los demás. En la comparación se cuenta cuántos elementos son más pequeños que el elemento que se está analizando, generando así una ENUMERACION. El número generado para cada elemento indicará su posición. Los métodos simples son: Inserción (o por inserción directa), selección, burbuja y shell, en dónde el último es una extensión al método de inserción, siendo más rápido. Los métodos más complejos son el quick-sort (ordenación rápida) y el heap sort. A continuación se mostrarán los métodos de ordenamiento más simples.
Método Burbuja.
El bubble sort, también conocido como ordenamiento burbuja, consiste en comparar un valor con el siguiente valor y de acuerdo a la condición se realizara el intercambio entre los datos, y este recorrido se va ir haciendo hasta culminar todos los elementos N-1 del arreglo.
Algoritmo:
Método de Shell.
Nombrado así debido a su inventor Donald Shell. Ordenamiento de disminución incremental, Ordena subgrupos de elementos separados K unidades (respecto de su posición en el arreglo) del arreglo original. El valor K es llamado incremento. Después de que los primeros K subgrupos han sido ordenados (generalmente utilizando INSERCION DIRECTA), se escoge un nuevo valor de K más pequeño, y el arreglo es de nuevo partido entre el nuevo conjunto de subgrupos. Cada uno de los subgrupos mayores es ordenado y el proceso se repite de nuevo con un valor más pequeño de K. Eventualmente el valor de K llega a ser 1, de tal manera que el subgrupo consiste de todo el arreglo ya casi ordenado. Al principio del proceso se escoge la secuencia de decrecimiento de incrementos; el último valor debe ser 1. "Es como hacer un ordenamiento de burbuja pero comparando e intercambiando elementos."
Desde(g=0 hasta N-1) // recorrido del vector
Desde (i=0 hasta N-1) //posiciones de comparación
si(vector[i] > vector[i+1])
aux= vector[i]
vector[i]= vector[i+1]
vector[i+1]=aux
fin_si
fin_desde
fin_desde
Técnica de Programación Orientada a Objetos 30
Cuando el incremento toma un valor de 1, todos los elementos pasan a formar parte del subgrupo y se aplica inserción directa.
El método se basa en tomar como salto N/2 (siendo N el número de elementos) y luego se va reduciendo a la mitad en cada repetición hasta que el salto o distancia vale 1.
Procedimiento Shell Sort;
Ejemplo:
Para el arreglo a = [6, 1, 5, 2, 3, 4, 0]
Tenemos el siguiente recorrido:
Recorrido Salto Lista Ordenada Intercambio
1 3 2,1,4,0,3,5,6 (6,2), (5,4), (6,0)
2 3 0,1,4,2,3,5,6 (2,0)
3 3 0,1,4,2,3,5,6 Ninguno
4 1 0,1,2,3,4,5,6 (4,2), (4,3)
5 1 0,1,2,3,4,5,6 Ninguno
Procedimiento SHELL(variables Vector:A; entero:n)
variables
entero: aux,i,int
logico: band
Incio
int=n+1;
Mientras (int>1)
int=1mod(int div 2)
band=true
Mientras (band=true )
band=false
i=1
Mientras ((i+int)<=n)
si(a[i] > a[i+int]) entonces
aux=a[i]
a[i]=a[i+int]
a[i+int]=aux
band=true
fin_si
i=i+1
Fin_Mientras
Fin_Mientras
Fin_Mientras
Fin
Técnica de Programación Orientada a Objetos 31
Ejemplos en código JAVA:
.
void shell_sort(int A[], int size){ int i, j, incrmnt, temp; incrmnt = size/2; while (incrmnt > 0) { for (i=incrmnt; i < size; i++) { j = i; temp = A[i]; while ((j >= incrmnt) && (A[j-incrmnt] > temp)) { A[j] = A[j - incrmnt]; j = j - incrmnt; } A[j] = temp; } incrmnt /= 2; } }
void ordenamientoBurbuja(int v[], int util_v) { int temp; for (int i = 0; i <= util_v - 2; i++) { for (int j = i + 1; j <= util_v - 1; j++) { if (v[i] > v[j]) { temp = v[i]; v[i] = v[j]; v[j] = temp; } } } }
Técnica de Programación Orientada a Objetos 32
Búsqueda Un algoritmo de búsqueda es aquel que está diseñado para localizar un elemento concreto dentro de una estructura de datos. Consiste en solucionar un problema de existencia o no de un elemento determinado en un conjunto finito de elementos, es decir, si el elemento en cuestión pertenece o no a dicho conjunto, además de su localización dentro de éste. Este problema puede reducirse a devolver la existencia de un número en un vector.
Búsqueda secuencial
Permite localizar el dato dentro del arreglo desde la posición inicial hasta la posición final, la existencia se puede asegurar desde el momento que el elemento es localizado (pero no podemos asegurar la no existencia hasta no haber analizado todos los elementos del arreglo).
Búsqueda binaria Se utiliza cuando el vector en el que queremos determinar la existencia o no de un elemento está ordenado, o puede estarlo, este algoritmo reduce el tiempo de búsqueda considerablemente, ya que disminuye exponencialmente con el número de iteraciones.
Datos de Entrada:
vec: nombre de la colección de todos los datos
tam: tamaño del vector
dato: elemento que se quiere buscar.
Variables
entero: pos
Inicio
leer(dato)
pos = 0
Mientras(pos < tam)
Si (vec[pos]= dato) entonces
Devolver= verdadero
sino
pos = pos + 1
fin_si
fin_Mientras
1ero.- se deberá de aplicar un ordenamiento de
datos ya sea ascendeste o descendente.
2do.- aplicará cualquier técnica de búsqueda.
Técnica de Programación Orientada a Objetos 33
Ejemplos
Caso 01
Dentro de una lista de 10 nombres, verifique si el nombre ingresado existe o no y en que
posicion.
public class FrmBus extends JFrame {
final int tam=5;
String nom[]=new String[tam];
int x; *** *** *** void agregar(){
if(x<tam){
nom[x]=txtnom.getText();
modlstn.addElement((x+1)+".- "+nom[x]);
++x;
txtnom.setText("");
txtnom.requestFocus();
}else{
JOptionPane.showMessageDialog(null,"Ya no se puede ingresar mas
nombres\n"+"Termino el Ingreso");
txtnom.setEnabled(false);
}
}
void busqueda(){
int sw=0,posi=0;
String n=JOptionPane.showInputDialog("Ingresar Nombre a buscar");
for(int f=0;f<x;++f){
if(n.equalsIgnoreCase(nom[f])){
sw=0;
posi=f;
break;
}
else
sw=1;
}
if(sw==0){
lblb.setText("El Nombre Encontrado");
lblp.setText(" "+(posi+1));
}
else
lblb.setText("El Nombre No Existe");
}
Técnica de Programación Orientada a Objetos 34
private void btnnom_actionPerformed(ActionEvent e) {
agregar();
}
private void btnBuscar_actionPerformed(ActionEvent e) {
busqueda();
}
Técnica de Programación Orientada a Objetos 35
Caso 02
Dentro de una lista de 25 distritos muestre si existe o no el distrito de Villa el Salvador.
Caso 03
Crear una Aplicación donde permita llenar datos a los vectores Nombres, Apellidos Año de
Nacimiento y edad. Permitirá hasta 20 registros.
La edad se calcula de acuerdo al Año de Nacimiento
El programa permitirá :
o Ordenar por Apellido
o Buscar Datos por Nombres y decir cuántos Nombres son iguales.
public class FrmEjem01 extends JFrame {
final int filas=20;
String nom[]=new String[filas];
String ape[]=new String[filas];
int edad[]=new int[filas];
int anac[]=new int[filas];
int Reg;
private void jbInit() throws Exception {
------------------------------------------------------
//llenando el combo con las fechas
Se define la dimensión y
los nombres de los
Arreglos
Se define el Contador
del Registro
Se Establece valores
al Combo
Técnica de Programación Orientada a Objetos 36
for(int g=1970;g<=2010;++g)
cboAnac.addItem(g);
void LeerDatos(){
if(Reg<filas){
nom[Reg]=txtNom.getText();
ape[Reg]=txtApe.getText();
}
else
JOptionPane.showMessageDialog(null,"Ya no puede ingresar mas registros");
}
void llenarRegistros(){
modTbDatos.setValueAt((Reg+1),Reg,0);
modTbDatos.setValueAt(nom[Reg],Reg,1);
modTbDatos.setValueAt(ape[Reg],Reg,2);
modTbDatos.setValueAt(anac[Reg],Reg,3);
modTbDatos.setValueAt(edad[Reg],Reg,4);
++Reg;
}
private void btnAceptar_actionPerformed(ActionEvent e) {
LeerDatos();
llenarRegistros();
}
private void cboAnac_actionPerformed(ActionEvent e) {
anac[Reg]=Integer.parseInt(cboAnac.getSelectedItem().toString());
edad[Reg]=2010-anac[Reg];
lbledad.setText(""+edad[Reg]);
}
void OrdenarB(){
String tempA,tempN;
int tempAn,tempE;
for (int i = 0; i <Reg - 1; i++) {
for (int j = 0; j < Reg - 1; j++) {
if ((ape[j].compareTo(ape[j+1]))>0) {
tempA = ape[j];
ape[j] = ape[j+1];
ape[j+1] = tempA;
//
tempN = nom[j];
nom[j] = nom[j+1];
nom[j+1] = tempN;
//
tempAn = anac[j];
anac[j] = anac[j+1];
anac[j+1] = tempAn;
Preguntando si el Registro es
menor al total de Filas.
Llena los datos a los Arreglos
Muestra los datos que tiene el
Arreglo
Incremento el Registro para
controlar el total de datos
ingresados.
Calcula la edad según el año
seleccionado.
Ordenamiento Burbuja.
Por medio del Apellido
El resto de los vectores tambien
deben de realizar solo el
intercambio para seguir el orden.
Técnica de Programación Orientada a Objetos 37
//
tempE = edad[j];
edad[j] = edad[j+1];
edad[j+1] = tempE;
}
}
}
// visualizar datos ordenados
modTbDatos.setRowCount(15);
for(int g=0;g<Reg;++g){
modTbDatos.setValueAt((g+1),g,0);
modTbDatos.setValueAt(nom[g],g,1);
modTbDatos.setValueAt(ape[g],g,2);
modTbDatos.setValueAt(anac[g],g,3);
modTbDatos.setValueAt(edad[g],g,4);
}
}
private void BtnOrdenart_actionPerformed(ActionEvent e) {
modTbDatos.setRowCount(0);
OrdenarB();
}
Para la Busqueda. Deberá de aparecer la ventana para buscar el nombre y visualizar si se
encontro y cuantas veces.
Establecer el total de filas
según al total de registros.
Mostrar los Datos Ordenados.
Eliminar todas las filas de la
tabla.
Llamar al Ordenamiento y
volver a mostrar los datos. Y
se Visualizara en la tabla
ordenado por Apellido.
Técnica de Programación Orientada a Objetos 38
Por lo tanto agrega el metodo busqueda_Nom() y lo llamaremos en el boton Busqueda.
void busqueda_Nom(){
int f=0,c=0;
String Vb=JOptionPane.showInputDialog("Ingresar Nombres a Buscar");
while(f<Reg){
if(Vb.equalsIgnoreCase(nom[f])){
c=c+1;
}
++f;
}
if(c>0)
JOptionPane.showMessageDialog(null,"Nombre Encontrado"+"\n"+"y se Repite
:"+(c)+"Veces");
else
JOptionPane.showMessageDialog(null,"No se Encontrado el Nombre");
}
private void btnBusqueda_actionPerformed(ActionEvent e) {
Técnica de Programación Orientada a Objetos 39
busqueda_Nom();
}
Insertar el Botón Eliminar Registro Intenta estableciendo el siguiente código
private void btnEliminar_actionPerformed(ActionEvent e) {
//Fila seleccionada de la Tabla
int FilSelec=jTable1.getSelectedRow();
modTbDatos.removeRow(FilSelec);
nom[FilSelec]="";
ape[FilSelec]="";
edad[FilSelec]=0;
anac[FilSelec]=0;
}
Técnica de Programación Orientada a Objetos 40
Contenidos
- Introducción a la programación Orientada a Objetos POO. - Caracteristicas de la programación orientada a objetos. - Definición de Clases - Constructores, Estructura de una clase - Nivel de acceso(public, private, protected) - Uso de atributo static. - Interfaces, definición. - Paquete, distribución, mencionar la razón de trabajar en capas, manejo de capas
(Lógica y Presentación ) - Encapsulación (get y set de los atributos) - Herencia: extends, Polimorfismo - Sobrecarga de Métodos
____________________________________________________________________________
Programación Orientada a Objetos
Es un paradigma de programación que usa objetos y sus interacciones, para diseñar
aplicaciones y programas de ordenador. Está basado en varias técnicas, incluyendo herencia,
modularidad, polimorfismo y encapsulamiento. Su uso se popularizó a principios de la década
de 1990. En la actualidad, existe variedad de lenguajes de programación que soportan la
orientación a objetos.
Un objeto es en realidad un conjunto de funciones y procedimientos, todos ellos relacionados con un determinado concepto del mundo real. Los objetos son entidades que combinan estado (atributo), comportamiento (método) e identidad:
El estado está compuesto de datos, será uno o varios atributos a los que se habrán asignado unos valores concretos (datos).
El comportamiento está definido por los procedimientos o métodos con que puede operar dicho objeto, es decir, qué operaciones se pueden realizar con él.
La identidad es una propiedad de un objeto que lo diferencia del resto, dicho con otras palabras, es su identificador (concepto análogo al de identificador de una variable o una constante).
Técnica de Programación Orientada a Objetos 41
La programación orientada a objetos, expresa un programa como un conjunto de estos objetos, que colaboran entre ellos para realizar tareas. Esto permite hacer los programas y módulos más fáciles de escribir, mantener, y reutilizar.
Un objeto contiene toda la información que permite definirlo e identificarlo frente a otros objetos pertenecientes a otras clases e incluso frente a objetos de una misma clase, al poder tener valores bien diferenciados en sus atributos. A su vez, los objetos disponen de mecanismos de interacción llamados métodos, que favorecen la comunicación entre ellos. Esta comunicación favorece a su vez el cambio de estado en los propios objetos. Esta característica lleva a tratarlos como unidades indivisibles, en las que no se separa el estado y el comportamiento.
Los métodos (comportamiento) y atributos (estado) están estrechamente relacionados por la propiedad de conjunto. Esta propiedad destaca que una clase requiere de métodos para poder tratar los atributos con los que cuenta. El programador debe pensar indistintamente en ambos conceptos, sin separar ni darle mayor importancia a alguno de ellos. Hacerlo podría producir el hábito erróneo de crear clases contenedoras de información por un lado y clases con métodos que manejen a las primeras por el otro. De esta manera se estaría realizando una programación estructurada camuflada en un lenguaje de programación orientado a objetos.
La POO difiere de la programación estructurada tradicional, en la que los datos y los procedimientos están separados y sin relación, ya que lo único que se busca es el procesamiento de unos datos de entrada para obtener otros de salida. La programación estructurada anima al programador a pensar sobre todo en términos de procedimientos o funciones, y en segundo lugar en las estructuras de datos que esos procedimientos manejan. En la programación estructurada sólo se escriben funciones que procesan datos. Los programadores que emplean POO, en cambio, primero definen objetos para luego enviarles mensajes solicitándoles que realicen sus métodos por sí mismos.
Características de la POO
Existe un acuerdo acerca de qué características contempla la "orientación a objetos", las características siguientes son las más importantes:
Abstracción: Denota las características esenciales de un objeto, donde se capturan
sus comportamientos.Cada objeto en el sistema sirve como modelo de un "agente" abstracto que puede realizar trabajo, informar y cambiar su estado, y "comunicarse" con otros objetos en el sistema sin revelar cómo se implementan estas características. Los procesos, las funciones o los métodos pueden también ser abstraídos y cuando lo están, una variedad de técnicas son requeridas para ampliar una abstracción.
Encapsulamiento: Significa reunir a todos los elementos que pueden considerarse
pertenecientes a una misma entidad, al mismo nivel de abstracción. Esto permite aumentar la cohesión de los componentes del sistema. Algunos autores confunden este concepto con el principio de ocultación, principalmente porque se suelen emplear conjuntamente.
Principio de ocultación: Cada objeto está aislado del exterior, es un módulo
natural, y cada tipo de objeto expone una interfaz a otros objetos que especifica cómo pueden interactuar con los objetos de la clase. El aislamiento protege a las propiedades de un objeto contra su modificación por quien no tenga derecho a acceder a ellas, solamente los propios métodos internos del objeto pueden acceder a su estado. Esto asegura que otros objetos no pueden cambiar el estado interno de un objeto de maneras inesperadas, eliminando efectos secundarios e interacciones inesperadas. Algunos lenguajes relajan esto, permitiendo un acceso directo a los datos internos del objeto de una manera controlada y limitando el grado de abstracción. La aplicación entera se reduce a un agregado o rompecabezas de objetos.
Técnica de Programación Orientada a Objetos 42
Polimorfismo: comportamientos diferentes, asociados a objetos distintos, pueden
compartir el mismo nombre, al llamarlos por ese nombre se utilizará el comportamiento correspondiente al objeto que se esté usando. O dicho de otro modo, las referencias y las colecciones de objetos pueden contener objetos de diferentes tipos, y la invocación de un comportamiento en una referencia producirá el comportamiento correcto para el tipo real del objeto referenciado. Cuando esto ocurre en "tiempo de ejecución", esta última característica se llama asignación tardía o asignación dinámica. Algunos lenguajes proporcionan medios más estáticos (en "tiempo de compilación") de polimorfismo, tales como las plantillas y la sobrecarga de operadores de C++.
Herencia: las clases no están aisladas, sino que se relacionan entre sí, formando una
jerarquía de clasificación. Los objetos heredan las propiedades y el comportamiento de todas las clases a las que pertenecen. La herencia organiza y facilita el polimorfismo y el encapsulamiento permitiendo a los objetos ser definidos y creados como tipos especializados de objetos preexistentes. Estos pueden compartir (y extender) su comportamiento sin tener que volver a implementarlo. Esto suele hacerse habitualmente agrupando los objetos en clases y estas en árboles o enrejados que reflejan un comportamiento común. Cuando un objeto hereda de más de una clase se dice que hay herencia múltiple.
Recolección de basura: la Recolección de basura o Garbage Collector es la técnica
por la cual el ambiente de Objetos se encarga de destruir automáticamente, y por tanto desasignar de la memoria, los Objetos que hayan quedado sin ninguna referencia a ellos. Esto significa que el programador no debe preocuparse por la asignación o liberación de memoria, ya que el entorno la asignará al crear un nuevo Objeto y la liberará cuando nadie lo esté usando. En la mayoría de los lenguajes híbridos que se extendieron para soportar el Paradigma de Programación Orientada a Objetos como C++ u Object Pascal, esta característica no existe y la memoria debe desasignarse manualmente.
Clases en POO Las clases son declaraciones de objetos, también se podrían definir como abstracciones de objetos(quiere decir que la definición de un objeto es la clase). Cuando programamos un objeto y definimos sus características y funcionalidades en realidad lo que estamos haciendo es programar una clase.
Propiedades en clases Las propiedades o atributos son las características de los objetos. Cuando definimos una propiedad normalmente especificamos su nombre y su tipo. Nos podemos hacer a la idea de que las propiedades son algo así como variables donde almacenamos datos relacionados con los objetos.
Métodos en las clases Son las funcionalidades asociadas a los objetos. Cuando estamos programando las clases las llamamos métodos. Los métodos son como funciones que están asociadas a un objeto.
Objetos en POO Los objetos son ejemplares de una clase cualquiera. Cuando creamos un ejemplar tenemos que especificar la clase a partir de la cual se creará. Esta acción de crear un objeto a partir de una clase se llama instanciar (que viene de una mala traducción de la palabra instace que en inglés significa ejemplar). Por ejemplo, un objeto de la clase fracción es por ejemplo 3/5. El concepto o definición de fracción sería la clase, pero cuando ya estamos hablando de una fracción en concreto 4/7, 8/1000 o cualquier otra, la llamamos objeto. Para crear un objeto se tiene que escribir una instrucción especial que puede ser distinta dependiendo el lenguaje de programación que se emplee, pero será algo parecido a esto. miCoche = new Coche()
Técnica de Programación Orientada a Objetos 43
Con la palabra new especificamos que se tiene que crear una instancia de la clase que sigue a continuación. Dentro de los paréntesis podríamos colocar parámetros con los que inicializar el objeto de la clase coche.
Estados en objetos Cuando tenemos un objeto sus propiedades toman valores. Por ejemplo, cuando tenemos un coche la propiedad color tomará un valor en concreto, como por ejemplo rojo o gris metalizado. El valor concreto de una propiedad de un objeto se llama estado. Para acceder a un estado de un objeto para ver su valor o cambiarlo se utiliza el operador punto. miCoche.color = rojo El objeto es miCoche, luego colocamos el operador punto y por último el nombre e la propiedad a la que deseamos acceder. En este ejemplo estamos cambiando el valor del estado de la propiedad del objeto a rojo con una simple asignación.
Mensajes en objetos Un mensaje en un objeto es la acción de efectuar una llamada a un método.
Otras cosas Hay mucho todavía que conocer de la POO ya que sólo hemos hecho referencia a las cosas más básicas. También existen mecanismos como la herencia y el polimorfismo que son unas de las posibilidades más potentes de la POO. La herencia sirve para crear objetos que incorporen propiedades y métodos de otros objetos. Así podremos construir unos objetos a partir de otros sin tener que reescribirlo todo. El polimorfismo sirve para que no tengamos que preocuparnos sobre lo que estamos trabajando, y abstraernos para definir un código que sea compatible con objetos de varios tipos. Son conceptos avanzados que cuesta explicar en las líneas de ese informe. No hay que olvidar que existen libros enteros dedicados a la POO y aquí solo pretendemos dar un repaso a algunas cosas para que os suenen cuando tengáis que poneros delante de ellas en los lenguajes de programación que debe conocer un desarrollador del web.
Técnica de Programación Orientada a Objetos 44
Creación de Clases en JAVA Crear la aplicación con su proyecto, luego elegir crea la Class y saldrá esta ventana.
Para crear una sub clase (hija), deberá de seleccionar
la opción public estarás. Y su estructura quedaría así.
Para crear una clase main (principal), deberá de seleccionar la opción public y generate
Main Method. Y su estructura quedaría así.
Ejemplo 01: mostrar mis datos personales desde una clase Main.
public class ClassEjecutar1 {
public static void main(String[] args) {
//referencia de la clase
ClassEjecutar1 Ejecutar = new ClassEjecutar1();
String nombres="Veronica Ysabel";
String ape="Escobar Runco";
String espe="Computacion e Informatica";
System.out.println("Nombres: "+nombres);
System.out.println("Apellidos: "+ape);
System.out.println("Especialidad: "+espe);
}
}
public class SubClaseHija1 {
//Cuerpo de la Clase Hija
}
public class ClassEjecutar {
//Atributos Globales
//Metdos
public static void main(String[] args) {
//referencia de la clase
ClassEjecutar Ejecutar = new ClassEjecutar();
//atributos Locales
}
}
Técnica de Programación Orientada a Objetos 45
Ejemplo 02: mostrar datos personales ingresado por el usuario desde una clase
Main.
public class ClassEjecutar2 {
public static void main(String[] args) {
//referencia de la clase
ClassEjecutar2 Ejecutar = new ClassEjecutar2();
String nombres=JOptionPane.showInputDialog("Ingresar Nombre");
String ape=JOptionPane.showInputDialog("Ingresar Apellido");
String espe=JOptionPane.showInputDialog("Ingresar Especialidad");
JOptionPane.showMessageDialog(null,"Nombres: "+nombres+"\n"+"Apellidos:"+ape
+"\n" +"Especialidad: "+espe,"Datos Personales",1);
}
}
Usando consola
Usando Message
Técnica de Programación Orientada a Objetos 46
Ejemplo 03: ingresar 2 números y mostrar las 4 operaciones básicas.
public class ClassEjecutar3 {
public static void main(String[] args) {
int num1, num2, sum,res,mul;
double divi;
num1=Integer.parseInt(JOptionPane.showInputDialog("Ingrece el #1"));
num2=Integer.parseInt(JOptionPane.showInputDialog("Ingrece el #2"));
sum=num1+num2;
res=num1-num2;
mul=num1*num2;
divi=num1/num2;
JOptionPane.showMessageDialog(null,"La suma de\t"+num1+"+"+num2+"="+
sum,"Operación de Suma",2);
JOptionPane.showMessageDialog(null,"La resta de\t"+num1+"-"+num2+"="+
res,"Operación de Resta",2);
JOptionPane.showMessageDialog(null,"La multiplicacion de\t"+num1+"*"+num2+"="+
mul,"Operación de Multiplicación",2);
JOptionPane.showMessageDialog(null,"La División de\t"+num1+"/"+num2+"="+
divi,"Operación de División",2);
}
}
Técnica de Programación Orientada a Objetos 47
Aplicando Herencia entre Clases
Ejemplo 01: ingresar 2 números y mostrar las 4 operaciones básicas usando
herencia.
Usando clases
public class SubClaseHija1 {
//Metodos
public int Suma(int a,int b){
return(a+b);
}
public int Resta(int a,int b){
return(a-b);
}
public int Multiplica(int a,int b){
return(a*b);
}
public int divi(int a,int b){
return(a/b);
}
}
---------------------------------------------------------------------------------------
package prjcaso1;
import javax.swing.JOptionPane;
public class ClassEjecutar extends SubClaseHija1 {
//Atributos Globales
public static void main(String[] args) {
//referencia de la clase
ClassEjecutar Ejecutar = new ClassEjecutar();
//atributos Locales
int num1, num2;
num1=Integer.parseInt(JOptionPane.showInputDialog("Ingrece el #1"));
num2=Integer.parseInt(JOptionPane.showInputDialog("Ingrece el #2"));
JOptionPane.showMessageDialog(null,"La suma de\t"+num1+"+"+num2+"="+
Ejecutar.Suma(num1,num2),"Operacion de Suma",2);
JOptionPane.showMessageDialog(null,"La resta de\t"+num1+"-"+num2+"="+
Ejecutar.Resta(num1,num2),"Operacion de Resta",2);
JOptionPane.showMessageDialog(null,"La multiplicacion de\t"+num1+"*"+num2+"="+
Ejecutar.Multiplica(num1,num2),"Operacion de Multiplicación",2);
JOptionPane.showMessageDialog(null,"La División de\t"+num1+"/"+num2+"="+
Ejecutar.divi(num1,num2),"Operacion de División",2);
}
Técnica de Programación Orientada a Objetos 48
}
Usando Referencias
public class SubClaseHija1 {
//Metodos
public int Suma(int a,int b){
return(a+b);
}
public int Resta(int a,int b){
return(a-b);
}
public int Multiplica(int a,int b){
return(a*b);
}
public int divi(int a,int b){
return(a/b);
}
}
_____________________________________________________________
// La clase Main
public class ClassEjecutar {
//Atributis Globales
public static void main(String[] args) {
//referencia del Frame
FrmOperaciones llamar=new FrmOperaciones();
llamar.setVisible(true);
//atributos Locales
}
}
Técnica de Programación Orientada a Objetos 49
Usando formulario para la presentación de la clase
public class SubClaseHija1 {
//Metodos
public int Suma(int a,int b){
return(a+b);
}
public int Resta(int a,int b){
return(a-b);
}
public int Multiplica(int a,int b){
return(a*b);
}
public int divi(int a,int b){
return(a/b);
}
}
//Diseño del Frame
public class FrmOperaciones extends JFrame {
//Referencia de la SubClase
SubClaseHija1 Ejecutar = new SubClaseHija1();
……………
………….
private void btnCalcular_actionPerformed(ActionEvent e) {
int num1, num2;
num1=Integer.parseInt(txta.getText());
num2=Integer.parseInt(txtb.getText());
txtSalida.append("La suma de\t"+num1+"+"+num2+"="+Ejecutar.Suma(num1,num2)+"\n");
txtSalida.append("La resta de\t"+num1+"-"+num2+"="+Ejecutar.Resta(num1,num2)+"\n");
txtSalida.append("La multiplicacion de:
"+num1+"*"+num2+"="+Ejecutar.Multiplica(num1,num2)+"\n");
txtSalida.append("La División de\t"+num1+"/"+num2+"="+Ejecutar.divi(num1,num2)+"\n");
}
}
Técnica de Programación Orientada a Objetos 50
Los constructores
Un objeto de una clase se crea llamando a una función especial denominada constructor de la clase. El constructor se llama de forma automática cuando se crea un objeto, para situarlo en memoria e inicializar los miembros datos declarados en la clase. El constructor tiene el mismo nombre que la clase. Lo específico del constructor es que no tiene tipo de retorno.
public class ClassConstructor {
public ClassConstructor() {
System.out.println("Alumno SISE");
}
public ClassConstructor(String Esp) {
System.out.println("Su Especialidad " + Esp);
}
public ClassConstructor(int Costo) {
System.out.println("El Costo " + Costo + " Soles");
}
public ClassConstructor(int Costo,String Esp) {
double de=0,neto;
if(Esp.equalsIgnoreCase("Sistemas"))
de=0.15*Costo;
if(Esp.equalsIgnoreCase("Contabilidad"))
de=0.10*Costo;
neto=Costo-de;
System.out.println("Descuento " + de);
System.out.println("Neto " + neto );
}
Llamando al constructor desde una clase Main
public static void main(String args[]) {
ClassConstructor Alum1 = new ClassConstructor();
String espe=JOptionPane.showInputDialog("Ingresar Especialidad");
int costo=Integer.parseInt(JOptionPane.showInputDialog("Ingresar Costo"));
ClassConstructor Alum2 = new ClassConstructor(espe);
ClassConstructor Alum3 = new ClassConstructor(costo,espe);
}
}
Técnica de Programación Orientada a Objetos 51
Calificadores: Public, Private, Protected, Static y Final.
El uso de calificadores de acceso en Java tiene sus bases en el uso de librerías
("packages"), al ser diseñado un programa existen diversas funciones/métodos y variables
dentro de éste, algunas de estas requerirán ser modificadas conforme incrementen las
necesidades del programa, mientras otras permanecerán inmóviles, la importancia de estos
cambios requiere que sean utilizados calificadores para permitir/negar el acceso a ciertos
segmentos del programa, analicemos el siguiente caso:
Usted ya diseño 300 clases que están siendo re-utilizadas por otros programas, sin
embargo, se le ha solicitado una modificación radical a estos objetos base, cuales
métodos/campos de estas 300 Clases puede modificar sin quebrantar los otros programas
que hacen uso de estas ? Aquí puede surgir un serio problema sino han sido utilizados los
calificadores de acceso acordemente.
Ahora bien, además de los calificadores de acceso que permiten restringir el uso de
métodos/campos a determinadas situaciones, también existen otros calificadores que
afectan directamente la creación y uso de instancias por clase estos calificadores son static
yfinal.
public : Acceso libre .
El uso del calificador public significa que toda definición será accesible de cualquier punto,
ya sea un método, campo o clase. Su uso implica un acceso global, desde luego el uso de
este calificativo en Clases que serán modificadas constantmente es fuertemente
desalentado, ya que puede quebrantar dependencias forjadas en versiones previas.
private : Solo en la misma Clase .
El calificador private indica que dicho componente será accesible únicamente dentro de la
Clase en cuestión, si se intenta accesar cualquier elemento de este tipo dentro de otra
Clase será generado un error de compilación.
El calificador private suele utilizarse en Clases que serán modificadas continuamente, esto
permite evitar futuros quebrantos en otras Clases como fue mencionado al inicio.
protected : Clases Heredadas y misma Clase.
El uso de protected es utilizado bajo los conceptos de Herencias ("Inheritance"), aunque
este tema será descrito en otra sección, mediante protected es posible accesar elementos
de la Clase Hereditaria ("Inherited"), aunque no aquellos que utilicen el calificador private.
En otras palabras, si determinada Clase hijo hereda ("inherit") el comportamiento de una
Clase padre, la Clase hijo tendrá acceso a todos aquellos campos/métodos definidos como
protected en padre, pero no aquellos declarados como private en padre.
Técnica de Programación Orientada a Objetos 52
Ningún Calificador : Clase en Librería y misma Clase .
Finalmente, cuando no es empleado ninguno de los calificadores de acceso mencionados
anteriormente los elementos son considerados amigables, esto implica que todo
campo/método carente de calificador será accesible dentro de todas Clases pertenecientes
a su misma librería("package").
static : Una sola instancia .
El uso del vocablo static ha venido siendo utilizado en los métodos principales (main) de los
programas escritos anteriormente, su uso esta relacionado directamente al uso de
instancias en Clases; en ocasiones es necesario o conveniente generar elementos que
tomen un mismo valor para cualquier número de instancias generadas o bien
invocar/llamar métodos sin la necesidad de generar instancias, y es bajo estas dos
circunstancias que es empleado el calificador static.
El primer uso de static puede ser poco evidente, pero tomemos el caso de la Clase
mencionada al inicio de este curso de una Lampara, en caso de requerirse un elemento
como un apagador pudiera resultar sobrado generar una instancia para cada Lampara, en
este caso pudiera ser restringido un apagador a una sola instancia mediante el calificador
static permitiendo que dicho elemento sea utilizado por todas las instancias de Lampara ahí
generadas; desde luego la descripción anterior esta trivializada, sin embargo, conforme se
avance en el presente curso serán ilustrados otros ejemplos con este mecanismo.
La segunda situación para el uso de static puede ser ejemplificada perfectamente a través
del método main Java, el método main puede ser llamado automáticamente al invocarse la
respectiva Clase debido a que no se encuentra asociado con ningún tipo de instancia, esto
implica que su comportamiento siempre será el mismo independientemente de la instancia
que realza su llamada.
Dos aspectos característicos de utilizar el calificador static en un elemento Java son los
siguientes :
No puede ser generada ninguna instancia (Uso de new) de un elemento static puesto que
solo existe una instancia.
Todos los elementos definidos dentro de una estructura static deben ser static ellos mismos
, o bien, poseer una instancia ya definida para poder ser invocados.
NOTA: Lo anterior no implica que no puedan ser generadas instancias dentro de un
elemento static; no es lo mismo llamar/invocar que crear/generar.
La teoría del concepto static puede ser un poco difícil de digerir, sin embargo, como fue
mencionado anteriormente, conforme avance el curso serán descritos diversos fragmentos
de código para dejar en claro su uso.
Técnica de Programación Orientada a Objetos 53
final : Una sola instancia y definitiva.
El calificador final estrechamente relacionado con el uso de static implica una asignación
única y definitiva al elemento de una clase. A diferencia de static que implica una sola
instancia, el termino final lleva dicha instancia a una definición única y como su nombre lo
implica final.
Generalmente final es utilizado en aquellos elementos que no serán modificados al
momento de ejecutarse ("Run-Time") un programa o clase , a través de final se asigna un
valor que no podrá ser modificado bajo ninguna circunstancia al momento de ejecución
("Run-Time), en efecto logrando un nivel de eficiencia en ejecución.
De igual manera que la utilización de static el uso de final será ilustrado conforme se
avanze en este curso.
Atributo Static
El atributo static, que se puede utilizar con propiedades declaradas con las palabras clave var,
const o function, permite asociar una propiedad a la clase en lugar de asociarla a instancias de
la clase. El código externo a la clase debe llamar a propiedades estáticas utilizando el nombre
de la clase en lugar de un nombre de instancia. Las subclases no heredan las propiedades
estáticas, pero las propiedades forman parte de una cadena de ámbitos de subclase. Esto
significa que en el cuerpo de una subclase se puede utilizar una variable o un método estático
sin hacer referencia a la clase en la que se definió.
Técnica de Programación Orientada a Objetos 54
Interfaces
El concepto de Interface lleva un paso más adelante la idea de las clases abstractas. En Java una interface es una clase abstracta pura, es decir una clase donde todos los métodos son abstractos (no se implementa ninguno). Permite al diseñador de clases establecer la forma de una clase (nombres de métodos, listas de argumentos y tipos de retorno, pero no bloques de código). Una interface puede también contener datos miembro, pero estos son siempre static y final. Una interface sirve para establecer un 'protocolo' entre clases.
Para crear una interface, se utiliza la palabra clave interface en lugar de class. La interface puede definirse public o sin modificador de acceso, y tiene el mismo significado que para las clases. Todos los métodos que declara una interface son siempre public.
Para indicar que una clase implementa los métodos de una interface se utiliza la palabra clave implements. El compilador se encargará de verificar que la clase efectivamente declare e implemente todos los métodos de la interface. Una clase puede implementar más de una
interface.
Declaración y uso
Una interface se declara:
interface nombre_interface { tipo_retorno nombre_metodo ( lista_argumentos ) ; . . . }
Como Crear la Interface:
Crear una Aplicación Normal (La Clase y los Frame) Luego inserte una interface de la siguiente manera, presionando click derecho sobre el
proyecto y seleccionar General y Java Interface
Técnica de Programación Orientada a Objetos 55
Por ejemplo:
public interface IntEjemplo01 { void Ejemplo1(); void Ejemplo2 (); void Ejemplo3 (); String mensaje1(); String mensaje2(); }
Y una clase que implementa la interface:
Presione Alt Enter para validar la implementación y luego presione en el foquito para que pueda jalar los métodos de la interface quedando de la siguiente manera.
Técnica de Programación Orientada a Objetos 56
Referencias a Interfaces
Es posible crear referencias a interfaces, pero las interfaces no pueden ser instanciadas. Una referencia a una interface puede ser asignada a cualquier objeto que implemente la interface. Por ejemplo:
Llamando a los métodos
Extensión de interfaces
Las interfaces pueden extender otras interfaces y, a diferencia de las clases, una interface puede extender más de una interface. La sintaxis es:
interface nombre_interface extends nombre_interface , . . . { tipo_retorno nombre_metodo ( lista_argumentos ) ; . . . }
ClassImplementa usoInterface=new ClassImplementa();
int v1=Integer.parseInt(txtv1.getText());
int v2=Integer.parseInt(txtv2.getText());
txtsalida.append("Método que calcula la suma de los 2 numeros:"+ usoInterface.Ejemplo1(v1,v2)+ "\n");
txtsalida.append("Método que calcula la división de los 2 numeros:"+ usoInterface.Ejemplo2(v1,v2)+"\n");
txtsalida.append("Método que calcula la multiplica de los 2 numeros:"+ usoInterface.Ejemplo3(v1,v2)+"\n");
txtsalida.append("Brinda el mensaje que es el nombre de nuestra institurción:"+ usoInterface.mensaje1()+"\n");
txtsalida.append("Brinda el mensaje de años de fundación :"+ usoInterface.mensaje2()+"\n");
Técnica de Programación Orientada a Objetos 57
Los paquetes
Los paquetes son una forma de organizar grupos de clases. Un paquete contiene un conjunto de clases relacionadas bien por finalidad, por ámbito o por herencia.
Los paquetes resuelven el problema del conflicto entre los nombres de las clases. Al crecer el número de clases crece la probabilidad de designar con el mismo nombre a dos clases diferentes.
Las clases tienen ciertos privilegios de acceso a los miembros dato y a las funciones miembro de otras clases dentro de un mismo paquete.
En el Entorno Integrado de Desarrollo (IDE) JBuilder de Borland, un proyecto nuevo se crea en un subdirectorio que tiene el nombre del proyecto. A continuación, se crea la aplicación, un archivo .java que contiene el código de una clase cuyo nombre es el mismo que el del archivo. Se pueden agregar nuevas clases al proyecto, todas ellas contenidas en archivos .java situadas en el mismo subdirectorio. La primera sentencia que encontramos en el código fuente de las distintas clases que forman el proyecto es package o del nombre del paquete.
La palabra reservada import
Para importar clases de un paquete se usa el comando import. Se puede importar una clase individual
import java.awt.Font;
o bien, se puede importar las clases declaradas públicas de un paquete completo, utilizando un arterisco (*) para reemplazar los nombres de clase individuales.
import java.awt.*;
Realicemos esta estructura creando los paquetes correspondientes
Técnica de Programación Orientada a Objetos 58
Herencia
La herencia es uno de los conceptos más cruciales en la POO. La herencia básicamente consiste en que una clase puede heredar sus variables y métodos a varias subclases (la clase que hereda es llamada superclase o clase padre). Esto significa que una subclase, aparte de los atributos y métodos propios, tiene incorporados los atributos y métodos heredados de la superclase. De esta manera se crea una jerarquía de herencia.
Por ejemplo, imaginemos que estamos haciendo el análisis de un Sistema para una tienda
que vende y repara equipos celulares.
En general, podemos tener una gran jerarquía de Clases tal y como vemos en el siguiente gráfico:
Técnica de Programación Orientada a Objetos 59
Ejemplos:
Se puede heredar clases propias de Java como por ejemplo:
public class FrmDiseño extends JFrame
public panel pnlDatos extends JPanel
para cada herencia pedira una importacion como por ejemplo
import javax.swing.JFrame;
import javax.swing.JPanel;
y otras propias del usuario.
public class ClassEJemplo1 extedns subClase01
public class ClassEJemplo1 extedns subClase02
Ejemplo:
Empleemos esta estructura de paquetes para poder realizar la siguiente
aplicación:
Usara interface ya realizada anteriormente, la clase main para llamar al
frame y una subclase que se usara como herencia y poder ser llamada en
el frame mediante la interface.
Técnica de Programación Orientada a Objetos 60
Es la subclase: solo tiene un método que emite un mensaje
Otra subclase: que permita implementar el contenido por cada método
que se estableció en la interface
Frame: permitirá establecer la referencia a la clase que implementa la
interface y la herencia.
Herencia
Técnica de Programación Orientada a Objetos 61
ENCAPSULAMIENTO
El encapsulamiento es la característica de autonomía de la OO. Esta característica permite
generar componentes autónomos de software tomando una parte de funcionalidad y ocultando
los detalles de la implementación al mundo exterior.
Los términos módulo, componente o bean se suelen utilizan en lugar de “componente
encapsulado de software”.
Una vez encapsulada, una entidad de software se puede visualizar como una caja negra.
Ejemplo:
Declare los atributos que desea encapsular:
Luego presione click derecho
sobre los atributos y elija
REFACTOR luego
ENCAPSULATE FIELDS
Luego presentara esta ventana
donde tendrá que seleccionar
todos los atributos que estarán
encapsulados
Técnica de Programación Orientada a Objetos 62
Luego se crearan los get y set por cada atributo.
Técnica de Programación Orientada a Objetos 63
Sobrecarga
En programación orientada a objetos la sobrecarga se refiere a la posibilidad de tener dos o más funciones con el mismo nombre pero funcionalidad diferente. Es decir, dos o más funciones con el mismo nombre realizan acciones diferentes. El compilador usará una u otra dependiendo de los parámetros usados. A esto se llama también sobrecarga de funciones.
También existe la sobrecarga de operadores que al igual que con la sobrecarga de funciones se le da más de una implementación a un operador.
Sobrecarga es la capacidad de un lenguaje de programación, que permite nombrar con el mismo identificador diferentes variables u operaciones
El mismo método dentro de una clase permite hacer cosas distintas en función de los parámetros
Java no permite al programador implementar sus propios operadores sobrecargados, pero sí utilizar los predefinidos como el + del ejemplo anterior. • C++, por el contrario si permite hacerlo.
Sobrecarga de Métodos y de Constructores La firma de un método es la combinación del tipo de dato que regresa, su nombre y su lista de argumentos. La sobrecarga de métodos es la creación de varios métodos con el mismo nombre pero con diferentes firmas y definiciones. Java utiliza el número y tipo de argumentos para seleccionar cuál definición de método ejecutar. Java diferencia los métodos sobrecargados con base en el número y tipo de argumentos que tiene el método y no por el tipo que devuelve. También existe la sobrecarga de constructores: Cuando en una clase existen constructores múltiples, se dice que hay sobrecarga de constructores.
Algunos métodos en una clase pueden tener el mismo nombre. Estos métodos deben contar con diferentes argumentos. El compilador decide qué método invocar comparando los argumentos. Se generara un error si los métodos sólo varían en el tipo de retorno.
Técnica de Programación Orientada a Objetos 64
Ejemplos
Caso 01
Crear una sobrecarga que permita sumar 2 números y será llamado de acuerdo al tipo
de dato que se le envie.
public class ClassSobreCalculos { public int Totales(int a,int b){ return(a+b); } public double Totales(double a, double b){ return(a+b); } public long Totales(long a, long b){ return(a+b); } }
Caso 02
Crear una sobrecarga de métodos donde permita hallar el sueldo, descuento y el neto. El sueldo dependerá del costo y cantidad de horas El descuento según el estado de Honorarios o Planilla Neto según el sueldo y el descuento. package pckLogico; public class ClassSobre { public double Calcular(int ch,int costo){ return(ch*costo); }
public double Calcular(int sueld, String estado){
double de=0; if(estado.equalsIgnoreCase("Planilla")) de=0.12*sueld; if(estado.equalsIgnoreCase("Honorarios")) de=0.07*sueld; return(de); }
public double Calcular(int sueld,double de){
return(sueld-de); } } Package pckLogico; public class ClassEncapsular {
Técnica de Programación Orientada a Objetos 65
int sueldo,costo,ch; double desc,neto; String estado; public int getSueldo() { return sueldo; } public void setSueldo(int sueldo) { this.sueldo = sueldo; } public int getCosto() { return costo; } public void setCosto(int costo) { this.costo = costo; } public int getCh() { return ch; } public void setCh(int ch) { this.ch = ch; } public double getDesc() { return desc; } public void setDesc(double desc) { this.desc = desc; } public double getNeto() { return neto; } public void setNeto(double neto) { this.neto = neto; } public String getEstado() { return estado; } public void setEstado(String estado) { this.estado = estado; } }
Llamando las clases Encapsulada y sobrecarga en el JFRAME package pclPrincipal;
public class FrmDatos extends JFrame { ClassSobre metodos=new ClassSobre(); ClassEncapsular atri=new ClassEncapsular(); private void btnAceptar_actionPerformed(ActionEvent e) { atri.setCh(Integer.parseInt(txtch.getText())); atri.setCosto(Integer.parseInt(txtcosto.getText())); atri.setSueldo(metodos.Calcular(atri.getCh(),atri.getCosto())); lblSuel.setText(""+atri.getSueldo()); atri.setDesc(metodos.Calcular(atri.getSueldo(),atri.getEstado())); atri.setNeto(metodos.Calcular(atri.getSueldo(),atri.getDesc())) ; lblDes.setText(""+atri.getDesc()); lblN.setText(""+atri.getNeto()); Object valores[]={c,atri.getCh(),atri.getCosto(),atri.getSueldo(),atri.getDesc(),atri.getEstado(), atri.getNeto()}; ModDatos.addRow(valores); ++c; // contador de registros } private void rbtPla_actionPerformed(ActionEvent e) { atri.setEstado("Planilla"); } private void rbtHo_actionPerformed(ActionEvent e) { atri.setEstado("Honorarios"); } }
Técnica de Programación Orientada a Objetos 66
Caso 03
Crear una sobrecarga de métodos donde permita hallar el sueldo, descuento y el neto. El sueldo dependerá del costo y cantidad de horas El descuento será del 10% si el sueldo supera a los 1500 Neto según el sueldo y el descuento.
public class ClassMetodos extends ClassEncapsular{
public int pago(int ch,int cst){
return(ch*cst);
}
public double pago(int sueldo){
double d=0;
if(sueldo>1500)
d=0.10*sueldo;
return(d);
}
public double pago(int sueldo,double dsct){
return(sueldo-dsct);
}
}
//Campos encapsulado public class ClassEncapsular {
int c,cs,suel;
double np,des;
public int getC() {
return c;
}
public void setC(int c) {
this.c = c;
}
public int getCs() {
return cs;
}
public void setCs(int cs) {
this.cs = cs;
}
public int getSuel() {
return suel;
}
public void setSuel(int suel) {
this.suel = suel;
}
public double getNp() {
return np;
}
public void setNp(double np) {
this.np = np;
}
public double getDes() {
return des;
Técnica de Programación Orientada a Objetos 67
}
public void setDes(double des) {
this.des = des;
}
}
// Frame: public class FrmVentana extends JFrame {
Class1 x = new Class1();
*****
public FrmVentana() {
try {
jbInit();
} catch (Exception e) {
e.printStackTrace();
}
}
private void jbInit() throws Exception {
*******
******
******
}
private void btnCalcular_actionPerformed(ActionEvent e) {
x.setC(Integer.parseInt(txtch.getText()));
x.setCs(Integer.parseInt(txtcst.getText()));
x.setSuel(x.pago(x.getC(),x.getCs()));
x.setDes(x.pago(x.getSuel()));
x.setNp(x.pago(x.getSuel(),x.getDes()));
lblSueldo.setText(""+x.getSuel());
lblDesc.setText(""+x.getDes());
lblnp.setText(""+x.getNp());
}
private void btnLlamar_actionPerformed(ActionEvent e) {
FrmResultados j=new FrmResultados();
j.setVisible(true);
j.lblr.setText(""+x.getNp());
}
}
// Clase Main public class Class1 extends ClassMetodos{
public static void main(String[] args) {
FrmVentana ven=new FrmVentana();
ven.setVisible(true);
}
Técnica de Programación Orientada a Objetos 68
}
Caso 04
Crear una sobrecarga de métodos donde permita hallar el precio, total, igv y el neto. Según el articulo saldrá el precio. El total será deacuerdo a la cantidad y precio y el neto será deacuero al total y a la selección del Igv.
// Clase encapsulada package pckLogico;
public class ClassEncapsular {
int precio,cantidad;
double total,igv;
String articulo;
public int getPrecio() {
Técnica de Programación Orientada a Objetos 69
return precio;
}
public void setPrecio(int precio) {
this.precio = precio;
}
public int getCantidad() {
return cantidad;
}
public void setCantidad(int cantidad) {
this.cantidad = cantidad;
}
public String getArticulo() {
return articulo;
}
public void setArticulo(String articulo) {
this.articulo = articulo;
}
public double getTotal() {
return total;
}
public void setTotal(double total) {
this.total = total;
}
public double getIgv() {
return igv;
}
public void setIgv(double igv) {
this.igv = igv;
}
}
// clase sobrecarga package pckLogico;
public class ClassSobreCarga {
public int Calcular(String articulo){
int pre = 0;
if(articulo.equalsIgnoreCase("Monitor"))
pre=259;
if(articulo.equalsIgnoreCase("Teclado"))
pre=15;
if(articulo.equalsIgnoreCase("Memorias"))
pre=175;
if(articulo.equalsIgnoreCase("Case"))
Técnica de Programación Orientada a Objetos 70
pre=550;
if(articulo.equalsIgnoreCase("Lectora"))
pre=25;
return(pre);
}
public double Calcular(int cantidad, int precio){
return(cantidad*precio);
}
public double calcular(double total){
return(total*0.19);
}
public double calcular(double total,double igv){
return(total+igv);
}
}
//Frame public class FrmDatos extends JFrame {
ClassEncapsular atributo = new ClassEncapsular();
ClassSobreCarga metodos = new ClassSobreCarga();
String Titulos[]={"registro","articulo","precio","cantidad","total"};
String valores[][]={};
int c=1;
*************
***************
private void jbInit() throws Exception {
*********************
*********************
*********************
cboArticulo.addItem("Seleccionar");
cboArticulo.addItem("Monitor");
cboArticulo.addItem("Teclado");
cboArticulo.addItem("Memorias");
cboArticulo.addItem("Case");
cboArticulo.addItem("Lectora");
}
private void cboArticulo_actionPerformed(ActionEvent e) {
lblTotal.setText("");
txtCantidad.setText("");
atributo.setArticulo(cboArticulo.getSelectedItem().toString());
lblPrecio.setText(""+metodos.Calcular(atributo.getArticulo()));
atributo.setPrecio(metodos.Calcular(atributo.getArticulo()));
lblPrecio.setText(""+atributo.getPrecio());
}
private void btnAgregar_actionPerformed(ActionEvent e) {
atributo.setCantidad(Integer.parseInt(txtCantidad.getText()));
atributo.setPrecio(atributo.getPrecio());
atributo.setTotal(metodos.Calcular(atributo.getCantidad(),atributo.getPrecio()));
lblTotal.setText(""+atributo.getTotal());
Técnica de Programación Orientada a Objetos 71
if(chkIGV.isSelected())
atributo.setIgv(metodos.calcular(atributo.getTotal()));
else
atributo.setIgv(0);
lblIGV.setText(""+atributo.getIgv());
lblneto.setText(""+metodos.calcular(atributo.getTotal(),atributo.getIgv()));
Object
valores[]={c,atributo.getArticulo(),atributo.getPrecio(),atributo.getCantidad(),atributo.getTotal()};
ModDatos.addRow(valores);
++c;
}
private void btnLimpiar_actionPerformed(ActionEvent e) {
txtCantidad.setText("");
cboArticulo.setSelectedIndex(0);
lblIGV.setText("");
lblneto.setText("");
lblPrecio.setText("");
lblTotal.setText("");
}
}
Técnica de Programación Orientada a Objetos 72
Contenidos
- Manejo de Paneles(JPanel) - Clase GregorianCalendar - Clase String: Uso de la Clase String String.valueOf(), length(), charAt(), toString(),
substring(), indexOf(), lastIndexOf(), equalsIgnoreCase(), compareTo(), - Uso de la Clase String: concat(), replace(), toLowerCase(), toUperCase().
____________________________________________________________________________
PANEL Construir directamente programas o aplicaciones directamente en un FRAME, produce rápidamente un amontonamiento de controles o componentes en la propia forma. Es más conveniente usar componentes de agrupamiento visuales que faciliten la separación física y lógica de las diversas partes que componen un programa o aplicación. Estos controles de agrupamiento son conocidos como paneles, aunque en visual basic se conocen como frames (no confundirlos con frame de java). Java tiene los siguientes tipos de paneles, PANEL, SPLITPANE, SCROLLPANE, TABBEDPANE, TOOLBAR. Recordar además que los panels pueden y deben usar su propio layout para acomodar los componentes visuales que contendrá. En particular frame usando su layout acomoda sus paneles y panel usando su layout acomoda los componentes.
El panel es un área de Java Desktop System en la que se pueden ejecutar aplicaciones y realizar otras tareas.
La clase Panel es el más simple de los Contenedores de Componentes gráficos. En realidad, se trataba de crear una clase no-abstracta (Container sí lo es) que sirviera de base a los applet y a otras pequeñas aplicaciones. La clase Panel consta de dos métodos propios: el constructor, cuyo fin es crear un nuevo Panel con un LayoutManager de tipo FlowLayout (el de defecto), y el método addNotify() que, sobrecargando la función del mismo nombre en la clase Container, llama al método createPanel() del Toolkit adecuado, creando así un PanelPeer. El AWT enviará así al Panel (y por tanto al applet) todos los eventos que sobre él ocurran. Esto que
Técnica de Programación Orientada a Objetos 73
puede parecer un poco rebuscado, obedece al esquema arquitectónico del AWT; se trata del bien conocido esquema de separación interface/implementación que establece por un lado una clase de interface y por otras distintas clases de implementación para cada una de las plataformas elegidas.
Técnica de Programación Orientada a Objetos 74
GregorianCalendar
Según la documentación del API de java, la clase Calendar es una clase abstracta base para convertir entre un objeto de tipo Date (java.util.Date) y un conjunto de campos enteros como YEAR (año), MONTH (mes), DAY (día), HOUR (hora), etc.
Una subclase de Calendar representa una fecha de acuerdo a las reglas de un calendario específico. La plataforma provee una subclase concreta de Calendar: GregorianCalendar. Futuras subclases podrían representar varios tipos de calendarios lunares usados en diferentes lugares del mundo.
La clase Calendar tiene mucho del comportamiento que esperaríamos de la clase java.util.Date, es decir, cuando obtenemos una instancia de la clase Calendar obtenemos un instante de tiempo específico con gran precisión similar a lo que obtenemos con la clase date. Sí es cierto, podemos decir aquí que los milisegundos juegan un papel fundamental en esta clase; pero el verdadero sentido de la clase Calendar no es obtener un instante de tiempo sino extraerle datos. Recordemos que la clase java.util.Date tiene métodos que permiten obtener el año, mes y día, pero estos métodos están obsoletos precisamente por que para eso existe Calendar y de hecho cuando usamos el método getYear() de la clase java.util.Date esta recurre a las funcionalidades que posee la clase Calendar.
Hay que mencionar también que obtener un instante de tiempo específico y diferente del actual es supremamente sencillo con esta clase, indicándole simplemente el día, mes y año con que se desea trabajar, o se puede especificar aún más dando hora, minuto y segundo deseado. Veamos: El método getInstance() de la clase nos devuelve una subclase de Calendar con el tiempo ajustado a la hora actual, y usamos el método set(args…) para forzarlo a tomar la fecha deseada:
Calendar ahoraCal = Calendar.getInstance(); System.out.println(ahoraCal.getClass()); ahoraCal.set(2004,1,7); System.out.println(ahoraCal.getTime()); ahoraCal.set(2004,1,7,7,0,0); System.out.println(ahoraCal.getTime());
Extraer los datos La clase Calendar tiene un único método get para obtener todos sus datos para lo cual se ayuda de una serie de atributos constantes que permiten obtener o ajustar un atributo determinado de la fecha; los más importantes son (al lado los valores que representan): YEAR: Año. MONTH: Mes. DATE, DAY_OF_MONTH: Día del mes. DAY_OF_WEEK: Día de la semana entre 1 (MONDAY) y 7 (SATURDAY). HOUR: Hora antes o después del medio día (en intervalos de 12 horas). HOUR_OF_DAY: Lo hora absoluta del día (en intervalos de 24 horas). MINUTE: El minuto dentro de la hora. SECOND: El segundo dentro del minuto.
Están también los atributos que representan los meses, como: JANUARY, MARCH, JUNE, DECEMBER, etc. que van desde 0 (JANUARY) hasta 11 (DECEMBER).
Técnica de Programación Orientada a Objetos 75
También hay atributos que representan los días: SUNDAY, TUESDAY, SATURDAY, etc. estos empiezan con 1 (SUNDAY) y van hasta 7 (SATURDAY).
Hay más atributos pero con estos es suficiente para los objetivos de este artículo, si deseas conocerlos todos recurre a la documentación del lenguaje.
Para extraer algún atributo se usa el método get pasándole como parámetro alguna de las constantes que vimos anteriormente y el método devuelve siempre un dato de tipo int; así para obtener el año, mes, día y hora, usaríamos el siguiente código:
System.out.println("ANYO: "+ahoraCal.get(Calendar.YEAR)); System.out.println("MES: "+ahoraCal.get(Calendar.MONTH)); System.out.println("DIA: "+ahoraCal.get(Calendar.DATE)); System.out.println("HORA: "+ahoraCal.get(Calendar.HOUR)); if (ahoraCal.get(Calendar.MONTH) == Calendar.JUNE){ System.out.println("ES JUNIO"); }else{ System.out.println("NO ES JUNIO"); }
Si el objeto tiene la fecha equivalente a 5:30 p.m. del 22 de junio de 2004 se ve la siguiente salida:
AÑO:2010 MES:Mayo DIA:02 HORA:5 ES JUNIO
Modificar Un Atributo
Modificar un atributo de Calendar es tan sencillo como obtenerlo, solamente es necesario usar el método set(int atributo, int valor), en donde atributo es una de las constante mencionadas anteriormente y valor es la cantidad que se le quiere asignar. Por ejemplo: ahoraCal.set(Calendar.MONTH,Calendar.JANUARY) o ahoraCal.set(Calendar.YEAR, 1980) ajustarían la fecha almacenada en el objeto ahoraCal a enero o al año 1980 sin modificar ninguno de los otros atributos.
Aclaremos esto con un ejemplo. Mi cumpleaños es en octubre 27 :-), y deseo saber qué día lo celebraré en el 2010; para eso obtengo una instancia de Calendar (que siempre devuelve un objeto del tipo GregorianCalendar) y la ajusto hasta el 27 de octubre de 2010, luego obtengo el nombre del día, veamos:
Calendar cumpleCal = Calendar.getInstance(); cumpleCal.set(2010,9,27); //La hora no me interesa y recuerda que los meses van de 0 a 11 int dia = cumpleCal.get(Calendar.DAY_OF_WEEK); System.out.println(dia); //Día 4 = WEDNESDAY = MIÉRCOLES
La salida es: 4, lo que quiere decir que en el 2010 el 27 de octubre será un día miércoles (así que probablemente lo celebre el viernes 29 :-));
Técnica de Programación Orientada a Objetos 76
Clase GregorianCalendar y operaciones
Realizar operaciones como sumar o restar días no es algo que dependa directamente de Calendar sino más bien de una subclase de esta que implemente algún tipo de calendario usado, pues no todos los calendarios tienen 12 meses ni años de 365 días como el que nosotros (en casi todo occidente) usamos.
Este calendario usado en occidente, llamado gregoriano fue adoptado por primera vez en 1582 por el imperio romano (o aproximadamente) y posteriormente se fue adoptando en muchos otros países, por ejemplo 1752 en Gran Bretaña y 1918 en Rusia.
A grandes rasgos sabemos que el calendario gregoriano consta de años que son definidos por cada traslación (vuelta de la tierra alrededor del sol), cada año tiene doce meses de los cuales 7 tienen 31 días, 4 tienen 30 días y 1 tiene 28 días excepto en años bisiestos que tiene 29. Estos años bisiestos se implantaron para corregir el desfase que tenemos cada cuatro años (un año real dura 365 días y 6 horas aproximadamente), regla completa para los años bisiestos según el calendario gregoriano es la siguiente:
"Un año es bisiesto si es divisible por 4, a menos que sea divisible por 100 y no por 400".
Todo esto quizá suene un poco tonto, pero es absolutamente necesario tenerlo claro para entender el funcionamiento de la clase GregorianCalendar.
GregorianCalendar es una subclase de Calendar y es la implementación directa del calendario gregoriano (de hecho es la única implementación de un calendario en jdk1.4) tal y como lo conocemos hoy día. Es con esta clase con la que podemos sumar 2 ó 3 días a una fecha sin preocuparnos por desbordamientos o recalcular meses o años, pues ella lo hace automáticamente tomando en cuenta las reglas en los párrafos anteriores. De igual forma podemos obtener información como el día de la semana o la semana del año que fue una fecha determinada.
Los métodos roll() y add()
Anteriormente vimos los métodos set() y get() de la clase Calendar para obtener fechas y los datos de esas fechas, ahora veremos los métodos add() y roll() que nos permiten avanzar un tiempo exacto sobre los datos obtenidos anteriormente.
El método add(CONSTATE, valor) suma algebraicamente valor a una fecha; el valor a sumar asume el significado dado por CONSTANTE, que es una de las definidas para la clase y que se mencionaron en la sección anterior (MONTH, YEAR, SECOND, etc).
Por ejemplo agreguemos 3 días y 2 meses a la fecha actual:
Calendar hoy = Calendar.getInstance(); hoy.add(Calendar.DATE, 3); hoy.add(Calendar.MONTH, 2); System.out.println(hoy.getTime());
Ahora restemos 5 años y 50 días (Prúebalo en tu PC):
Calendar hoy = Calendar.getInstance();
Técnica de Programación Orientada a Objetos 77
hoy.add(Calendar.YEAR, -5); hoy.add(Calendar.DATE, -50); System.out.println(hoy.getTime());
Técnica de Programación Orientada a Objetos 78
Clase String
Java posee gran capacidad para el manejo de cadenas dentro de sus clases String y StringBuffer. Un objeto String representa una cadena alfanumérica de un valor constante que no puede ser cambiada después de haber sido creada. Un objeto StringBuffer representa una cadena cuyo tamaño puede variar.
Los Strings son objetos constantes y por lo tanto muy baratos para el sistema. La mayoría de las funciones relacionadas con cadenas esperan valores String como argumentos y devuelven valores String.
Hay que tener en cuenta que las funciones estáticas no consumen memoria del objeto, con lo cual es más conveniente usar Character que char. No obstante, char se usa, por ejemplo, para leer ficheros que están escritos desde otro lenguaje.
MÉTODOS PRINCIPALES:
Para poder aplicar estos métodos es necesario crear un objeto String. Además de estos métodos, la clase String cuenta con otros muchos.
int length(): devuelve la longitud de la String, incluyendo espacios en blanco. La longitud siempre es una unidad mayor que el índice asociado al último carácter de la String.
Ejemplo:
int indexOf(String str, int indice): devuelve el índice en el que aparece por primera vez la String del primer argumento en la que se aplica el método, a partir del índice especificado en el segundo argumento. Recordar que una String está indexada. Si el índice a partir del que se inicia la búsqueda no existe o la String no aparece, devuelve -1. MUY USADO.
Ejemplo:
int indexOf(char ch): devuelve el índice en el que aparece por primera vez el carácter que se le pasa al argumento. Si no se encuentra el carácter devuelve -1. Se observa que el nombre de este método es igual al anterior aunque su número de argumentos es distinto además de su tipo. A esto, en Java, se le llama sobrecarga de métodos: mismo nombre pero distinto nº de argumentos o distinto tipo de argumentos o distinto orden. Ir a la API para
String s=”SISE tiene 27 años…..!”;
int longitud=str.length();
String s=”Sebastian Aquino”; Cad=s.indexOf(“t”,s.length());
Técnica de Programación Orientada a Objetos 79
comprobar que hay más con este mismo nombre. Este concepto se tratará más en profundidad en temas posteriores.
String replace (char viejoChar, char nuevoChar): cambia el carácter asociado al primer argumento por el que se le pasa al segundo, de la String sobre la que se aplica el método generando una nueva. La String sobre la que se aplica el método no cambia, simplemente se crea otra nueva en base a la String sobre la que se aplica el método.
Ejemplo:
String toLowerCase(): devuelve una nueva String convirtiendo todos los caracteres de la String sobre la que se aplica el método, en minúsculas.
String toUpperCase(): devuelve una nueva String convirtiendo todos los caracteres de la String sobre la que se aplica el método, en mayúsculas.
boolean equals(String str): investiga si dos String tienen los mismos caracteres y en el mismo orden. Si es así devuelve true y si no false. MUY USADO
boolean equalsIgnoreCase(String str): investiga si dos String tienen los mismos caracteres y en el mismo orden sin tener en cuenta las mayúsculas. Si es así devuelve true y si no false. MUY USADO
boolean startsWith(String str): devuelve true si la String sobre la que se aplica comienza por la del argumento; false si esto no ocurre.
boolean startsWith(String str, int indice): devuelve true si la String sobre la que se aplica comienza por la del argumento a partir de un determinado índice asociado al segundo argumento; false si esto no ocurre.
String s1=”Angie”; Cad=s.replace(„e‟,‟E‟);
String s=”william”;
JOptionPane.showMessageDialog(null,s.toUpperCase());
String s=”Laboratorios SIse ”; Cad=s.indexOf(„S‟);
String s=”SEBASTIAN”;
JOptionPane.showMessageDialog(null,s.toLowerCase());
Técnica de Programación Orientada a Objetos 80
boolean endsWith(String str): devuelve true si la String sobre la que se aplica acaba en la del argumento; false si esto no ocurre.
String trim(): devuelve una String en base a la que se le pasa al argumento, pero sin espacios en blanco al principio ni al final. No elimina los espacios en blanco situados entre las palabras.
Ejemplo:
String substring(int indiceIni, int indiceFin): devuelve una String obtenida a partir del índice inicial incluido y del índice final excluido; es decir, se comporta como un intervalo semiabierto [indiceIni, indiceFin). Si el índice final sobrepasa la longitud de la String, lanza una IndexOutOfBoundsException. MUY USADO.
Ejemplo:
char charAt (int indice): devuelve el carácter asociado al índice que se le pasa como argumento de la String sobre la que se aplica el método. Si el índice no existe se lanza una StringIndexOutOfBoundsException que hereda de IndexOutOfBoundsException. MUY USADO.
String s=” Hola William ”; //primero visualicemos la longitud Int l=s.length(); JOptionPane.showMessageDialog(null,I) //quitemos el espacio en blanco Cad=s.trim(); //vuelve a mostrar la longitud Int l=s.length(); JOptionPane.showMessageDialog(null,I)
String s=”Docentes de Programacion”;
Cad=s.substring(4,9);
Técnica de Programación Orientada a Objetos 81
Contenidos
- Clase String: Definición de Archivos - Archivos de Textos: Lectura / Escritura. - Aplicar la capa de Datos con Manejo de Archivos. - Manejo de Excepciones y try … catch, - Manejo de las clases BufferedReader, BufferedWriter, PrintWriter, FileReader,
readLine, StringTokenizer, nextToken. - Apertura de Archivos, Grabar Datos a un archivo.
____________________________________________________________________________
Definición de ARCHIVOS.
Los archivos también denominados ficheros (file); es una colección de información (datos relacionados entre sí), localizada o almacenada como una unidad en alguna parte de la computadora.
Los archivos son el conjunto organizado de informaciones del mismo tipo, que pueden utilizarse en un mismo tratamiento; como soporte material de estas informaciones.
Introducción a los archivos.
Los archivos como colección de datos sirve para la entrada y salida a la computadora y son manejados con programas.
Los archivos pueden ser contrastados con Arrays y registros; Lo que resulta dinámico y por esto en un registro se deben especificar los campos, él número de elementos de un arrays (o arreglo), el número de caracteres en una cadena; por esto se denotan como "Estructuras Estáticas".
En los archivos no se requiere de un tamaño predeterminado; esto significa que se pueden hacer archivos de datos más grandes o pequeños, según se necesiten.
Técnica de Programación Orientada a Objetos 82
Cada archivo es referenciado por su identificador (su nombre).
Características de los Archivos
Independencia de las informaciones respecto de los programas
La información almacenada es permanente
Un archivo puede ser accedido por distintos programas en distintos momentos
Gran capacidad de almacenamiento.
Clasificación de los Archivos
Los archivos se clasifican según su uso en tres grupos:
Permanentes o Maestros:
Estos contienen información que varia poco. En algunos casos es preciso actualizarlos periódicamente.
De Movimientos
Se cercan para actualizar los archivos maestros. Sus registros son de tres tipos: alta, bajas y modificaciones.
De Maniobra o Trabajo.
Tienen una vida limitada, normalmente menor que la duración de la ejecución de un programa. Su utilizan como auxiliares de los anteriores.
Tipos De Archivos
Los elementos de un archivo pueden ser de cualquier tipo, simples o estructurados o según su función.
Según su función.
Se define por:
a.- Archivos Permanentes: Son aquellos cuyos registros sufren pocas o ninguna variación a lo largo del tiempo, se dividen en:
Constantes: Están formados por registros que contienen campos fijos y campos de baja frecuencia de variación en el tiempo.
De Situación: Son los que en cada momento contienen información actualizada.
Históricos: Contienen información acumulada a lo largo del tiempo de archivos que han sufridos procesos de actualización o bien acumulan datos de variación periódica en el tiempo.
b.- Archivos de Movimiento: Son aquellos que se utilizan conjuntamente con los maestros (constantes), y contienen algún campo común en sus registros con aquellos, para el procesamiento de las modificaciones experimentados por los mismos.
c.- Archivo de Maniobra o Transitorio: Son los archivos creados auxiliares creados durante la ejecución del programa y borrados habitualmente al terminar el mismo.
Según sus elementos.
Archivo de Entrada: Una colección de datos localizados en un dispositivo de entrada.
Técnica de Programación Orientada a Objetos 83
Archivo de Salida: Una colección de información visualizada por la computadora.
Constantes: están formados por registros que contienen campos fijos y campos de baja frecuencia de variación en el tiempo.
De Situación: son los que en cada momento contienen información actualizada.
Históricos: Contienen información acumulada a lo largo del tiempo de archivos que han sufrido procesos de actualización, o bien acumulan datos de variación periódica en el tiempo.
Archivos de Movimiento o Transacciones: Son aquellos que se utilizan conjuntamente con los maestros (constantes), y contienen algún campo común en sus registros con aquellos, para el procesamiento de las modificaciones experimentados por los mismos.
Archivos de Maniobra o Transitorios: Son los archivos auxiliares creados durante la ejecución del programa y borrados habitualmente al terminar el mismo.
Acceso a los Archivos
Se refiere al método utilizado para acceder a los registros de un archivo prescindiendo de su organización. Existen distintas formas de acceder a los datos:
Secuenciales; los registros se leen desde el principio hasta el final del archivo, de tal forma que para leer un registro se leen todos los que preceden.
Directo; cada registro puede leerse / escribirse de forma directa solo con expresar su dirección en el fichero por él numero relativo del registro o por transformaciones de la clave de registro en él numero relativo del registro a acceder.
Por Índice; se accede indirectamente a los registros por su clave, mediante consulta secuenciales a una tabla que contiene la clave y la dirección relativa de cada registro, y posterior acceso directo al registro.
Dinámico; es cuando se accede a los archivos en cualquier de los modos anteriormente citados.
La elección del método está directamente relacionada con la estructura de los registros del archivo y del soporte utilizado.
Tipos de accesos
Acceso Secuencial. Exige el tratamiento de elemento, para esto es necesario una exploración secuencial comenzando desde el primer momento (Pascal permite este acceso)
Secuenciales: archivo de texto que debe ser leído del principio hasta el final.
Acceso Directo. Permite procesar o acceder a un elemento determinado y referencia directamente por su posición en el soporte de almacenamiento (Turbo Pascal permite este acceso.
Aleatorios: Es un archivo con registros de un mismo largo. Un programa puede accesar directamente cualquier registro sin tener que leer los registros previos.
Binarios: Es un archivo que lee byte por byte sin asumir ninguna estructura. Los archivos Binarios no son un nuevo tipo de archivo, pero si una nueva forma de manipular cualquier tipo de archivo. Las técnicas de archivo binarios permiten leer o cambiar cualquier byte de un archivo. Son herramientas extremadamente potentes, pero como toda herramienta potente debe manejarse con cuidado
Operaciones generales que se realizan sobre un archivo.
Técnica de Programación Orientada a Objetos 84
Las operaciones generales que se realizan son:
Creación. Escritura de todos sus registros.
Consulta. Lectura de todos sus registros.
Actualización. Inserción supresión o modificación de algunos de sus registros
Clasificación. Reubicación de los registros de tal forma que queden ordenados según
determinados criterios.
Borrado. Eliminando total del archivo, dejando libre el espacio del soporte que ocupaba.
Excepciones
Excepcion es, o sencillamente problemas. En la programación siempre se producen errores, más o menos graves, pero que hay que gestionar y tratar correctamente. Por ello en java disponemos de un mecanismo consistente en el uso de bloques try/catch/finally . La técnica básica consiste en colocar las instrucciones que podrían provocar problemas dentro de un bloque try, y colocar a continuación uno o más bloques catch, de tal forma que si se provoca un error de un determinado tipo, lo que haremos será saltar al bloque catch capaz de gestionar ese tipo de error específico. El bloque catch contendrá el codigo necesario para gestionar ese tipo específico de error. Suponiendo que no se hubiesen provocado errores en el bloque try, nunca se ejecutarían los bloques catch.
Veamos ahora la estructura del bloque try/catch/finally:
try {
//Código que puede provocar errores
} catch(Tipo1 var1) {
//Gestión del error var1, de tipo Tipo1
}
[ ...
catch(TipoN varN) {
//Gestión del error varN, de tipo TipoN
} ]
[
finally {
//Código de finally
}
Técnica de Programación Orientada a Objetos 85
Como podemos ver es obligatorio que exista la zona try, o zona de pruebas, donde pondremos las instrucciones problemáticas. Después vienen una o más zonas catch, cada una especializada en un tipo de error o excepción. Por último está la zona finally, encargada de tener un código que se ejecutará siempre, independientemente de si se produjeron o no errores.
Se puede apreciar que cada catch se parece a una función en la cuál sólo recibimos un objeto de un determinado tipo, precisamente el tipo del error. Es decir sólo se llamará al catch cuyo argumento sea coincidente en tipo con el tipo del error generado
Archivos de Texto
Archivos necesarios:
Los archivos nos permiten guardar nuestro trabajo para que no perdamos datos una vez que
cerremos la aplicación. Existen dos tipos de archivos en Java, en este trial veremos los
primeros. Los archivos de texto en Java se manejan mediante la clase BufferedReader y la
clase PrintWriter. Estas dos clases nos permiten manejar los archivos de texto como podemos
ver en la presentación a continuación:
Archivos de Texto
Además de los ejemplos y ejercicios de la presentación puedes basarte en el siguiente archivo
para aprender a manejar archivos de texto:
¿Cómo guardar en archivos de texto?
En la computadora, los archivos son un bitstream o "flujo de bits". Esto es para que se puedan construir fácilmente programas que puedan escribir a cualquier tipo de flujo, ya sean archivos, la pantalla, la impresora o una red. La clase que nos srive para imprimir bits a un bitstream es PrintWriter. En la imagen de la izquierda podemos ver que el constructor del PrintWriter recibe un FileWriter, esto se debe a que el PrintWriter sabe escribir a un flujo, pero no sabe a cuál, la clase FileWriter le permite escribir a un flujo de archivos.
El constructor de FileWriter es muy importante, puede recibir uno o dos parámetros, el primer parámetro es el nombre del archivo o un objeto de la clase File que represente el archivo que queremos abrir, el segundo (que es opcional) es un boolean que indica si se debe sobreescribir el archivo o escribir al final.
Hay dos maneras de escribir a un archivo una vez que ya tenemos el PrintWriter, pero primeor
tenemos que entender una cosa de esta clase. El PrintWriter es un buffer, como una caja en la
que se guarda lo que se va a escribir al archivo y una vez que ya está todo listo se manda al
archivo.
Técnica de Programación Orientada a Objetos 86
Para mandar un String a un archivo de texto podemos utilizar dos métodos, el primero es
println() que recibe una línea de texto y la imprime en el archivo con un cambio de línea ("\n") al
final, el segundo método que se utiliza frecuentemente es el método print que funciona
básicamente de la misma manera, pero no pone un salto de línea al final y no imprime los datos
al archivo sino únicamente los deja en el buffer, por lo que tenemos que utilizar el método
flush() para que lo imprima al archivo.
Es muy importante recordar que debemos cerrar el archivo al terminar de utilizarlo, ya que en
caso contrario no estamos seguros de que todos los cambios se guarden en el archivo. Para
poder cerrar el archivo utilizamos el método close() del PrintWriter.
Es muy importante recordar que debemos cerrar el archivo al terminar de utilizarlo, ya que en
caso contrario no estamos seguros de que todos los cambios se guarden en el archivo. Para
poder cerrar el archivo utilizamos el método close() del PrintWriter.
¿Cómo leer de archivos de texto?
El bitstream que creamos al guardar un archivo podemos leerlo mediante la clase
BufferedReader. Pero al igual que la clase PrintWriter esta clase no sabe qué tipo de archivo
está leyendo por lo que hay que especificarle queobtenga el bitstream desde un archivo
utilizando la clase FileReader.
Para construir un FileReader lo único que tenemos que hacer es utilizar el constructor que
recibe el nombre de archivo o un objeto de la clase File representando el archivo que queremos
leer. Una vez que ya tenemos el FileReader debemos utilizarlo para construir un
BufferedReader, de la manera que se ve a la izquierda.
Una vez que tengamos el BufferedReader podemos utilizar varios métodos que nos permiten
escribir a archivos de texto. El primero que vamos a ver es el método read(), que nos devuelve
un int con el código Unicode del carácter leído, para poder convertir este código en un carácter
debemos utilizar un cast a char. Para hacer un cast de un tipo de dato a otro tenemos que
poner la variable que queremos que reciba el valor, un símbolo de igual, el tipo de dato al que
queremos convertir y el valor que queremos convertir, como se ve en la imagen de la izquierda.
Técnica de Programación Orientada a Objetos 87
El otro método del BufferedReader que nos va a ser muy útil es el método readLine(), este
método nos permite leer todo un archivo mucho más rápido y nos es muy útil cuando queremos
obtener datos de un archivo de inicio ya que podemos leer una línea cada vez y utilizarla de la
manera que nos convenga.
Al igual que cuando utilizamos el PrintWriter debemos cerrar el archivo al terminarlo de utilizar
utilizando el método close() del BufferedReader ya que aunque en este caso no se pierden
datos, otros programas no van a poder utilizar el archivo hasta que lo cerremos.
Por último vamos a darle un rápido vistazo a la clase File que nos es muy útil siempre que
trabajamos con archivos.
El constructor de File recibe un String con la ruta del archivo, una vez que creamos el
objeto tipo File podemos utilizar los siguientes métodos:
f.canRead(): Devuelve un boolean verdadero en caso de que se pueda leer el archivo,
falso en caso de que no se pueda leer.
f.canWrite(): Devuelve un boolean verdadero en caso de que se pueda escribir el
archivo, falso en caso de que no se pueda escribir.
f.delete(): Intenta borrar el archivo, devuelve true si pudo hacerlo, false en caso de que
no lo haya borrado.
f.deleteOnExit(): Borra el archivo al terminar el programa, muy útil cuando
necesitamos un lugar para guardar muchos datos y no queremos saturar la memoria
porque nos permite crear un archivo temporal en el que se guarden los datos.
Técnica de Programación Orientada a Objetos 88
Para poder leer archivos de texto en Java debemos crear un objeto de tipo
BufferedReader. BufferedReader es una clase que contiene métodos predefinidos para
poder leer de una secuencia de bits.
Para poder guardar archivos de texto en Java debemos crear un objeto de tipo
PrintWriter. PrintWriter es una clase que contiene métodos predefinidos para meter
datos a una secuencia de bits.
Puedes hacer click en los nombres para ver el API que contiene muchos métodos
útiles.
BufferedReader El constructor que vamos a utilizar para crear un BufferedReader es:
BufferedReader fileIn = new BufferedReader(new
FileReader(fileName);
Ya que tenemos el objeto tipo BufferedReader podemos utilizar varios métodos para
leer, él más común es: fileIn.readLine();
Este método lee una línea y la devuelve o devuelve null si llegamos al final del archivo
y no hay nada que leer.
Es importante recordar cuando trabajamos con archivos que cada que leemos o
escribimos a un archivo debemos hacerlo dentro de un try.
Un try es un manejador de excepciones, cuando sucede un error en la ejecución de
nuestro programa ejecuta ciertas instrucciones dependiendo del tipo de error que
sucedió.
Otro método muy importante es el método: fileIn.read();
Técnica de Programación Orientada a Objetos 89
Este método nos permite leer un solo carácter del flujo de datos. El método regresa un
número (int) del 1 al 65535 si puede leer del archivo o regresa -1 si no.
try {
BufferedReader fileIn = new BufferedReader(
new FileReader(fileName));
int i = fileIn.read(); //Iniciamos una variable a la que
//vamos a leer
char c = (char) i; //Como lo que leimos es un int debemos
// hacer un cast a char
} catch (IOException ioe) {
} catch (FileNotFoundException fnfe) {
}
PrintWriter
El constructor que vamos a utilizar para crear un PrintWriter es:
PrintWriter fileOut = new PrintWriter(new FileWriter(fileName);
Ya que tenemos el objeto PrintWriter podemos utilizar varios métodos para escribir, los
más comunes son:
fileOut.print(String);
fileOut.println(String);
Estos dos métodos reciben un String y lo imprimen en el archivo, el segundo método le
pone un carácter de fin de línea al final.
Al igual que al leer debemos recordar utilizar un try. Cuando utilizamos el PrintWriter
todo entra a un buffer y una vez que terminemos de escribir los datos debemos
recordar utilizar el método flush() del PrintWriter para escribir todo al archivo.
Al terminar de usar el archivo también debemos recordar que debemos cerrarlo
mediante el método close() del PrintWriter.
String fileName = "Texto.txt";
PrintWriter fileOut = null;
try {
fileOut = new PrintWriter(new FileWriter(fileName));
String s = "Una linea de texto";
fileOut.println(s);
fileOut.flush();
} catch (IOException ioe) {
System.out("Error, disco protegido contra lectura");
} catch (FileNotFoundException fnfe) {
System.out("Error, no se encuentra el archivo");
} finally {
if (fileIn != null) {
try {
fileIn.close();
} catch (IOException ioe) {
}
Técnica de Programación Orientada a Objetos 90
}
}
Ejemplos:
Caso 01
package prjarchivos;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.JFrame;
public class ArchivoApp2{
public static void main(String[] args) {
FileReader entrada=null;
StringBuffer str=new StringBuffer();
try {
entrada=new FileReader("VERARCHI01.txt");
int c;
while((c=entrada.read())!=-1){
str.append((char)c);
}
System.out.println(str);
System.out.println("--------------------------------------");
}
catch (IOException ex) {
System.out.println("El archivo no existe");
}
finally{
//cerrar los flujos de datos
if(entrada!=null){
try{
entrada.close();
}
catch(IOException ex){}
}
System.out.println("el bloque finally siempre se ejecuta");
}
}
}
Caso 02
package prjrarchivos2;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.JOptionPane;
import pckPrincipal.FrmLlamar;
Técnica de Programación Orientada a Objetos 91
public class Class1 extends FrmLlamar{
public Class1() {
String nombre=" VERARCHI02.txt";
BufferedReader entrada;
try {
entrada = new BufferedReader(new FileReader(nombre));
String texto="";
while(true){
texto = entrada.readLine();
//JOptionPane.showMessageDialog(null,texto);
if(texto==null) break;
System.out.println(texto);
this.txt.append(texto+"\n");
}
entrada.close();
this.setVisible(true);
}catch(FileNotFoundException f){
} catch (IOException e) {
// TODO
}
}
}
Caso 03
package pckClase;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import pckAplica.FrmArchivo3;
public class ClassAr3 {
public String datos[]=new String[50];
public int i,pos,tam;
public ClassAr3() {
}
public void llamar(){
String subStr="";
String nombre="ArchivoApp2.txt";
BufferedReader entrada;
try {
entrada = new BufferedReader(new FileReader(nombre));
String texto="";
Técnica de Programación Orientada a Objetos 92
while(true){
texto = entrada.readLine();
/* tam=texto.length();
for(int g=0;g<tam;++g){
String j=String.valueOf(texto.charAt(g));
//JOptionPane.showMessageDialog(null,j);
if(j.equals(",")){
datos[i]=subStr;
++i;
}
else
subStr=subStr+j;
} */
if(texto==null) break;
System.out.println(texto);
}
entrada.close();
}catch(FileNotFoundException f){
} catch (IOException e) {
// TODO
}
}
}
Caso Práctico: Usando la Técnica P.O.O:
Guarda registro, código, Nombre, Apellido, Carrera y pago dentro de un Archivo. Para ello cree
la siguiente estructura de trabajo.
Desarrollo:
Técnica de Programación Orientada a Objetos 93
En el paquete Paneles se usaran: Contenido(tendrá los controles para el ingreso de
datos) y pie(presentara la fecha y hora del sistema, utilizaremos el GregorianCalendar).
En la capa lógica 2 subclases: ClassEncapsulada(se crearan los get y set por cada
atributo que se tenga) y ClassMetodos(se creara los métodos para generar el código y
hallar el pago de acuerdo a la especialidad)
Los Frame son los objetos visualizadores de los paneles
Empecemos a codificar
package pckLogico;
public class ClassEncapsulada {
String nom,ape,cod;
int p,reg;
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getApe() {
return ape;
}
public void setApe(String ape) {
this.ape = ape;
}
public int getP() {
return p;
}
public void setP(int p) {
this.p = p;
}
public int getReg() {
return reg;
}
public void setReg(int reg) {
this.reg = reg;
}
public String getCod() {
return cod;
}
Técnica de Programación Orientada a Objetos 94
public void setCod(String cod) {
this.cod = cod;
}
}// fin de la clase encapsulada
package pckLogico;
public class ClassMetodos {
int x=11,dv,pag;
GregorianCalendar formato=new GregorianCalendar();
int devNV(char letra){
switch(letra){
case 'a':case 'A':dv=1;break;
case 'e':case 'E':dv=2;break;
case 'i':case 'I':dv=3;break;
case 'o':case 'O':dv=4;break;
case 'u':case 'U':dv=5;break;
default : dv=x;
++x;
}
return(dv);
}
public String genera(String cadN,String cadA){
int año=formato.get(formato.YEAR);
int mes=formato.get(formato.MONTH)+1;
//Datos del Nombre
char n1=cadN.charAt(0);
int largoN=cadN.length();
char n2=cadN.charAt(largoN-1);
//datos del Apellido
char a1=cadA.charAt(0);
int largoA=cadA.length();
char a2=cadA.charAt(largoA-1);
String cad=(""+año+devNV(n1)+devNV(n2)+devNV(a1)+devNV(a2)+mes);
return(cad);
}
public int pago(int index){
switch(index){
case 1: pag=850;break;
case 2: pag=750;break;
case 3: pag=600;break;
case 4: pag=700;break;
case 5: pag=750;break;
case 6: pag=680;break;
}
return(pag);
}
}// fin de la clase Metodos
Técnica de Programación Orientada a Objetos 95
Uso de los paneles: diseñe todo este formato
package pckPaneles;
public class pnlContenido extends JPanel {
ClassMetodos llamar=new ClassMetodos();
ClassEncapsulada atri=new ClassEncapsulada();
ClassArchivo datos=new ClassArchivo();
int dv,c=1,x=11;
String titulos[]={"Registro","Codigo","Nombres","Apellidos","Categoria","Pago"};
String contenido[][]={};
private JTextField TXTNOM = new JTextField();
private JTextField TXTAPE = new JTextField();
private JComboBox cboespe = new JComboBox();
private JLabel lblp = new JLabel();
private JSeparator jSeparator1 = new JSeparator();
private JSeparator jSeparator2 = new JSeparator();
private JButton btnañadir = new JButton();
private JButton btnsalir = new JButton();
private JScrollPane jScrollPane1 = new JScrollPane();
private JTable jTable1 = new JTable();
private DefaultTableModel modtbdatos = new DefaultTableModel(contenido,titulos);
private JButton btnLsitaAr = new JButton();
*******************
private void jbInit() throws Exception {
************************
modtbdatos.setColumnCount(6);
***************************
jTable1.setModel(modtbdatos);
cboespe.addItem("Seleccionar cat");
cboespe.addItem("Sistemas");
cboespe.addItem("Redes");
cboespe.addItem("Diseño Grafico");
cboespe.addItem("Contabilidad");
cboespe.addItem("Administracion");
cboespe.addItem("Otros");
}
private void btnañadir_actionPerformed(ActionEvent e) {
atri.setReg(c);
x=11;
atri.setNom(TXTNOM.getText());
atri.setApe(TXTAPE.getText());
atri.setCod(llamar.genera(atri.getNom(),atri.getApe()));
Object
valores[]={atri.getReg(),atri.getCod(),atri.getNom(),atri.getApe(),cboespe.getSelectedItem(),atri.
getP()};
modtbdatos.addRow(valores);
Técnica de Programación Orientada a Objetos 96
datos.Grabar(atri.getReg(),atri.getCod(),atri.getNom(),atri.getApe(),atri.getCod(),atri.getP());
++c;
}
private void cboespe_actionPerformed(ActionEvent e) {
atri.setCod(cboespe.getSelectedItem().toString());
lblp.setText(""+atri.getP());
atri.setP(llamar.pago(cboespe.getSelectedIndex()));
}
private void btnListaAr_actionPerformed(ActionEvent e) {
Frmlectura x=new Frmlectura();
x.setVisible(true);
}
}//fin del panel contenido
// Panel Pie
package pckPaneles;
public class pnlPie extends JPanel {
GregorianCalendar formato=new GregorianCalendar();
************************
private void jbInit() throws Exception {
********************************
int dia=formato.get(formato.DAY_OF_MONTH);
int mes=formato.get(formato.MONTH)+1;
int año=formato.get(formato.YEAR);
lblf.setText(""+dia+"/"+mes+"/"+año);
Técnica de Programación Orientada a Objetos 97
lblf.setFont(new Font("Dialog", 1, 11));
int hora=formato.get(formato.HOUR_OF_DAY);
int min=formato.get(formato.MINUTE);
int seg=formato.get(formato.SECOND);
lblh.setFont(new Font("Dialog", 1, 11));
lblh.setText(""+hora+":"+min+":"+seg);
}
}//fin del panel pie
// estableciendo los paneles al Frame
package pckPresentacion;
public class FrmPresenta extends JFrame {
int dv=0;
ClassEncapsulada atri=new ClassEncapsulada();
GregorianCalendar formato=new GregorianCalendar();
private pnlPie pnlPie1 = new pnlPie();
private pnlContenido pnlEncabezado1 = new pnlContenido();
public FrmPresenta() {
try {
jbInit();
} catch (Exception e) {
e.printStackTrace();
}
}
private void jbInit() throws Exception {
this.getContentPane().setLayout( null );
this.setSize(new Dimension(400, 408));
this.setResizable(false);
this.setTitle("Usando Archivos");
pnlPie1.setBounds(new Rectangle(0, 345, 395, 40));
pnlEncabezado1.setBounds(new Rectangle(0, 0, 395, 345));
this.getContentPane().add(pnlEncabezado1, null);
this.getContentPane().add(pnlPie1, null);
}
}
Técnica de Programación Orientada a Objetos 98
Técnica de Programación Orientada a Objetos 99
Contenidos
- Definición de la Clase Vector. - Definición de la Clase ArrayList. - Diferencias entre ellas - Métodos de la clase Vector y ArrayList - Aplicando atributos encapsulados usando estas clases - Definición de la la Clase Hashtable. - Métodos get y put
____________________________________________________________________________
Vector Es una clase que permite crear matrices dinámicas, es decir matrices que varían en cantidad
de elementos durante la ejecución del programa, lo cual no se puede hacer en java con la clase
Array que es la clase que generalmente se utiliza para crear matrices.
En un Vector, puedo agregar cualquier cosa, incluso puedo agregar diferentes tipos de objetos
a un mismo vector, esto se debe a que Vector almacena objetos de tipo Object que es la clase
base de Java. Esto no puedo hacerlo con un Array ya que todos sus elementos deben ser del
mismo tipo.
Por este motivo, cuando accedo a un elemento de un Vector, debo moldearlo a su tipo
específico de datos, de lo contrario obtendré un objeto de tipo Object.
La clase Enumeration se utiliza con un vector o mejor dicho, se crea a partir de la cantidad de
elementos de un vector, ya que lo único que hace Enumeration es enumerar los elementos de
un vector. Enumeration lo único que hace es recorrer los elementos de un vector hacia
adelante mediante el método nextElement (), asegurando que nunca se pasará del índice del
vector, esto lo hace mediante el método hasMoreElements().
Solo para eso sirve Enumeration, pero asegura que no habrá error por salirse del índice del
vector. Este es un ejemplo de cómo utilizar ambas clases juntas:
Técnica de Programación Orientada a Objetos 100
Crear un vector
Para usar la clase Vector hemos de poner al principio del archivo del código fuente la siguiente sentencia import
import java.util.*; import java.util.Vector; Cuando creamos un vector u objeto de la clase Vector, podemos especificar su dimensión inicial, y cuanto crecerá si rebasamos dicha dimensión.
Tenemos un vector con una dimensión inicial de 20 elementos. Si rebasamos dicha dimensión y guardamos 21 elementos la dimensión del vector crece a 25.
Al segundo constructor, solamente se le pasa la dimensión inicial.
Si se rebasa la dimensión inicial guardando 21 elementos, la dimensión del vector se duplica.
El programador ha de tener cuidado con este constructor, ya que si se pretende guardar un número grande de elementos se tiene que especificar el incremento de la capacidad del vector, si no se quiere desperdiciar inútilmente la memoria el ordenador.
Con el tercer constructor, se crea un vector cuya dimensión inicial es 10.
La dimensión del vector se duplica si se rebasa la dimensión inicial, por ejemplo, cuando se pretende guardar once elementos.
Añadir elementos al vector Hay dos formas de añadir elementos a un vector. Podemos añadir un elemento a continuación del último elemento del vector, mediante la función miembro addElement. Podemos también insertar un elemento en una determinada posición, mediante insertElementAt. El segundo parámetro o índice, indica el lugar que ocupará el nuevo objeto. Si tratamos de insertar un elemento en una posición que no existe todavía obtenemos una excepción del tipo ArrayIndexOutOfBounds. Por ejemplo, si tratamos de insertar un elemento en la posición 9 cuando el vector solamente tiene cinco elementos.
Vector VecDatos=new Vector(20, 5);
Vector VecDatos =new Vector(20);
Vector VecDatos =new Vector();
VecDatos.addElement("uno");
Técnica de Programación Orientada a Objetos 101
Ejemplo: Para insertar el string "tres" en la tercera posición del vector v, escribimos En la siguiente porción de código, se crea un vector con una capacidad inicial de 10 elementos, valor por defecto, y se le añaden o insertan objetos de la clase String.
private void btnAgregar_actionPerformed(ActionEvent e) {
Vector vecDatos =new Vector();
vecDatos.addElement("Veronica");
vecDatos.addElement("William");
vecDatos.addElement("Sebastian");
vecDatos.addElement("Angie");
vecDatos.addElement("Victor");
vecDatos.addElement("Carlos");
vecDatos.addElement("Henrry");
vecDatos.addElement("Eduardo");
//vecDatos.insertElementAt("Tres", 2);
//se crea una enumeracion de acuerdo a los elementos del vector
Enumeration enume =vecDatos.elements();
//mientras queden elementos en la enumeracion
while(enume.hasMoreElements())
modLstDatos.addElement(enume.nextElement());
}
VecDatos.insertElementAt("tres", 2);
Técnica de Programación Orientada a Objetos 102
Para saber cuántos elementos guarda un vector, se llama a la función miembro size. Para saber la dimensión actual de un vector se llama a la función miembro capacity. Agregue esta 2 líneas al código anterior.
Podemos eliminar todos los elementos de un vector, llamando a la función miembro removeAllElements. O bien, podemos eliminar un elemento concreto, por ejemplo el que guarda el string "tres".
Podemos eliminar dicho elemento, si especificamos su índice.
Acceso a los elementos de un vector
El acceso a los elementos de un vector no es tan sencillo como el acceso a los elementos de un array. En vez de dar un índice, usamos la función miembro elementAt. Por ejemplo, vecDatos.elementAt(4) sería equivalente a vecDatos [4], si vecDatos fuese un array.
Para acceder a todos los elementos del vector, escribimos un código semejante al empleado para acceder a todos los elementos de un array.
for(int i=0; i<v.size(); i++){
System.out.print(vecDatos.elementAt(i)+"\t");
}
Existe otra alternativa, que es la de usar las funciones del interface Enumeration. Este interface declara dos funciones pero no implementa ninguna de ellas. Una Enumeration nos permite acceder a los elementos de una estructura de datos de forma secuencial, como ya lo hemos mostrado en el ejemplo anterior.
lblT.setText(""+vecDatos.size());
lblD.setText(""+vecDatos.capacity());
vecDatos.removeElement("Angie");
vecDatos.removeElementAt(2);
Técnica de Programación Orientada a Objetos 103
public interface Enumeration {
boolean hasMoreElements();
Object nextElement();
}
La función miembro elements de la clase Vector devuelve un objeto de la clase VectorEnumerator que implementa el interface Enumeration y tiene que definir las dos funciones hasMoreElements y nextElement.
final class VectorEnumerator implements Enumeration {
Vector vector;
int count;
VectorEnumerator(Vector vecDatos) {
vector = vecDatos;
count = 0;
}
public boolean hasMoreElements() {
//...
}
public Object nextElement() {
//...
}
}
El objeto enum devuelto por la función miembro elements es de la clase VectorEnumerator, sin embargo no podemos escribir
VectorEnumerator enum= vecDatos.elements();
porque VectorEnumerator no es una clase pública. Como podemos ver en su definición, no tiene la palabra reservada public delante de class. Sin embargo, podemos guardar un objeto de la clase VectorEnumerator en una variable enum del tipo Enumeration, por que la clase implementa dicho interface.
Enumeration enum= vecDatos.elements();
while(enum.hasMoreElements()){
System.out.print(enum.nextElement()+"\t");
}
Técnica de Programación Orientada a Objetos 104
Desde el objeto enum devuelto por la función miembro elements de la clase Vector llamamos a las funciones miembro hasMoreElements y nextElement de la clase VectorEnumerator. La función hasMoreElements devuelve true mientras haya todavía más elementos que se puedan acceder en el vector v. Cuando se ha llegado al último elemento del vector, devuelve false. La función nextElement devuelve una referencia al próximo elemento en la estructura de datos. Esta función devuelve una referencia a un objeto de la clase base Object, que el programador precisará en ciertos casos, como veremos más abajo, promocionar (casting) a la clase adecuada.
Para buscar objetos en un vector se puede usar una Enumeration y hacer una comparación elemento por elemento mediante equals, tal como vemos en la siguiente porción de código
Algunos de los métodos de la clase Vector se muestran a continuación:
Vector ( )
Constructor: crea un vector inicialmente vacío
void addElement (Objet obj)
Inserta el objeto especificado al final del vector
void setElementAt (Object obj, int indíce)
Inserta el objeto específicado en el vector en la posición específicada
Object remove (int indíce)
Elimina el objeto que se encuentra en la posición específicada y lo regresa
boolean removeElement (Object obj)
Elimina la primera occurencia del objeto específicado en el vector
void removeElementAt (int indíce)
Elimina el objeto específicado en el índice del vector
void clear ( )
Elimina todos los objetos del vector
boolean contains (Object obj)
Enumeration enum=vecDatos.elements();
while(enum.hasMoreElements()){
String elemento=(String)enum.nextElement();
if(elemento.equals("William")){
lblEnc.setText("Encontrado William");
break;
}
}
Técnica de Programación Orientada a Objetos 105
Regresa verdadero si el objeto dado pertenece al vector
int indexOf (Object obj)
Regresa el índice del objeto específicado. Regresa -1 si no fue encontrado
el objeto
Object elementAt (int indíce)
Regresa el componente en el índice específicado
boolean isEmpty ( )
Regresa verdadero si el vector no contiene elementos
int size ( )
Regresa el número de elementos en el vector
Ejemplo 01:
import java.util.Vector;
public class VerCasoVector{
public static void main () {
Vector DocentesSta = new Vector ();
DocentesSta.addElement ("Veronica");
DocentesSta.addElement ("William");
DocentesSta.addElement ("Victor");
DocentesSta.addElement ("Rogelio");
DocentesSta.addElement ("Carlos");
ModLstDatos.addElement(DocentesSta);
//Quita el elemento
DocentesSta.removeElement ("Rogelio");
ModLstDatos.setText(DocentesSta);
lblP.setText("En la posición 1 está: " + DocentesSta.elementAt (1));
DocentesSta.insertElementAt ("Angie", 2);
lblT.setTexr("Tamaño de la banda: " + DocentesSta.size ());
for (int i = 0; i < DocentesSta.size (); i++)
ModLstDatos.addElement(DocentesSta);
}
}
Técnica de Programación Orientada a Objetos 106
Si se necesitan añadir valores de datos primitivos a un Vector se pueden utilizar las clases
conocidas como envoltorios que son: Integer, Long, Double y Float. Sus métodos de conversión
respectivos son: intValue ( ), longValue ( ), doubleValue ( ) y floatValue ( ).
Ejercicio:
Complemente la siguiente clase, escribiendo las instrucciones necesarias donde se muestran
los subguiones(__), guíate del ejemplo anterior:
import java.util.*;
/**
* Uso de las clases Vector e Integer
*/
public class EjercicioVector
{
public static void main ()
{
Vector vecDatos = new Vector ();
vecDatos.add (new Integer (1));
vecDatos.add (new Integer (3));
vecDatos.add (new Integer (5));
for (int i = 0; i < v.size (); i++) {
Integer iI = (Integer) v.get (i);
ModLstDatos.addElement(iI.______________() + " ");
}
// Insertar un nuevo Objeto de tipo Integer cuyo valor sea 10
______________________
//El nuevo vector es
__________________
____________________
// Insertar un nuevo Objeto de tipo Integer cuyo valor sea 6 en la pos.3
System.out.println ("Se inserta un nuevo objeto cuyo valor es 6 en la posición 3");
___________________________
//El nuevo vector es
_______________________________________
// Eliminar el objeto que contiene al Integer cuyo valor es 3
____________________
//El nuevo vector es
_______________________________
// Escribir el valor del segundo objeto
txtArea.append("El valor del segundo objeto es: " + _____________+”\n”);
// Determinar el número de objetos del vector
txtArea.append ("El tamaño del vector es: " + _____________+”\n”);
// Eliminar el tercer objeto y escribir su valor
txtArea.append ("En la tercera posición había un: " + _____________+”\n”);
Técnica de Programación Orientada a Objetos 107
//El nuevo vector es
_____________________________
}
}
Ejemplo 02:
package pckLogico;
import java.util.Enumeration;
import java.util.Vector;
public class ClassVector1 {
Vector Numeros = new Vector();//se crea un vector
public ClassVector1() {
for (int a = 0; a < 100; a++){
Numeros.addElement(a);//se agrega elementos al vector
}
Enumeration enume = Numeros.elements();//se crea una enumeracion de acuerdo a los
elementos del vector
while(enume.hasMoreElements())//mientras queden elementos en la enumeracion
System.out.println((Integer)enume.nextElement()); //se moldea el objeto del vector para
poder imprimirlo
}
}
package pckEjecutar;
import pckLogico.ClassVector1;
public class ClassPrincipal {
public static void main(String[] args) {
ClassVector1 x;
x=new ClassVector1();
}
}
Técnica de Programación Orientada a Objetos 108
La clase ArrayList Las aplicaciones frecuentemente necesitan almacenar un grupo de datos en un sólo objeto. Los arrays sirven bien para este propósito, pero algunas veces necesitamos incrementar o reducir dinámicamente el número de elementos del array, o hacer que contenga distintos tipos de datos
Esto es común entre las aplicaciones como las tiendas online. Un cliente añade una mercancía a su carro de la compra, y detrás de la escena, los ítems son almacenados y eliminados automáticamente.
Para esta clase de grupos de datos crecientes y menguantes, podemos usar la clase Vector , o la reciente clase ArrayList del paquete java.util .
Un ArrayList contiene tantos objetos como necesitemos.
ArrayList tiene varios constructores, dependiendo de cómo necesitemos construir el ArrayList
Los siguientes dos constructores nos ayudarán a empezar:
Un objeto ArrayList sólo contiene referencias a objetos. Para almacenar tipos primitivos como double long o float ,
Si necesitamos circular a través de los elementos del ArrayList , usamos la clase Iterator y sus métodos hasNext y next :
ArrayList es una de las muchas clases del Collection Framework , que proporciona un conjunto de interfaces y clases bien-diseñados para almacenar y manipular grupos de datos como una sola unidad, una colección.
Es una Lista volcada en un Array. Se debe utilizar en lugar de Vector como almacenamiento de objetos de propósito general. Permite un acceso aleatorio muy rápido a los elementos, pero realiza con bastante lentitud las operaciones de insertado y borrado de elementos en medio de la Lista. Se puede utilizar un ListIterator para moverse hacia atrás y hacia delante en la Lista, pero no para insertar y eliminar elementos.
Ventajas • Un ArrayList es un array dinámico. No tiene restricciones de capacidad. Su tamaño se ajusta de forma dinámica.
ArrayList() construye un ArrayList con capacidad cero por defecto, pero crecerá según le vayamos añadiendo: ArrayList al = new ArrayList();
ArrayList(int initialCapacity) construye un ArrayList vacío con una capacidad inicial especificada: ArrayList al2 = new ArrayList(5);
Iterator alIt = al.iterator();
while (alIt.hasNext()){
ModLstDatos(alIt.next() + " ");
}
Técnica de Programación Orientada a Objetos 109
• Constructor por defecto: new ArrayList(). Inicialmente, la capacidad de un ArrayList creado así es 0. • Los elementos dentro de un ArrayList son Objetos. No pueden ser de tipo básico, pero pueden ser de cualquier tipo de objeto. • La clase ArrayList forma parte del paquete java.util • Para poner un elemento dentro de esta estructura, usamos el método add y para recoger un elemento usamos el método get.
Ejemplo 01: ArrayListEjem01
import java.util.*; public class ArrayListEjem01 { public static void main(String[ ] args) { ArrayList Saludo = new ArrayList(); Saludo.add("Sise"); Saludo.add("te"); Saludo.add("da la"); Saludo.add("Bienvenidaa"); Saludo.add("….."); for (int i=0;i<Saludo.size();i++) ModLstSaludos(Saludos.get(i)+" "); } }
Métodos de ArrayList int size().- El tamaño actual (puede ser 0)
void add(obj).- Añade un objeto al final del ArrayList, incrementando su tamaño de
obj es un objeto.
Object get(N).- Devuelve el elemento almacenado a la posición N en el ArrayList.
N tiene que ser un entero entre 0 y size()-1. Nota:
En ArrrayListInteger.java, se convierte el objeto devuelto por get() a un Integer con casting.
En ArrayListString.java, se convierte el objeto devuelto por get() a un String llamando al método toString() de Object.
Ejemplo 01: Usando el ArrayList
import java.util.ArrayList; public class ArrayListEntero { public static void main(String[] args) { ArrayList numeros = new ArrayList(); Integer num1 = new Integer(10); Integer num2 = new Integer(20); Integer num3 = new Integer(30); Integer num4 = new Integer(40); numeros.add(num1); numeros.add(num2); numeros.add(num3); numeros.add(num4); int suma=0; for (int i=0;i<numeros.size();i++) { Integer vanum = (Integer)numeros.get(i); suma = suma + vanum.intValue(); txtArea.append(vanum); if (i<numeros.size()-1) txtArea.append ("+"); else txtArea.append ("="); }
Técnica de Programación Orientada a Objetos 110
txtArea.append(“\n”+suma); } }
import java.util.*; public class ArrayListString { public static void main(String[] args) { ArrayList Saludo = new ArrayList(); Saludo.add("Sise"); Saludo.add("te"); Saludo.add("da la"); Saludo.add("Bienvenidaa"); Saludo.add("….."); for (int i=0;i<Saludo.size();i++) Object objecto = Saludo.get(i); String cadena = objecto.toString(); cadena = cadena.toUpperCase(); txtSalida.append(cadena+" "); } }
Más Métodos de ArrayList void set(index, obj): Sustituye el elemento en la posición index por el objeto obj. (index tiene que ser entre 0 y size()-1) dentro del ArrayList, sustituyendo el elemento previamente almacenado a la posición N. Es equivalente a A[N] = obj para un array A. Object remove(index) -- Elimina el elemento a la posición index (index entre 0 y size()-1).
ArrayList remplaza a Vector y Iterator remplaza a Enumeration:
Se puede crear un objeto ArrayList y moldearlo a una Collection. Al utilizar métodos de
Collection, cualquier objeto de una clase derivada de Collection debería funcionar, pero se crea
un ArrayList porque es el caballo de batalla de las colecciones y viene a tomar el relevo al
Vector.
El método add(), como su nombre sugiere, coloca un nuevo elemento en la colección. Sin
embargo, la documentación indica claramente que add() "asegura que la colección contiene el
elemento indicado". Esto es para que un Set tenga significado, ya que solamente añadirá el
elemento si no se encuentra en la colección. Para un ArrayList, o cualquier otra lista ordenada,
add() significa siempre "colocarlo dentro".
Todas las colecciones pueden producir un Iterator invocando al método iterator(). Un Iterator
viene a ser equivalente a una Enumeration, a la cual reemplaza, excepto en los siguientes
puntos:
Utiliza un nombre que está históricamente aceptado y es conocido en toda la literatura de
programación orientada a objetos
Utiliza nombres de métodos más cortos que la Enumeration: hasNext() en vez de
hasMoreElements(), o next() en lugar de nextElement().
Técnica de Programación Orientada a Objetos 111
Crear el siguiente Caso utilizando la clase primita ArrayList.
// Clase Encapsulada
package PckLogico;
public class ClassEncapsulada {
String nombre,apellido,condicion;
int reg,nota1,nota2,nota3,nota4;
double promedio;
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getApellido() {
return apellido;
}
public void setApellido(String apellido) {
this.apellido = apellido;
}
public int getNota1() {
return nota1;
}
public void setNota1(int nota1) {
this.nota1 = nota1;
}
public int getNota2() {
return nota2;
}
public void setNota2(int nota2) {
this.nota2 = nota2;
}
Técnica de Programación Orientada a Objetos 112
public int getNota3() {
return nota3;
}
public void setNota3(int nota3) {
this.nota3 = nota3;
}
public int getNota4() {
return nota4;
}
public void setNota4(int nota4) {
this.nota4 = nota4;
}
public String getCondicion() {
return condicion;
}
public void setCondicion(String condicion) {
this.condicion = condicion;
}
public int getReg() {
return reg;
}
public void setReg(int reg) {
this.reg = reg;
}
public double getPromedio() {
return promedio;
}
public void setPromedio(double promedio) {
this.promedio = promedio;
}
}//fin de la clase encapsulada
// ClassMetodos
package PckLogico;
import java.util.ArrayList;
public class ClassMetodo{
static ArrayList Registros;
public ClassMetodo(){
Registros= new ArrayList();
}
public void AddRegistro(ClassEncapsulada Datos){
Registros.add(Datos);
}
public ClassEncapsulada getEncapsulada(int i){
return((ClassEncapsulada)Registros.get(i));
}
public int tamaño(){
return(Registros.size());
}
}
Técnica de Programación Orientada a Objetos 113
//ClassEjecutar
package PckPrincipal;
import PckPresentacion.FrmAcceso;
import PckPresentacion.FrmDatos;
public class ClassEjecutar {
public static void main(String[] args) {
FrmAcceso prin= new FrmAcceso();
prin.setVisible(true);
// Cerrar una ventana
}
}
// uso del FRAME
public class FrmDatos extends JFrame {
//inicializacion
ClassEncapsulada atri;
ClassMetodo metodos;
String valores[][]={};
Stringnombres[]={"Reg","Nombre","Apellido","Nota 1","Nota 2","Nota 3","Nota 4",
"Promedio","Condicion"};
int R=1;
**********************************
**********************************
private void jbInit() throws Exception {
**********************************
**********************************
**********************************
**********************************
lblreg.setText(""+R);
atri=new ClassEncapsulada();
metodos=new ClassMetodo();
}
void datos(){
atri.setNombre(txtnom.getText());
atri.setApellido(txtape.getText());
atri.setNota1(Integer.parseInt(txtN1.getText()));
atri.setNota2(Integer.parseInt(txtN2.getText()));
atri.setNota3(Integer.parseInt(txtN3.getText()));
atri.setNota4(Integer.parseInt(txtN4.getText()));
atri.setPromedio((atri.getNota1()+atri.getNota2()+atri.getNota3()+atri.getNota4())/4.0);
lblPromedio.setText(""+atri.getPromedio());
if(atri.getPromedio()>=10.5) atri.setCondicion("Aprobado");
else atri.setCondicion("Desaprobado");
lblCondicion.setText(atri.getCondicion());
}
Técnica de Programación Orientada a Objetos 114
void Eliminar(){
int fila=tbl_d.getSelectedRow();
modTDatos.removeRow(fila);
}
private void btnAgregar_actionPerformed(ActionEvent e) {
datos();
Object valores[]={R,atri.getNombre(),atri.getApellido(),atri.getNota1(),atri.getNota2(),
atri. getNota3(),atri.getNota4(),atri.getPromedio(),atri.getCondicion()};
modTDatos.addRow(valores);
++R;
}
private void jButton1_actionPerformed(ActionEvent e) {
//Ir al Inicio del registro de la Tabla
tbl_d.setRowSelectionInterval (0,0);
}
private void jButton2_actionPerformed(ActionEvent e) {
//Ir al Siguiente Registro de la Tabla
if ( tbl_d.getSelectedRow() != 0 ) {
tbl_d.setRowSelectionInterval (tbl_d.getSelectedRow()+1, tbl_d.getSelectedRow() +1);
}
}
private void jButton3_actionPerformed(ActionEvent e) {
//Ir al Anterio de la Tabla
if ( tbl_d.getSelectedRow() != 0 ) {
tbl_d.setRowSelectionInterval (tbl_d.getSelectedRow()-1, tbl_d.getSelectedRow() -1);
}
}
private void jButton4_actionPerformed(ActionEvent e) {
//Implementa para ir al final del registro de la tabla
}
private void btnSalir_actionPerformed(ActionEvent e) {
System.exit(0);
}
private void btnEliminar_actionPerformed(ActionEvent e) {
Eliminar();
}
private void btnBuscar_actionPerformed(ActionEvent e) {
/* Implementa Este boton
}
}// fin del Frame
Técnica de Programación Orientada a Objetos 115
//Frame Acceso
private void btnAceptar_actionPerformed(ActionEvent e) {
String Nombre, clave;
Nombre= txtNombre.getText();
clave=txtClave.getText();
if(Nombre.equalsIgnoreCase("SISE")&&clave.equalsIgnoreCase("2010")){
FrmDatos prin=new FrmDatos();
prin.setVisible(true);
this.dispose();
}
}
Técnica de Programación Orientada a Objetos 116
Contenidos
- Uso de menús(JMenu) - JProgressBar, - JColorChooser, JFileChooser, - InternalFrame - Implementación de Librerías - Creación de Archivos Jar Ejecutables
____________________________________________________________________________
Menús
Un menú en una aplicación no es más que un MenuBar en el que hay varios menús.
Pensemos en un programa cualquiera con las voces de menú File Edit y Help. Estas tres voces
en Java son unos objetos de la clase Menú y se tienen que añadir a un objeto de la clase
MenuBar que se une a la ventana. Cada menú tiene varias voces. Por ejemplo, el menú
Archivo tendrá las voces: Abrir, Cerrar, Guarda y Salir. Éstos en Java son unos objetos de la
clase MenuItem (o también Menú si incluyen otros submenús).
Por lo tanto, si a una aplicación le quisieramos añadir un menú tendríamos hacer las siguientes cosas siguiendo un órden cualquiera:
Crear los objetos MenuItem
Crear los objetos menú y pegarles los MenuItem
Crear una MenuBar y pegarles los Menús
Además, como siempre, tenemos que escribir unos gestores para los sucesos de los menús y
asociarlos a los menús.
Los sucesos de los MenuItem son los que tenemos que gestionar nosotros a diferencia de los
sucesos de los menús que los gestiona el sistema. Mientras los segundos sirven para que
aparezcan y desaparezcan las voces del menú, los primeros son los clicks sobre la orden
correspondiente al Item.
Técnica de Programación Orientada a Objetos 117
Por lo tanto, para éstos tendremos que escribir unos ActionListener, como para los botones.
Realmente no son otra cosa que unos botones especiales. Los constructores son tres:
MenuItem() , que construye un MenuItem sin etiqueta.
MenuItem(String label), que construye MenuItem con etiqueta label.
MenuItem(String label, MenuShortcut s), que construye un MenuItem con etiqueta label
y acelerador (tecla de opción rápida) definido en MenuShortcut s.
Algunos métodos son:
addActionListener(ActionListener l), asocia un ActionListener al MenuItem para
escuchar los sucesos de tipo ActionEvent (el clic).
void deleteShortcut(), borra la tecla de opción rápida para el menuitem.
String getActionCommand(), da la acción asociada al MenuItem. La acción es la
que pasa al actionListener del botón para identificar el botón mismo. Así varios item
pueden tener el mismo gestor de sucesos que podrá distinguir el botón clicado
basándose en la órden que le llega.
String getLabel(), devuelve la etiqueta del MenuItem
EventListener[]getListeners(Class listenerType) , devuelve todos los oyentes de
sucesos asociados al MenuItem, del tipo listenerType.
MenuShortcut getShortcut(), devuelve la definición del acelerador para el
MenuItem.
boolean isEnabled(), dice si el menú esta disponible o no. Si no lo está se
visualizará en gris.
void removeActionListener(ActionListener l), elimina el oyente asociado.
void setActionCommand(String command), ajusta la orden asociada al
MenuItem. Si no está especificado, la órden es la etiqueta del MenuItem.
void setEnabled(boolean b), habilita y deshabilita el MenuItem.
void setLabel(String label), ajusta la etiqueta para el MenuItem.
void setShortcut(MenuShortcut s), define el acelerador para el menú.
Por lo tanto, para crear los Item del menú Archivo descrito antes tendremos que escribir:
MenuItem abrir=new MenuItem("Abrir");
MenuItem cerrar=new MenuItem("Cerrar");
MenuItem guardar=new MenuItem("Guardar");
MenuItem salir=new MenuItem("Salir");
Por tanto creamos el objeto Menu para pegar los MenuItem.
Dos constructores del objeto son:
Menu(), construye un Menú sin etiqueta
Menu(String label), construye un menú con etiqueta label.
Técnica de Programación Orientada a Objetos 118
¿Cómo Usar MonitoProgress?
Una tarea ejecutándose en un programa puede tardar un poco en completarse. Un programa amigable proporciona alguna indicación al usuario sobre lo que puede tardar la tarea y lo que ya lleva realizado.
El paquete Swing proporciona tres clases para ayudar a crear GUIs que monitoricen y muestren el progreso de tareas de larga duración.
JProgressBar
Una barra de progreso que muestra gráficamente qué cantitad total de la tarea se ha
terminado. Puedes ver Cómo usar Progress Bars para más información.
ProgressMonitor
Un ejemplar de esta clase monitoriza el progreso de una tarea. Si el tiempo enlapsado
de la tarea excede un valor especificado en el programa, el monitor trae un diálogo con
una descripción de la tarea, una nota de estado, una barra de progreso, un botón Ok, y
un botón Cancel. Puedes ver Cómo usar Progress Monitors para más detalles.
ProgressMonitorInputStream
Un stream de entrada con un monitor de progreso añadido, que monitoriza la lectura
desde el stream. Se utiliza un ejemplar de este stream como cualquier otro stream. Se
puede obtener el monitor de progreso del stream llamando a getProgressMonitor y
configurándolo como se describe en Cómo usar Progress Monitors.
Después de ver una barra de progreso y un monitor de progreso en acción, Decidir si utilizar una Barra o un Monitor de Progreso puede ayudarnos a decidir cuál es el apropiado para nuestra aplicación.
Técnica de Programación Orientada a Objetos 119
JFileChooser
JFileChooser es una clase java que nos permite mostrar fácilmente una ventana para la selección de un fichero. Si queremos abrirlo para leer el fichero, podemos llamarlo así A la vuelta, en seleccion tendremos
JFileChooser.CANCEL_OPTION Si el usuario le ha dado al botón cancelar.
JFileChooser.APPROVE_OPTION Si el usuario le ha dado al botón aceptar
JFileCHooser.ERROR_OPTION Si ha ocurrido algún error. Comprobando que se ha dado al botón aceptar, podemos obtener el fichero seleccionado por el usuario así Para seleccionar un fichero para guardar datos, el mecanismo es igual, pero se llama al método showSaveDialog() La única diferencia entre uno y otro es la etiqueta del diálogo y de los botones. Uno pondrá "Abrir" y otro "Guardar"
Filtrar los ficheros visibles
Si no queremos que el JFileChooser muestre todos los ficheros del directorio, podemos añadirle un filtro. Básicamente hay que hacer una clase que herede de FileFilter y definir el método accept(). Este método recibe un parémetro File y nosotros debemos decidir si pasa o no el filtro, devolviendo true o false. Por ejemplo, si sólo queremos ver fichero .jpg, podemos hacer este filtro.
JFileChooser fileChooser = new JFileChooser(); int seleccion = fileChooser.showOpenDialog(areaTexto);
if (seleccion == JFileChooser.APROVE_OPTION){ File fichero = fileChooser.getSelectedFile(); // Aquí debemos abrir y leer el fichero. ... }
JFileChooser fileChooser = new JFileChooser(); int seleccion = fileChooser.showSaveDialog(areaTexto); if (seleccion == JFileChooser.APPROVE_OPTION){ File fichero = fileChooser.getSelectedFile(); // Aquí debemos abrir el fichero para escritura // y salvar nuestros datos. ... }
Técnica de Programación Orientada a Objetos 120
Debemos definir ambos métodos. La descripción puede ser cualquier cadena de texto que nos sirva como descripción del filtro. Finalmente, debemos pasar este filtro al JFileChooser fileChooser.setFilter(new FiltroDeJPG()); Sin embargo, una de las bondades ofrecidas por el JDK 1.6, es el ahorro en la codificación de una clase filtro, pues este, ya viene con una incluida a la cual solo necesitamos invocarla, la sintaxis es la siguiente: Tenes definir un FileFilter , es decir, creas una clase que herede de FileFilter y le das las propiedades que deseas. Por ejemplo:
Import javax.swing.filechooser.FileFilter; ... public class FiltroDeJPG extends FileFilter{ public boolean accept (File fichero) { if (tieneExtensionJPG (fichero)) return true; else return false; } public String getDescription() { return ("Filtro JPGs"); } }
JFileChooser jf = new JFileChooser(); FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & GIF", "jpg", "gif"); jf.setFilter(filter);
JFileChooser chooser = new JFileChooser(); ExampleFileFilter filter = new ExampleFileFilter(); File fichero = null; filter.addExtension("txt"); filter.addExtension("bat"); filter.setDescription("Ficheros de texto"); chooser.setFileFilter(filter); int returnVal = chooser.showOpenDialog(this); if(returnVal == JFileChooser.APPROVE_OPTION) fichero = chooser.getSelectedFile();
Técnica de Programación Orientada a Objetos 121
Si queres trabajar con directorios tenes que cambiar el modo de selección usando la constante JFileChooser.DIRECTORIES_ONLY. El modo de selección también puede ser cambiado para permitir elegir mas de un fichero o directorio a la vez:
chooser.setFileSelectionMode(JFileChooser.DIRECTOR IES_ONLY);
Técnica de Programación Orientada a Objetos 122
JInternalFrame
Con la clase JInternalFrame, se puede mostrar un JFrame - como una ventana dentro de otra ventana. Para crear un frame interno que parezca un diálogo sencillo, se pueden utilizar los métodos showInternalXxxDialog de JOptionPane, como se explicó en Cómo crear Diálogos.
Normalmente, los frames internos se muestran dentro de un JDesktopPane.
JDesktopPane es una subclase de JLayeredPane al que se le ha añadido el API para manejar
el solapamiento de múltiples frames internos. Generalmente, se pone el panel superior dentro
del panel de contenido de un JFrame.
public class Frame1 extends JFrame {
private JDesktopPane jDesktopPane1 = new JDesktopPane();
private JInternalFrame hija1 = new JInternalFrame();
private JDesktopPane jDesktopPane2 = new JDesktopPane();
private JInternalFrame hija2 = new JInternalFrame();
private void jbInit() throws Exception {
………………………………….
jDesktopPane1.add(hija1, null);
jDesktopPane2.add(hija2, null);
Técnica de Programación Orientada a Objetos 123
hija1.getContentPane().setLayout(null);
hija2.getContentPane().setLayout(null);
hija1.setVisible(true);
hija2.setVisible(true);
}
}
Para poder visualizar las ventanas u ocultarlas podra usar el metodo setVisble true o false en el
momento que usted desee ver la ventana deseada.
Técnica de Programación Orientada a Objetos 124
Implementación de Librerías
En la mayoría de los sistemas operativos actuales, se ofrece una cantidad de código para simplificar la tarea de programación. Este código toma la forma, normalmente, de un conjunto de librerías dinámicas que las aplicaciones pueden llamar cuando lo necesiten. Pero la Plataforma Java está pensada para ser independiente del sistema operativo subyacente, por lo que las aplicaciones no pueden apoyarse en funciones dependientes de cada sistema en concreto. Lo que hace la Plataforma Java, es ofrecer un conjunto de librerías estándar, que contiene mucha de las funciones reutilizables disponibles en los sistemas operativos actuales.
Las librerías de Java tienen tres propósitos dentro de la Plataforma Java. Al igual que otras librerías estándar, ofrecen al programador un conjunto bien definido de funciones para realizar tareas comunes, como manejar listas de elementos u operar de forma sofisticada sobre cadenas de caracteres. Además, las librerías proporcionan una interfaz abstracta para tareas que son altamente dependientes del hardware de la plataforma destino y de su sistema operativo. Tareas tales como manejo de las funciones de red o acceso a ficheros, suelen depender fuertemente de la funcionalidad nativa de la plataforma destino. En el caso concreto anterior, las librerías java.net y java.io implementan el código nativo internamente, y ofrecen una interfaz estándar para que aplicaciones Java puedan ejecutar tales funciones. Finalmente, no todas las plataformas soportan todas las funciones que una aplicación Java espera. En estos casos, las librerías bien pueden emular esas funciones usando lo que esté disponible, o bien ofrecer un mecanismo para comprobar si una funcionalidad concreta está presente.
Creación de Archivos Jar Ejecutable
Los ejecutables en JAVA, no son ".exe", debemos tomar esto en cuenta. Pues si fueran .exe solo funcionarían en Windows, y como JAVA es multiplataforma, es por ello que tiene otra forma de ejecutar sus archivos. No requieren de un IDE para ejcutarse, el IDE, lo unico que hace es probar si todo funciona correctamente, y ejecutarle en tiempo de desarrollo del programa, pero no para producción. Los programas en JAVA, para ser ejecutados pasan por dos procesos, uno de compilación (o pseudo compilación) y otro de interpretación (que es en si la ejecución), la compilación es para convertir el código fuente (.java) en (.class) de esa manera se obtienen un archivo independiente de la plataforma. Que puede ser distribuido incluso por la red, por su ligero tamaño. (por eso decimos que JAVA es un lenguaje de red). El proceso de Interpretación lo hace el JRE (java runtime engine), ayudado claro, con el plugin, que esta preinstalado en el sistema operativo. El JRE, es independiente de la plataforma tambien, pero el plugin, si es dependiente de la plataforma (Sistema operativo), pero como este plugin viene desde fábrica, entonces, es transparente para nosostros. Si quieres tener un archivo ejecutable de JAVA, siempre tendra que seguir estos dos pasos, compilar y ejecutarse(interpretarse). Si es windows, creas un BAT, y si es linux, creas un SCRIPT, que te haga las veces de "ejecutor". Si no quieres esa manera, tienes otra forma más estándar, por el lado de JAVA, tenemos a los archivos ".jar", que son archivos que pueden compimir a un conjunto de clases JAVA, y que pueden ser ejecutados por los Sistemas operativos, si tiene una clase ocn un método "main"
Técnica de Programación Orientada a Objetos 125
Pasos para crear el Jar (datos comprimidos)
1. Apertura su aplicación que desee crear como ejecutable: 2. Luego sleccionar con click derecho el proyecto 3. Elegir new y aparecerá esta ventana(seguir los 4 pasos)
4. Luego establecer el nombre del archivo Ejecutable
5. Al darle aceprtar aparecerá esta ventana donde deberá de elegir la clase que ejecute la aplicación (clase Main), busque la clase.
1
1 1
1
2 3
3
4
3
Técnica de Programación Orientada a Objetos 126
6. El nombre se establecera en el main Class de la ventana
Técnica de Programación Orientada a Objetos 127
Contenidos
Threads ____________________________________________________________________________
Una thread es un único flujo de contrrol dentro de un programa. Algunnaas veces es llammado contexto de ejecución porque cada thread debe tenner sus propios recurssos, como el prrogram counter y el stack de ejecución, como el contexto dee ejecución. Sin embargo, toda thread en un programa aun comparte muchos recursos, tales como espacio de memoria y archivvos abiertos. Threads tambien son llamadas procesos livianos (lightweight prrocess).
Compartición de datos
Todos los hilos de proceso que pertenecen a un mismo proceso comparten un área común de datos que sirve para intercambiar información entre ellos. No es necesario acudir a técnicas de comunicación entre procesos tales como paso de mensajes, ya que todos los hilos son capaces de acceder directamente a los datos compartidos.
Por otro lado, la conmutación entre hilos de un mismo proceso es muy rápida, puesto que la cantidad de información que ha de ser salvada y/o restaurada por el sistema es mucho menor. Por eso, cuando se trata con hilos siempre se habla de cambios de contexto ligeros, en contraposición a los cambios de contexto pesados, que implican el manejo de procesos.
Técnica de Programación Orientada a Objetos 128
Ejemplo 01
Crear una Aplicación que presente la hora del sistema usando hilos.
public class PanelReloj extends JPanel{
JLabel reloj;
public PanelReloj(){
reloj= new JLabel("", JLabel.CENTER);
reloj.setForeground(Color.blue);
reloj.setFont(new Font("Arial", Font.BOLD, 30));
add(reloj, BorderLayout.CENTER);
MiReloj hilo= new MiReloj(reloj);
hilo.start();
try {
jbInit();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class MiReloj extends Thread{
JLabel lblReloj;
// constructor
public MiReloj(JLabel lblReloj){
this.lblReloj= lblReloj;
}
// puesta en marcha del hilo
public void run() {
while(true) {
Date hoy= new Date();
SimpleDateFormat sdf= new SimpleDateFormat("hh:mm:ss");
lblReloj.setText(sdf.format(hoy));
try { sleep(1000); } catch (Exception ex) {}
}
}
}
Técnica de Programación Orientada a Objetos 129
public class CFrmP extends JFrame{
public static void main(String[] arg){
CFrmP ver = new CFrmP ();
PanelReloj panel = new PanelReloj();
ver.setContentPane(panel);
ver.setSize(250,100);
ver.setLocationRelativeTo(null);
ver.setVisible(true);
}
}
Ejemplo 02
crear el Panel por medio de Codigo: Solo inserte el panel y digite los siguiente, crea una
clase main y una subclase.
public class PanelCarrera extends JPanel implements ActionListener{
public JLabel lblJ1 = new JLabel("1",JLabel.CENTER);
public JLabel lblJ2 = new JLabel("2",JLabel.CENTER);
JLabel barrera=new JLabel();
JButton b= new JButton("Inicia carrera");
//Constructor
public PanelCarrera(){
setLayout(new BorderLayout());
JPanel p= new JPanel();
p.setLayout(null);
lblJ1.setBounds(0,25, 20,20);
lblJ1.setBackground(Color.blue);
lblJ1.setOpaque(true);
lblJ1.setForeground(Color.white);
lblJ2.setBounds(0,50, 20, 20);
lblJ2.setBackground(Color.red);
lblJ2.setOpaque(true);
lblJ2.setForeground(Color.white);
barrera.setBounds(310,0, 2,400);
barrera.setBackground(Color.green);
barrera.setOpaque(true);
b.addActionListener(this);
p.add(lblJ1);
p.add(lblJ2);
Técnica de Programación Orientada a Objetos 130
p.add(barrera);
add(p, BorderLayout.CENTER);
add(b, BorderLayout.SOUTH);
}
public void actionPerformed(ActionEvent e){
lblJ1.setLocation(0, lblJ1.getLocation().y);
lblJ2.setLocation(0, lblJ2.getLocation().y);
ClassCarreraHilo st1= new ClassCarreraHilo(lblJ1, this);
ClassCarreraHilo st2= new ClassCarreraHilo(lblJ2, this);
st1.start();
st2.start();
}
}
// creación de la clase Hilo
class ClassCarreraHilo extends Thread{
JLabel eti;
PanelCarrera p;
//contructor de la clase
public ClassCarreraHilo(JLabel eti, PanelCarrera p){
this.eti=eti;
this.p= p;
}
// meto de inicializacion de la clase Threads
public void run() {
int c1, c2;
while(true){
//usando un un Try
try {
//usando sleep de la clase threads
sleep((int)(Math.random() * 1000));
c1= p.lblJ1.getLocation().x;
c2= p.lblJ2.getLocation().x;
if(c1<290 && c2<290){
eti.setLocation(eti.getLocation().x + 10, eti.getLocation().y);
//usando el panel
p.repaint();
}
else break;
} catch (InterruptedException e) {}
}
Técnica de Programación Orientada a Objetos 131
// determina el ganador si alguien llegó a la meta
if (eti.getLocation().x>=290)
if (c1>c2)
JOptionPane.showMessageDialog(null,"Gano 1");
else if (c2>c1)
JOptionPane.showMessageDialog(null,"Gano 2");
else
JOptionPane.showMessageDialog(null,"Empate");
}
}
// Usando el Jframe dentro de una clase con herencia de las propiedades del Frame
public class ClassFrmHiloJuego extends JFrame{
public static void main(String[] arg){
ClassFrmHiloJuego Carrera = new ClassFrmHiloJuego();
PanelCarrera panel = new PanelCarrera();
Carrera.setContentPane(panel);
Carrera.setSize(350,200);
Carrera.setTitle("Juego de 2 - Ganador Aleatorio - VER");
Carrera.setLocationRelativeTo(null);
Carrera.setVisible(true);
}
}
Técnica de Programación Orientada a Objetos 132
Ejemplo 03
Muestre la palabra SISEpuede cada cierto tiempo
public class ClassBlink implements Runnable {
Thread Blink=new Thread(this);
JLabel tiempo=new JLabel();
public ClassBlink() {
JFrame ventana = new JFrame("Visualizar Palabra");
ventana.setSize(250,100);
ventana.setVisible(true);
ventana.add(tiempo);
//Blink=new Thread(this);
Blink.start();
try {
jbInit();
} catch (Exception e) {
e.printStackTrace();
}
}
public void run(){
try {
while(true){
tiempo.setText("Sise puede..");
Blink.sleep(1000);
tiempo.setText(" ");
Blink.sleep(1000);
}
} catch (InterruptedException ex) {
System.out.println("Error...");
}
}
public static void main(String[] args) {
new ClassBlink();
}
private void jbInit() throws Exception {
tiempo.setBackground(new Color(0, 0, 165));
tiempo.setForeground(new Color(247, 255, 214));
tiempo.setOpaque(true);
tiempo.setFont(new Font("Dialog", 1, 21));
}
}
Técnica de Programación Orientada a Objetos 133
Proyecto Final: Caso Practico.
Crear un Proyecto final donde aplique la Tecnica de programación orientada a Objetos
(herencias, sobrecarga de métodos, encapsulamiento), uso de métodos, paneles establecer
archivos, uso de imágenes, hilo para el reloj activo, etc.
Todos los datos estarán guardados dentro de un Archivo llama Datos.txt
La estructura a trabajar seria:
Agregue al Proyecto una Interface llamada intImpleMetodoso en el Paquete pckInterface
donde defina todos los metodos a utilizar por el proyecto
Técnica de Programación Orientada a Objetos 134
Ademas Agregue 2 Frame en la capa Presentacion:
Para el Acceso de Usuario: Que estarán registrados dentro un Archivo.
Para el reporte de Datos: donde mostrara, el total de sueldos desembolsados por la
empresa, total de descuentos, aumentos y netos, cuantos tuvieron aumentos y cuantos
descuentos
Presentación Final
Panel Encabezado
Panel Pie: use la Clase GregorianCalendar y Hilos
Panel Listado: usara el JFileChooiser para jalar la foto
Técnica de Programación Orientada a Objetos 135
El botón agregar solo almacenara datos al ArrayList, lo botones modificar, eliminar, dependerá
de la selección del JTable y buscar pedirá el numero para mostrar todos los elementos en el
panel contenido.
Panel Contenido
Todos permitirá mostrar todos los datos dentro del arrayList asi como aquellos que ya estaban
en el archivo.
X apellido: según a las letras o palabra completa se realizará el filtro por apellidos en el Jtable.
Técnica de Programación Orientada a Objetos 136
Contenidos
Introducción a la Plataforma .NET o Componentes de la Plataforma .NET: NET Framework, Building Block
Services, Visual Studio .NET, .NET Enterprise Servers o NET Framework: Beneficios. Lenguajes. Componentes: CLR, Class
Library, ADO.NET, ASP .NET, Web Forms, Windows Forms. o Namespaces o Entorno integrado de Visual Studio .NET 2005
Variables y Tipos de Datos o Tipos de Datos. Conversión Explícita e Implícita de Tipos. o Funciones de Conversión. o Variables. Ámbito: Local, Privado y Público o Estructuras. Creación y Uso. Declaración. Enumeraciones.
Diseño de Aplicaciones Windows en Visual Basic .NET 2005 o Windows Forms. Propiedades y Eventos. o Controles Básicos: TextBox, Label, Button. Propiedades y Eventos o Eventos y Delegados. La palabra clave Handles
Introducción a la Plataforma .NET
Si bien solemos tener la sensación de que los paradigmas de programación de tecnologías
Microsoft se encuentran en constante cambio, la realidad nos muestra que los grandes cambios
vienen ocurriendo aproximadamente cada 10 años. Uno de ellos se dio a finales de la década
de 1990 y principios de la década del 2000, con el desarrollo y la introducción al mercado de la
plataforma Microsoft .NET. Hubo varios factores que motivaron al desarrollo de esta plataforma,
entre los cuales podemos mencionar:
- La amplia disponibilidad de conexiones a Internet de alta velocidad, e incluso inalámbricas
- La proliferación de nuevos tipos de dispositivos de hardware que son usados en la vida diaria (teléfonos inteligentes, Pocket PC‟s, HandHelds, Media Centers, etc.)
- El creciente poder de cómputo de las computadoras personales y servidores basados en arquitecturas x86.
- El surgimiento de estándares de Internet para permitir la comunicación e integración entre diversas plataformas de software.
Técnica de Programación Orientada a Objetos 137
Que no es .NET?
Antes de decir qué es .NET, es conveniente aclarar qué NO es .NET:
- .NET no es un sistema operativo, como si lo es Microsoft Windows en sus distintas versiones.
- .NET no es un Lenguaje de Programación: si bien la plataforma Microsoft .NET incluye lenguajes de programación de aplicaciones, su concepto es más amplio y va más allá de éstos.
- .NET no es un Entorno de Desarrollo: si bien la plataforma Microsoft .NET incluye entornos de desarrollo integrados (IDEs), su concepto es más amplio y va más allá de éstos.
- .NET no es un servidor de aplicaciones (Application Server) - .NET no es un producto empaquetado que se pueda comprar como tal, sino que es una
plataforma que engloba distintas aplicaciones, servicios y conceptos y que en conjunto permiten el desarrollo y la ejecución de aplicaciones.
¿Qué es .NET?Plataforma de Desarrollo compuesta de Entorno de Ejecución (Runtime) Bibliotecas de Funcionalidad (Class Library) Lenguajes de Programación Compiladores Herramientas de Desarrollo (IDE & Tools) Guías de Arquitectura
La evolución de la plataforma COM
Microsoft .NET es una plataforma de desarrollo y ejecución de aplicaciones. Esto quiere decir
que no sólo nos brinda todas las herramientas y servicios que se necesitan para desarrollar
modernas aplicaciones empresariales y de misión crítica, sino que también nos provee de
mecanismos robustos, seguros y eficientes para asegurar que la ejecución de las mismas sea
óptima. Los componentes principales de la plataforma .NET son:
Un entorno de ejecución de aplicaciones, también llamado “Runtime”, que es un componente de software cuya función es la de ejecutar las aplicaciones .NET e interactuar con el sistema operativo ofreciendo sus servicios y recursos.
Un conjunto de bibliotecas de funcionalidades y controles reutilizables, con una enorme cantidad de componentes ya programados listos para ser consumidos por otras aplicaciones.
Un conjunto de lenguajes de programación de alto nivel, junto con sus compiladores y linkers, que permitirán el desarrollo de aplicaciones sobre la plataforma .NET.
Un conjunto de utilitarios y herramientas de desarrollo para simplificar las tareas más comunes del proceso de desarrollo de aplicaciones.
Documentación y guías de arquitectura, que describen las mejores prácticas de diseño, organización, desarrollo, prueba e instalación de aplicaciones .NET
Técnica de Programación Orientada a Objetos 138
Componentes de la Plataforma .NET
Las tecnologías intrínsecas que integran la plataforma .NET incluyen:
NET Framework
El .NET Framework se basa en un nuevo entorno de ejecución de lenguaje común
(CLR - Common Language Runtime). Este motor de ejecución proporciona un conjunto
de servicios comunes para los proyectos generados en Visual Studio .NET, con
independencia del lenguaje. Estos servicios proporcionan bloques de desarrollo
fundamentales para aplicaciones de cualquier tipo, para todas las capas y niveles de la
arquitectura de aplicaciones.
Servicios .NET Building Blocks
Los servicios .NET Building Block son servicios programables distribuidos que están
disponibles tanto en modo conectado como desconectado. Un servicio puede invocarse
desde un ordenador aislado no conectado a Internet, ofrecido por un servidor local
dentro de una empresa, o puede ser accedido a través de Internet. Los servicios .NET
Building Blocks pueden utilizarse desde cualquier plataforma que soporte el protocolo
SOAP. Los servicios pueden incluir identidad, notificación y mensajería,
personalización, almacenamiento esquematizado, calendario, directorio, búsqueda y
distribución de software.
Visual Studio .NET
Visual Studio .NET ofrece un entorno de desarrollo de alto nivel para desarrollar
aplicaciones que se ejecutan sobre el .NET Framework. Proporciona las tecnologías
fundamentales para simplificar la creación, implantación y evolución constante de
aplicaciones y Servicios Web seguros, escalables y de alta disponibilidad. También
permite crear una nueva generación de aplicaciones basadas en Windows con
numerosas y nuevas características disponibles gracias al .NET Framework.
Servidores .NET Enterprise Servers
Los servidores .NET Enterprise Servers proporcionan escalabilidad, fiabilidad, gestión e
integración dentro de la empresa y entre organizaciones, tales como Microsoft SQL
Server™ 2005.
Técnica de Programación Orientada a Objetos 139
NET FRAMEWORK
El .NET Framework proporciona todos los servicios comunes necesarios para ejecutar las
aplicaciones Visual Basic .NET.
Crear componentes en el .NET Framework
Antes del modelo COM, las aplicaciones estaban formadas por entidades totalmente separadas
con poca o ninguna integración. Al utilizar COM, es posible integrar componentes dentro de
una aplicación y entre aplicaciones exponiendo una serie de interfaces comunes. Sin embargo,
todavía es necesario que los desarrolladores escriban el código para envolver, gestionar e
integrar componentes y objetos. En el .NET Framework, los componentes se construyen sobre
una base común. Ya no es necesario escribir código para permitir que los objetos interactúen
directamente entre sí. En el entorno .NET, ya no es necesario escribir envoltorios de
componentes, puesto que los componentes no los utilizan. El .NET Framework puede
interpretar las construcciones a los que los desarrolladores están acostumbrados utilizando
lenguajes orientados a objetos. El .NET Framework soporta totalmente clases, herencia,
métodos, propiedades, eventos, polimorfismo, constructores y otras construcciones orientadas
a objetos.
Common Language Specification
La especificación Common Language Specification (CLS) define los mínimos estándares que
deben satisfacer los lenguajes y desarrolladores si desean que sus componentes y
aplicaciones sean ampliamente utilizados por otros lenguajes compatibles con .NET. La
especificación CLS permite a los desarrolladores de Visual Basic .NET crear aplicaciones como
parte de un equipo que utiliza múltiples lenguajes con la seguridad de que no habrá problemas
con la integración de los diferentes lenguajes. La especificación CLS también permite a los
desarrolladores de Visual Basic .NET heredar de clases desarrolladas en lenguajes diferentes.
Técnica de Programación Orientada a Objetos 140
Visual Studio .NET
En el .NET Framework, Visual Studio .NET ofrece las herramientas que permiten el desarrollo
rápido de aplicaciones.
1. Beneficios
El .NET Framework fue diseñado para satisfacer los siguientes objetivos:
Basado en estándares y prácticas Web
El .NET Framework soporta totalmente las tecnologías existentes de Internet, incluyendo
Hypertext Markup Language (HTML), XML, SOAP, Extensible Stylesheet Language for
Transformations (XSLT), Xpath y otros estándares Web. El .NET Framework promueve la
creación de servicios Web débilmente conectados y sin estado.
Extensible
La jerarquía del .NET Framework no queda oculta al desarrollador. Podemos acceder y
extender clases .NET (a menos que estén selladas) utilizando herencia. También podemos
implementar herencia multi-lenguaje.
Fácil de usar por los desarrolladores
En el .NET Framework, el código está organizado en espacios de nombres jerárquicos y
clases. El Framework proporciona un sistema de tipos común, denominado sistema de
tipos unificado, que utiliza cualquier lenguaje compatible con .NET. En el sistema de tipos
unificado, todo es un objeto. No existen tipos variant, sólo hay un tipo de cadena (string), y
todos los datos de la cadena son Unicode.
Diseñado utilizando modelos de aplicaciones unificados
La funcionalidad de una clase .NET está disponible desde cualquier modelo de
programación o lenguaje compatible con .NET.
Técnica de Programación Orientada a Objetos 141
2. Lenguajes La plataforma .NET es independiente del lenguaje (el .NET Framework proporciona
todos los servicios comunes necesarios para permitir la ejecución de los programas). El
.NET Framework ofrece soporte para numerosos lenguajes de programación,
incluyendo lenguajes de Microsoft y de terceros.
Microsoft Visual Basic .NET
Visual Basic .NET ofrece importantes innovaciones del lenguaje respecto a versiones
anteriores de Visual Basic. Visual Basic .NET soporta herencia, constructores,
polimorfismo, sobrecarga, excepciones estructuradas, estricta verificación de tipos, free
threading, y muchas otras características. En esta versión, Visual Basic Scripting
Edition proporciona funcionalidad completa Visual Basic.
Microsoft Visual C#
C# ha sido diseñado específicamente para la plataforma .NET y es el primer lenguaje
moderno orientado a componentes de la familia de C y C++. Puede incrustarse en
páginas ASP.NET. Algunas de las principales características de este lenguaje incluyen
clases, interfaces, delegados, boxing y unboxing, espacios de nombres, propiedades,
indexadores, eventos, sobrecarga de operadores, versionado, atributos, código
inseguro, y la creación de documentación en formato XML. No son necesarios archivos
de cabecera ni archivos IDL (Interface Definition Language).
Extensiones gestionadas C++
La actualización de Visual C++ es una mínima extensión gestionada del lenguaje C++.
Esta extensión proporciona acceso al .NET Framework incluyendo el recolector de
basura, herencia de implementación simple y herencia de interfaz múltiple. Esta
actualización también elimina la necesidad de escribir código de fontanería para los
componentes. Ofrece acceso a bajo nivel donde sea necesario.
Microsoft J#
J# .NET es un lenguaje para los desarrolladores que utilicen el lenguaje Java que
quieran generar las aplicaciones y servicios para el .NET Framework. J# .NET está
totalmente integrado con el IDE de Visual Studio .NET y está diseñado para aprovechar
al máximo el .NET Framework.
Lenguajes de terceros
Varios lenguajes de terceros soportan la plataforma .NET. Estos lenguajes incluyen
APL, COBOL, Pascal, Eiffel, Haskell, ML, Oberon, Perl, Python, Scheme y SmallTalk.
Técnica de Programación Orientada a Objetos 142
3. Componentes Los componentes principales del .NET Framework son los siguientes:
Common Language Runtime - CLR
Biblioteca de clases del .NET Framework
ADO.NET: datos y XML
ASP.NET: Formularios Web y Servicios Web
Interfaz de usuario
3.1. COMMON LANGUAGE RUNTIME
El CLR (Common Language Runtime) simplifica el desarrollo de aplicaciones,
proporciona un entorno de ejecución robusto y seguro, soporta múltiples lenguajes,
simplifica la implantación y administración de aplicaciones y proporciona un entorno
gestionado.
Técnica de Programación Orientada a Objetos 143
¿Qué es un entorno gestionado?
Un entorno gestionado es aquel que proporciona servicios comunes de forma
automática. Algunos ejemplos de los tipos de servicios que proporciona un entorno
gestionado son el recolector de basura y la seguridad.
Componentes del Common Language Runtime
La siguiente tabla describe las características del Common Language Runtime.
3.2. CLASS LIBRARY
La biblioteca de clases del .NET Framework expone características del entorno de
ejecución y proporciona en una jerarquía de objetos otros servicios de alto nivel que
todo programador necesita. Esta jerarquía de objetos se denomina espacio de
nombres.
Técnica de Programación Orientada a Objetos 144
Espacios de nombres System
El espacio de nombres System contiene clases fundamentales y clases base que
definen tipos de datos valor y referencia comúnmente utilizados, eventos y descriptores
de eventos, interfaces, atributos y procesamiento de excepciones. Otras clases
proporcionan servicios como la conversión de tipos de datos o la manipulación de
parámetros de métodos, operaciones matemáticas, invocación local y remota de
programas, administración de los entornos de aplicaciones y la supervisión de
aplicaciones gestionadas y no gestionadas.
El espacio de nombre System.Collections proporciona listas clasificadas, tablas hash
y otras formas de agrupar datos. El espacio de nombres System.IO proporciona E/S de
archivos, flujos, etc. El espacio de nombres System.NET proporciona soporte de
Transmission Control Protocol/Internet Protocol (TCP/IP) y sockets. Si desea más
información sobre los espacios de nombres, realice una búsqueda de “espacio de
nombres” en la documentación del .NET Framework SDK.
3.3. ADO .NET Y XML
ADO.NET es la siguiente generación de la tecnología ActiveX® Data Objects (ADO).
ADO.NET proporciona un soporte mejorado para el modelo de programación
desconectado. También ofrece un completo soporte de XML.
Espacio de nombres System.Data
El espacio de nombres System.Data está compuesto por clases que constituyen el
modelo de objetos ADO.NET. A alto nivel, el modelo de objetos ADO.NET se divide en
dos capas: la capa conectada y la capa desconectada. El espacio de nombres
System.Data incluye la clase DataSet, que representa múltiples tablas y sus
relaciones. Estos conjuntos de datos son estructuras de datos completamente
autocontenidas que pueden poblarse desde diversas fuentes de datos. Una posible
Técnica de Programación Orientada a Objetos 145
fuente de datos podría ser XML, otra podría ser OLE DB, y una tercera fuente de datos
podría ser el adaptador directo para SQL Server.
Espacio de nombres System.Xml
El espacio de nombres System.Xml proporciona soporte para XML. Incluye un
parseador y un escritor XML, siendo compatibles con el W3C. Las transformaciones las
proporciona el espacio de nombres System.Xml.Xsl y la implementación de XPath que
permite navegación de grafos de datos en XML. El espacio de nombres
System.XML.Serialization proporciona toda la infraestructura básica para los Servicios
Web, incluyendo características como el movimiento atrás y adelante entre objetos y
una representación XML.
3.4. ASP.NET: WEB FORMS Y WEB SERVICES
ASP.NET es un marco de trabajo de programación basado en el Common Language
Runtime y que puede ser utilizado en un servidor para crear potentes aplicaciones
Web. Los Formularios Web de ASP.NET proporcionan una forma fácil y potente de
Técnica de Programación Orientada a Objetos 146
generar interfaces de usuario (IUs) Web dinámicos. Los Servicios Web de ASP.NET
proporcionan las piezas para construir aplicaciones distribuidas basadas en la Web.
Los Servicios Web están basados en estándares abiertos de Internet, como HTTP y
XML. Podemos pensar en un Servicio Web como un componente reutilizable accesible
a través de Internet, en lugar de estar limitado a clientes Windows en una red de área
local.
El Common Language Runtime proporciona un soporte nativo para crear y exponer
Servicios Web utilizando una abstracción de programación coherente y familiar para
desarrolladores tanto de Active Server Pages (ASP) como de Visual Basic. El modelo
resultante es escalable y extensible. Este modelo se basa en estándares abiertos de
Internet (HTTP, XML, SOAP y SDL) y, por tanto, puede ser accedido e interpretado
desde cualquier cliente o dispositivo habilitado para Internet. Algunas de las clases
ASP.NET más habituales se describen en los siguientes párrafos.
Espacio de nombres System.Web
En el espacio de nombres System.Web, existen servicios como la gestión de caché,
seguridad, configuración y otros que son compartidos por los Servicios Web y por el
interfaz de usuario (IU) Web.
Espacio de nombres System.Web.Services
El espacio de nombres System.Web.Services gestiona los requerimientos de los
Servicios Web como los protocolos de transporte y el descubrimiento de servicios.
Espacio de nombres System.Web.UI
El espacio de nombres System.Web.UI proporciona dos clases de controles: los
controles HTML y los controles Web. Los controles HTMLControl proporcionan un
mapeado directo de las etiquetas HTML, como <INPUT>. Existen también otros
controles WebControl más ricos que permiten estructurar controles mediante plantillas
(por ejemplo, un control de rejilla).
3.5. INTERFAZ DE USUARIO
Técnica de Programación Orientada a Objetos 147
Las aplicaciones Windows pueden ahora proporcionar interfaces de usuario más
potentes que nunca utilizando los espacios de nombres System.Windows.Forms y
System.Drawing del .NET Framework. El aspecto de los nuevos formularios Windows
Forms de .NET resultará muy familiar para los desarrolladores de Visual Basic.
Espacio de nombres System.Windows.Forms Podemos utilizar las clases del
espacio de nombres System.Windows.Forms para crear el IU cliente. Esta clase nos
permite implementar el IU de Windows estándar en nuestras aplicaciones .NET.
Muchas funciones a las que anteriormente sólo podían accederse mediante llamadas a
la API (Application Programming Interface) están ahora disponibles como parte de los
propios formularios, lo cual hace el desarrollo mucho más fácil y potente.
Espacio de nombres System.Drawing El espacio de nombres System.Drawing
proporciona acceso a la funcionalidad de gráficos básica de GDI+. Los espacios de
nombres System.Drawing.Drawing2D, System.Drawing.Imaging y
System.Drawing.Text ofrecen funcionalidades más avanzadas.
Técnica de Programación Orientada a Objetos 148
NAMESPACES
.NET Framework incluye un gran conjunto de ensamblados que forman las bibliotecas de
clases, que conjuntamente contienen cientos de tipos. Estos ensamblados proporcionan
acceso a funcionalidades del sistema en nuestro proceso de desarrollo.
Objetivo de los espacios de nombres
Debido a que la biblioteca de clases del .NET Framework incluye definiciones para numerosos
tipos, la biblioteca se organiza en un espacio de nombres de estructura jerárquica.
Los espacios de nombres utilizan un esquema nombres con una sintaxis basada en un punto
para agrupar lógicamente clases relacionadas de modo que puedan buscarse y reverenciarse
fácilmente. Por ejemplo, el espacio de nombres System.Data contiene clases que constituyen
la arquitectura de ADO.NET. El espacio de nombres System.Xml es el espacio de nombres
global para todas las clases XML que proporcionan soporte basado en estándares para
procesar XML.
El espacio de nombres System
El espacio de nombres System es el espacio de nombres raíz para los tipos en el .NET
Framework. El espacio de nombres System contiene el tipo base Object, desde el que se
derivan otros tipos.
El espacio de nombres System también contiene tipos para la gestión de excepciones,
recolector de basura, E/S de consola, varios tipos de herramientas, tipos de datos de formato,
generadores de números aleatorios y funciones matemáticas.
Introducción a los Tipos de Datos
El tipo de datos de un elemento de
programación hace referencia a la clase de
datos que puede contener y a cómo se
almacenan los datos. El sistema de tipos
comunes (Common Type System – CTS)
define los tipos de datos que soporta el
Common Language Runtime. Visual Basic
.NET utiliza tipos de datos que se
corresponden directamente con los tipos de
datos del sistema de tipos comunes.
Técnica de Programación Orientada a Objetos 149
¿Qué es el sistema de tipos comunes?
El sistema de tipos comunes define cómo se declaran, utilizan y gestionan los tipos en el
Common Language Runtime. Cada tipo de datos utilizado en Visual Basic .NET corresponde
directamente a un tipo definido en el sistema de tipos comunes.
Ventajas del sistema de tipos comunes
El sistema de tipos comunes tiene una gran importancia en la creación de aplicaciones para la
plataforma Microsoft .NET. Hace posible que un desarrollador pueda crear un proyecto en
Visual Basic .NET e integrarlo con un componente creado por otro desarrollador en Microsoft
Visual C#™ y una función escrita por un tercer desarrollador en otro lenguaje compatible con
.NET. Todas estas piezas pueden integrarse en una única solución. Los compiladores y
herramientas de Microsoft Visual Studio® .NET y el Common Language Runtime dependen del
sistema de tipos comunes para proporcionar:
o Integración entre lenguajes.
Código con seguridad de tipos, lo que significa que únicamente se accede a los tipos de forma
permisible y bien definida.
Las herramientas que gestionan y permiten una ejecución del código de alto rendimiento.
o Tipo valor vs. Tipo referencia
El sistema de tipos comunes soporta dos categorías generales de tipos: tipos valor y tipos
referencia.
Una variable de tipo valor contiene directamente sus datos. Cada variable de tipo valor tiene su
propia copia de datos, de modo que las operaciones en una variable de tipo valor no pueden
afectar a otra variable.
Una variable de tipo referencia contiene una referencia o puntero al valor de un objeto. Dos
variables de tipo referencia pueden referirse al mismo objeto, de modo que las operaciones en
Técnica de Programación Orientada a Objetos 150
una variable de tipo referencia pueden afectar al objeto referenciado por otra variable de tipo
referencia.
Tipos de datos
.NET Framework VB .NET C# Descripción
Boolean Boolean bool True / false
Byte Byte byte 0 a 255
Int16 Short short -32768 a 32767
Int32 Integer int
-2147483648 a
2147483647
Int64 Long long -10 E19 a 10 E19
Single Single float -10 E38 a 10 E38
Double Double double -10 E308 a 10 E308
Decimal Decimal decimal -10 E28 a 10 E28
DateTime Date System.DateTime 1/1/0001 a 31/12/9999
String String string -
Char Char char -
Object Object object -
Sbyte SByte sbyte -128 a 127
UInt16 UShort ushort 0 a 65535
UInt32 UInteger uint 0 a 4.294.967.295
UInt64 ULong ulong 0 a 1.8 E19
A estos tipos de datos se les conoce como TIPOS PRIMITIVOS.
Los TIPOS PRIMITIVOS forman parte del CTS (COMMON TYPE LANGUAGE). Los
últimos tipos de datos forman parte del CTS pero no del CLS (COMMON LANGUAGE
SPECIFICATION), y no deben ser usados si se desea crear aplicaciones que
interoperen con otros lenguajes de .NET.
Cuando a una variable a la que se le ha asignado un valor, sobrepasa el rango tolerado se dice que ocurre un ERROR DE DESBORDAMIENTO (OVERFLOW).
Técnica de Programación Orientada a Objetos 151
Cómo escoger un tipo de dato
Visual Basic no requiere que seleccione explícitamente un tipo de datos cuando declara una
variable. Sin embargo, es una buena idea hacerlo, ya que de esta forma sus aplicaciones serán
más fiables y requerirán menos memoria. El tipo de datos determina los valores permitidos para
una variable, que, a su vez, determinan las operaciones que pueden realizarse sobre esa
variable.
Seleccionar un tipo de datos
Puede seguir las directrices generales que se muestran en la ilustración anterior para
seleccionar el tipo de datos adecuado para una variable.
Tipado fuerte
Si usted declara variables sin tipo de datos, se les otorga de forma predeterminada el tipo de
datos Object. Esto facilita la escritura rápida de programas, pero puede hacer que éstos se
ejecuten más lentamente. La especificación de tipos de datos para todas sus variables se
denomina tipado fuerte. Se recomienda el uso de tipado fuerte porque:
Minimiza la cantidad de memoria que utiliza la aplicación.
Permite al compilador realizar la verificación de tipos. Este proceso detecta las instrucciones que pueden fallar en tiempo de ejecución debido a variables y valores que no concuerdan.
La ejecución del código es más rápida.
Permite el soporte de Microsoft IntelliSense® en sus variables. Esta tecnología permite ver sus propiedades y demás miembros mientras escribe el código.
Técnica de Programación Orientada a Objetos 152
Uso de variables
Antes de que pueda utilizar una variable en su aplicación, necesita nombrar, declarar la variable y asignarle un valor.
¿Qué son las variables?
A menudo, cuando realizamos cálculos en Visual Basic necesitamos almacenar valores temporalmente. Por ejemplo, es posible que necesitemos calcular varios valores, compararlos y realizar diferentes operaciones con ellos dependiendo del resultado de la comparación.
Utilizamos variables para almacenar valores que pueden cambiar cuando una aplicación se está ejecutando.
Técnica de Programación Orientada a Objetos 153
Elementos de las variables Una variable tiene los seis elementos siguientes:
Elemento Descripción
Nombre La palabra que utilizamos para hacer referencia a la variable en código.
Dirección La ubicación de memoria donde se almacena el valor de la variable.
Tipo de datos El tipo y tamaño inicial de datos que la variable puede almacenar.
Valor El valor en la dirección de la variable.
Ámbito El conjunto de todo el código que puede acceder y utilizar la variable.
Tiempo de vida El intervalo de tiempo durante el cual una variable es válida y está
disponible para poder ser utilizada. Su valor puede cambiar durante
su vida, pero siempre mantiene alguno mientras existe en memoria.
Ejemplos de variables
Una variable puede utilizarse de muchas formas, incluyendo las siguientes:
Como contador que almacena el número de veces en que un evento se produce
Como almacenamiento temporal para valores de propiedades
Como ubicación para guardar un valor de retorno de una función
Como ubicación para almacenar nombres de directorio o archivos
Cómo nombrar las variables
Cuando declaramos una variable, es importante desarrollar una estrategia de asignación de
nombres. Tanto la claridad como la coherencia son importantes, especialmente cuando otros
necesitarán leer o mantener nuestro código.
Técnica de Programación Orientada a Objetos 154
Reglas
Cuando nombramos una variable en Visual Basic .NET, debemos tener en cuenta las
siguientes reglas:
Iniciar cada nombre de variable con un carácter alfabético o un guión bajo (_).
No utilizar espacios ni símbolos.
No utilizar palabras clave como Integer o Date.
Recomendaciones
Se recomienda que tenga en cuenta las siguientes directrices cuando nombre variables:
Proporcione nombres descriptivos y con significado, como numeroCuenta.
Aunque escribir un nombre largo de variable puede resultar tedioso en el momento de escribir código, hará que el código sea más fácil de leer y mantener.
Inicie cada palabra del nombre de una variable pública con letra mayúscula, como NombreCliente. Esto se denomina PascalCasing.
Evite el uso de abreviaturas.
Aunque es posible utilizar un nombre de variable como nocta, el código será mucho más fácil de leer si utilizamos el nombre numeroCuenta. En caso de ser necesario el uso de abreviaturas, debemos asegurarnos de que sean coherentes en toda la aplicación.
Utilice un nombre único dentro del ámbito de la variable. Ámbito (scope) hace referencia al subconjunto del código que reconoce la variable.
Cuando declare variables locales y privadas, inicie la primera palabra con un carácter en minúscula, como en nuevoCliente. Esto se denomina camelCasing.
Cómo declarar variables
Técnica de Programación Orientada a Objetos 155
Introducción Declaramos una variable para especificar su nombre y características. La instrucción de
declaración tanto para variables de tipo valor como de tipo referencia es la instrucción Dim. La
ubicación y el contenido de la declaración determinan las características de la variable.
Sintaxis
Para declarar una variable, utilice la siguiente sintaxis:
Dim nombreVariable As Type
Utilizamos la instrucción Dim para declarar y asignar espacio de almacenamiento para
variables en bloques, procedimientos, módulos, estructuras y clases. Utilizamos la cláusula As
en la instrucción Dim para especificar el tipo de datos de la variable.
Nota La palabra clave Dim es una abreviatura de la palabra dimensión.
Ejemplos de tipos valor
Los siguientes ejemplos muestran cómo declarar las variables con tipos valor predefinidos:
Dim numberBooks As Integer
Dim squareFootage As Single
Ejemplos de tipos referencia
Los siguientes ejemplos muestran cómo declarar las variables con tipos referencia:
Dim myForm As Form
Dim userInput As String
Técnica de Programación Orientada a Objetos 156
Aunque la sintaxis para declarar variables de tipo valor y de tipo referencia es similar, el
entorno de ejecución los gestiona de modo distinto. Una variable de tipo referencia siempre
contiene un puntero a un valor de ese tipo o una referencia nula. Una variable de tipo valor
contiene el valor real de la variable.
Cómo afecta Option Explicit a las variables
Introducción
En general, debería declarar explícitamente las variables de su aplicación antes de utilizarlas.
De este modo, se reduce la probabilidad de errores lógicos y se facilita el mantenimiento del
código. Aunque no es recomendable, puede utilizar variables en su aplicación sin antes
declararlas. Este proceso se denomina declaración implícita.
Cómo funciona Option Explicit
Cuando Option Explicit está On (de forma predeterminada está habilitado), debe declarar
explícitamente variables antes de poder utilizarlas, de lo contrario el compilador generará un
error. Cuando Option Explicit no está habilitado (Off), puede declarar implícitamente una
variable simplemente utilizándola en su código. Se creará como un tipo objeto. Aunque puede
resultar conveniente declarar variables implícitamente, se incrementa la probabilidad de
conflictos de nombres y de un comportamiento imprevisto debido a errores de ortografía.
Además, genera un uso ineficaz del almacenamiento de memoria.
Técnica de Programación Orientada a Objetos 157
Ejemplo de una ventaja de Option Explicit
Por ejemplo, supongamos que la variable sueldoActual guarda el salario anual de un
empleado. Un procedimiento utiliza esta variable en una fórmula que calcula el bonus del
empleado. Supongamos que la variable sueldoActual se escribe incorrectamente, como se
muestra en el siguiente ejemplo:
Dim sueldoActual As Integer
bonusActual = sueldoActual * .10
Con Option Explicit no habilitado (Off), este cálculo supondrá un bonus de $0.00 debido a que
la variable sueldoActual se declarará implícitamente como una nueva variable Object y se
inicializará vacía. Cuando sueldoActual se utilice en el cálculo, Visual Basic lo convertirá
automáticamente a 0. Si este cálculo se realiza varias veces en una estructura cíclica, la
aplicación se ejecutará sustancialmente más lentamente porque Visual Basic necesita tiempo
para crear, inicializar, y convertir la variable cada vez.
Configurar Option Explicit
Puede establecer Option Explicit como On u Off a nivel de proyecto del entorno de desarrollo.
1. En el Explorador de soluciones, haga clic en el nombre del proyecto para el que desea configurar Option Explicit.
2. En el menú Ver, haga clic en Propiedades.
3. Activar la página Compilar y haga clic en Off u On según lo deseado en la lista Option Explicit.
Técnica de Programación Orientada a Objetos 158
También puede configurar Option Explicit como On u Off mediante la instrucción adecuada al
inicio de su código:
' This turns Option Explicit On
Option Explicit On
' This turns Option Explicit Off
Option Explicit Off
Cómo asignar valores a las variables
Introducción
Antes de poder utilizar variables en su aplicación, debe asignarles un valor. Puede asignar un
valor a una variable después de declararla o mientras la declara.
Sintaxis
Para asignar un valor a una variable, utilice el operador de asignación (=), como se muestra en
la siguiente expresión:
NombreVariable = Valor
El valor del lado derecho de la expresión se asigna a la variable del lado izquierdo de la
expresión.
Técnica de Programación Orientada a Objetos 159
Asignar un valor después de declarar
Puede asignar valores a variables después de declararlas, como se muestra en el siguiente
ejemplo:
Dim cumpleaños As Date
cumpleaños = #3/9/1974#
Cuando creamos una variable con la instrucción Dim, Visual Basic inicializa automáticamente
las variables numéricas a 0, las cadenas de texto a vacías ("") y las variables de fecha a 1 de
enero de 0001.
Asignar valores mientras se declara
También puede asignar un valor a una variable mientras la declara, como se muestra en los
siguientes ejemplos:
Dim cumpleaños As Date = #3/9/1974#
Dim goodNews As String = "Su cheque está en el correo."
Dim testCondition As Boolean = True
Nota
Los valores de fecha (Date) deben estar encerrados entre almohadillas (##), y los valores de
cadena (String) deben estar encerrados entre comillas ("").
Técnica de Programación Orientada a Objetos 160
Variables vs. Constantes
Introducción
Si una variable de su programa contiene un valor que no cambia nunca, considere almacenar
el valor como una constante en lugar de una variable. Las constantes proporcionan una forma
de utilizar nombres con significado en lugar de un valor que no cambia (como , una cantidad
matemática fija).
Cómo funcionan las constantes
Las constantes almacenan valores que, como su nombre indica, permanecen constantes
durante la ejecución de una aplicación. Algunas ventajas de utilizar constantes son:
Hacen que el código sea más fácil de leer.
Utilizan menos memoria que las variables.
Hacen que los cambios a nivel de aplicación sean más fáciles de implementar.
Sintaxis
Para declarar una constante, utilice la instrucción Const con la siguiente sintaxis:
Const nombreConstante As Type
Nombramos y especificamos los niveles de ámbito de las constantes siguiendo las mismas
reglas que para las variables.
Técnica de Programación Orientada a Objetos 161
Ejemplo
El siguiente ejemplo muestra cómo declarar y utilizar una constante:
Dim area, radio, circunferencia As Double
Const Pi As Double = 3.1415
area = Pi * radio ^ 2
circunferencia = 2 * Pi * radio
Técnica de Programación Orientada a Objetos 162
Ámbito de una variable
Cuando utilizamos variables, debemos asegurarnos de que son accesibles desde todas las áreas de código que hacen referencia a ellas. Por otra parte, es posible que necesite restringir el acceso a determinadas variables. Todo el conjunto de código que puede hacer referencia a una variable por su nombre se denomina ámbito (scope) de la variable. Esta lección describe los diferentes niveles de ámbito aplicables a variables y explica cómo asegurarse de que cada variable de nuestra aplicación tiene el ámbito adecuado.
¿Qué es el ámbito?
Cuando declaramos variables, uno de los primeros aspectos que probablemente consideraremos es el ámbito. Si utilizamos una variable fuera de su ámbito, el compilador generará un error.
Técnica de Programación Orientada a Objetos 163
Definiciones Para estudiar el modo de trabajo del ámbito con variables, debemos estar familiarizados con los términos y definiciones de la siguiente tabla:
Término Definición
Ámbito de la variable Conjunto de código al que se refiere una variable por su nombre
asignado sin cualificadores.
Bloque Bloque de código que empieza con una condición como If o While y
termina con una instrucción End, Loop o Next.
Procedimiento Bloque de código que empieza con una instrucción de declaración
como Sub y termina con una instrucción End.
Módulo Archivo que agrupa procedimientos comunes y datos globales para
hacerlos accesibles a su uso en uno o más proyectos.
Ensamblado Un archivo ejecutable independiente en el que se compilan los diversos
archivos cuando genera una solución.
Modificador de Palabra clave como Public o Friend que utilizamos para especificar el
acceso nivel de una variable o su contenedor (módulo, clase o estructura).
Factores que afectan al ámbito Asignamos el ámbito de una variable cuando la declaramos. Existen tres factores principales
que afectan al ámbito de una variable:
Dónde la declaramos: dentro de un bloque, procedimiento, módulo, clase o estructura.
El nivel de acceso (Public, Friend o Private) del módulo, clase o estructura en que se declara. El ámbito de una variable no puede exceder el ámbito de su contenedor.
La sintaxis que utilizamos para declarar la variable (Dim, Private, Friend o Public).
Niveles de ámbito
Una variable puede tener uno de los siguientes niveles de ámbito:
Nivel de ámbito Descripción
Bloque Disponible sólo dentro del bloque de código en el que se declara
Procedimiento Disponible únicamente dentro del procedimiento en el que se declara
Módulo Disponible para todo el código del módulo, clase o estructura en el que
se declara
Espacio de nombres Disponible para todo el código del espacio de nombres
Podemos definir todavía más el ámbito de una variable de módulo declarando un modificador
de acceso (Private, Public o Friend) cuando la declaramos.
Técnica de Programación Orientada a Objetos 164
Cómo declarar variables locales
Cuando declaramos variables en un bloque o procedimiento, nos referimos a variables locales
y significa que su ámbito está limitado al bloque o procedimiento en el que se declaran. Si
consideramos el ámbito, las variables locales son una buena elección para cualquier tipo de
cálculo temporal. Utilizan memoria sólo cuando su procedimiento se está ejecutando, y sus
nombres no son susceptibles de conflictos de nomenclatura.
Sintaxis
Para declarar una variable local, utilice la instrucción Dim con la siguiente sintaxis:
Dim nombreVariable As Type
Ejemplo de ámbito a nivel de bloque
El siguiente ejemplo muestra cómo declarar una variable local denominada blockNumber con
ámbito a nivel de bloque:
If x <> 0 Then
Dim blockNumber As Integer
blockNumber = 1 / x
End If
Técnica de Programación Orientada a Objetos 165
Nota
En general, cuando declaramos cualquier variable, es una buena práctica de programación
mantener el ámbito lo más estrecho posible (el ámbito de bloque es el más estrecho). Mantener
el ámbito estrecho ayuda a conservar memoria y minimiza las posibilidades de que el código
haga referencia a una variable equivocada.
Ejemplo de ámbito a nivel de procedimiento
El siguiente ejemplo muestra cómo declarar una variable local name con ámbito a nivel de
procedimiento:
Sub ShowMessage_Click( )
Dim name As String
name = NameTextBox.Text
MessageBox.Show("Bienvenido de nuevo, " & name & "!")
End Sub
Técnica de Programación Orientada a Objetos 166
Cómo declarar variables estáticas
La vida de una variable local empieza cuando un procedimiento la invoca y acaba cuando el
procedimiento finaliza. Cuando acaba la vida de una variable local, la instancia de la variable se
destruye y su valor se pierde. En ocasiones, es posible que deseemos que la vida de una
variable local sea más larga que la vida del procedimiento. Por ejemplo, podemos desear que
un procedimiento realice una acción específica la primera vez que sea invocado y que no haga
nada en las siguientes llamadas. Podemos declarar una variable estática para conseguir esta
funcionalidad.
Definición
Una variable estática perdurará mientras la aplicación siga ejecutándose. Las variables
estáticas siguen existiendo y conservan sus últimos valores entre invocaciones al
procedimiento en el que se han declarado. Sin embargo, el código de otros procedimientos no
puede acceder a ellas.
Sintaxis
Para declarar una variable estática local, utilizaremos la siguiente sintaxis:
Static variableName As Type
Ejemplo
Las variables estáticas resultan útiles para mantener contadores que se utilizan únicamente
dentro de un procedimiento. El siguiente ejemplo muestra cómo declarar una variable estática
que realiza el seguimiento de cuántas veces se ejecuta el procedimiento AddItem. Cada vez
que el procedimiento se ejecuta, el valor almacenado en items se incrementa en 1.
Técnica de Programación Orientada a Objetos 167
Sub AddItem_Click( )
Static items As Integer
' Añadir 1 al contador
items += 1
' Usar ampersand(&) para combinar una cadena y una variable
Messagebox.Show("El contador es ahora " & items)
End Sub
Nota
Puede conseguir los mismos resultados que con el código anterior declarando items como una
variable de módulo. Sin embargo, otros procedimientos tendrían acceso a la variable y podrían
cambiarla. A menos que se desee ámbito a nivel de módulo, es recomendable utilizar una
variable estática.
Técnica de Programación Orientada a Objetos 168
Cómo declarar variables de módulo
Las variables declaradas en un módulo, clase o estructura pero no dentro de un procedimiento
se denominan variables de módulo. Después de declarar una variable de módulo, podemos
asignarle un valor, asignar su ámbito utilizando un modificador de acceso y utilizarla dentro de
ese ámbito.
Sintaxis
Para declarar una variable de módulo, utilice la siguiente sintaxis:
AccessModifier nombreVariable As Type
Existen varios modificadores de acceso, incluyendo los descritos en la siguiente tabla:
Nota
El ámbito de una variable de módulo está determinado no sólo por el modificador de acceso
utilizado para declararla, sino también por el nivel de acceso del módulo, clase o estructura en
el que se declara. El ámbito de la variable no puede ser mayor que el ámbito de su contenedor.
Técnica de Programación Orientada a Objetos 169
Ejemplo de ámbito a nivel de módulo
El siguiente ejemplo muestra cómo declarar y utilizar una variable con el ámbito a nivel de
módulo:
' Put the following declaration at module level (not in any procedure)
Private myModuleMessage As String
' ...
Sub InitializeModuleVariable( )
myModuleMessage = "This variable has module-level scope."
End Sub
' ...
Sub UseModuleVariable( )
MessageBox.Show(myModuleMessage)
End Sub
Ejemplo de ámbito a nivel de proyecto
El siguiente ejemplo muestra cómo declarar y utilizar una variable con el ámbito a nivel de
proyecto:
' Put the following declaration at module level (not in any procedure)
Friend MyProjectMessage As String
' ...
Sub InitializeProjectVariable( )
MyProjectMessage = "This variable has project-level scope."
End Sub
' ...
Sub UseProjectVariable( )
MessageBox.Show(MyProjectMessage)
End Sub
Técnica de Programación Orientada a Objetos 170
Ejemplo de ámbito a nivel de solución
El siguiente ejemplo muestra cómo declarar y utilizar una variable con el ámbito a nivel de
solución:
' Put the following declaration at module level (not in any procedure)
Public MySolutionMessage As String
' ...
Sub InitializeSolutionVariable( )
MySolutionMessage = "This variable has solution-level scope."
End Sub
' ...
Sub UseSolutionVariable( )
MessageBox.Show(MySolutionMessage)
End Sub
Técnica de Programación Orientada a Objetos 171
Convertir tipos de datos
El proceso de convertir el valor de un tipo de datos en otro se denomina conversión o casting.
Podemos convertir explícitamente valores de un tipo en otro antes de que sean utilizados,
evitando así errores en nuestro código y haciendo que éste se ejecute más rápidamente. Visual
Basic .NET también puede realizar algunas conversiones de tipos de datos automática o
implícitamente, como convertir algunas cadenas a enteros. Sin embargo, las conversiones
implícitas pueden producir resultados imprevistos.
¿Cuáles son las funciones de conversión?
Podemos utilizar funciones de conversión para forzar el resultado de una operación a un tipo
de datos particular en lugar del tipo de datos por defecto.
Por ejemplo, podemos convertir un valor de tipo cadena a un valor entero.
Técnica de Programación Orientada a Objetos 172
Definición
Las funciones de conversión permiten convertir explícitamente un valor de un tipo de datos a
otro.
Ejemplos de funciones de conversión
Visual Basic ofrece una amplia lista de funciones de conversión, incluyendo las descritas en la
siguiente tabla:
El código siguiente muestra cómo utilizar varias funciones de conversión:
Private Sub Button1_Click(...)
' Use string conversion on Integer
Dim myVariable As Integer
myVariable = 1234
MessageBox.Show(myVariable)
MessageBox.Show(CStr(myVariable) & "1")
End Sub
Private Sub Button2_Click(...)
' Use integer conversion on Double
Dim myVariable As Double
myVariable = 567.9894
MessageBox.Show(myVariable)
Técnica de Programación Orientada a Objetos 173
MessageBox.Show(CInt(myVariable))
End Sub
Private Sub Button3_Click(...)
' Use date conversion on String
Dim myVariable As String
myVariable = "February 12, 1992"
MessageBox.Show(myVariable)
MessageBox.Show(CDate(myVariable))
End Sub
Cómo convertir explícitamente tipos de datos
Se recomienda el uso de funciones de conversión para convertir valores explícitamente antes
de que sean utilizados. Las conversiones explícitas se ejecutan más rápidamente que las
conversiones implícitas porque no hay llamada a un procedimiento para llevar a cabo la
conversión. Una conversión implícita es una conversión automática de un valor de un tipo en
otro.
Sintaxis
Para utilizar una función de conversión, se sitúa en el lado derecho de una instrucción de
asignación, utilizando la siguiente sintaxis:
VariableName = CFunction(Expression)
Técnica de Programación Orientada a Objetos 174
El parámetro expression puede ser cualquier expresión válida, como una variable, un resultado
de una función o un valor constante.
Conversiones anchas frente a conversiones estrechas
Una conversión ancha cambia un valor a un tipo de datos que puede contener cualquier valor
posible de los datos originales, como convertir un Integer en un Long. Una conversión
estrecha cambia un valor a un tipo de datos que es posible que no pueda guardar algunos de
los valores posibles, como cambiar un String en un Integer, o un Long en un Integer.
Ejemplo
El siguiente ejemplo muestra cómo utilizar las funciones de conversión CStr y CDbl para
escribir código que convierte pies y pulgadas A metros.
Private Sub Calculate_Click(...)
Dim feet As Double, inches As Double
Dim millimeters As Double, meters As Double
'First, extract feet and inches from the text boxes.
'The Text property returns a string, but we need a double,so CDbl( ) is used to perform the conversion.
feet = CDbl(FeetTextBox.Text)
inches = CDbl(InchesTextBox.Text)
'Next, convert feet and inches to millimeters.
millimeters = (inches * MillimetersPerInch) + _
(feet * MillimetersPerInch * InchesPerFoot)
'Convert millimeters to meters.
meters = millimeters / 1000
'Display the result in a label. Because the Text property is a string, use CStr( ) to convert the double.
MeterResult.Text = CStr(meters)
End Sub
En este ejemplo, podemos asumir que los valores constantes MillimetersPerInch e
InchesPerFoot han sido declarados y se les han asignado valores adecuados a nivel de
módulo.
Técnica de Programación Orientada a Objetos 175
Ejemplo de CInt
El siguiente ejemplo muestra cómo utilizar la función CInt para convertir un valor Double en un
Integer:
Dim myDouble As Double
Dim myInt As Integer
myDouble = 2345.5678
' Set myInt to 2346
myInt = CInt(myDouble)
Ejemplo de CDate
El siguiente ejemplo muestra cómo utilizar la función CDate para convertir cadenas en valores
Date. En general, no se recomienda codificar explícitamente fechas y horas como cadenas
(como muestra este ejemplo). En lugar de ello, utilicemos literales de fecha y hora, como #Feb
12, 1969# y #4:45:23 PM#.
Dim myDateString, myTimeString As String
Dim myDate, myTime As Date
myDateString = "February 12, 1969"
myTimeString = "4:35:47 PM"
' ...
' Convert to Date data type
myDate = CDate(myDateString)
myTime = CDate(myTimeString)
Técnica de Programación Orientada a Objetos 176
Cómo funciona la conversión de datos implícita
Visual Basic puede realizar algunas conversiones de tipos de datos implícitamente. Una
conversión implícita se produce cuando un valor se convierte automáticamente de un tipo de
datos en otro requerido por el código en que el tipo de datos se utiliza. No requiere ninguna
sintaxis especial en el código fuente.
Ejemplos
Si colocamos la cadena “1234” en una variable Integer, Visual Basic convertirá
automáticamente la cadena en un entero. O, si una cadena como “100” se añade a un valor
numérico en la fórmula “100” + 10, Visual Basic convierte implícitamente la cadena en el valor
entero 100 y lo añade a 10.
Inconvenientes
Existen inconvenientes al depender de Visual Basic para realizar conversiones implícitas. Las
conversiones implícitas pueden producir resultados imprevistos.
Por ejemplo, cuando se juntan dos cadenas, Visual Basic concatena las cadenas con
independencia de su contenido; por tanto “100” + “10” = “10010.” Si se requiere una conversión
estrecha, los datos pueden truncarse. Además, cuando Visual Basic debe realizar conversiones
implícitas, el código se ejecuta más lentamente debido al trabajo extra que Visual Basic debe
llevar a cabo.
Cómo afecta Option Strict a las conversiones de datos
Con Option Strict deshabilitado (Off) (predeterminado), todas las conversiones anchas y
estrechas pueden realizarse implícitamente. Con Option Strict habilitado (On), únicamente
están permitidas implícitamente las conversiones anchas, y las conversiones estrechas deben
ser explícitas o el compilador generara un error.
Técnica de Programación Orientada a Objetos 177
Crear y utilizar estructuras
En Visual Basic .NET, podemos combinar variables de varios tipos de datos diferentes para
crear un tipo definido por el usuario denominado estructura. Las estructuras resultan útiles
cuando deseamos crear una única variable que agrupe varias piezas de información
relacionadas.
¿Qué son las estructuras?
Podemos combinar elementos de datos de distintos tipos para crear una combinación de tipos
de datos única denominada estructura. Las estructuras resultan útiles cuando deseamos que
una única variable guarde varias piezas de información relacionadas. Después de declarar una
estructura, podemos declarar variables de ese tipo.
Técnica de Programación Orientada a Objetos 178
Definición
Una estructura es una combinación de tipos de datos que se crea combinando otros tipos de
datos. Las estructuras son de tipo valor (es decir, una variable de tipo estructura contiene los
datos de la estructura, en lugar de una referencia a los datos como hace el tipo referencia). Las
estructuras pueden tener datos, propiedades, métodos y procedimientos y pueden invocar y
manipular eventos.
Ejemplo
El uso más simple y habitual de las estructuras es encapsular variables relacionadas, creando
un tipo de datos definido por el usuario. Por ejemplo, es posible que deseemos guardar juntos
el nombre, fecha de contratación, cargo y salario de un empleado. Podríamos utilizar varias
variables para esta información, o podemos definir una estructura y utilizarla como la variable
de un único empleado. La ventaja de la estructura se hace patente cuando tiene muchos
empleados y, por tanto, muchas instancias de la variable. El siguiente ejemplo muestra una
estructura Employee simple:
Public Structure Employee
Public FirstName As String
Public LastName As String
Public HireDate As Date
Public JobTitle As String
Private Salary As Decimal
End Structure
Nota
El ejemplo anterior utiliza la estructura Employee para gestionar una sencilla lista de atributos.
La estructura Employee también podría tener miembros como un método Hire y un evento
Promoted. Sin embargo, si el diseño de su aplicación puede beneficiarse de utilizar Employee
como plantilla para otro elemento de programación, como un Manager o un StaffMember, sería
mejor crear Employee como clase. Las clases pueden utilizarse como plantillas, y son más
extensibles que las estructuras.
Estructuras proporcionadas en Visual Basic .NET
Visual Basic .NET también proporciona numerosas estructuras predefinidas que podemos
utilizar. Por ejemplo, la siguiente lista describe varias estructuras existentes que soportan
gráficos en la plataforma .NET. Estas estructuras forman parte del espacio de nombres
System.Drawing.
Técnica de Programación Orientada a Objetos 179
La estructura Point representa un par ordenado de coordenadas x e y de enteros que define un punto en un plano bidimensional. Podemos utilizar la estructura Point para capturar la ubicación del ratón cuando el usuario hace clic en nuestra aplicación.
La estructura Size representa el tamaño de una región rectangular utilizando un par ordenado de anchura y altura. Utilizamos la estructura Size cuando modificamos la propiedad Size de un formulario.
La estructura Color representa un color ARGB (alpha, red, green, blue). Utilizamos la estructura Color cuando modificamos el color de un formulario o de un control.
Cómo declarar estructuras
El primer paso para crear una estructura es declararla. Podemos declarar estructuras en un
archivo fuente o dentro de un módulo o clase, pero no dentro de un procedimiento.
Sintaxis
Iniciamos la declaración de una estructura con la instrucción Structure, y la finalizamos con la
instrucción End Structure. Entre ambas instrucciones, debemos declarar al menos un
miembro. Los miembros pueden ser de cualquier tipo de datos. Podemos utilizar la siguiente
sintaxis para declarar una estructura:
AccessModifier Structure StructureName
' Declare structure members here
End Structure
Técnica de Programación Orientada a Objetos 180
Miembros de la estructura
Debemos declarar cada miembro de los datos de una estructura y especificar un nivel de
acceso. Esto significa que cada sentencia de la sección de declaración de variable de la
estructura debe utilizar Dim, Friend, Private o Public. Si Option Explicit está On, es una
buena idea incluir la cláusula As en cada sentencia. Los miembros declarados con Dim tienen
por defecto acceso Public, y los miembros declarados sin la cláusula As tienen por defecto el
tipo de datos Object.
No podemos inicializar ninguno de los miembros de datos en la declaración de la estructura. Al
declarar una variable de tipo estructura, asignamos valores a los miembros accediendo a ellos
a través de la variable.
Niveles de acceso Puede accederse a las estructuras desde cualquier lugar del archivo,
módulo o clase en el que estén declaradas. Una estructura en un archivo es Friend por
defecto. Podemos especificar el nivel de acceso de una estructura utilizando el modificador de
acceso Public, Protected, Friend o Private como se describe en la siguiente tabla:
Ejemplo
El siguiente ejemplo muestra cómo declarar una estructura Employee para definir un conjunto
de datos relacionados con un empleado. Muestra cómo utilizar los modificadores de acceso
Public, Friend y Private para reflejar la sensibilidad de los elementos de datos.
Public Structure Employee
' Public members, accessible throughout declaration region
Public FirstName As String
Public MiddleName As String
Public LastName As String
Técnica de Programación Orientada a Objetos 181
' Friend members, accessible anywhere in the same assembly
Friend EmployeeNumber As Integer
Friend BusinessPhone As Long
' Private members, accessible only in the structure itself
Private HomePhone As Long
Private Salary As Double
Private Bonus As Double
End Structure
Técnica de Programación Orientada a Objetos 182
Cómo utilizar las estructuras
Una vez creada una estructura, podemos declarar variables a nivel de procedimiento y a nivel
de módulo como ese tipo estructura. Podemos asignar valores a los miembros de datos de la
estructura de la variable y escribir código para utilizar los miembros de la estructura.
Procedimiento
Generalmente, los pasos para utilizar las estructuras son los siguientes:
1. Declarar una estructura. Por ejemplo, podemos crear una estructura que registre información sobre el sistema
de un ordenador, como sigue:
Private Structure computerInfo
Public processor As String
Public memory As Long
Public purchaseDate As Date
End Structure
2. Declarar una variable del tipo de estructura declarado. Una vez declarada una estructura, podemos crear una variable de ese tipo de
estructura, como sigue:
Dim mySystem As computerInfo
Técnica de Programación Orientada a Objetos 183
3. Asignar valores a los miembros de datos. Para asignar y recuperar valores desde los elementos de una variable estructura,
utilizamos el nombre de la variable que hemos creado junto con el elemento en el
bloque de estructura. Separamos el nombre del elemento con un punto. Por ejemplo,
podemos acceder e inicializar las variables declaradas en la estructura computerInfo
como sigue:
mySystem.processor = "x86"
mySystem.purchaseDate = #1/1/2003#
mySystem.memory = TextBox1.Text
4. Escribir código para utilizar los miembros de la estructura. Después de asignar valores a los miembros de datos, podemos escribir código para
utilizarlos desde cualquier lugar de nuestro código que se encuentre dentro de su
ámbito.
Nota
Una estructura puede contener cualquiera de los tipos de datos definidos en Visual Basic .NET,
incluyendo matrices, objetos y otras estructuras.
Técnica de Programación Orientada a Objetos 184
Enumeraciones: Constantes agrupadas Una enumeración es una serie de constantes que están relacionadas entre sí. La utilidad de las enumeraciones es más manifiesta cuando queremos manejar una serie de valores constantes con nombre, es decir, podemos indicar un valor, pero en lugar de usar un literal numérico, usamos un nombre, ese nombre es, al fin y al cabo, una constante que tiene un valor numérico. En Visual Basic 2005 las enumeraciones pueden ser de cualquier tipo numérico integral, incluso enteros sin signo, aunque el valor predefinido es el tipo Integer. Podemos declarar una enumeración de varias formas:
Sin indicar el tipo de datos, por tanto serán de tipo Integer:
Enum Colores
Rojo
Verde
Azul
End Enum
Indicando el tipo de datos que realmente tendrá:
Enum Colores As Long
Rojo
Verde
Azul
End Enum
En este segundo caso, el valor máximo que podemos asignar a los miembros de una enumeración será el que pueda contener un tipo de datos Long.
Indicando el atributo FlagsAttibute, (realmente no hace falta indicar el sufijo Attribute
cuando usamos los atributos) de esta forma podremos usar los valores de la enumeración para indicar valores que se pueden "sumar" o complementar entre sí, pero sin perder el nombre, en breve veremos qué significa esto de "no perder el nombre".
<Flags()> _
Enum Colores As Byte
Rojo = 1
Verde = 2
Azul = 4
End Enum
Técnica de Programación Orientada a Objetos 185
Nota:
Los atributos los veremos con más detalle en otra lección de este mismo módulo.
El nombre de los miembros de las enumeraciones
Tanto si indicamos o no el atributo Flags a una enumeración, la podemos usar de esta forma:
Dim c As Colores = Colores.Azul Or Colores.Rojo Es decir, podemos "sumar" los valores definidos en la enumeración. Antes de explicar con detalle que beneficios nos puede traer el uso de este atributo, veamos una característica de las enumeraciones. Como hemos comentado, las enumeraciones son constantes con nombres, pero en Visual Basic 2005 esta definición llega más lejos, de hecho, podemos saber "el nombre" de un valor de una enumeración, para ello tendremos que usar el método ToString, (el cual se usa para convertir en una cadena cualquier valor numérico). Por ejemplo, si tenemos la siguiente asignación:
Dim s As String = Colores.Azul.ToString
La variable s contendrá la palabra "Azul" no el valor 4.
Esto es aplicable a cualquier tipo de enumeración, se haya o no usado el atributo FlagsAttribute. Una vez aclarado este comportamiento de las enumeraciones en Visual Basic 2005, veamos que es lo que ocurre cuando sumamos valores de enumeraciones a las que hemos aplicado el atributo Flags y a las que no se lo hemos aplicado. Empecemos por este último caso. Si tenemos este código:
Enum Colores As Byte
Rojo = 1
Verde = 2
Azul = 4
End Enum
Dim c As Colores = Colores.Azul Or Colores.Rojo
Dim s As String = c.ToString El contenido de la variable s será "5", es decir, la representación numérica del valor contenido: 4 + 1, ya que el valor de la constante Azul es 4 y el de la constante Rojo es 1. Pero si ese mismo código lo usamos de esta forma (aplicando el atributo Flags a la enumeración):
<Flags()> _
Enum Colores As Byte
Rojo = 1
Técnica de Programación Orientada a Objetos 186
Verde = 2
Azul = 4
End Enum
Dim c As Colores = Colores.Azul Or Colores.Rojo
Dim s As String = c.ToString El contenido de la variable s será: "Rojo, Azul", es decir, se asignan los nombres de los miembros de la enumeración que intervienen en ese valor, no el valor "interno".
1- Los valores de una enumeración no son simples números Como hemos comentado, los miembros de las enumeraciones realmente son valores de un tipo de datos entero (en cualquiera de sus variedades) tal como podemos comprobar en la figura:
Por tanto, podemos pensar que podemos usar cualquier valor para asignar a una variable declarada como una enumeración, al menos si ese valor está dentro del rango adecuado. En Visual Basic 2005 esto no es posible, al menos si lo hacemos de forma "directa" y con Option Strict conectado, ya que recibiremos un error indicándonos que no podemos convertir, por ejemplo, un valor entero en un valor del tipo de la enumeración. En la figura podemos ver ese error al intentar asignar el valor 3 a una variable del tipo Colores (definida con el tipo predeterminado Integer). El error nos indica que no podemos realizar esa asignación, pero el entorno integrado de Visual Studio 2005 también nos ofrece alternativas para que ese error no se produzca, esa ayuda se obtiene presionando en el signo de admiración que tenemos justo donde está el cursor del mouse, pero no solo nos dice cómo corregirlo, sino que también nos da la posibilidad de que el propio IDE se encargue de corregirlo, tal como podemos apreciar en la figura.
Técnica de Programación Orientada a Objetos 187
Lo único que tendríamos que hacer es presionar en la sugerencia de corrección, que en este caso es la única que hay, pero en otros casos pueden ser varias las opciones y tendríamos que elegir la que creamos adecuada. El código final (una vez corregido) quedaría de la siguiente forma:
Dim c As Colores = CType(3, Colores) CType es una de las formas que nos ofrece Visual Basic 2005 de hacer conversiones entre diferentes tipos de datos, en este caso convertimos un valor entero en uno del tipo Colores. Si compilamos y ejecutamos la aplicación, ésta funcionará correctamente. Aunque sabemos que es posible que usando CType no asignemos un valor dentro del rango permitido. En este caso, el valor 3 podríamos darlo por bueno, ya que es la suma de 1 y 2 (Rojo y Verde), pero ¿que pasaría si el valor asignado es, por ejemplo, 15? En teoría no deberíamos permitirlo.
Estas validaciones podemos hacerlas de dos formas: 1- Con la clásica solución de comprobar el valor indicado con todos los valores posibles. 2- Usando funciones específicas del tipo Enum. Aunque en este último caso, solo podremos comprobar los valores definidos en la enumeración. En el siguiente ejemplo podemos hacer esa comprobación.
Sub mostrarColor(ByVal c As Colores)
' comprobar si el valor indicado es correcto
' si no está¡ definido, usar el valor Azul
If [Enum].IsDefined(GetType(Colores), c) = False Then
c = Colores.Azul
End If
Console.WriteLine("El color es {0}", c)
End Sub Este código lo que hace es comprobar si el tipo de datos Colores tiene definido el valor contenido en la variable c, en caso de que no sea así, usamos un valor predeterminado.
Nota: La función IsDefined sólo comprueba los valores que se han definido en la enumeración, no las posibles combinaciones que podemos conseguir sumando cada uno de sus miembros, incluso aunque hayamos usado el atributo FlagsAttribute.
Técnica de Programación Orientada a Objetos 188
Diseño de Aplicaciones Windows en Visual Basic .NET 2005
Windows Forms. Propiedades y Eventos. Visual Basic es un sistema que esta diseñado para crear programas ya sea tan sencillos como los que vamos a ver y tan difíciles (aunque es solo una expresión) como lo es con base de datos.
Ahora, lo que más nos interesa, crear un nuevo proyecto, al dar clic en el botón nuevo proyecto te aparecerá el siguiente explorador
Técnica de Programación Orientada a Objetos 189
Si se habrán dado cuenta, siempre se inicia en el visual Basic, y aparece seleccionada la opción Aplicación para Windows, justamente lo que más vamos a utilizar, para programar. En donde dice nombre, va a ir el nombre de nuestro proyecto, y en donde dice ubicación es en donde se va a ubicar nuestro proyecto o mejor dicho en donde lo vamos a guardar. En el proyecto, se habrá creado un formulario, el cual seguramente te lo mostrará de forma automática. En el lado derecho de la pantalla, verás que hay un "panel" o ventana en la que se indica el proyecto actual y se muestran los ficheros que lo componen. Ese panel es el "Solution Explorer" o Explorardor de Soluciones.
Técnica de Programación Orientada a Objetos 190
Para que se muestre el formulario (Form1), haz doble click en dicho "elemento" del explorador de soluciones.
Lo que vamos a hacer ahora es cambiar la separación de los puntos que se muestran en el formulario, ese "grid" o grilla, servirá para ajustar los controles (ya sabrás de qué hablo) que se añadan a dicho formulario. Por defecto la separación es de 8x8 puntos o pixels... y vamos a ponerlo en 4x4. Selecciona el formulario, simplemente con hacer un click en él es suficiente. En el panel de la derecha, debajo del explorador de soluciones, está la ventana de propiedades del elemento que actualmente esté seleccionado. en nuestro caso son las propiedades del Form1. Vamos a buscar el elemento GridSize para poder cambiar el tamaño de separación. Verás que se muestran dos valores separados por punto y coma, pero también hay una cruz a la izquierda de la palabra GridSize, si pulsas en esa cruz, se mostrarán los tamaños a lo que se refiere esos valores separados por punto y coma:
Técnica de Programación Orientada a Objetos 191
Controles Básicos
Label (Etiqueta)
Propiedades:
Name: por motivos de reconocimiento, se puede anteceder el prefijo lbl al nombre. Debe ser establecido generalmente cuando el control intervenga en algún proceso.
Autosize: el valor True redimensiona el largo del control al texto contenido.
Font: Permite establecer el tipo de fuente (Name), tamaño (Size), Negrita (Bold), Cursiva (Italic), Subrayado (Underline).
Forecolor: Establece el color de la fuente.
Text: Establece el texto mostrado por la etiqueta.
Textbox (Caja de Texto)
Propiedades:
Name: por motivos de reconocimiento, se puede anteceder el prefijo txt al nombre.
Backcolor: establece el color de fondo del control.
Enabled: el valor FALSE evita que el usuario pueda interactuar con el control.
MaxLength: establece el número máximo de caracteres permitidos.
Multiline: el valor TRUE permite que el textbox soporte varias líneas de texto.
PasswordChar: establece el carácter de password que ocultará el contenido de la caja de texto.
Text: Establece el texto mostrado por la caja de texto.
Button (Botón)
Propiedades:
Name: por motivos de reconocimiento, se puede anteceder el prefijo btn al nombre.
Image: establece la imagen que será mostrada dentro del botón.
ImageAlign: define la alineación de la imagen insertada en el botón.
Text: Establece el texto mostrado por el botón.
TextAlign: define la alineación del texto del botón.
Técnica de Programación Orientada a Objetos 192
Diseñar una aplicación que permita ingresar el nombre de un cliente, su clave de 3 caracteres,
y que luego se muestre un mensaje de bienvenida.
Objeto Propiedad Valor
Formulario
Name frmBienvenida
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
AceptButton Button1
Text INGRESO DE DATOS
Label1 Text Nombre del Cliente:
Label2 Text Clave secreta:
Label3
Name lblMensaje
Autosize False
BorderStyle FixedSingle
Text
TextBox1
Name txtCliente
BackColor Personalizado(255, 255, 192)
ForeColor Blue
Font Bold: True
Text
TextBox2
(Copiar y pegar el anterior, y modificar las siguientes propiedades)
Name txtClave
MaxLength 3
PasswordChar *
Button1 Name btnMostrar
Text Mostrar
Técnica de Programación Orientada a Objetos 193
Técnica de Programación Orientada a Objetos 194
Contenido.
Uso de Estructuras de Control o Condicionales, Selectivas Múltiples o Repetitivas
Uso de Controles o Opciones: CheckBox, RadioButtons o Listados: ListBox, ComboBox o Gráficos: PictureBox
Construcción de Aplicaciones MDI o Posicionamiento de formularios Windows en formularios MDI o Funcionamiento de Aplicaciones MDI o Diseño de Menús con el control MenuStrip, barras de Herramientas con
el ToolStrip y barras de estado con el StatusStrip.
Estructuras de Control
Estructuras Condicionales. Son procesos que permiten evaluar una condición o expresión lógica, y realizar un
bloque de instrucciones si el resultado es Verdadero, u otro, si el resultado es Falso.
If ExpresiónLógica Then
….
Instrucciones del Bloque de Verdad
…
Else
….
Instrucciones del Bloque de Falsedad
…
End If
Técnica de Programación Orientada a Objetos 195
Aplicación de ejemplo:
Diseñar un programa que permita ingresar el nombre de un alumno, y sus dos notas
correspondientes a Examen Parcial y Examen Final. Mostrar el promedio de dichas
notas, y mostrar la condición de APROBADO o DESAPROBADO.
o Al iniciar la aplicación el botón Calcular debe estar deshabilitado, y en las notas de Examen Parcial y Final deben mostrarse 0.
o Al ingresar el nombre del alumno se debe habilitar el botón Calcular.
o Permitir que solamente ingresen valores numéricos en Examen Parcial y Final.
Private Sub frmCalculos_Load(..)
btnCalcular.Enabled=False
txtEP.Text = "0"
txtEF.Text = "0"
End Sub
Private Sub txtAlumno_TextChanged(..)
If Len(Trim(txtAlumno.Text))>0 then
btnCalcular.Enabled=True
Else
btnCalcular.Enabled=False
End If
End Sub Private Sub txtEP_TextChanged(..)
If not IsNumeric(txtEP.Text) then
txtEP.Text=”0”
txtEP.Focus()
End If
End Sub
Técnica de Programación Orientada a Objetos 196
o Realizar el cálculo del promedio, y mostrar la condición.
Estructuras Selectivas Múltiples Son procesos en donde se evalúa el valor de una variable, y
Los valores se pueden evaluar de manera individual, especificando los valores
separados por comas, definiendo el rango de valores usando to o estableciendo los
valores con IS.
Select Case Variable
Case Valor1:
Instrucciones 1
Case Valor2:
Instrucciones 2
Case Expresion:
Instrucciones3
Case Else
Instrucciones
End Select
Private Sub txtEF_TextChanged(..)
If not IsNumeric(txtEF.Text) then
txtEF.Text=”0”
txtEF.Focus()
End If
End Sub
Private Sub btnCalcular_Click(..)
Dim P as Single
Dim EP as Single=CSng(txtEP.text)
Dim EF as Single=CSng(txtEF.text)
P=(EP+EF)/2
If P>=10.5 then
txtCondicion.Text=”Aprobado”
Else
txtCondicion.Text=”Desaprobado”
End If
End Sub
Técnica de Programación Orientada a Objetos 197
Aplicación de ejemplo:
En la aplicación anterior, se debe realizar una modificación al mostrar la condición, de
acuerdo a la siguiente tabla.
PROMEDIOS CONDICION
20 Excelente
Entre 15 y 19 Bueno
Entre 11 y menor a 15 Regular
Menor que 11 Malo
Otras notas ingresadas Error en las notas
Private Sub btnCalcular_Click(..)
Dim P as Single
Dim EP as Single=CSng(txtEP.text)
Dim EF as Single=CSng(txtEF.text)
P=(EP+EF)/2
Select Case Math.Round(P)
Case 20
txtCondicion.Text=”Excelente”
Case 15,16,17,18,19
txtCondicion.Text=”Bueno”
Case 11 to 14
txtCondicion.Text=”Regular”
Case Is<11
txtCondicion.Text=”Malo”
Case else
txtCondicion.Text=”Error en las notas”
End Select
End Sub
Técnica de Programación Orientada a Objetos 198
Estructuras Repetitivas Son procesos que permiten repetir una serie de instrucciones, ya sea controlada
mediante un contador o mediante el resultado de evaluar una expresión lógica.
Do While (ExprLógica)
Instrucciones (si la Exp. Lógica es Verdadera)
….
[Exit Do]
…
Loop
Do
Instrucciones (si la Exp. Lógica es Verdadera)
….
[Exit Do]
…
Loop While (ExprLógica)
For Var=ValorInicial to ValorFinal [step inc / dec ]
Instrucciones
….
[Exit For]
Next
Do
Instrucciones (si la Exp. Lógica es Falsa)
….
[Exit Do]
…
Loop Until (ExprLógica)
Técnica de Programación Orientada a Objetos 199
Aplicación de ejemplo:
Construir una aplicación que permita generar los 10 primeros múltiplos de 5, en una
caja de texto de tipo multilínea.
o Usando Do While
o Usando Do …Loop While
Private Sub btnGenerar_Click(..)
Dim cont,num as Integer
Do while cont<10
cont+=1
num=cont*5
txtSerie.AppendText(CStr(num)+vbCrLf)
Loop
End Sub
Private Sub btnGenerar_Click(..)
Dim cont,num as Integer
Do
cont+=1
num=cont*5
txtSerie.AppendText(CStr(num)+vbCrLf)
Loop While cont<10
End Sub
Técnica de Programación Orientada a Objetos 200
o Usando Do …Loop Until
o Usando For
Private Sub btnGenerar_Click(..)
Dim cont,num as Integer
Do
cont+=1
num=cont*5
txtSerie.AppendText(CStr(num)+vbCrLf)
Loop Until cont>=10
End Sub
Private Sub btnGenerar_Click(..)
Dim i,num as Integer
For i=1 to 10
num=i*5
txtSerie.AppendText(CStr(num)+vbCrLf)
Next
End Sub
Técnica de Programación Orientada a Objetos 201
Uso de Controles de Opciones
1. Botón de Radio (RadioButton) Se utiliza para presentar al usuario un conjunto de opciones mutuamente excluyentes
entre si es decir, si el usuario selecciona un componente RadioButton todos los
demás se desmarcan o deseleccionan solos.
Propiedades:
Name: por motivos de reconocimiento, se puede anteceder el prefijo rbt al nombre. Checked: Establece si el botón de radio se encuentra activo (True) o no (False).
2. Casilla de Verificación (CheckBox) Un control CheckBox indica cuando un valor particular esta encendido o apagado,
verdadero o falso, si o no, puede ser utilizado también para seleccionar múltiples items
de una lista de opciones.
Propiedades:
Name: por motivos de reconocimiento, se puede anteceder el prefijo chk al nombre.
Checked: Establece si el checkbox se encuentra marcado (True) o desmarcado (False).
3. Grupo de Botones(GroupBox) Antes conocido como Frame, es un contenedor que se utiliza para agrupar varias
opciones, que pueden ser: de opción única como los RadioButton o de opción múltiple
como los CheckBox. Este control se utiliza como contenedor y por si solo no tiene
mucha funcionalidad.
Propiedades:
Name: por motivos de reconocimiento, se puede anteceder el prefijo gbx al nombre.
Enabled: habilita (True) o deshabilita (False) los controles contenidos. Text: Establece el texto que se mostrará como encabezado. Visible: Muestra (True) u oculta (False) los controles contenidos.
Técnica de Programación Orientada a Objetos 202
Aplicación de ejemplo:
Diseñar una aplicación que permita ingresar el sueldo de una persona (Sueldo Bruto).
Se podrán seleccionar los descuentos a los cuales esta afecto como Impuesto a la
Renta (5%), descuento por AFP (2%) y descuento por ESSALUD (1%), todos se
aplican sobre el sueldo bruto. Además, se dará una bonificación de 100.00 a los
empleados que tienen estado civil CASADO. Mostrar los importes totales de los
descuentos, bonificaciones y Sueldo Neto.
o Al iniciar la aplicación se deberá mostrar en el Sueldo Bruto, Total Bonificaciones, Total Descuentos y Sueldo Neto el valor de 0
o Restringiremos que solamente ingresen valores numéricos en el Sueldo Bruto, y si ingresan caracteres se deberá limpiar el contenido.
Private Sub frmCalculos_Load(..)
txtSBruto.Text = "0"
txtTBon.Text = "0"
txtTDesc.Text = "0"
txtSNeto.Text = "0"
End Sub
Private Sub txtSBruto_TextChanged(..)
If Not IsNumeric(txtSBruto.Text) Then
txtSBruto.Text = 0
End If
End Sub
Técnica de Programación Orientada a Objetos 203
o Podríamos realizar todo el proceso de cálculo de las bonificaciones y descuentos en el botón Procesar.
o Ejecute la aplicación y compruebe. A continuación, se realizará el mismo proceso de manera directa desde los radiobuttons y desde los checkbox.
Private Sub btnProcesar_Click(..)
Dim SB As Single = CSng(txtSBruto.Text)
Dim IR, DAFP, DESSALUD, TBON As Single
„----En los RadioButtons-----
If rbtSol.Checked Then
TBON = 0
End If
If rbtCas.Checked Then
TBON = 100
End If
„----En los CheckBox---------
If chkIR.Checked Then
IR = 0.05 * SB
Else
IR = 0
End If
If chkAFP.Checked Then
DAFP = 0.03 * SB
Else
DAFP = 0
End If
If chkEssalud.Checked Then
DESSALUD = 0.01 * SB
Else
DESSALUD = 0
End If
TDESC=IR+DAFP+DESSALUD
NETO=SB+TBON-TDESC
txtTBon.Text = TBON
txtTDesc.Text = TDESC
Private Sub rbtSol_CheckedChanged(..)
txtTBon.Text = 0
End Sub Private Sub rbtCas_CheckedChanged(..)
txtTBon.Text = 100
End Sub
Técnica de Programación Orientada a Objetos 204
o O usando el manejador de eventos.
o Según la forma anterior, también se podría utilizar en la codificación del grupo de checkbox.
Private Sub rbtCas_CheckedChanged(..)Handles
rbtCas.CheckedChanged, rbtSol.CheckedChanged
Select Case CType(sender, RadioButton).Name
Case "rbtSol"
txtTBon.Text = 0
Case "rbtCas"
txtTBon.Text = 100
End Select
End Sub
Private Sub chkIR_CheckedChanged(..)Handles chkIR.CheckedChanged,
chkEssalud.CheckedChanged,chkAfp.CheckedChanged
Dim sb As Single = CSng(txtSBruto.Text)
Static d1, d2, d3 As Single
Select Case CType(sender, CheckBox).Name
Case "chkIR"
If chkIR.Checked Then
d1 = sb * 0.05
Else
d1 = 0
End If
Case "chkEssalud"
If chkEssalud.Checked Then
d2 = sb * 0.03
Else
d2 = 0
End If
Case "chkAFP"
If chkAFP.Checked Then
d3 = sb * 0.02
Else
d3 = 0
End If
Técnica de Programación Orientada a Objetos 205
Uso de Controles de Listas
1. Cuadro de Lista (ListBox) Una caja de lista es útil cuando al usuario se le presenta un conjunto de opciones fijas
(el puede escoger solamente de las opciones mostradas, no hay posibilidad de teclear
otra alternativa).
Un ejemplo puede ser al ofrecer una lista de los dias de la semana, los lugares para
vacacionar de una agencia de viajes, o los tratamientos ofrecidos por un salón de
belleza.
Propiedades:
Name: por motivos de reconocimiento, se puede anteceder el prefijo lst al nombre.
Aplicación de ejemplo:
Diseñar la siguiente aplicación.
o Agregar los elementos “Aries” y “Tauro” en tiempo de diseño usando la propiedad Items.
Técnica de Programación Orientada a Objetos 206
o Agregar los elementos “Geminis” y “Cancer” al cargar el formulario.
o Habilitar el botón Agregar al escribir un Signo en el textbox txtSigno.
o Agregar el elemento introducido en el textbox al listbox.
o Eliminar el elemento seleccionado del listbox.
Private Sub Form_Load(..)
lstSignos.Items.Add(“Geminis”)
lstSignos.Items.Add(“Cancer”)
End Sub
Private Sub txtSigno_TextChanged(..)
If Len(Trim(txtSigno.Text))>0 then
btnAgregar.Enabled=True
Else
btnAgregar.Enabled=False
End If
End Sub Private Sub btnAgregar_Click(..)
Dim cad as String = Trim(txtSigno.Text)
lstSignos.Items.Add(cad)
txtSigno.Text=””
txtSigno.Focus()
End Sub
Técnica de Programación Orientada a Objetos 207
o Eliminar todos los elementos del listbox.
2. Cuadro Combinado (ComboBox) Un ComboBox es un control que combina las características de un ListBox y de un
TextBox, es decir, permite mostrar una serie de elementos o ítems en la parte de la
lista, y se comporta como un textbox por que el usuario puede ingresar datos.
Hay tres tipos de Cuadros combinadas (Simple, DropDown y DropDownList). El valor
que se coloca en la propiedad DropDownStyle es el que determina el tipo. Los Cuadros
Combinados DropDown y DropDownList son una buena opción cuando el espacio es
limitado, porque toda la lista se muestra como un menú de cascada, así no ocupa el
espacio en la pantalla hasta que se da clic a la flecha hacia abajo. Los Cuadros
Combinados Simple y DropDown se considera cuando el usuario puede introducir una
opción que no esté predefinida.
Propiedades:
Name: por motivos de reconocimiento, se puede anteceder el prefijo cbo al nombre.
DropDownStyle: determina el estilo del ComboBox.
Private Sub btnEliminar_Click(..)
Dim item As Integer = lstSignos.SelectedIndex
lstSignos.Items.RemoveAt(item)
End Sub
Private Sub btnBorrarTodo_Click(..)
lstSignos.Items.Clear()
End Sub
Técnica de Programación Orientada a Objetos 208
Aplicación de ejemplo:
Diseñar la siguiente aplicación con tres ComboBox, de estilos diferentes y nombres
cboEstilo1, cboEstilo2 y cboEstilo3.
o Adicionar los elementos en tiempo de ejecución, al cargar el formulario.
Private Sub Form_Load(..)
cboEstilo1.Items.Add(“Aries”)
cboEstilo1.Items.Add(“Tauro”)
cboEstilo1.Items.Add(“Geminis”)
cboEstilo1.Items.Add(“Acuario”)
cboEstilo1.Items.Add(“Escorpio”)
cboEstilo1.Items.Add(“Capricornio”)
With cboEstilo2.Items
.Add(“Aries”)
.Add(“Tauro”)
.Add(“Geminis”)
.Add(“Acuario”)
.Add(“Escorpio”)
.Add(“Capricornio”)
End with
Dim signos()={“Aries”,”Tauro”,”Geminis”,”Acuario”,
”Escorpio”,”Capricornio”}
cboEstilo3.Items.Addrange(signos)
End Sub
Técnica de Programación Orientada a Objetos 209
Uso de Controles Gráficos
PictureBox (PictureBox) El PictureBox es un control que permite insertar un archivo de formato gráfico, el cual
puede ser importado desde un archivo de recursos, o como referencia a un archivo en
alguna ubicación.
Propiedades:
Name: por motivos de reconocimiento, se puede anteceder el prefijo pic al nombre. BorderStyle: establece el tipo de borde del control, puede ser un borde fijo simple
(FixedSingle) o un borde 3D (Fixed3D). Image: establece el archivo que será insertado en el picturebox. SizeMode: establece el tipo de ajuste del contenido sobre el tamaño del control.
Aplicación de ejemplo:
Diseñar la siguiente aplicación.
o Insertar un picturebox y establecer las siguientes propiedades: Name: picEmoticon
BorderStyle: FixedSingle
SizeMode: StretchImage
Técnica de Programación Orientada a Objetos 210
Image:
o En el checkbox Mostrar (chkMostrar), definir el código que permita mostrar u ocultar el picturebox.
o Añadir un ComboBox que permita mostrar los elementos: Burlon, Golpeado, Tragon y Emoticon. Cuando el usuario seleccione uno de estos elementos se debe cargar las imágenes respectivas.
Private Sub chkMostrar_CheckedChanged(..)
If chkMostrar.Checked then
picEmoticon.Visible = True
Else
picEmoticon.Visible = False
End If
End Sub
Técnica de Programación Orientada a Objetos 211
o El formato de archivo de recursos .resx consiste en entradas XML, que especifican objetos y cadenas en etiquetas XML. La ventaja que ofrecen los archivos .resx es que al abrirlos en un editor de texto (como Bloc de Notas o Microsoft Word), es posible analizarlos, manipularlos y escribir en ellos. Cuando se ve un archivo .resx, se puede observar realmente la forma binaria de un objeto incrustado (por ejemplo, una imagen) cuando esta información binaria es parte del manifiesto del recurso. Además de ofrecer esta información binaria, los archivos .resx son completamente legibles y susceptibles de mantenimiento.
o Ir al Explorador de Soluciones y activar Mostrar todos los archivos, y observar el archivo de recursos.
o Ir a Agregar recurso > Agregar archivo existente, y adicionar las otras imágenes que requiere.
Técnica de Programación Orientada a Objetos 212
o Observar el explorador de soluciones.
o En el combobox:
Aplicación de ejemplo:
Diseñar un formulario que muestre dos cuadros de lista y una serie de botones que
permitan pasar los elementos de una lista a otra.
Private Sub cboImagenes_SelectedIndexChanged (..)
Select Case cboImagenes.SelectedIndex
Case 0
picEmoticon.Image = My.Resources.burlon
Case 1
picEmoticon.Image = My.Resources.golpeado
Case 2
picEmoticon.Image = My.Resources.tragon
Case 3
picEmoticon.Image = My.Resources.emoticon
End Select
End Sub
Técnica de Programación Orientada a Objetos 213
Declarar tres constantes que almacenen textos que serán usados en cajas de mensaje: "Lista de Elementos", "Para eliminar un dato, debe seleccionarlo previamente", "Para pasar un dato, debe seleccionarlo previamente".
Mostrar 12 elementos en el primer cuadro de lista, y en el label, la cantidad de elementos.
El botón Añadir, permite agregar nuevos elementos al cuadro de lista 1.
Private Const msgbox_Title As String = "Lista de
Elementos"
Private Const msgbox_Eliminar As String = "Para eliminar
un dato, debe seleccionarlo previamente"
Private Const msgbox_Pasar_Dato As String = "Para pasar un
dato, debe seleccionarlo previamente"
Private Sub Form1_Load(..)
With ListBox1
.Items.Add("Naranja")
.Items.Add("Pera")
.Items.Add("Melocotón")
.Items.Add("Albaricoque")
.Items.Add("Manzana")
.Items.Add("Plátano")
.Items.Add("Melón")
.Items.Add("Mango")
.Items.Add("Uvas")
.Items.Add("Sandía")
.Items.Add("Limón")
.Items.Add("Fresquilla")
End With
Label1.Text = ListBox1.Items.Count & " elemento(s)"
End Sub
Private Sub Button5_Click(..)
'Añadir ListBox1
If TextBox1.Text <> "" Then
ListBox1.Items.Add(TextBox1.Text)
Label1.Text = ListBox1.Items.Count & "
elemento(s)"
TextBox1.Text = ""
End If
End Sub
Técnica de Programación Orientada a Objetos 214
El botón Eliminar, permite eliminar un elemento seleccionado del cuadro de lista 1.
Pasar un elemento del cuadro de lista 1 al cuadro de lista 2.
Pasar todos los elementos del cuadro de lista 1 al cuadro de lista 2.
Private Sub Button6_Click(..)
'Eliminar ListBox1
If ListBox1.SelectedIndex <> -1 Then
'Si hay datos seleccionados en el control,
'eliminamos el dato seleccionado
ListBox1.Items.RemoveAt(ListBox1.SelectedIndex)
Label1.Text = ListBox1.Items.Count & "
elemento(s)"
Else
MessageBox.Show(msgbox_Eliminar, msgbox_Title,
MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub
Private Sub Button2_Click(..)
Dim a As Integer = 0
'Pasa un dato seleccionado del control ListBox1 al
control ListBox2
If ListBox1.SelectedIndex <> -1 Then
' 'Si hay datos seleccionados en el control,
' 'pasamos el dato seleccionado
While a < ListBox1.Items.Count
' si el elemento esta seleccionado
If ListBox1.GetSelected(a) = True Then
ListBox2.Items.Add(ListBox1.Items.Item(a))
ListBox1.SetSelected(a, False)
Private Sub Button6_Click(..)
'Eliminar ListBox1
If ListBox1.SelectedIndex <> -1 Then
'Si hay datos seleccionados en el control,
'eliminamos el dato seleccionado
ListBox1.Items.RemoveAt(ListBox1.SelectedIndex)
Label1.Text = ListBox1.Items.Count & "
elemento(s)"
Else
MessageBox.Show(msgbox_Eliminar, msgbox_Title,
MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End Sub
Técnica de Programación Orientada a Objetos 215
Pasar un elemento del cuadro de lista 2 al cuadro de lista 1.
'Si hay datos seleccionados en el control,
'pasamos el dato seleccionado
ListBox2.Items.Add(ListBox2.SelectedItem)
ListBox1.Items.RemoveAt(ListBox2.SelectedIndex)
Label1.Text = ListBox1.Items.Count & " elemento(s)"
Label2.Text = ListBox2.Items.Count & " elemento(s)"
Else
If ListBox1.Items.Count > 0 Then
MessageBox.Show(msgbox_Pasar_Dato, msgbox_Title,
MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End If
End Sub
Private Sub Button3_Click(..)
'Pasa un dato seleccionado del control ListBox2 al
control ListBox1
If ListBox2.SelectedIndex <> -1 Then
'Si hay datos seleccionados en el control,
'pasamos el dato seleccionado
ListBox1.Items.Add(ListBox2.SelectedItem)
ListBox2.Items.RemoveAt(ListBox2.SelectedIndex)
Label1.Text = ListBox1.Items.Count & " elemento(s)"
Label2.Text = ListBox2.Items.Count & " elemento(s)"
Else
If ListBox2.Items.Count > 0 Then
MessageBox.Show(msgbox_Pasar_Dato, msgbox_Title,
MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End If
End Sub
Técnica de Programación Orientada a Objetos 216
Pasar todos los elementos del cuadro de lista 2 al cuadro de lista 1.
El botón Ordenar datos permitirá ordenar alfabéticamente los elementos de ambos cuadros de lista.
Private Sub Button4_Click(..)
'Pasa todos los elementos del control ListBox2 al
control ListBox1
While ListBox2.Items.Count > 0
ListBox2.SelectedIndex = ListBox2.Items.Count - 1
ListBox1.Items.Add(ListBox2.SelectedItem)
ListBox2.Items.RemoveAt(ListBox2.SelectedIndex)
End While
Label1.Text = ListBox1.Items.Count & " elemento(s)"
Label2.Text = ListBox2.Items.Count & " elemento(s)"
End Sub
Private Sub Button7_Click(ByVal ..)
ListBox2.Sorted = True
ListBox2.Sorted = False
End Sub
Técnica de Programación Orientada a Objetos 217
Construcción de Aplicaciones MDI
Visual Basic permite crear aplicaciones empleando una interfaz de múltiples documentos (MDI:
Multiple Document Interface), o dicho en términos de Visual Basic, múltiples formularios. En
una aplicación MDI, se pueden abrir varias ventanas hijas. Cada una de estas ventanas hijas
(formularios) son iguales entre sí. En una aplicación MDI puede haber varias ventanas hijas,
pero solo una ventana padre por aplicación. El formulario padre actúa como contenedor de los
formularios hijos. Muchos procesadores de textos bajo Windows son buenos ejemplos de
aplicaciones MDI.
Para cargar formularios en un proyecto y poder interactuar entre ellos, tenemos diferentes
opciones:
1.- Instanciamos un formulario y lo cargamos. Este es la forma tradicional de la orientación a
objetos clásica y que es la usada en VB.NET 2002 y VB.NET 2003. También utilizada en VB
2005 por supuesto:
Private Sub Button1_Click(..) Handles Button1.Click
Dim MiF As New Form2
MiF.Show()
End Sub
2.- Utilizamos una instancia por defecto para cargar el formulario utilizando el nombre de
espacio My (sólo para Visual Basic 2005):
Private Sub Button1_Click(..) Handles Button1.Click
My.Forms.Form2.Show()
End Sub
3.- Utilizamos una instancia por defecto para cargar el formulario de forma directa (sólo para
Visual Basic 2005):
Formulario Padre
Formulario Hijo 1
Formulario Hijo 2
Formulario 1
Formulario 2
Formulario 3
Ejemplo: MDI (Multiple Document Interface) Ejemplo: SDI (Simple Document Interface)
Técnica de Programación Orientada a Objetos 218
Private Sub Button1_Click(..) Handles Button1.Click
Form2.Show()
End Sub
En esta sesión, crearemos un formulario de acceso que permita abrir un formulario principal de
tipo MDI, que a su vez contenga una barra de Menú (MenuStrip) desde donde llame a otros
formularios hijos, y una barra de estado (StatusStrip) que permita mostrar cierta información.
Como agregar un formulario MDI al Proyecto?
- Crear un proyecto de Visual Basic de nombre SISTEMA, que se guarde en el Escritorio.
- Creación del formulario de Acceso.
Objeto Propiedad Valor
Formulario
Name frmAcceso
FormBorderStyle FixedSingle
MaximizeBox False
MinimizeBox False
Text ACCESO AL SISTEMA
TextBox1 Name txtUsuario
TextBox2
Name txtPassword
PasswordChar *
Button1
Name btnIngresar
Text &Ingresar
Enabled False
Button2
Name btnCancelar
Text &Cancelar
Técnica de Programación Orientada a Objetos 219
Para agregar otro formulario al proyecto, ir al Menú Proyecto > Agregar Windows Forms
Establecer las siguientes propiedades para el nuevo formulario. La propiedad IsMDIContainer definirla a True para que se comporte como un MDI o contenedor de formularios.
Objeto Propiedad Valor
Formulario
Name frmPrincipal
IsMDIContainer True
Text PANEL PRINCIPAL
WindowState Maximized
Como insertar una Barra de Menú al formulario MDI?
El control MenuStrip permite insertar una barra de Menú que presenta opciones que permiten realizar diferentes tipos de acciones, como abrir formularios, cargar aplicaciones, salir del proyecto, etc.
Técnica de Programación Orientada a Objetos 220
Escribir las opciones siguientes:
Insertar un separador.
Añadir la opción de Salir con un ShortcutKey de Ctrl + F4
Completar las opciones del Menú.
Técnica de Programación Orientada a Objetos 221
Para insertar las imágenes junto a las opciones del menú, establecer en la
propiedad Image el valor de
Como insertar una Barra de Estado al formulario MDI?
El control StatusStrip permite insertar una barra de Estado que presenta paneles en los cuales se puede mostrar información como por ejemplo, un mensaje de confirmación, una acción a realizar, opciones activas del sistema como activación del teclado numérico o mayúsculas, etc.
Asumiendo que la resolución del monitor es un estándar de 1024x768, crearemos tres paneles de texto (StatusLabel) de ancho 150, 624 y 150. Para cada panel modificaremos algunas propiedades:
Técnica de Programación Orientada a Objetos 222
Objeto Propiedad Valor
ToolStatusStrip3
BorderSides Todo (All)
Autosize False
BorderStyle SunkenOuter
Size > Width 150
Text 0:0:0
Image (Insertar Reloj al archivo de recursos)
ImageAlign MiddleRight
ToolStatusStrip2
BorderSides Todo (All)
Autosize False
BorderStyle SunkenOuter
Size > Width 624
Text
ToolStatusStrip1
BorderSides Todo (All)
Autosize False
BorderStyle SunkenOuter
Size > Width 150
Text Usuario:
Image (Insertar User al archivo de recursos)
ImageAlign MiddleLeft
Como insertar una Barra de Herramientas al formulario MDI?
El control ToolStrip permite insertar una barra de herramientas que muestra botones que permitan realizar las acciones más importantes, como carga de formularios o aplicaciones.
Técnica de Programación Orientada a Objetos 223
Modificar las propiedades del ToolStrip para que se muestre de la siguiente manera:
Objeto Propiedad Valor
(Button)
ToolStripButton1
DisplayStyle Image
Image (Insertar Calculadora del archivo
de recursos)
ToolTipText Calculadora
(Button)
ToolStripButton2
DisplayStyle Image
Image (Insertar Excel del archivo de
recursos)
ToolTipText MS Excel 2007
(Separator)
ToolStripSeparator1
(Button)
ToolStripButton4
DisplayStyle ImageAndText
Image (Insertar Tabla del archivo de
recursos)
Text Tabla de Multiplicar
Técnica de Programación Orientada a Objetos 224
En el formulario frmAcceso, habilitar el botón btnIngresar solamente cuando el usuario haya ingresado el nombre de usuario y password.
Si el password ingresado es SISE (mayúsculas o minúsculas), ocultar frmAcceso y mostrar frmPrincipal.
En el formulario frmPrincipal, la funcionalidad de las opciones de menú Calculadora y Excel 2007, permitirán ejecutar estas aplicaciones usando la instrucción Shell dentro de un Try..Catch para interceptar el error en caso de que el archivo no se encuentre en el equipo.
Private Sub txtUsuario_TextChanged(..)Handles
txtUsuario.TextChanged, txtPassword.TextChanged
If Len(Trim(txtUsuario.Text)) > 0 And
Len(Trim(txtPassword.Text)) > 0 Then
btnIngresar.Enabled = True
Else
btnIngresar.Enabled = False
End If
End Sub
Private Sub txtUsuario_TextChanged(..)Handles
txtUsuario.TextChanged, txtPassword.TextChanged
If UCase(txtPassword.Text) = "SISE" Then
Me.Hide()
frmPrincipal.Show()
End If
End Sub
Private Sub CalculadoraDeWindowsToolStripMenuItem_Click(..)
Handles CalculadoraDeWindowsToolStripMenuItem.Click
Try
Dim n = Shell("C:\Windows\System32\calc.exe",
AppWinStyle.NormalFocus)
Catch ex As Exception
MessageBox.Show("No se ha encontrado la
aplicacion", "Error", MessageBoxButtons.OK,
MessageBoxIcon.Warning)
End Try
End Sub
Técnica de Programación Orientada a Objetos 225
Defina las instrucciones para la opción MS Excel 2007.
Como este bloque de acciones es el mismo que debe ser ejecutado al pulsar el botón respectivo en el ToolStrip, entonces podríamos modificar el Handles.
Se pueden heredar las características de un formulario?
La herencia es una de las características resaltantes de la programación orientada a objetos, y
cuando diseñamos un formulario con determinadas propiedades, podemos hacer que otros
formularios hereden dichas propiedades, ahorrando bastante tiempo en el diseño de las
interfaces.
Agregar al proyecto anterior un formulario Windows,y establecer las siguientes propiedades:
Objeto Propiedad Valor
Formulario
Name frmPlantilla
Backcolor (Amarillo claro)
FormBorderStyle FixedSingle
Font > Bold True
MaximizedButton False
MinimizeButton False
Text
Private Sub CalculadoraDeWindowsToolStripMenuItem_Click(..)
Handles CalculadoraDeWindowsToolStripMenuItem.Click,
ToolStripButton1.Click
Try
Dim n = Shell("C:\Windows\System32\calc.exe",
AppWinStyle.NormalFocus)
Catch ex As Exception
MessageBox.Show("No se ha encontrado la
aplicacion", "Error", MessageBoxButtons.OK,
MessageBoxIcon.Warning)
End Try
End Sub
Técnica de Programación Orientada a Objetos 226
Ir al Menú Generar > Generar Sistema (este nombre depende del nombre del proyecto).
Agregar un formulario Windows, pero esta vez seleccionar Formulario Heredado, y establecer por nombre frmTabla.
Seleccionar el formulario que será usado para heredar las propiedades a los hijos.
Técnica de Programación Orientada a Objetos 227
El formulario resultante podrá ahora ser modificado y tener la siguiente apariencia.
Realizar el mismo procedimiento para el diseño del formulario frmArea.
Como se llaman a los formularios hijos?
En la página X (Construcción de Aplicaciones MDI), se detallan los métodos de carga, el
primero permite abrir varias instancias del formulario hijo, mientras que los otros, permiten abrir
solo una instancia.
En el Menú Aplicaciones > Matemáticas > Área de un Rectángulo, de un doble clic para abrir la ventana de código y escribir.
Private Sub AreaDeUnRectanguloToolStripMenuItem_Click (..)
Dim form As New frmArea
form.MdiParent = Me
form.Show()
End Sub
Técnica de Programación Orientada a Objetos 228
En la opción Tabla de Multiplicar, del mismo menú, escribir este otro código, y notar las diferencias entre ambos.
En frmTabla, escribir el código que debe ser usado en el botón Generar para mostrar la tabla de multiplicar del 1 al 12 de un número entero cualquiera ingresado en la caja de texto (Consistencie que solamente ingresen números)
En frmArea, escribir el código que debe ser usado en el botón Operar para calcular el Área de un Rectángulo. Debe consistenciar que solamente ingresen valores numéricos en las cajas de texto de base y altura.
Ejercicios propuestos.
1- Ingrese por teclado en una caja de texto la hora en formato de 24 horas y en otra caja de texto la cantidad de minutos al hacer clic en un botón deberá salir la hora en formato de 12 horas por ejemplo si se ingresa 23 en una caja y en la otra 12 el resultado seria 11:12:PM
2- Ingrese la cantidad de minutos hablados por una persona y escoja el tipo de llamada (Local, Nacional, Internacional).Se visualizara el importe de la llamada sabiendo que por los 3 primeros minutos se paga S/ 1.00 y por cada minuto adicional se paga 0.50 en caso sea local si es nacional se incrementa el 25% y si es internacional se incrementa el 60% a los precios por minuto.
3- Ingresar el nombre de un trabajador, la cantidad de hijos y su sueldo, si este tiene hijos se le dará una bonificación de S./40.00 por hijo y si no tiene hijos se le dará el 25% de su sueldo se deberá mostrar la bonificación y el sueldo final.
4- Ingrese por teclado dos números y al escoger un signo de operación se deberá mostrar el resultado de la operación.
Private Sub GeneracionDeTablasDeMultiplicarToolStripMenuItem_Click (..)
frmTabla.MdiParent = Me
frmTabla.Show()
End Sub
Técnica de Programación Orientada a Objetos 229
5- Ingrese un numero máximo de 2 cifras si el numero es de una cifra se deberá mostrar cuanto falta para convertirse en un numero de 2 cifras, y si es de 2 cifras se deberá mostrar cuanto falta para convertirse en un numero de 3 cifras.
6- Ingrese un número cualquiera y muestre la cantidad de cifras que tiene según sea el caso.
Ejemplo: 203 = “Tiene 3 cifras”, 45678 = “Tiene 5 cifras” tome en cuenta que el numero
máximo a ingresar es un millón.
7- Ingrese por teclado el nombre, año de nacimiento y sexo de una persona (M o F),se deberá mostrar uno de los siguientes mensajes. - Varón mayor de edad - Varón menor de edad - Dama mayor de edad - Dama menor de edad
8- Ingrese un número y visualícelo en romano.
9- Ingrese por teclado el día de nacimiento y el mes de nacimiento de una persona al hacer clic se deberá mostrar su signo zodiacal así como también deberá aparecer la imagen del signo Zodiacal en un control PictureBox.
10- Se deberá desarrollar un algoritmo en el cual se deberá ingresar el nombre de un alumno y se deberá escoger el turno en el que estudia (M , T y N) así como también el ciclo (I, II, III, IV, V, VI y SIDET) y la carrera (CI, Enfermería y Administración) se deberá calcular el pago de su pensión en base a los siguientes datos:
el precio por carrera es:
CI = 320.00
Enfermería = 280.00
Administración = 270.00
Además que dependiendo del ciclo en el que están se pagara un recargo del precio de
10,20,30,40,50,60 y 70% (para SIDET). Así como también si es del turno “M” se
deberá recargar 10% mas solo si esta en I, II, o III ciclo, si es del turno “T” se recarga el
15 % mas solo si esta en I, o II y por último si es del turno “N” se le hará un descuento
del 15 % solo si esta en SIDET
Al finalizar solo se debe mostrar el monto de la pensión.
Técnica de Programación Orientada a Objetos 230
11- Realizar el siguiente formulario:
12- Se deberá ingresar el largo y el ancho del terreno y conforme vayan digitándolo deberá salir el total (Largo * ancho)
13- Se deberá ingresar el precio por metro y al escoger una categoría el precio se incrementara en un 10, 20, y 30 % respectivamente según la categoría, además de salir el precio total que será el total de área * el precio y si se escogió en tipo de alquiler Contado se le hará un Descuento de 10% al precio total y si es crédito se le hará un recargo de 15 %.
14- Finalmente se deberá escoger si se pagara alumbrado, parques o serenazgo sacando los % correspondientes al precio total según indica el formulario el precio final deberá salir al hacer clic en el botan calcular.
15- Ingrese un numero y Genere las siguientes series: (el resultado se mostrara en un label o en un text) - 1,3,5,7,..... - -1,+3,-5,+7... - 1,3,2,5,3,7,4,9,5,11.... - 0,1,1,2,3,5,8,13...(Serie Fibonacci)
16- Genere 100 números aleatorios y diga cuantos primos mayores a 50 hay, perfectos menores a 10 hay, pares e impares.
Técnica de Programación Orientada a Objetos 231
17- Genere 100 números aleatorios y al finalizar diga cual es el mayor y el menor.
18- Ingrese un numero de cualquier cifra y mostrarlo en forma invertida
19- Ingrese un numero y conviértalo en base 2
20- Ingrese una cadena y muestre lo siguiente: - La cadena en forma invertida - Diga cuantas vocales tiene - Diga cuantos espacios en blancos hay
21- Ingrese una cadena y conviértalo en mayúscula y en minúsculas sin utilizar las funciones ucase y lcase.
22- Genere 10 números aleatorios y si el numero es par se deberá incrementar el numero con la suma de su raíz cuadrada, si el numero es impar se deberá incrementar el numero con la suma del seno del numero. AL finalizar se debe mostrar la suma de todos los números.
23- Ingrese Una fecha y diga cuantos días faltan para acabar el año, cuantos días han pasado desde esa fecha hasta la fecha actual, que día cae esa fecha (Lunes, martes), y muestre la misma fecha en el siguiente formato: “Lunes 15 de Abril de 2003” (Por ejemplo)
24- Ingrese en una caja de texto una cadena y al finalizar diga cuantas palabras tiene dicha cadena y cual es la cantidad de caracteres que tiene la palabra con mayor longitud
25- Ingrese un usuario y un password y si se equivoca tres veces debe salir de la aplicación
26- Realice el siguiente formulario: En este formulario se deberá escoger un color y un objeto (checks,text, options) y al
hacer clic en fondo o en letra deberá cambiar al color que se escogió ya sea el
fondo(backcolor o la letra(forecolor)
Luego al hacer clic en cursiva( font.italic) o en negrita (font.bold) o subrayado
(font.underline) se debera cambiar la apariencia de los controles que se escogio (Checks,
text ,Options)
Técnica de Programación Orientada a Objetos 232
27- Realice el siguiente formulario:
28- Cuando se haga clic en Mostrar Resultado se debe mostrar la edad del trabajador, el tiempo de servicio y el código que se generara de la siguiente manera: el año de ingreso luego la letra “M” o “F” según su sexo , los 2 primeros caracteres de su apellido paterno, los 2 primeros caracteres de su apellido materno, el primer carácter de su nombre y un correlativo
29- Además al ingresar sus nombres al perder el enfoque se deberá cambiar el texto por mayúsculas y al entrar al enfoque de algún texto el color de fondo deberá cambiar y al salir del enfoque deberá regresar al color original que tuvo.
Técnica de Programación Orientada a Objetos 233
Contenido.
Introducción a la Estructura de Datos o Conceptos o Operaciones: Asignación y obtención de valores. Recorrido por los
elementos de un Arreglo.
Metodologías de trabajo usadas en la construcción de aplicaciones con Vectores y Matrices.
Los Arrays (término en inglés que se refiere a los Arreglos), en las versiones anteriores de
Visual Basic eran tipos de datos de los llamados por valor, al igual que lo son los tipos Integer,
Double, etcétera. Pero en Visual Basic .NET, los arrays realmente son tipos por referencia.
Las variables que hemos estado usando hasta ahora, eran de tipo escalar: sólo pueden
contener un valor a la vez, pero resulta que en ocasiones nos podemos ver en la necesidad de
querer tener en una misma variable, valores que de alguna forma están relacionados. Por
ejemplo, si tenemos una colección de discos, nos podría interesar tener esa discografía incluida
en una misma variable para poder acceder a cualquiera de esos discos sin necesidad de tener
que crear una variable distinta para cada uno de los discos, ya que sería totalmente ineficiente
si, por ejemplo, quisiéramos imprimir una relación de los mismos.
Realmente para el ejemplo, hay otros tipos de datos que serían más prácticos, pero cuando
veamos esos otros tipos de datos, serás tú el que decida cual utilizar.
Una de las formas en las que podemos agrupar varios datos es mediante los arrays (o
matrices). Usando un array, podemos acceder a cualquiera de los valores que tenemos
Técnica de Programación Orientada a Objetos 234
almacenado mediante un índice numérico. Por ejemplo, si tenemos la variable discografía y
queremos acceder al tercer disco, podríamos hacerlo de la siguiente forma: discografía(3).
Sabiendo esto, podemos comprobar que sería fácil recorrer el contenido de los arrays mediante
un bucle For.
¿Qué tipos de datos se pueden usar para crear arrays?
Los tipos de datos de las variables usadas como array, pueden ser de cualquier tipo,
dependiendo de lo que queramos guardar. Por ejemplo, si queremos guardar los nombres de
los discos que tenemos, podemos usar un array del tipo String, que lo que nos interesa es
saber el porcentaje de goles por partido de nuestro equipo de fútbol favorito, el tipo de datos
del array podía ser Integer. Incluso si queremos, también podemos crear un array de un tipo
que nosotros hayamos definido o de cualquier clase que exista en el .NET Framework.
Declarar variables como arrays
Para poder indicarle al VB que nuestra intención es crear un array podemos hacerlo de dos
formas distintas, para este ejemplo crearemos un array de tipo Integer:
1. La clásica (la usada en versiones anteriores)
2. La nueva forma introducida en .NET:
De cualquiera de estas dos formas estaríamos creando un array de tipo Integer llamada X.
Cuando declaramos una variable de esta forma, sólo le estamos indicando al VB que nuestra
intención es que la variable a sea un array de tipo Integer, pero ese array no tiene reservado
ningún espacio de memoria.
Asignar valores a un array
Para asignar un valor a un elemento de un array, se hace de la misma forma que con las
variables normales, pero indicando el índice (o posición) en el que guardará el valor.
Dim X() As Integer
Dim X As Integer()
Técnica de Programación Orientada a Objetos 235
Por ejemplo, para almacenar el valor 3 en la posición 3 del array X, haríamos lo siguiente:
Acceder a un elemento de un array
De igual forma, si queremos utilizar ese elemento que está en la posición 3 para una operación,
podemos hacerlo como con el resto de las variables, pero siempre usando el paréntesis y el
número de elemento al que queremos acceder:
El índice para poder acceder al elemento del array puede ser cualquier expresión numérica,
una variable o como hemos estado viendo en estos ejemplos, una constante. La única
condición es que el resultado sea un número entero.
Los límites de los índices de un array
Como ya he comentado antes, el índice inferior de un array, siempre es cero, esto es
invariable, todos los arrays de .NET Framework empiezan a contar por cero.
Pero el índice superior puede ser el que nosotros queramos, aunque sin pasarnos, que la
memoria disponible se puede agotar si pretendemos usar un valor exageradamente alto.
X(3) = 3
A = B*X(3)
10
12
8
3
X(0)
X(1) X(2)
X(3)
Técnica de Programación Orientada a Objetos 236
Saber el tamaño de un array
Cuando tenemos un array declarado y asignado, podemos acceder a los elementos de ese
array mediante un índice, esto ya lo hemos visto; pero si no queremos "pasarnos" cuando
queramos acceder a esos elementos, nos será de utilidad saber cuántos elementos tiene el
array, para ello podemos usar la propiedad Length, la cual devuelve el número total de
elementos, por tanto, esos elementos estarán comprendidos entre 0 y Length - 1.
Esto es útil si queremos acceder mediante un bucle For, en el siguiente código se mostrarían
todos los elementos del array a:
Inicializar un array al declararla
Al igual que las variables normales se pueden declarar y al mismo tiempo asignarle un valor
inicial, con los arrays también podemos hacerlo, pero de una forma diferente, ya que no es lo
mismo asignar un valor que varios.
Aunque hay que tener presente que si inicializamos un array al declararla, no podemos indicar
el número de elementos que tendrá, ya que el número de elementos estará supeditado a los
valores asignados.
Para inicializar un array debemos declarar ese array sin indicar el número de elementos que
contendrá, seguida de un signo igual y a continuación los valores encerrados en llaves.
Veamos un ejemplo:
También podemos hacerlo de esta otra forma:
For i=0 to X.Length – 1
‘ Leer X(i)
Next
Dim X() As Integer = {4, 2, 5, 9, 10}
Dim X() As Integer = {4, 2, 5, 9, 10}
Técnica de Programación Orientada a Objetos 237
Usando cualquiera de estas dos formas mostradas, el número de elementos será 5, por tanto
los índices irán desde 0 hasta 4.
Los arrays pueden ser de cualquier tipo
En el caso de que sean datos de tipo String, los valores a asignar deberán estar entre comillas
dobles o ser variables de tipo String. Por ejemplo:
Usar un bucle For Each para recorrer los elementos de un array
El tipo de bucle For Each es muy útil para recorrer los elementos de un array, además de ser
una de las pocas, por no decir la única, formas de poder acceder a un elemento de un array sin
indicar el índice.
Ámbito de Alcance de los Arrays
Al igual que las variables, el array podrá ser declarado en un ámbito Local, Privado o Global,
dependiendo de la complejidad de la aplicación o de los requerimientos, se tendrá que usar el
ámbito adecuado.
Dim Cad As String() = {"Hola", "Mundo", "te", "saludo"}
Cad(3)=”Mario”
For i=0 to Cad.Length -1
‘ Leer Cad(i)
Next
Dim Cad As String() = {"Hola", "Mundo", "te", "saludo"}
Dim i as Integer
For Each i in Cad
‘ Leer Cad(i)
Next
Técnica de Programación Orientada a Objetos 238
Aplicación de ejemplo:
Diseñar un formulario (frmDistritos) que al iniciar muestre los distritos Ate, Barranco y
Cercado de Lima, que sean leídos desde un arreglo de nombre Distritos y sea mostrado en un
ListBox.
Declaramos el array Distritos con los elementos y una variable encargada de contabilizar la cantidad de elementos que serán agregados, luego añadirlos al listbox.
Public Class frmDistritos
Private distritos()as String={“Ate”,”Barranco”,”Cercado
de Lima”}
Private cont as Integer
Private Sub frmDistritos_Load(..)
Dim i As Integer
cant = distritos.Length
For i = 0 To distritos.Length - 1
lstLista.Items.Add(distritos(i))
Next
End Sub
Técnica de Programación Orientada a Objetos 239
Al agregar, se mostrará un cuadro de diálogo que permita agregar nuevos distritos al arreglo, y luego mostrarlos nuevamente en el cuadro de lista.
Private Sub btnAgregar_Click(..)
Dim cad As String = InputBox("Nombre del Distrito:",
"Agregar")
If cad.Trim.Length > 0 Then
cant += 1
ReDim Preserve distritos(cant - 1)
distritos(cant - 1) = cad
lstLista.Items.Clear()
For i As Integer = 0 To distritos.Length - 1
lstLista.Items.Add(distritos(i))
Next
Else
MessageBox.Show("Escriba un nombre valido",
"Error", MessageBoxButtons.OK,
MessageBoxIcon.Information)
End If
End Sub
Técnica de Programación Orientada a Objetos 240
Al eliminar, se eliminara el elemento del arreglo y luego se mostrarán los
elementos del arreglo.
Private Sub btnEliminar_Click(..)
Dim item As Integer = lstLista.SelectedIndex
For i As Integer = item To distritos.Length - 1
If i <> distritos.Length - 1 Then
distritos(i) = distritos(i + 1)
End If
Next
cant -= 1
ReDim Preserve distritos(cant - 1)
„------- Mostrar los elementos en el Listbox
lstLista.Items.Clear()
For cont As Integer = 0 To distritos.Length - 1
lstLista.Items.Add(distritos(cont))
Next
End Sub
Técnica de Programación Orientada a Objetos 241
Propiedades de los Arreglos
Entre las más importantes tenemos:
1- Length.- Devuelve la cantidad de elementos que tiene un arreglo
Ejemplo :
Dim v(4) as String
v.length() esto devolvería 5 , ya que el arreglo “v” tiene 5 elementos (0 al 4)
2- Sort.- Ordena un arreglo. Se utiliza la clase Array
Ejemplo
Dim V(3) as Integer ={13,7,16}
Array.Sort(V) aquí la clase Array esta ordenado el Arreglo “V”
3- CopyTo.- Copia los datos de un arreglo a otro en una posición dada.
Sintaxis: Arreglo1.CopyTo (Arreglo2, Posición)
Ejemplo
Dim V1(3) as Integer ={13,7,16}
Dim V2(3) as Integer
V1.CopyTo(V2,0) Aquí se esta copiando en el arreglo V2 a partir de la posición 0 los
datos que hay en el arreglo V1
4- GetUpperBound (Indice_Dimension).- Esta función devuelve el índice mayor de un arreglo.
Dim V(3) as Integer
Si nos damos cuenta el arreglo declarado es un arreglo de una dimensión.
Esta dimensión seria la dimensión 0
v.GetUpperBound(0) esto devolvería 3
Técnica de Programación Orientada a Objetos 242
Ahora si el arreglo tuviera2 dimensiones Dim M (2,3) as Integer, tendríamos la
dimensión 0 (0 al 2) y la dimensión 1 (0 al 3)
M.GetUpperBound (0) esto devuelve 2
M.GetUpperBound (1) esto devuelve 3
5- GetLowerBound (Indice_Dimension).- Esta función devuelve el índice menor de un arreglo.
Casi siempre el índice menor será 0 al no ser que el arreglo empiece con otro índice.
Técnica de Programación Orientada a Objetos 243
Aplicaciones.
1- Llene un vector de 5 elementos con números aleatorios y muéstrelos en un listbox
Private Sub Button2_Click(..)
Dim vec (4) As Integer „Se declara el vector
Dim I As Int16
Dim N As Int16
„Hacemos un for desde 0 hasta el índice mayor del arreglo
For I = 0 To Vec.GetUpperBound(0)
„Generamos el numero aleatorio
N = CInt (Rnd () * 100)
„Guardamos el numero en el vector
Vec (I) = N
„Agregamos al Listbox el dato del vector
Me.ListBox1.Items.Add(vec(I))
Next
End Sub
Técnica de Programación Orientada a Objetos 244
2- Ingrese un numero en una caja de texto, al hacer click en el botón “Agregar” se debe de agregar el numero a un arreglo dinámico además de mostrador en un listbox
„Aquí se declara el arreglo que es dinámico (nótese que no va nada
entre los paréntesis)
Private V () As Int16
„Este procedimiento se encarga de llenar el listbox con los datos
que tiene el vector
Sub Listar()
Me.ListBox1.Items.Clear()
Dim i As Int16
Me.ListBox1.Items.Clear()
For i = 0 To V.GetUpperBound(0)
Me.ListBox1.Items.Add(V(i))
Next
End Sub
Private Sub Form2_Load(..)
„Aqui se el asigna un elemento al vector (el índice de ese
elemento será 0) ni bien carga el „formulario
ReDim Preserve V(0)
End Sub
Private Sub Button1_Click(..)
Dim pos As Int16
„Capturamos el índice mayor del arreglo
pos = V.GetUpperBound (0)
Técnica de Programación Orientada a Objetos 245
3- Llene un vector de 100 elementos con números aleatorios sin que estos se repitan y muéstrelos en un listbox
„Declaramos el vector
Private Vec (99) As Integer
„Ahora creamos una función llamada “BuscarItem”, esta función recibirá como
parámetro un „numero y se buscara en todo el vector.
„Si ese numero se encuentra la función devuelve “True” caso contrario “False”
Function BuscarItem(ByVal N%) As Boolean
Dim Estado As Boolean = False
Dim I As Integer
For I = 0 To Vec.GetUpperBound(0)
If Vec(I) = N Then
Estado = True
Exit For
End If
Next
BuscarItem = Estado
End Function
Private Sub Button1_Click(..)
Dim N As Int16
Dim J As Int16 = 0
Me.ListBox1.Items.Clear()
„Aquí se inicia el bucle para llenar los datos al vector
Do While J <= Vec.GetUpperBound (0)
„Se genera el numero aleatorio
N = CInt (Rnd () * 100)
„Llamamos a la función BuscarItem y le enviamos el „numero
„generado si la función devuelve “False” „quiere decir que no lo
encontró.
„Si no lo encontró lo agrega al vector.
If Not BuscarItem(N) Then
Vec(J) = N
Técnica de Programación Orientada a Objetos 246
„Ademas de agrega a la lista
Me.ListBox1.Items.Add (Vec (J))
J = J + 1
„aumentamos el valor de la variable J que es la que esta controlando la
„posición del vector que se esta llenando
End If
Loop
End Sub
End Class
Técnica de Programación Orientada a Objetos 247
4- Llene un vector dinámico con nombres de países. Al hacer click en el botón “Agregar” se mostrara un INPUTBOX donde se debe de
ingresar el nombre del país, inmediatamente se mostrara un mensaje indicando si se
quiere continuar alo cual si se responde “Si” se repetirá el proceso.
El proceso terminara cuando se responda “No”
Además hay un botón “Buscar” que mostrar un INPUTBOX donde se ingresara el nombre de un
país, si ese país existe en el arreglo se seleccionara del Listbox, caso contrario se mostrara un
mensaje indicando que “No existe”
Técnica de Programación Orientada a Objetos 248
Desarrollo
„Se declara el arreglo dinámico
Private V () As String
Private Sub CmdAgregar_Click(..)
Dim Rpta As Integer, P As String
Dim I As Integer = 0
„Empieza el proceso hasta que en el mensaje se responda “No”
Do
„Se abre un cuadro de dialogo para ingresar un país
P = InputBox ("Ingrese País")
„Se agrega un elemento al vector
ReDim Preserve V (I)
„Se agrega el país al vector
V (I) = P
„Se agrega el valor del vector al Listbox
Me.ListBox1.Items.Add (UCase (V (I)))
„Se incrementa la variable “I” es la que controla la „posición
del elemento que se esta llenando en le „vector
I = I + 1
„Aquí se muestra el mensaje y la respuesta se guarda „en la
variable “Rpta” (Son 2 posibles „respuestas Si „–VbYes y No –
VbNo)
Rpta = MsgBox ("Desea Continuar...?", MsgBoxStyle.Question +
MsgBoxStyle.YesNo, "Confirmar")
Loop Until Rpta = vbNo
End Sub
Private Sub CmdBuscar_Click(..)
Dim P As String
Dim Estado As Boolean = False
„Se ingresa el país a buscar
P = InputBox ("Ingrese país a buscar")
Dim I%
For I = 0 To V.GetUpperBound(0)
„Se busca y si e encuentra se selecciona el listbox
Técnica de Programación Orientada a Objetos 249
If UCase (P) = V (I) Then
Me.ListBox1.SelectedIndex = I
Estado = True
End If
Next
„Al final si Estado es igual “False” quiere decir que no se „encontró
If Not Estado Then
MsgBox("No se encontró el país", MsgBoxStyle.Critical,
"Advertencia")
End If
End Sub
Técnica de Programación Orientada a Objetos 250
5- Llene una matriz con números aleatorios y muéstrelos en un “Listview”
Private m (4, 4) As Integer „Se declara la matriz
„Este sub se encarga de llenar los datos de la matriz al Listview
Sub Llenar ()
Dim F%, C%
For F = 0 To m.GetUpperBound(0)
Me.ListView1.Items.Add(m(F, 0))
For C = 1 To m.GetUpperBound(1)
Me.ListView1.Items(F).SubItems.Add(m(F, C))
Next
Next
End Sub
Private Sub Form5_Load(..)
Dim F%, C%
For F = 0 To m.GetUpperBound(0)
For C = 0 To m.GetUpperBound(1)
m(F, C) = CInt(Rnd() * 100)
Next
Next
Me.ListView1.Columns.Add("1", 40, HorizontalAlignment.Center)
Me.ListView1.Columns.Add("2", 40, HorizontalAlignment.Center)
Me.ListView1.Columns.Add("3", 40, HorizontalAlignment.Center)
Me.ListView1.Columns.Add("4", 40, HorizontalAlignment.Center)
Me.ListView1.Columns.Add("5", 40, HorizontalAlignment.Center)
Me.ListView1.View = View.Details
Call Llenar()
End Sub
Técnica de Programación Orientada a Objetos 251
Bueno para este ejercicio 5 tenemos que tener en cuenta algo:
Se esta utilizando un “Listview” para poder mostrar los datos de la matriz, este control permite
tener varias columnas y filas como si se tratase de una tabla.
Para agrega una columna se hace lo sgte:
Me.ListView1.Columns.Add("1", 40, HorizontalAlignment.Center)
Aquí se esta agregando una columna llamada “1” que tiene de ancho 40 y su alineación será al
centro
Hay que tener en cuenta también:
Me.ListView1.View = View.Details
Esto hace que se vea las columnas, ya que sin esta propiedad no se podría ver los
encabezados de las columnas ni tampoco todas las filas creadas.
Ahora para llenar algo a un “ListView” se hace:
Me.ListView1.Items.Add(“Peru”)
En este ejemplo se esta agregando “Perú” al listview, cada vez que se agrega un Ítem al
Listview este toma un índice que empezara de 0.
Que pasaría si queremos seguir llenando mas países en la misma fila pero en otras columnas?
La sentencia seria esta
Me.ListView1.Items(0).SubItems.Add(“Bolivia”)
Notese esto: Items(0).SubItems.Add(“Bolivia”)
Aquí dice que Bolivia será un SubItem de la fila 0 ósea se mostrara en otra columna que no sea
la principal (La principal seria la columna 0)
6- Llene 2 matrices con números aleatorios y en una tercera matriz guarde la suma de las 2 anteriores, muestre las matrices en “Listview”
Técnica de Programación Orientada a Objetos 252
Private m1(4, 4) As Integer
Private m2(4, 4) As Integer
Private m3(4, 4) As Integer
„Se crea un procedimiento llamado “FormatoLista” es te recibe como
parámetro el listview y le dará „el formato correspondiente
Sub FormatoLista(ByRef Lista As ListView)
Lista.Columns.Add("1", 40, HorizontalAlignment.Center)
Lista.Columns.Add("2", 40, HorizontalAlignment.Center)
Lista.Columns.Add("3", 40, HorizontalAlignment.Center)
Lista.Columns.Add("4", 40, HorizontalAlignment.Center)
Lista.Columns.Add("5", 40, HorizontalAlignment.Center)
Lista.View = View.Details
End Sub
„Se crea un procedimiento llamado “Llenar” este recibe como
parámetro el listview y el arreglo al „cual llenara el Listview
enviado
Sub Llenar(ByRef Lista As ListView, ByVal X(,) As Integer)
Dim F%, C%
For F = 0 To X.GetUpperBound(0)
Lista.Items.Add(X(F, 0))
For C = 1 To X.GetUpperBound(1)
Lista.Items(F).SubItems.Add(X(F, C))
Next
Next
End Sub
Técnica de Programación Orientada a Objetos 253
Private Sub Form6_Load(..)
Randomize()
Dim F%, C%
„Aqui se llenan las 3 matrices con números aleatorios
For F = 0 To m1.GetUpperBound(0)
For C = 0 To m1.GetUpperBound(1)
m1(F, C) = CInt(Rnd() * 100)
Next
Next
For F = 0 To m2.GetUpperBound(0)
For C = 0 To m2.GetUpperBound(1)
m2(F, C) = CInt(Rnd() * 100)
Next
Next
For F = 0 To m3.GetUpperBound(0)
For C = 0 To m3.GetUpperBound(1)
m3(F, C) = m1(F, C) + m2(F, C)
Next
Next
Call FormatoLista (Me.ListView1)
„Se le da formato al ListView1
Call FormatoLista(Me.ListView2)
Call FormatoLista(Me.ListView3)
Call Llenar (Me.ListView1, m1)
„Aqui se llena el Listview1 con la matriz m1
Call Llenar(Me.ListView2, m2)
Call Llenar(Me.ListView3, m3)
End Sub
Técnica de Programación Orientada a Objetos 254
7- Llene 1 matriz con números aleatorios muéstrela en un ListView, Al hacer click en el botón “Calcular” se debe de mostrar la suma de su diagonal principal y secundaria.
Private m(4, 4) As Integer
Sub Llenar ()‟Este sub llena de la matriz al ListView
Dim F%, C%
For F = 0 To m.GetUpperBound(0)
Me.ListView1.Items.Add(m(F, 0))
For C = 1 To m.GetUpperBound(1)
Me.ListView1.Items(F).SubItems.Add(m(F, C))
Next
Next
End Sub
Private Sub Form7_Load(..)
Dim F%, C%
For F = 0 To m.GetUpperBound(0) „Aqui se sella la matriz
For C = 0 To m.GetUpperBound(1)
m(F, C) = CInt(Rnd() * 10)
Next
Next
„Se le da formato al ListView
Me.ListView1.Columns.Add("1", 40,
HorizontalAlignment.Center)
Me.ListView1.Columns.Add("2", 40,
HorizontalAlignment.Center)
Me.ListView1.Columns.Add("3", 40,
HorizontalAlignment.Center)
Me.ListView1.Columns.Add("4", 40,
HorizontalAlignment.Center)
Me.ListView1.Columns.Add("5", 40,
HorizontalAlignment.Center)
Técnica de Programación Orientada a Objetos 255
„Se le da formato al ListView
Me.ListView1.Columns.Add("1", 40, HorizontalAlignment.Center)
Me.ListView1.Columns.Add("2", 40, HorizontalAlignment.Center)
Me.ListView1.Columns.Add("3", 40, HorizontalAlignment.Center)
Me.ListView1.Columns.Add("4", 40, HorizontalAlignment.Center)
Me.ListView1.Columns.Add("5", 40, HorizontalAlignment.Center)
Me.ListView1.View = View.Details
Call Llenar()
End Sub
Private Sub CmdCalcular_Click(..)
Dim F%, C%, Suma1%, Suma2%
For F = 0 To m.GetUpperBound(0)
For C = 0 To m.GetUpperBound(1)
If F = C Then
suma1 = suma1 + m(F, C)
End If
If F + C = 4 Then
Suma2 = Suma2 + m(F, C)
End If
Next
Next
Me.lbldiag1.Text = Suma1
Me.lbldiag2.Text = Suma2
End Sub
Técnica de Programación Orientada a Objetos 256
Ejercicios propuestos.
1- Al hacer clic en un botón “Agregar” se ingresara en un “InputBox” una cadena, esta cadena se agregara a un vector dinámico y se mostrara en un listbox.
2- Luego se deberá de ingresar Una letra en una caja de texto, al hacer clic en un botón “Buscar” se debe de mostrar la cantidad de veces que se repite esa letra en todo el arreglo dinámico.
3- Generar 100 números aleatorios y guardarlos en un arreglo.
4- Al hacer clic en un botón “Separar” se deberá de recorrer el arreglo anterior y se separaran los pares de los impares en arreglos diferentes. Los 3 arreglos se mostraran en un listbox
5- Llenar una matriz de 5 x 5 con números aleatorios sin que estos se repitan, luego mostrarlos en un ListView
6- Llenar un vector de 25 elementos con números aleatorios, luego pasarlo a una matriz de 5 x 5. Mostrar el arreglo en un listbox y la matriz en un Listview
7- Llenar 2 matrices de 5 x 5 con números aleatorios, luego se deberá de escoger entre un grupo de opciones (Radiobutton) un signo de operación que podrá ser +, - , *, /. Al hacer clic en un botón “Calcular” se deberá de llenar una tercera matriz con la
operación seleccionado entre la matriz 1 y la matriz 2, es decir si se escoge el signo “+”
por ejemplo se deberá de sumar cada elemento de la matriz 1 con la matriz 2
5. Llenar un vector con números aleatorios. Luego se debe de ingresar un número, si este existe se debe de eliminar dicho número del arreglo. Utilice un arreglo dinámico.
Técnica de Programación Orientada a Objetos 257
Contenido.
Procedimientos y Funciones definidas por el Usuario o Tipos de Procedimientos. o Creación de procedimientos Sub y Function. o Parámetros por Valor y Referencia. o Invocar procedimientos y funciones. o Paso de matrices como argumentos.
Recursividad.
PROCEDIMIENTOS Y FUNCIONES DEFINIDAS POR EL
USUARIO
El desarrollo de una aplicación, especialmente si se trata de un proyecto de gran tamaño, es
más fácil si se divide en piezas más pequeñas. El uso de procedimientos puede ayudarnos a
agrupar nuestro código en secciones lógicas y condensar tareas repetidas o compartidas, como
cálculos utilizados frecuentemente.
Los procedimientos son las sentencias de código ejecutable de un programa. Las instrucciones
de un procedimiento están delimitadas por una instrucción de declaración y una instrucción
End.
Nota:
Es posible que encontremos los términos métodos, procedimientos y funciones de forma
intercambiable en varias referencias.
Tipos de Procedimientos.
Existen tres tipos de procedimientos en Microsoft Visual Basic® .NET: procedimientos Sub,
procedimientos Function y procedimientos Property.
Técnica de Programación Orientada a Objetos 258
Los procedimientos Sub realizan acciones pero no devuelven un valor al procedimiento que
origina la llamada. Los controladores de eventos son procedimientos Sub que se ejecutan en
respuesta a un evento.
Los procedimientos Function pueden devolver un valor al procedimiento que origina la llamada.
La instrucción MessageBox.Show es un ejemplo de función.
Los procedimientos Property devuelven y asignan valores de propiedades de clases,
estructuras o módulos.
Uso de Procedimientos.
Un procedimiento puede ser invocado, o llamado, desde otro procedimiento. Cuando un
procedimiento llama a otro procedimiento, se transfiere el control al segundo procedimiento.
Cuando finaliza la ejecución del código del segundo procedimiento, éste devuelve el control al
procedimiento que lo invocó.
Debido a esta funcionalidad, los procedimientos resultan útiles para realizar tareas repetidas o
compartidas. En lugar de escribir el mismo código más de una vez, podemos escribir un
procedimiento e invocarlo desde varios puntos de nuestra aplicación o desde otras
aplicaciones.
Accesibilidad.
Utilizamos un modificador de acceso para definir la accesibilidad de los procedimientos que
escribimos (es decir, el permiso para que otro código invoque al procedimiento). Si no
especificamos un modificador de acceso, los procedimientos son declarados public de forma
predeterminada.
La siguiente tabla muestra las opciones de accesibilidad para declarar un procedimiento dentro
de un módulo:
Modificador de
acceso
Descripción
Public Ninguna restricción de acceso
Friend Accesible desde el programa que contiene la declaración y desde
cualquier otro lugar del mismo ensamblado
Private Accesible únicamente en el módulo que contiene la declaración
Nota.
El modificador de acceso Protected únicamente puede utilizarse en procedimientos declarados
dentro de una clase
Técnica de Programación Orientada a Objetos 259
Como crear procedimientos Sub
Un procedimiento Sub es una serie de instrucciones de Visual Basic delimitadas por las
instrucciones Sub y End Sub. Los procedimientos Sub realizan acciones pero no devuelven un
valor al procedimiento que origina la llamada.
Sintaxis para la creación de procedimientos Sub
Utilicemos la siguiente sintaxis para crear un procedimiento Sub:
[accessibility] Sub subname[(argumentlist)]
' Statements of the Sub procedure go here
End Sub
Ejemplo de procedimientos Sub
El siguiente código crea un procedimiento Sub (Sub AboutHelp) que utiliza un cuadro de
mensaje para mostrar un nombre de producto y un número de versión:
Private Sub AboutHelp( )
MessageBox.Show("MyProgram V1.0", "MyProgram Help")
End Sub
Creación de procedimientos Function
Un procedimiento Function es una serie de instrucciones Visual Basic delimitadas por las
instrucciones Function y End Function. Los procedimientos Function son similares a los
procedimientos Sub, pero las funciones pueden devolver un valor al programa que origina la
llamada.
Sintaxis para crear a Function procedimiento
Utilicemos la siguiente sintaxis para crear un procedimiento Function:
[accessibility] Function functionname[(argumentlist)] As _
datatype
' Statements of the function go here, including optional
' Return statement
End Function
Técnica de Programación Orientada a Objetos 260
Ejemplo de un procedimiento Function
El siguiente código crea una función denominada Square que devuelve el cuadrado de un
número entero (integer):
Function Square(SquareValue As Integer) As Integer
Square = SquareValue * SquareValue
End Function
Valores de retorno
El valor que devuelve un procedimiento Function al programa que origina la llamada se
denomina valor de retorno. La función devuelve el valor en una de las dos formas siguientes:
- Asigna un valor al nombre de su propia función en una o más instrucciones dentro del procedimiento. El control no se devuelve al programa que origina la llamada hasta que se ejecuta una instrucción Exit Function o End Function. La instrucción Exit Function provoca la salida inmediata de un procedimiento
Function. Cualquier número de instrucciones Exit Function pueden aparecer en
cualquier lugar del procedimiento.
- Utiliza una instrucción Return para especificar el valor devuelto, y devuelve el control inmediatamente al programa que origina la llamada.
La ventaja de asignar el valor devuelto al nombre de función es que el control no se devuelve
desde la función hasta que el programa encuentra una instrucción Exit Function o End
Function. Esto permite asignar un valor preliminar y ajustarlo más tarde si es necesario.
Ejemplo de asignación del valor de retorno
El siguiente ejemplo asigna el valor de retorno al nombre de función DoubleTheValue y utiliza
la instrucción Exit Function para volver al procedimiento de llamada:
Function DoubleTheValue(ByVal j As Integer) As Double
. . .
DoubleTheValue = j*2
' Control remains within the function
. . .
Exit Function
' Control returns to the calling function
. . .
End Function
Técnica de Programación Orientada a Objetos 261
Si salimos de la función sin asignar un valor devuelto, la función devuelve el valor
predeterminado apropiado para el tipo de datos de la función. Por ejemplo, devuelve 0 para
Byte, Char, Decimal, Double, Integer, Long, Short y Single.
Ejemplo de uso de la instrucción Return
La instrucción Return asigna simultáneamente el valor devuelto y sale de la función, como se
muestra en el siguiente ejemplo:
Function DoubleTheValue(ByVal j As Integer) As Double
. . .
Return j*2
' Control is immediately returned to the calling function
. . .
End Function
Cómo declarar argumentos en procedimientos
Un procedimiento que realiza tareas repetidas o compartidas utiliza distinta información en
cada llamada. Esta información puede estar formada por variables, constantes y expresiones
que se pasan al procedimiento por el procedimiento que origina la llamada. Cada valor que se
pasa a un procedimiento se denomina argumento.
Parámetros vs. argumentos
Cuando definimos un procedimiento en Visual Basic .NET, describimos los datos y los tipos de
datos para los que el procedimiento está diseñado para aceptar desde un procedimiento de
llamada. Los elementos definidos en el procedimiento se denominan parámetros.
Cuando invocamos el procedimiento, sustituimos un valor actual de cada parámetro. Los
valores que asignamos en lugar de los parámetros se denominan argumentos.
Nota
A pesar de esta sutil diferencia, los términos argumento y parámetro a menudo se utilizan
indistintamente. Este módulo utiliza la terminología utilizada en la documentación de Visual
Studio .NET.
Técnica de Programación Orientada a Objetos 262
Paso ByVal y ByRef
Cuando definimos un procedimiento, definimos el modo en el que otros procedimientos pueden
pasar argumentos al procedimiento. Podemos escoger pasarle argumentos por referencia
(ByRef) o por valor (ByVal). En Visual Basic .NET, el mecanismo predeterminado de paso de
parámetros es por valor. Si no especificamos ByVal ni ByRef en nuestras definiciones de
parámetros, ByVal se añade automáticamente a la definición del parámetro.
Mecanismo
de paso
Explicación Implicaciones Ventaja
Por valor
Palabra
clave: ByVal
El procedimiento
invocado recibe una
copia de los datos
cuando es invocado.
Si el procedimiento invocado
modifica la copia, el valor
original de la variable
permanece intacto. Cuando la
ejecución retorna al
procedimiento de llamada, la
variable contiene el mismo
valor que tenía antes de que el
valor se pasara.
Protege la variable
de ser cambiada por
el procedimiento
invocado.
Por
referencia
Palabra
clave: ByRef
El procedimiento
invocado recibe una
referencia a los datos
originales (la dirección
de los datos en
memoria) cuando es
invocado.
El procedimiento invocado
puede modificar la variable
directamente. Cuando la
ejecución retorna al
procedimiento de llamada, la
variable contiene el valor
modificado.
El procedimiento
invocado puede
utilizar el argumento
para devolver un
nuevo valor al
código de llamada.
Excepciones
El elemento de programación que subyace en un argumento puede ser un elemento variable,
cuyo valor puede ser cambiado, o un elemento no variable. Los argumentos no variables nunca
son modificados en el código de llamada, aunque se pasen por referencia. El procedimiento
invocado podría modificar su copia de ese argumento, pero la modificación no afectaría al
elemento subyacente en el código de llamada.
La siguiente tabla muestra elementos variables y no variables.
Elementos variables (pueden modificarse) Elementos no variables
Variables declaradas, incluyendo variables de objetos Constantes
Campos (de clases) Literales
Elementos de matrices Enumeraciones
Elementos de estructuras Expresiones
Técnica de Programación Orientada a Objetos 263
Declarar argumentos
Utilizamos la misma sintaxis para declarar los argumentos para procedimientos Sub y
procedimientos Function. Declaramos cada argumento de un procedimiento del mismo modo
en que declaramos una variable, especificando el nombre del argumento y el tipo de datos.
También podemos especificar el mecanismo de paso y si el argumento es opcional.
La sintaxis para cada argumento en la lista de argumentos de un procedimiento es como sigue:
([ByVal|ByRef] [ParamArray] nombreargumento As datatype)
Nota
Si el argumento es opcional, debemos incluir también la palabra clave Opcional y proporcionar
un valor predeterminado en la declaración, como sigue:
Opcional [ByVal|ByRef] nombreargumento As datatype = defaultvalue
Ejemplo de declaración de un argumento
En el siguiente ejemplo, el procedimiento Sub Hello está diseñado para tomar un argumento
Name de tipo String por valor desde un procedimiento de llamada.
Public Sub Hello(ByVal Name As String)
MessageBox.Show("Hello, " & Name & "!")
End Sub
Nota
No es necesario que los nombres de argumentos utilizados cuando se invoca un procedimiento
coincidan con los nombres de parámetros utilizados para definir el procedimiento.
Técnica de Programación Orientada a Objetos 264
Cómo utilizar argumentos opcionales
Podemos especificar que el argumento de un procedimiento es opcional y no es necesario
proporcionarlo cuando el procedimiento es invocado. Esto ofrece flexibilidad cuando nuestro
procedimiento es invocado por otro procedimiento. El usuario puede decidir proporcionar o no
un argumento.
Declarar un argumento opcional
Los argumentos opcionales están indicados por la palabra clave Optional en la definición del
procedimiento. Además, cuando declaramos un argumento opcional, se aplican las siguientes
reglas:
- Debe especificarse un valor predeterminado para todos los argumentos opcionales. - El valor predeterminado de un argumento opcional debe ser una expresión
constante. - Todos los argumentos que sigan a un argumento opcional en la definición del
procedimiento también deben ser opcionales.
El siguiente código muestra la sintaxis para declarar un argumento opcional:
Optional [ByVal|ByRef] nombreargumento As datatype = defaultvalue
Ejemplo de argumento opcional
El siguiente ejemplo muestra una declaración de procedimiento con un argumento opcional:
Function Add(ByVal value1 As Integer, ByVal value2 As _
Integer, Optional ByVal value3 As Integer = 0) As Integer
' The default valor for the optional argument is 0
Ejemplo de argumento opcional incorrecto
El siguiente ejemplo contiene un error; recordemos que los argumentos que siguen a un
argumento opcional también deben ser opcionales.
Function Add(ByVal value1 As Integer, Optional ByVal _
value2 As Integer = 0, ByVal value3 As Integer) As Integer
' Causes an error
Técnica de Programación Orientada a Objetos 265
Procedimientos de llamada con argumentos opcionales
Cuando invocamos un procedimiento con un argumento opcional, podemos escoger entre
proporcionar o no el argumento. Si no proporcionamos el argumento, el procedimiento utiliza el
valor predeterminado declarado para ese argumento.
Cuando omitimos uno o más argumentos opcionales en la lista de argumentos, utilizamos
comas sucesivas para separar los espacios marcando sus posiciones. La siguiente invocación
proporciona los argumentos primero y cuarto, pero no proporciona el segundo ni el tercero:
SubCount(arg1, , , arg4)
' Leaves out arg2 and arg3
Reutilización de código
Uno de los procesos más importantes en la creación de una aplicación basada en Visual Basic
es diseñar código para su reutilización. El modo como escribimos el código afecta a su
reutilización.
Escribir código para reutilizar
Podemos escribir código para ser reutilizado, incluyendo procedimientos, en estructuras,
módulos o clases. La siguiente tabla proporciona una descripción de las situaciones en las que
deberíamos escoger cada una de estas opciones:
Usar
un(a)…
para… Ejemplo
Estructura Crear objetos que no necesitan
ser extendidos y que tienen un
tamaño de instancia pequeño
Size y Point son estructuras disponibles
en la biblioteca de clases del Microsoft
.NET Framework
Módulo Proporcionar funciones de
utilidad y datos globales para su
uso por múltiples módulos o
clases
Funciones de utilidad como conversión
de temperatura, cálculo de área, acceso
a datos, etc., necesarias para múltiples
módulos
Clase Extender objetos, o para objetos
que necesitan liberar recursos
Clase Forms, clase Button, etc.
Técnica de Programación Orientada a Objetos 266
Escribir procedimientos en una estructura
El siguiente código muestra cómo podemos escribir un procedimiento en una estructura.
Asumimos que las variables x, y y z del ejemplo ya han sido declaradas.
Structure TableDimensions
Private legHeight, topWidth, topDepth As Integer
Public Sub New(ByVal legHeight As Integer, _
ByVal topWidth As Integer, ByVal topDepth as Integer)
Me.legHeight = x
Me.topWidth = y
Me.topDepth = z
End Sub
End Structure
Técnica de Programación Orientada a Objetos 267
Crear un módulo
Para crear un módulo, añadimos primero un módulo a nuestro proyecto. A continuación,
escribimos las instrucciones del código que definen los datos y procedimientos de nuestro
módulo.
Añadir un módulo a un proyecto
o Si el Explorador de soluciones no está abierto, en el menú Ver, hacer clic en Explorador de soluciones.
o En el Explorador de soluciones, hacer clic con en botón derecho en nuestro proyecto, seleccionar Agregar y, a continuación, hacer clic en Agregar nuevo elemento.
o En el cuadro de diálogo Agregar nuevo elemento, en el cuadro Nombre, escribir un nombre para su módulo, seleccione Módulo en las Plantillas y, a continuación, hacer clic en Abrir.
Sintaxis
La siguiente sintaxis declara un bloque de módulo:
[Public|Friend] Module nombremódulo
' Add classes, properties, methods, fields, and events for
' the module
End Module
Accesibilidad de un módulo
Al igual que con los procedimientos y las variables, utilizamos los modificadores de acceso para
definir la accesibilidad de un módulo. Si no utilizamos un modificador de acceso, los módulos
se declaran Friend de modo predeterminado.
La siguiente tabla define los modificadores de acceso disponibles para un módulo:
Modificador de
acceso
Definición
Public Ninguna restricción de acceso
Friend Accesible desde dentro del programa que contiene la declaración y
desde cualquier lugar del mismo ensamblado
Técnica de Programación Orientada a Objetos 268
Uso de procedimientos
Uno de los principales beneficios del uso eficaz de procedimientos es la reutilización de código.
Los procedimientos que creamos en un programa pueden utilizarse en ese programa y en otros
proyectos, frecuentemente con poca o nula modificación. Los procedimientos son útiles para
tareas repetidas o compartidas, como cálculos utilizados frecuentemente.
Cómo utilizar los procedimientos Sub
Para utilizar un procedimiento Sub, lo invocamos desde otro procedimiento.
Flujo de código
Cada vez que se invoca un procedimiento Sub, se ejecutan sus instrucciones, empezando por
la primera instrucción ejecutable después de la instrucción Sub y finalizando con la primera
instrucción End Sub, Exit Sub o Return encontrada. Después de que el procedimiento Sub
ejecute nuestro código, devuelve la ejecución del programa a la línea de código que sigue a la
línea que invocó el procedimiento Sub.
Invocar un procedimiento Sub
La sintaxis para invocar un procedimiento Sub es la siguiente:
[Call] Subname [(Argumentlist)]
- Debemos invocar el procedimiento Sub en una línea por sí mismo en nuestro código (no puede invocarlo utilizando su nombre dentro de una expresión).
- La instrucción de llamada debe proporcionar valores para todos los argumentos que no son opcionales.
- Opcionalmente, podemos utilizar la instrucción Call para invocar un procedimiento Sub. El uso de la instrucción Call puede mejorar la legibilidad de nuestro programa.
Técnica de Programación Orientada a Objetos 269
Nota
Los procedimientos Sub no devuelven un valor a la instrucción de llamada. Sin embargo, un
procedimiento Sub pasar información de retorno al código de llamada modificando argumentos
pasados por referencia.
Ejemplo de una invocación simple
El siguiente código muestra un procedimiento de evento que invoca un procedimiento Sub
denominado SetData:
Sub DataButton_Click(...)
SetData( )
End Sub
Ejemplo de uso de la instrucción Call
También puede utilizar el siguiente código para realiza la misma tarea:
Sub DataButton_Click(...)
Call SetData( )
End Sub
Ejemplo de invocación simple incorrecta
La siguiente invocación contiene un error:
Sub DataButton_Click(...)
MessageBox.Show(SetData( ))
End Sub
' Causes an error, because the Show method expects a String
' data type, not un procedure
Técnica de Programación Orientada a Objetos 270
Ejemplo de invocación con argumentos
Observe la siguiente definición para el procedimiento Sub SetData:
Public Sub SetData(ByVal cars As Integer, ByVal trucks As _ Integer, ByVal vans As
Integer)
' Code for SetData Procedure
End Sub
La sintaxis para invocar este procedimiento incluye el nombre del procedimiento y la lista de
argumentos en paréntesis, como se muestra en el siguiente código:
Sub DataButton_Click(...)
SetData(10, 20, 30)
End Sub
Ejemplo incorrecto de una llamada con argumentos
La siguiente llamada al procedimiento SetData definido en el ejemplo a continuación contiene
un error.
Sub DataButton_Click( )
SetData(10, 20)
End Sub
' Causes an error, because there is no valor for the third
' parametre of the SetData procedure. The calling statement
' must provide values for all arguments that are not optional.
Técnica de Programación Orientada a Objetos 271
Cómo utilizar los procedimientos Function
Un procedimiento Function se diferencia de un procedimiento Sub en que el primero puede
devolver un valor al procedimiento de llamada.
Invocar una función
Invocamos un procedimiento Function incluyendo su nombre y sus argumentos en el lado
derecho de una instrucción de asignación o en una expresión. Piense en la siguiente función,
que convierte una temperatura en Fahrenheit a una temperatura en Celsius.
Function FtoC(ByVal temperature As Single) As Single
' Convert Fahrenheit to Celsius
FtoC = (temperature - 32.0) * (5 / 9)
End Function
Las siguientes llamadas de ejemplo muestran cómo podríamos invocar esta función:
Dim celsiusTemperature As Single
celsiusTemperature = FtoC(80)
' Call the procedure by including its name and arguments on
' the right side of an assignment statement. In this call,
' the value 80 is passed to the FtoC function, and the
Técnica de Programación Orientada a Objetos 272
' value returned is assigned to celsiusTemperature.
If FtoC(userValue) < 0 Then . . .
' Call the procedure by using it in an expression. In this
' call, the FtoC function is used as part of an expression.
End If
Flujo de código
Cada vez que se invoca la función se ejecutan sus instrucciones, empezando por la primera
instrucción ejecutable tras la instrucción Function y finalizando con la primera instrucción End
Function, Exit Function o Return encontrada.
Cómo pasar matrices a procedimientos
Podemos pasar matrices como argumentos a un procedimiento igual que otros argumentos.
Visual Basic .NET también proporciona la palabra clave ParamArray para declarar una matriz
de parámetros en la definición de parámetros de un procedimiento.
Pasar matrices
Podemos pasar matrices unidimensionales o multidimensionales a procedimientos del mismo
modo que pasamos otros argumentos.
El siguiente ejemplo muestra cómo pasar una matriz unidimensional a un procedimiento:
Sub PassArray(ByVal testScores As Integer( ))
...
End Sub
Dim scores( ) As Integer = {80, 92, 73}
PassArray(scores)
Técnica de Programación Orientada a Objetos 273
El siguiente ejemplo muestra cómo pasar una matriz bidimensional a un procedimiento:
Sub Pass2DArray(ByVal rectangle As Integer(,))
...
End Sub
Dim rectangle(,) As Integer = {{12, 1}, {0, 12}}
Pass2DArray(rectangle)
Uso de ParamArray
Normalmente, no podemos invocar un procedimiento con más argumentos de los especificados
en su declaración. Cuando necesitamos un número indefinido de argumentos, podemos
declarar una matriz de parámetros, que permite que un procedimiento acepte una matriz de
valores para un argumento. No es necesario conocer el número de elementos de la matriz de
parámetros cuando definimos el procedimiento. El tamaño de la matriz está determinado de
forma individual por cada invocación al procedimiento.
Utilizamos la palabra clave ParamArray para denotar una matriz de parámetros. Esta palabra
clave indica que el argumento de un procedimiento es una matriz opcional de elementos de un
tipo especificado. Se aplican las siguientes reglas:
- Un procedimiento sólo puede tener una matriz de parámetros, y debe ser el último argumento de la definición del procedimiento.
- La matriz de parámetros debe pasarse por valor. Es una buena práctica de programación incluir explícitamente la palabra clave ByVal en la definición del procedimiento.
- El código dentro del procedimiento debe tratar la matriz de parámetros como una matriz unidimensional, siendo cada elemento de la misma el mismo tipo de datos que el tipo de datos ParamArray.
- La matriz de parámetros es automáticamente opcional. Su valor predeterminado es una matriz unidimensional vacía del tipo de elemento del parámetro de la matriz.
- Todos los argumentos que preceden a la matriz de parámetros deben ser obligatorios. La matriz de parámetros debe ser el único argumento opcional.
Invocar un procedimiento con un argumento de matriz de parámetros
Cuando invocamos un procedimiento con un argumento de matriz de parámetros, podemos
pasar alguna de las opciones siguientes para la matriz de parámetros:
- Nada. Es decir, podemos omitir el argumento ParamArray. En este caso, se pasa al procedimiento una matriz vacía. También podemos pasar la palabra clave Nothing, produciendo el mismo efecto.
Técnica de Programación Orientada a Objetos 274
- Una lista de un número indefinido de argumentos, separados por comas. El tipo de datos de cada argumento debe ser implícitamente convertible al tipo de elemento ParamArray.
- Una matriz con el mismo tipo de elemento que la matriz de parámetros.
Ejemplo de declaración ParamArray
El siguiente código muestra cómo podemos definir un procedimiento con una matriz de
parámetros:
Sub StudentScores(ByVal name As String, ByVal ParamArray _
scores( ) As String)
' Statements for Sub procedure
End Sub
Ejemplos de invocaciones a un procedimiento con una matriz de parámetros
Los siguientes ejemplos muestran invocaciones posibles a StudentScores.
StudentScores("Anne", "10", "26", "32", "15", "22", "16")
StudentScores("Mary", "High", "Low", "Average", "High")
Dim JohnScores( ) As String = {"35", "Absent", "21", "30"}
StudentScores("John", JohnScores)
Cómo crear un Sub Main
Para abrir y cerrar una aplicación, la biblioteca de clases del .NET Framework proporciona la
clase Application. La clase Application proporciona métodos (procedimientos) y propiedades
para gestionar una aplicación, incluyendo métodos para abrir y cerrar una aplicación, métodos
para procesar mensajes de Microsoft Windows®, y propiedades para obtener información
sobre una aplicación.
El procedimiento Sub Main
Cuando creamos aplicaciones con la plantilla Aplicación para Windows en Visual Basic .NET,
Visual Basic crea automáticamente un procedimiento Sub oculto denominado Sub Main para la
clase Form. Este procedimiento se utiliza como punto de inicio para nuestra aplicación.
Técnica de Programación Orientada a Objetos 275
Crear un nuevo Sub Main
En el procedimiento Sub Main, Visual Basic .NET invoca el método Application.Run para iniciar
la aplicación. Podemos cambiar este comportamiento creando nuestro propio Sub Main y
convirtiéndolo en el objeto de inicio. Podemos crear Sub Main en un módulo o en otra clase.
Después de crear un Sub Main, necesitamos hacer de este nuevo procedimiento el objeto de
inicio utilizando la ventana Propiedades.
- Cambiar el objeto de inicio a Sub Main - Si el Explorador de soluciones no está abierto, en el menú Ver, hacer clic en
Explorador de soluciones. - En el Explorador de soluciones, hacer clic con el botón derecho en el nombre del
proyecto y, a continuación, en Propiedades. - En el panel izquierdo, debajo de Propiedades comunes, verificar que está
seleccionado General. - En la lista Objeto inicial, hacer clic en Sub Main para convertir este procedimiento
el nuevo objeto de inicio de nuestro proyecto.
Utilización de Application.Exit
Para cerrar una aplicación, invocamos el método Application.Exit utilizando la siguiente
sintaxis:
Application.Exit( )
Por ejemplo, podemos insertar este código en el controlador de eventos Click de un botón.
Cuando el usuario haga clic en el botón, la aplicación se cerrará.
Los eventos Form.Closed y Form.Closing no se lanzan cuando se invoca el método
Application.Exit para cerrar la aplicación. Si hay código en estos eventos que deba ser
ejecutado, invocar el método Form.Close para cada formulario abierto individualmente antes de
invocar el método Application.Exit.
Aplicaciones
Técnica de Programación Orientada a Objetos 277
Private intSum As Integer
Public Function minimo(ByVal ParamArray obj() As Integer) As
Integer
Dim z, con, min As Integer
con = 1
For Each z In obj
If con = 1 Then Min = z
If z < Min Then Min = z
con = con + 1
Next
Return Min
End Function
Sub Sum(ParamArray Nums() as integer)
Dim y,x As Integer
For Each x In Nums
y = y + x
Next x
intSum = y
End Sub
Private Sub Cmdcalculo_Click()
Sum Text2, Text3, Text4
Lbr1.Caption = intSum
Lbr2.Caption = minimo(Textbox1.text, Textbox2.text,
Textbox3.text)
Lbr3.Caption = minimo(5,7,3,8)
'la suma de 3 valores
Sum Text1, Text3, Text4
MsgBox "la suma del texto 1,3y 4 " & intSum
End Sub
Acepta un arreglo de datos y pueden ser
de cualquier tipo, nums es una variable
cualquiera receptor de datos
Llamado a la funcion y al procedimiento
Técnica de Programación Orientada a Objetos 278
Ejercicios propuestos
1- Escribir una función que dados a y b enteros devuelva ab.
2- Escribir una función que dado un número entero, devuelva una señal que indique si dicho número es primo o no.
3- Escribir una función que dados 2 números, calcule el porcentaje que el primero representa respecto del segundo.
4- Escribir una función que dados a y b devuelva el cociente de la división entera, sin utilizar el operador correspondiente del lenguaje. Validar los tipos de datos de entrada.
5- Escribir una función que dados a y b devuelva el resto de la división entera, sin utilizar el operador correspondiente de lenguaje. Validar los tipos de datos de entrada.
6- Escribir una función que dado un código numérico de m dígitos, separe un sub-código consistente en una cantidad n<m de dígitos a partir del k-ésimo lugar a contar del dígito menos significativo. Utilizarla en un programa que ingrese un listado de códigos numéricos junto con sus correspondientes parámetros m,n y k y liste dichos códigos de entrada junto con el sub-código deseado.
7- Un número entero positivo se dice perfecto si es igual a la suma de todos sus divisores, excepto el mismo.
8- Ejemplo: los números 6 (1+2+3), 28 (1+2+4+7+14) y 496 (1+2+4+8+16+31+62+124 +248)
Se pide:
a) Escribir una función booleana que llamada desde un programa, permita discernir si
un número (único parámetro) es perfecto.
b) Dar un ejemplo de cómo se hace referencia a dicha función desde un programa o
desde otro subprograma.
Nota: no usar variables globales.
8) Dos números se dicen amigos cuando uno de ellos es igual a la suma de todos los
divisores del otro excepto el mismo.
Ejemplo: los números 220 (1+2+4+5+10+11+20+22+44+55+110=284)
y 284 (1+2+4+71+142=220) son amigos.
Técnica de Programación Orientada a Objetos 279
Se pide:
a) escribir una función booleana que llamada desde un programa, permita discernir si
dos números (parámetros) son amigos.
b) Usar otra función para calcular la suma de los divisores de un número determinado.
c) Hacer referencia a dichas funciones desde un programa o desde otro subprograma.
Desarrollar los siguientes procedimientos cuyos nombres y parámetros por valor
se detallan en cada procedimiento:
1. Función pasando como parámetro un número de mes (1 al 12), devuelva la cantidad de días de 1dicho Mes, considere el presente año.
2. Función CUENTAVOCALES el cual pasando como parámetro una frase devuelva la cantidad de vocales contenidas en dicha frase. Ejemplo CUENTAVOCALES(“VISUAL BASIC”) -------- 5
3. Pasando como parámetro la base y la altura de un triángulo rectángulo devuelva su hipotenusa.
4. Funcion MINIMO pasando tres valores numericos de tipo entero que devuelva el menor de los tres numeros
5. Funcion MCD, pasando dos valore numericos, visualice el Maximo Comun Divisor de los numeros
6. Función SEGPALABRA el cual pasando como parámetro una FRASE, devuelva la segunda palabra de dicha frase Ejemplo: SEGPALABRA(“CURSO VISUAL BASIC”) -------- VISUAL
7. Función PRIMO pasando por valor un número entero devuelva True si el número es Primo y False si el número no es primo.
8. Pasando un monto en soles y el tipo de cambio, devuelva el monto convertido a Dólares.
9. Pasando tres números devuelva el Mínimo Común Múltiplo, de dichos números.
10. Pasando un número entero de cualquier longitud, devuelva el promedio de dichas cifras.
11. Pasando un número entero de cualquier longitud, devuelva el dígito mayor.
Técnica de Programación Orientada a Objetos 280
12. Pasando un número entero de cualquier longitud, devuelva el mismo valor de manera ordenada.
13. Pasando un número de Mes que devuelva dicho Mes en Letras.
14. Pasando una cadena, una posición inicial y el número de caracteres a borrar ELIMINE una subcadena de dicha cadena a partir de una posición especificada. Ejemplo : DELETEAR(“VISUAL BASIC”, 7, 6) ---- VISUAL
15. Pasando tres números que representan el día, mes y año devuelva una fecha como cadena. Ejemplo: FECHA(02, 12, 03) ---- 02 de Diciembre del 2003
16. Pasando un valor entero de grados centígrados y un carácter ( “R”, “K”, “F”) que representan Ranking, Kelvin y Fahrenheit respectivamente, devuelva su valor de conversión al grado especificado.
Técnica de Programación Orientada a Objetos 281
Recursividad
Propiedad que tienen los subprogramas de poder ser re-invocados sin haber finalizado el
proceso de las sentencias correspondientes a una invocación previa de si mismo. El concepto
deriva del de Relación Recurrente.
En toda relación recurrente / proceso recursivo se distinguen dos partes bien diferenciadas:
Caso Base : aquel que queda definido en si mismo.
Caso Recursivo : basado en un caso base o en otro caso recursivo.
Tipos de Recursividad
Directa : es aquella en la que la invocación recursiva se efectúa desde dentro del mismo modulo invocado.
Indirecta : es aquella donde la invocación recursiva la efectúa un segundo modulo.
Subprograma 1
Subprograma 2
Subprograma 1
Técnica de Programación Orientada a Objetos 282
Cómo funciona?
Cuando un subprograma se invoca a sí mismo lo hace como si estuviera invocando a otro
subprograma, y en esto se cumplen todas las reglas de invocación de subprogramas por parte
de otros subprogramas.
Es decir, todas las variables locales al programa invocante se almacenarán en el Stack, las
variables del programa invocado (el mismo) se inicializarán a basura y los parámetros tomaran
su valor correspondiente. Una vez finalizado el proceso, y no habiendo otra llamada recursiva,
se restauraran los valores de las variables del modulo invocante y se proseguirá su ejecución.
Ejemplos:
Forma Matemática Implementación Basic
Factorial n 0
f(n) = n * f(n-1) n>0
f(0) = 1
Function fact(n as Integer) as Long
If n>0 then
Fact=N*Fact(N – 1)
Else
Fact=1
End Function
Fibonaci n 0
f(n) = f(n-1) * f(n-2) n>1
f(n) = 1 n<=1
Function Fib( N as Integer) as Long
If N>1 Then
Fib=Fib(N-1)+Fib(N-2)
Else
Fib=1
End If
Ejemplos a desarrollar: Factorial, Fibonnaci, Producto de dos números, suma empleando
recursividad: (en Modulo.vb)
Técnica de Programación Orientada a Objetos 283
1. Implementar una función recursiva que devuelva el factorial de un número.
Public Function factorial(n As Integer) As Double
If n = 0 Then
factorial = 1
Else
factorial = n * factorial(n - 1)
End If
End Function
2. Implementar una función recursiva que calcule la serie de Fibonacci.
Function fibo(n As Integer) As Long
If n > 1 Then
fibo = fibo(n - 2) + fibo(n - 1)
Else
fibo = 1
Ejercicios Propuestos
1. Definir una función recursiva que dado un número entero, devuelva la suma de sus cifras. Utilizarla para definir si un número es divisible por 3.
2. Definir una función recursiva que calcule w elevado a la k mediante multiplicaciones sucesivas. (k natural)
3. Definir una función recursiva que devuelva la cantidad de dígitos de un número entero.
4. Definir una función recursiva que calcule z * y mediante sumas sucesivas.
5. Definir una función recursiva para cada uno de los siguientes problemas a) Calcular el promedio de los elementos del vector V de dimensión N. b) Buscar el mínimo elemento del vector V de dimensión N. c) Devolver la posición del máximo elemento del vector V de dimensión N.
Técnica de Programación Orientada a Objetos 284
Contenido.
Funciones de Sistema o Cadena o Numericos o Fecha
Formatenado la salida
FUNCIONES DE SISTEMA
Funciones de cadenas Se denomina CADENA a una sucesión de caracteres. Una cadena puede tener uno o varios caracteres alfanuméricos. Una cadena es también una sucesión de números.
Str(Expresión) Cuando los números se conviertan a cadenas, siempre se reservará un espacio inicial para el signo de Number. Si Number es positivo, la cadena devuelta contiene un espacio inicial; y el signo más se da por supuesto. Un número negativo incluirá el signo menos (-) y ningún espacio inicial.
Dim MyString As String
MyString = Str(459) ' Retorna " 459"
MyString = Str(-459.65) ' Retorna "-459.65"
Left (cadena, n) Extrae los n primeros caracteres de una cadena, comenzando por la izquierda.
Right (cadena, n) Extrae lo n últimos caracteres de la cadena
Técnica de Programación Orientada a Objetos 285
Para utilizar las dos funciones anteriores que son propias de visual basic emplear Microsoft.VisualBasic.Funcion
Dim myString As String = "Curso de Visual Net"
Dim subString As String
subString = Microsoft.VisualBasic.Right(myString, 3)
' Retorna "Net"
subString = Microsoft.VisualBasic.Left(myString, 5)
' Retorna "Curso"
Mid (cadena, m, n)
Extrae n caracteres de la cadena, siendo el primer carácter extraído el que ocupa el lugar m.
Resultado = Mid (cadena, 3, 10)
„Retorna “rso de Vis”
Segundo formato desde una posición hasta la posición final
Resultado=Mid(cadena,6)
„Retorna “de visual net”
LCase (cadena)
Devuelve otra cadena igual, pero con todos los caracteres en minúsculas. (LCase = Lower Case)
Resultado = Lcase (cadena)
„Retorna “curso de visual basic”
UCase (cadena)
Devuelve otra cadena igual, pero con todos loscaracteres en mayúsculas. (UCase = Upper Case)
Resultado = UCase (cadena)
„Retorna “CURSO DE VISUAL BASIC”
Técnica de Programación Orientada a Objetos 286
Len (cadena)
Devuelve la longitud de la cadena
Resultado = Len (cadena)
„Retorna “21”
Space (n)
Devuelve una cadena formada por n espacios.
Resultado = "A" + Space (6)+ "B"
„Retorna “A B”
LTrim
Elimina los posibles espacios que tenga una cadena por su izquierda.
Rtrim
Elimina los posibles espacios que tenga una cadena por su derecha.
Trim
Elimina los espacios que tenga una cadena, tanto por su izquierda como por su derecha. (No elimina los espacios centrales de la cadena).
InStr (cadena, cadena1)
Busca la cadena1 dentro de cadena y devuelve el número de orden dentro de cadena donde se encuentra la primera letra de cadena1
Resultado = InStr (cadena, "sua")
„Retorna “12”
StrConv
Convierte una cadena de caracteres en otra, según las instrucciones que le sigan. Puede sustituir a UCase o LCase si la instrucción es UpperCase o LowerCase respectivamente, o poner la primera letra de todas las palabras de la cadena en mayúsculas, si la instrucción es ProperCase.
Resultado = StrConv (cadena, UpperCase)
„Retorna “CURSO DE VISUAL BASIC”
Técnica de Programación Orientada a Objetos 287
Resultado = StrConv (cadena, LowerCase)
„Retorna “curso de visual basic”
Resultado = StrConv (cadena, ProperCase)
„Retorna “Curso De Visual Basic”
En este ejemplo se pone un texto todo en minúsculas.
Dim sText, sNewText As String sText = "Hello World" sNewText = StrConv(sText, VbStrConv.LowerCase) Debug.WriteLine (sNewText) ' Outputs "hello world".
FUNCIONES CON NUMEROS
Funcion Devuelve
Abs Valor absoluto de un numero real
Int Parte entera de un real
Rnd Un numero al azr entre 0 y 1
Exp Exponecial de un numero real es decir e = 2.71828
El objeto Math.
Funciones:
Math.round(n,d)
Redondea, con ciertos numeros de decimals
Math.Round(3.45, 1) 'Retorna 3.4
Math.Round(3.46, 1) 'Retorna 3.5
Math.PI
El valor de este campo es 3,14159265358979323846
Math.acos
Devuelve el ángulo cuyo coseno es el número especificado
Técnica de Programación Orientada a Objetos 288
Math.ceiling
Devuelve el número entero más pequeño mayor o igual que el número especificado.
Math.ceiling(3.1) 'Retorna 4
Math.Floor
Devuelve el número entero más grande menor o igual que el número especificado
Math.Floor(3.1) 'Retorna 3
Math.sqrt(n)
Devuelve la raíz cuadrada de un número especificado.
Math.pow(n)
Devuelve un número especificado elevado a la potencia especificada
Técnica de Programación Orientada a Objetos 289
Aplicaciones
1- Aplicación 1: Usando Funciones de Cadena
Private Sub BTNSPLIT_Click(..)
Dim CAD As String
Dim VEC() As String
Dim I As Integer
CAD = TXTCAD.Text.Trim
ListBox1.Items.Clear()
VEC = CAD.Split(" ".ToCharArray)
For I = 0 To UBound(VEC)
ListBox1.Items.Add(VEC(I))
Next
End Sub
Private Sub FRMCADENA_Activated(..)
TXTCAD.Text = "esto es una prueba"
End Sub
Técnica de Programación Orientada a Objetos 290
Private Sub HandleCheckedChanged(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles rbn1.CheckedChanged, rbn2.CheckedChanged,
rbn3.CheckedChanged, rbn4.CheckedChanged, rbn5.CheckedChanged,
rbn6.CheckedChanged, rbn7.CheckedChanged
DisplayText(CType(sender, RadioButton))
End Sub
Private Sub DisplayText(ByVal rbtn As RadioButton)
Dim cadr, texto As String
texto = TXTCAD.Text.Trim
If rbtn Is rbn1 Then
cadr = texto.Insert(3, " ojo")
ElseIf rbtn Is rbn2 Then
cadr = texto.Replace("prueba", "practica")
ElseIf rbtn Is rbn3 Then
'extraer apartir de la izquierda
cadr = texto.Substring(0, 3)
ElseIf rbtn Is rbn4 Then
'borrar los carect. desde la posicion 3 cinco caracteres
cadr = texto.Remove(3, 5)
ElseIf rbtn Is rbn5 Then
'extraer apartir de la derecha
cadr = texto.Substring(texto.Length - 3, 3)
ElseIf rbtn Is rbn6 Then
' extraer apartir de una posicion
cadr = texto.Substring(4, 5)
ElseIf rbtn Is rbn7 Then
' extraer apartir de una posicion
cadr = "posicion " & texto.IndexOf("t").ToString
End If
lblres.Text = cadr
End Sub
Técnica de Programación Orientada a Objetos 291
2- Aplicación 2: Empleando el Split
Mostrando el formulario principal
En el Formulario 3.
Private Sub Button1_Click(..)
Dim x As New Form1()
x.ShowDialog()
End Sub
Private Sub Button2_Click(..)
Dim x As New Form2()
x.ShowDialog()
End Sub
Técnica de Programación Orientada a Objetos 292
En el Formulario 1.
Private Sub btnSplit_Click(..)
Dim TempArray() As String
Dim CurIndex As Integer
lstOutput.Items.Clear()
If txtInput.Text.Length > 0 And _
txtSeparator.Text.Length > 0 Then
TempArray = txtInput.Text.Split(txtSeparator.Text)
For CurIndex = 0 To TempArray.GetUpperBound(0)
lstOutput.Items.Add(TempArray(CurIndex))
Next
End If
End Sub
Técnica de Programación Orientada a Objetos 293
En el Formulario 2.
Private Sub btnJoin_Click(..)
Dim TempArray() As String
Dim RandomInteger As New System.Random()
Dim CurIndex As Integer
Dim NumElements As Integer = Convert.ToInt32(txtArraySize.Text)
'Generate random numbers, put in TempArray
If NumElements > 0 Then
ReDim TempArray(NumElements)
For CurIndex = 0 To NumElements - 1
TempArray(CurIndex) = RandomInteger.Next(1000).ToString
Next
End If
'Join array elements into a comma-separated string
txtOutput.Text = String.Join(",", TempArray)
End Sub
Técnica de Programación Orientada a Objetos 294
3- Aplicación 3: Conversión de un numero al sistema binario y hexadecimal
Private Sub CmdBin_Click(….)
Dim cad as String
Dim N, r as String
n = Val(TxtNum.text)
cad = ""
Do While n <> 0
r = n Mod 2
n = n \ 2
cad = cad + Str(r)
Loop
LBR1 = StrReverse(cad)
End Sub
Private Sub Cmdhexa_Click(….)
Dim cad As String , N, R as integer
Dim n%
n = Val(Text1)
cad = ""
Do While n <> 0 „Hacer mientras n sea diferente a cero
r = n Mod 16
n = n \ 16
If r > 9 Then
cad = cad + Chr(55 + r)
Else
cad = cad + Str(r)
End If
Loop
Lbr2 = StrReverse(cad)
End Sub
Técnica de Programación Orientada a Objetos 295
4- Aplicación 4: Ingresando una frase por teclado invertir las palabras en su misma posición, luego visualizar la misma frase como una pirámide cuyo vértice es el centro de la frase.
Private Sub CmdInvertir_Click( ..)
Dim PA, P, K, M as Integer
Dim Cad, palabra, scad as String
cad = Trim(Text1.text) „la Frase ingresada
scad = "" „ Cadena Vacia Para Formar la frase invertida
PA = 1 „ es la posición inicial de la palabra
For M = 1 To Len(cad)
„Se pregunta si el caracter es un espacio blanco o M es la ultima posicion
If Mid(cad, M, 1) = " " Then
If M = Len(cad) Then P =M Else P = M - 1
PALABRA = "" „para formar la palabra invertida
For k = PA To P
PALABRA = Mid(cad, k, 1) + PALABRA
Next
scad = scad + " " + PALABRA
End If
PA = P + 1
Next
Text2.text = scad „Muestra cada palabra de forma invertida
End Sub
Técnica de Programación Orientada a Objetos 296
Private Sub CmdPiramide_Click()
List1.Items.Clear
cad = Trim(Text1.text) „ Almacena el valor de la Frase
List1.Width = Len(cad) * 100 „ El ancho queda definido por la frase en
centenas
P = Len(cad) \ 2 + 1 „ Obtiene la posición media de la frase
PL = Len(cad): a = 1: con = 1
CR = 1 „ Separamos en dos mitades la parte derecha un contador CR
CI = 1 „ Un contador para la parte Izquierda
cad3 = Space(P) & Mid(cad, P, 1) „ Coloca en el Vertice la Primera letra con
espacios
List1.AddItem cad3
For I = 1 To P
If P - CI < 1 Then Exit For „ si es un valor menor a uno sale del for
cad1 = Space(P - CI) & Mid(cad, P - CI, CI) „Cadena de la Izquierda
cad2 = Mid(cad, P + 1, cr) „Cadena de La derecha
cad4 = cad1 & Trim(cad3) & cad2 „Unimos las tres Cadenas
List1.AddItem cad4 „Lo Colocamos en la lista
CI = CI + 1
cr = cr + 1
Next
End Sub
Técnica de Programación Orientada a Objetos 297
Funciones con fechas.
Las fechas son cadenas especiales. Visual Basic sabe obtener y tratar la información relativa a
la fecha y la hora. Dispone para ello de una declaración de variable: Date. Una variable
declarada como date puede contener una fecha, una fecha y una hora o una hora solamente.
Dim MyDate As Date Dim MyMonth As Integer MyDate = #2/12/1969# ' Assign a date. MyMonth = Month(MyDate) ' MyMonth contains 2.
Now
Devuelve la fecha y hora actual.
WeekDay
Devuelve el día de la semana (En número, 1=Domingo, 2=Lunes,...)
Dim MyDate As Date Dim MyWeekDay As Integer MyDate = #2/12/1969# ' asigna una fecha
MyWeekDay = Weekday(MyDate) ' MyWeekDay contains 4
Day
Obtiene el día, a partir de una fecha
Dim MyDate As Date
Dim MyDay As Integer
MyDate = #2/12/1969# .
MyDay = Microsoft.VisualBasic.Day(MyDate) ' MyDay contains 12.
Month
Obtiene el mes a partir de una fecha.
MyMonth = Month(MyDate) ' MyMonth contains 2.
Year
Obtiene el año a partir de una fecha.
MyYear = Year(MyDate) ' MyYear contains 1969.
Técnica de Programación Orientada a Objetos 298
Hour
Obtiene la hora a partir de una hora
Minute
Obtiene el minuto a partir de una hora.
Second
Obtiene el segundo a partir de una hora.
DateAdd
Añade un intervalo de tiempo a una fecha
Interval
Requerido. Valor de enumeración DateInterval o expresión String que representa el
intervalo de tiempo que se desea agregar.
Number
Requerido. Double. Expresión de punto flotante que representa el número de
intervalos que se desea agregar. Number puede ser un valor positivo (para obtener
fechas u horas futuras) o negativo (para obtener fechas u horas pasadas). Puede
contener una parte decimal cuando Interval especifica horas, minutos o segundos.
Para otros valores de Interval, se omite cualquier parte decimal de Number.
DateValue
Requerido. Date. Expresión que representa la fecha y la hora a la que debe agregarse
el intervalo. El propio DateValue no se modifica en el programa que realiza la llamada.
Valores
El argumento Interval puede tener uno de los siguientes valores:
Valor de enumeración Cadena Unidad de intervalo de tiempo agregada
DateInterval.Day d Día; truncado al valor integral
DateInterval.DayOfYear y Día; truncado al valor integral
DateInterval.Hour h Hora; redondeada al milisegundo más cercano
Técnica de Programación Orientada a Objetos 299
DateInterval.Minute n Minuto; redondeado al milisegundo más cercano
DateInterval.Month m Mes; truncado al valor integral
DateInterval.Quarter q Trimestre; truncado al valor integral
DateInterval.Second s Segundo; redondeado al milisegundo más cercano
DateInterval.Weekday w Día; truncado al valor integral
DateInterval.WeekOfYear ww Semana; truncada al valor integral
DateInterval.Year yyyy Año; truncado al valor integral
Dim NextTime As Date = Now ' Current date and time.
NextTime = NextTime.AddDays(3.4) ' Increment by 3 2/5 days.
En este ejemplo se toma una fecha y mediante la función DateAdd, se muestra
la fecha correspondiente un número especificado de meses en el futuro.
Dim Msg, Number, StartDate As String 'Declare variables.
Dim Months As Double
Dim SecondDate As Date
Dim IntervalType As DateInterval
IntervalType = DateInterval.Month ' Especifica intervalos en meses.
StartDate = InputBox("Ingrese fecha ")
SecondDate = CDate(StartDate)
Number = InputBox("Ingrsa el numero de meses a adicionar")
Months = Val(Number)
Msg = "New date: " & DateAdd(IntervalType, Months, SecondDate)
MsgBox (Msg)
Técnica de Programación Orientada a Objetos 300
DateDiff
Obtiene el intervalo de tiempo entre dos fechas
DateDiff(intervalo, fecha1, fecha2[, primerdíasemana[, primerasemanaaño]])
Intervalo Descripción
yyyy Año
Q Trimestre
M Mes
Y Día del año
D Día
W Día de la semana
Ww Semana
H Hora
N Minuto
S Segundo
Este ejemplo utiliza la función DateDiff para mostrar el número de días entre una fecha dada y hoy.
Dim DatTim1 As Date = #1/4/2004# ' primera fecha.
Dim DatTim2 As Date = #1/9/2004# ' segunda fecha.
Dim dias As Long = DateDiff("d", DatTim1, DatTim2)
Dim meses As Long = DateDiff("m", DatTim1, DatTim2)
MsgBox(dias) devuelve 5
Msgbox(meses) devuelve 0
Técnica de Programación Orientada a Objetos 301
DatePart
Devuelve una parte de una fecha (semana, trimestre, etc.)
El argumento Interval puede tener uno de los siguientes valores:
Valor de enumeración Cadena Parte del valor de fecha u hora devuelta
DateInterval.Day D Día del mes (del 1 al 31)
DateInterval.DayOfYear Y Día del año (del 1 al 366)
DateInterval.Hour H Hora
DateInterval.Minute N Minuto
DateInterval.Month M Mes
DateInterval.Quarter Q Trimestre
DateInterval.Second S Segundo
DateInterval.Weekday W Día de la semana (del 1 al 7)
DateInterval.WeekOfYear Ww Semana del año (de la 1 a la 53)
DateInterval.Year yyyy Año
Este ejemplo obtiene una fecha y, utilizando la función DatePart, muestra el trimestre del año que ocurre.
Dim FirstDate, Msg As String 'Declare variables.
Dim SecondDate As Date
FirstDate = InputBox("Enter a date:")
SecondDate = CDate(FirstDate)
Msg = "Quarter: " & DatePart(DateInterval.Quarter, SecondDate)
MsgBox (Msg)
Técnica de Programación Orientada a Objetos 302
Datetime.
Representa un instante de tiempo, normalmente expresado en forma de fecha y hora
del día. (es propio del framework)
Dim objdate as datetime
Objdate.Metodo.- Lista de metodos
Objdate.day dia del mes
Similares a las funciones anteriores ,DayOfweek (dia de la
semana),Month,Now,Hour,Minute,seconds, etc
Función FORMAT
Esta función permite presentar cadenas de numéricas o fechas de una determinada forma. Permite establecer el Formato de esa cadena.
FechadeHoy = Format (Now, “yyyy-mm-dd”)
La variable FechadeHoy tendrá el valor 1998-05-21, que se refiere al día 21 de mayo de 1998, según el formato recomendado por la norma ISO-8601 para la presentación de fechas. Si hubiésemos puesto la expresión FechadeHoy = Format (Now, “dd/mm/yy”) , la variable FechadeHoy contendría el valor 21/05/98 referido al día citado.
firstdayofweek. Especifica el primer día de la semana. Puede tomar uno de estos valores o constantes :
Constante Valor Descripcion
VbSunday 1 Domingo (valor por defecto)
vbMonday 2 Lunes
vbTuesday 3 Martes
vbWednesday 4 Miercoles
vbThursday 5 Jueves
vbFriday 6 Viernes
vbSaturday 7 Sabado
Técnica de Programación Orientada a Objetos 303
Observe que usamos la expresión Variable =Format (1234567,”Formato”) para todos los ejemplos de números.
Para poner los números separados por millares :
Variable = Format(1234567, "##,###,###") Variable = 1.234.567
Ejemplos de funciones fecha:
Ingresando una fecha mostrar la edad exacta de cualquier presenta.
Public Class Form1
Private Sub BTnCalculo_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles BtnCalculo.Click
Dim FE, FA, FN As Date
FA = Today : FE = CDate(TXTFE.Text)
Dim DIAS, MES, AA, DA, DN As Integer
AA = Year(FA) - Year(FE)
FN = CDate(FE.Day & "/" & FE.Month & "/" & FA.Year)
DA = FA.DayOfYear : DN = FN.DayOfYear
If DN > DA Then AA = AA - 1
FE = FE.AddYears(AA)
MES = DateDiff("M", FE, FA)
Técnica de Programación Orientada a Objetos 304
FE = FE.AddMonths(MES)
If DN > DA Then
DIAS = DateDiff("D", FA, FE)
Else
DIAS = DateDiff("D", FE, FA)
End If
LBFE.Text = AA
LBDIA.Text = DIAS
LBMES.Text = MES
End Sub
End Class
Técnica de Programación Orientada a Objetos 305
Aplicaciones empleando funciones Fechas
1.- Realizar un programa que permita generar los códigos de los empleados que serán
almacenados en una lista, el código se genera en función del cargo y año de ingreso
Según: el código esta compuesto de seis Caracteres.
Apellidos = Laura Lee
Cargo = Docente fecha = 20/02/2001
Su código será : D01001
Consideración: el Campo apellido y nombre solo debe aceptar letras y espacios en Blanco,
La fecha debe ser correcta.
Técnica de Programación Orientada a Objetos 306
2.- Aplicando Fechas.- Ingrese como datos Monto de la cuota, fecha de vencimiento y
fecha de pago , calcular los días de mora , pago por mora y el pago total
Los pago por Mora es de acuerdo a:
Menor a una semana 1% por cada dia
Entre 2 y 3 semanas 1.5% por dia
Mayor a 3 semanas 2% por dia
3.- Ingrese por teclado cierta cantidad de Bolas de billar , con el cual se desea formar una
pirámide de base cuadrada, cada superficie esta formado por un numero cuadrado perfecto,
calcular el numero de superficies que se forman y el numero de bolas que sobran
Ejemplo para 20 Bolas serán 3 superficies y sobran 6 bolas.
4.- Alquiler de Maquinas
Técnica de Programación Orientada a Objetos 307
El pago hora es de acuerdo al usuario:
Estudiante S/. 1.50 Publico S/2.00 Docente S/1.0
4.- Realice una aplicación en donde se ingrese a cuadros de texto el Día(entre 1 y 31),
Mes(entre 1 y 12) y Año de Nacimiento(4 dígitos) de una persona, luego al pulsar un
clic sobre el botón “Calcular” mostrar su Edad y el signo Zodiacal (control Image) al
que pertenece.
NOTA: Validar que en los cuadros de texto sólo se debe ingresar dígitos.
Técnica de Programación Orientada a Objetos 308
Contenido.
Programación Orientada a Objetos en .NET o Entendiendo el modelo POO: Herencia, Polimorfismo, Encapsulamiento o Clases y Estructuras o Interfaces o Constructores y Destructores o Sobrecarga o Miembros de las Clases: Campos, Propiedades y Métodos. Ámbitos:
Public, Private, Protected, Friend, Protected Friend.
Recursividad.
Programación Orientada a Objetos en .NET
Visual Basic .NET tiene todas las características de la Programación Orientada a Objetos
(POO), ya que el Marco .NET soporta los requerimientos para que todos los lenguajes que
trabajen con él usen POO. Estas características son:
1. Encapsulación Cuando creamos un componente .NET este se encuentra encapsulado, ya que oculta la
lógica de programación a los usuarios que lo utilizan, permitiendo manejar dicho objeto a
través de sus miembros, tales como propiedades y métodos, realizando el desarrollo de
aplicaciones más simple, al ocultar la complejidad del código (encapsular).
2. Herencia La herencia es la característica en la cual una clase llamada “Clase Base” pasa o hereda
todas sus características a otra llamada “Clase Derivada”, permitiendo la total reusabilidad
del código escrito en las aplicaciones. La herencia de clases es una nueva característica de
Visual Basic .NET y no solo es a nivel de clases creadas en éste lenguaje sino a través de
cualquier lenguaje del Marco .NET.
Técnica de Programación Orientada a Objetos 309
3. Polimorfismo Otra característica interesante de la POO es el polimorfismo, en el caso de Visual Basic
.NET éste se puede crear cuando en una clase derivada se implementa de manera distinta
un método heredado de la clase base. Es decir, podemos tener un mismo método con dos
comportamientos distintos (códigos distintos) de acuerdo al tipo de objeto, que puede ser
creado de la clase base o de la derivada.
Como vemos las nuevas características de la Programación Orientación a Objetos (POO)
mezcladas con la facilidad de uso de la Programación Orientada a Componentes (POC) dan
como resultado la creación de aplicaciones poderosas y con un bajo costo de mantenimiento.
Sin duda, la reusabilidad y encapsulación ofrecida por la tecnología COM basada en
componentes se ve incrementada por la herencia de clases y el polimorfismo ofrecida por la
tecnología .NET orientada a objetos; lográndose una verdadera integración entre aplicaciones.
Para finalizar esta introducción a los componentes .NET, la otra gran ventaja con respecto a
COM es la distribución de componentes, que en este último era una pesadilla debido había que
registrar componentes y lidiar con los problemas de compatibilidad de versiones; en cambio
con .NET los componentes no se registran y su distribución es automática con solo copiar y
pegar la aplicación.
Elementos de una Clase (Miembros)
Todos los componentes están formados por clases y estas a su vez se componen de
elementos o miembros, los cuales trataremos en este capítulo. Para ilustrar mejor tenemos el
siguiente gráfico.
Estructura de un Componente .NET
Clase Base
Constantes
Enumeraciones
Campos
Propiedades
Métodos
Eventos
Delegados
Constructores
Destructores
Clase Derivada
Constantes
Enumeraciones
Campos
Propiedades
Métodos
Eventos
Delegados
Constructores
Destructores
Técnica de Programación Orientada a Objetos 310
A diferencia de Visual Basic 6 en donde las clases podían tener solo propiedades, métodos,
eventos y constantes enumeradas; en Visual Basic .NET las clases pueden tener campos,
delegados, constructores y destructores. Además pueda ser que una clase herede de otra que
este dentro del componente o en otro componente .NET.
Clase Una clase es la plantilla para crear el objeto, es aquí donde se definen las partes del objeto:
datos (propiedades, constantes, enumeraciones, campos) y procedimientos que operan sobre
los datos (métodos).
La clase define un nuevo tipo de datos que resulta de la abstracción de algún elemento en la
aplicación, por tanto, es necesario diseñar bien la aplicación antes de crear la clase, ya que
esta solo implementa el diseño de objetos previamente realizado.
Declaración de una Clase
A diferencia de Visual Basic 6, donde el tipo de clase estaba dado por la propiedad “Instancing”
de la clase, que podía ser privada (Private), dependiente (PublicNotCreateTable) o pública
(SingleUse, GlabalSingleUse, MultiUse, o GlobalMultiUse); en VB .NET no existe propiedades
para el módulo de clase, ya que las características de la clase dependen de la forma de su
declaración.
Sintaxis:
[Tipo de Declaración] Class <Nombre Clase>
<Definición de miembros de la clase>
<...>
End Class
Técnica de Programación Orientada a Objetos 311
Existen varias formas de declarar una clase, que detallamos a continuación en la siguiente
tabla:
Declaración Alcance o Ámbito
Public Puede usarse en cualquier otra clase del componente o en las
aplicaciones clientes.
Private No puede usarse en otras clases del componente ni en las
aplicaciones clientes.
Protected Solo puede ser usada por las clases derivadas de éste, pero no por las
aplicaciones clientes.
Friend Solo puede ser usada por las otras clases del componente, pero no por
las aplicaciones clientes.
Protected Friend Es una combinación de ambas, es decir, la clase puede ser usada por
otras clases del componente y por las clases derivadas.
Shadows Indica que los miembros de la clase pueden ocultarse en la clase
derivada, es decir que al heredar se ocultan ciertos miembros.
MustInherit Determina que los miembros de la clase pueden heredarse a una clase
derivada, pero no puede ser creada por aplicaciones clientes
NotInheritable La clase no puede heredarse pero si instanciarse desde aplicaciones
clientes.
Técnica de Programación Orientada a Objetos 312
Ejemplo:
Si queremos crear una aplicación de Planilla necesitamos diseñar un componente que
manipule información del empleado, sus horas trabajadas, tardanzas, faltas, etc.
Para crear la clase Empleado, de tal manera que pueda heredarse y utilizarse tanto dentro del
componente como en las aplicaciones clientes, definiríamos la clase en Visual Basic, tal como
sigue:
Public Class Empleado
End Class
Repaso: Constantes, Campos y Enumeraciones
Constantes
Una constante es un dato que permanece fijo en toda la ejecución de la aplicación, a diferencia
de la variable, cuyo valor va cambiándose en tiempo de ejecución.
Se utiliza para facilitar el mantenimiento del código, ya que si definimos un valor en una
constante, si este cambia, con solo cambiar el valor de la constante, la aplicación trabajaría con
el nuevo valor.
Sintaxis:
[Public | Private] Const <Nombre> [As <Tipo Dato>]=<Valor>
Ejemplo:
Podemos crear un par de constantes que almacenen el valor de las tasas de los impuestos a la
renta e impuesto extraordinario de solidaridad, para propósitos del cálculo de descuentos.
Private Const TasaIRenta As Single = 0.1
Private Const TasaIES As Single = 0.02
Técnica de Programación Orientada a Objetos 313
Nota:
En Visual Basic .NET si no se define el tipo de dato de la constante se asume que es Object,
ya no Variant como en Visual Basic 6, debido a que éste tipo de dato ya no existe.
Campos
Un campo es una variable local para la clase, es decir, solo puede ser usada internamente por
los miembros de la clase pero no por otras clases o por aplicaciones clientes.
El campo solo puede ser una variable privada o protegida que se use dentro de la clase para
almacenar un valor usado por alguna propiedad o método, sin que éste pueda ser visto o
instanciado por otras aplicaciones.
Sintaxis:
[Private | Friend] <Nombre Campo> [As <Tipo Dato>]
Ejemplo:
Podemos crear un par de campos que almacenen el cálculo de los impuestos a la renta e
impuesto extraordinario de solidaridad, para el total de descuentos.
Private IES As Single
Private IRenta As Single
Enumeraciones
Una enumeración es una estructura de datos personalizada que define un conjunto de valores
enteros. Por defecto, el primer dato enumerado empieza en 0, el segundo en 1 y así
sucesivamente, aunque esto puede cambiarse al momento de definir la enumeración.
Las enumeraciones son útiles para dar claridad al programa y evitar errores de asignación de
variables, ya que si definimos una variable de tipo enumerada, el valor que se puede asignar
está limitado por el rango de valores definido en la enumeración.
Técnica de Programación Orientada a Objetos 314
Sintaxis:
[Public | Private | Protected | Friend] Enum <Nombre Enumeración>
<Elemento1>[=<Valor1>]
<Elemento2>[=<Valor2>]
<Elemento3>[=<Valor3>]
<...>
End Enum
Ejemplo:
Vamos a crear dos enumeraciones, la primera que describa los cargos de los empleados que
se usará desde otras clases y aplicaciones, y la segunda que defina las áreas de la empresa
para propósitos internos de trabajar con información del empleado.
Public Enum Cargos
Auxiliar
Técnico
Ingeniero
Secretaria
Vendedor
End Enum
Private Enum Areas
Gerencia = 100
Contabilidad = 200
Producción = 300
Sistemas = 400
Ventas = 500
End Enum
.
Técnica de Programación Orientada a Objetos 315
Para usar estas enumeraciones creadas, tan solo basta declarar una variable de estos tipos y
asignarle un valor definido, por ejemplo, para el caso anterior sería como sigue:
Dim Cargo As Cargos
Cargo = Cargos.Vendedor
Dim Area As Areas
Area = Areas.Ventas
Propiedades
Una propiedad es una característica del objeto que tiene información sobre un cierto atributo de
éste como por ejemplo su nombre, descripción, etc. Las propiedades son métodos que se
trabajan como si fuesen campos, con la diferencia que el campo es interno solo para uso de la
clase, en cambio las propiedades se usan fuera de la clase.
A diferencia de la versión anterior de Visual Basic que existían 3 estructuras para declarar una
propiedad (Property Get, Let, y Set), ahora, en Visual Basic .NET solo existe una estructura
llamada Property donde internamente se define si la propiedad es de lectura (Get) y/o escritura
(Set), tal como se muestra debajo.
Sintaxis:
[Tipo de Declaración] Property <Nombre > [As <Tipo Dato>]
[[ReadOnly] Get
<Instrucciones>
End Get]
[[WriteOnly] Set (ByVal Value [As <Tipo Dato>])
<Instrucciones>
End Set]
End Property
Técnica de Programación Orientada a Objetos 316
Existen muchas formas de declarar una propiedad, que explicamos en la sgte tabla:
Declaración Uso
Default Indica que la propiedad es por defecto (no es necesario escribirla)
Public Puede ser usada desde cualquier clase o aplicación.
Private Solo puede ser accesada desde dentro de la clase.
Protected Se usa desde dentro de la clase o desde una clase derivada.
Friend Puede ser usada desde otras clases del componente pero no fuera.
Protected Friend Tiene las características de la protegida y amiga, es decir, se usa
dentro de la clase, desde una clase derivada o desde otra clase del
mismo componente, pero no en aplicaciones clientes.
ReadOnly Indica que el valor de la propiedad solo puede ser recuperado pero no
escrito. Solo puede tener la cláusula Get y no Set.
WriteOnly Indica que el valor de la propiedad solo puede ser escrito pero no
devuelto. Solo puede tener la cláusula Set y no Get.
Overloads Permite que la propiedad de la clase base sea sobrecargada, es decir
definida varias veces en las clases derivadas pero con diferentes
parámetros que la propiedad definida en la clase base.
Overrides Permite sobrescribir la propiedad por otra propiedad con el mismo
nombre en una clase derivada.
Overridable Permite sobrescribir la propiedad por un método con el mismo nombre
en una clase derivada.
Técnica de Programación Orientada a Objetos 317
NotOverridable Indica que la propiedad no puede ser sobrescrita por nadie en ninguna
clase derivada.
MustOverride Indica que la propiedad no puede ser implementada en esta clase y
puede ser implementada en una clase derivada.
Shadows Se usa para ocultar una propiedad de tal manera que no pueda
implementarse en una clase derivada.
Shared Permite que la propiedad sea compartida y pueda llamarse sin
necesidad de instanciar a la clase sino a través de su nombre.
Ejemplo:
Para nuestra clase Empleado, podemos implementar las propiedades código, nombre y básico
del empleado, de tal manera que se puedan leer y escribir en cualquier parte.
Private mvarCodigo As Integer
Private mvarNombre As String
Private mvarSueldo As Single
Public Property Codigo() As Integer
Get
Codigo = mvarCodigo
End Get
Set(ByVal Value As Integer)
mvarCodigo = Value
End Set
End Property
Public Property Nombre() As String
Técnica de Programación Orientada a Objetos 318
Get
Nombre = mvarNombre
End Get
Set(ByVal Value As String)
mvarNombre = Value
End Set
End Property
Public Property Sueldo() As Single
Get
Sueldo = mvarSueldo
End Get
Set(ByVal Value As Single)
mvarSueldo = Value
End Set
End Property
Métodos
Un método es un conjunto de instrucciones que modifica el estado de las propiedades; en
términos de objetos, un método es un servicio o función del objeto, mientras que en términos
de código un método es un procedimiento o función que realiza una tarea específica.
En Visual Basic .NET todos los miembros de una clase (propiedades, eventos, constructores,
destructores, etc.) son en realidad métodos; claro, estos últimos son métodos especiales.
Un procedimiento o función en una clase es un método, y sus características son las mismas
que cuando se encuentran en un módulo estándar, es decir, si es procedimiento la declaración
es con Sub, y si es función la declaración es con Function, tal como se muestra en la sintaxis
de abajo.
Técnica de Programación Orientada a Objetos 319
Sintaxis:
[Tipo Declaración] [Sub | Function] <Nombre >([Param]) [As <Tipo Dato>]
<Instrucciones>
[Exit [Sub | Function]]
End Property
En cuanto al tipo de declaración, es muy similar al de las propiedades, que describimos
anteriormente en una tabla, es decir, puede declararse el método como Public, Private,
Protected, Friend, Protected Friend y Shadows.
También hay que recordar que si el método es una función siempre se deberá devolver un
valor, que se puede hacer de dos formas: de manera clásica asignando un valor al nombre de
la función o de una nueva forma escribiendo la sentencia return y el valor.
Ejemplo:
En nuestro ejemplo de Empleado, podemos implementar dos métodos públicos, uno que
permita asignar valores a las propiedades creadas: código, nombre y sueldo del empleado y
otro método que permita actualizar el sueldo.
Public Sub CrearEmpleado(ByVal vCodigo As Integer, _
ByVal vNombre As String, ByVal vSueldo As Single)
mvarCodigo = vCodigo
mvarNombre = vNombre
mvarSueldo = vSueldo
End Sub
Public Sub ActualizarSueldo(ByVal vNuevoSueldo As Single)
mvarSueldo = vNuevoSueldo
End Sub
Técnica de Programación Orientada a Objetos 320
Eventos
Un evento es un suceso que le ocurre al objeto y que le indica o notifica sobre un cambio en
sus atributos o propiedades. Un evento es necesario para controlar el estado de las
propiedades e informar a las aplicaciones del nuevo estado, para que estas realicen la acción
correspondiente.
Es fácil entender eventos asociados a objetos visuales como los controles, por ejemplo en el
objeto “Button” se tiene el evento “Click” que se desencadena al seleccionar el botón, el evento
“MouseMove” que ocurre al pasar el mouse por el botón, y así hay muchos eventos asociados
al objeto botón; pero, cuando trabajamos con clases, los eventos son más abstractos y un poco
más difíciles de entender, ya que podía confundirse con los métodos.
Para aclarar el concepto de eventos definamos mentalmente una clase llamada “Cuenta” para
un componente llamado “Banco”. Esta clase cuenta tiene propiedades como “NumeroCta”,
“FechaApertura”, “TipoCta”, “NumeroTarjeta” y “Saldo”. Además tiene métodos como
“Depósito”, “Retiro” y “Transferencia” que modifican el estado del saldo. Cuando hacemos un
“Retiro” de nuestra cuenta donde el monto a retirar supera al “Saldo” se desencadena un
evento llamado “SaldoInsuficiente” y también cuando durante el día hemos retirado más del
monto permitido se desencadena el evento “LimiteRetiroDiario”.
Para crear un evento en la clase primero declare l evento con la sentencia “Event” y luego
llámelo con “RaiseEvent”, tal como se muestra en la sintaxis.
Declaración Sintaxis:
[Tipo Declaración] Event <Nombre > ([Parámetro(s)])
Declaración Llamada:
RaiseEvent <Nombre > ([Parámetro(s)])
El tipo de declaración, es igual que la de los métodos, es decir, puede ser Public, Private,
Protected, Friend, Protected Friend y Shadows.
Técnica de Programación Orientada a Objetos 321
Ejemplo:
Crear dos eventos que nos informen cuando el sueldo es bajo o alto; para nuestra realidad un
sueldo será bajo cuando es menor a 500 y alto cuando sea mayor a 3000.
Public Event SueldoBajo()
Public Event SueldoAlto()
Private Sub ChequearSueldo()
If mvarSueldo < 500 Then
RaiseEvent SueldoBajo()
ElseIf mvarSueldo > 3000 Then
RaiseEvent SueldoAlto()
End If
End Sub
Para finalizar, deberíamos llamar a la rutina “ChequearSueldo” al final de “CrearEmpleado” y
“ActualizarSueldo” que es donde se modifica el “Sueldo”.
Técnica de Programación Orientada a Objetos 322
Constructores y Destructores
Constructores
Un constructor es un método que se usa para inicializar características del objeto. Todas las
clases de Visual Basic .NET tienen un constructor por defecto que es el método “New”, pero se
pueden agregar varios constructores “New” diferenciándose por el número de parámetros.
Sintaxis:
Public Sub New ()
<Instrucciones>
End Sub
Public Sub New ([<Param1> As <Tipo Dato>])
<Instrucciones>
End Sub
Public Sub New ([<Param1> As <Tipo Dato>,<Param2> As <Tipo Dato>])
<Instrucciones>
End Sub
Public Sub New ([<P1> As <Dato>,<P2> As <Dato>,…,<PN> As <Dato>])
<Instrucciones>
End Sub
Nota:
Es requisito indispensable escribir los métodos constructores al inicio de la clase, de lo
contrario no funcionarían.
Técnica de Programación Orientada a Objetos 323
Ejemplo:
Continuando con nuestro ejemplo de la clase “Empleado” podemos crear 4 constructores que
permitan crear de cuatro maneras distintas un objeto de tipo empleado.
Public Sub New()
End Sub
Public Sub New(ByVal vCodigo As Integer)
mvarCodigo = vCodigo
End Sub
Public Sub New(ByVal vCodigo As Integer, ByVal vNombre As String)
mvarCodigo = vCodigo
mvarNombre = vNombre
End Sub
Public Sub New(ByVal vCodigo As Integer, ByVal vNombre As String,
ByVal vSueldo As Single)
mvarCodigo = vCodigo
mvarNombre = vNombre
mvarSueldo = vSueldo
End Sub
Técnica de Programación Orientada a Objetos 324
Destructores
Un destructor es un método que se usa para limpiar características del objeto antes que sea
destruido y liberado de la memoria. Por ejemplo, si tenemos una clase que accede a datos y
que abre una conexión hacia una base de datos para crear un Dataset, entonces recitamos un
destructor que permita cerrar el Dataset y la conexión antes de destruir el objeto que apunta a
dicha clase.
El FrameWork .NET solo provee de destructores a Visual C#, en cambio, en Visual Basic :NET
no existe un método especial para crear destructores; en vez de ello se crea un método
cualquiera que realice la labor de iniciar variables, liberar recursos, etc.
Sintaxis:
Public Sub <Nombre Destructor>()
<Instrucciones>
End Sub
Ejemplo:
Para la clase “Empleado” podemos crear un destructor llamado “Finalizar” que permita liberar
las variables usadas por las propiedades para almacenar sus valores.
Public Sub Finalizar()
mvarCodigo = Nothing
mvarNombre = Nothing
mvarSueldo = Nothing
End Sub
Técnica de Programación Orientada a Objetos 325
Creando una Librería de Clases
Después de ver los elementos de una clase, es momento de crear Componentes .NET los
cuales también son conocidos como “Librería de Clases”, para lo cual existen varias etapas
que detallamos a continuación.
Eligiendo el Tipo de Aplicación
Del menú “File”, elegir “New” y luego “Project” o pulsar [Ctrl + N]
En la opción “Project Types” elegir “Visual Basic Projects” y en la opción “Templates” elegir “Class Library”
Seleccionar la ubicación y escribir un nombre adecuado para el proyecto, generalmente, se acostumbra colocar el nombre de la Empresa, nosotros podemos llamar al componente “ACME” y luego “OK”.
Inmediatamente aparecerá una clase llamada “Class1”, proceder a cambiar de nombre físico y lógico, por ejemplo ponerle como nombre “Empleado”.
Técnica de Programación Orientada a Objetos 326
Añadiendo una Clase
Por defecto toda librería trae una clase, pero si queremos crear mas clase realizamos lo
siguiente:
Del menú “Project” elegimos la opción “Add Class”
Escribimos el nombre físico de la clase, este a su vez será por defecto el nombre lógico y damos clic en “Open”.
1. Por defecto aparecerá la siguiente estructura:
Public Class Cliente
End Class
Técnica de Programación Orientada a Objetos 327
2. Dependiendo del alcance que queramos que tenga el objeto se puede modificar el tipo de declaración “Public” a una de las vistas anteriormente, tales como: “Private”, “Protected”, “Friend”, “Shadows”, etc.
Creando Propiedades, Métodos, Eventos
La creación de propiedades, métodos y eventos se realiza dentro del módulo de clase tal como
se mostró anteriormente. Por ejemplo para la clase “Empleado” podemos crear lo siguiente.
1. Añadiendo una propiedad:
Private mvarSueldo As Single
Public Property Sueldo() As Single
Get
Sueldo = mvarSueldo
End Get
Set(ByVal Value As Single)
mvarSueldo = Value
End Set
End Property
2. Añadiendo un método:
Public Sub ActualizarSueldo(ByVal vNuevoSueldo As Single)
mvarSueldo = vNuevoSueldo
End Sub
3. Añadiendo eventos:
Public Event SueldoBajo()
Public Event SueldoAlto()
4. Llamando eventos:
Técnica de Programación Orientada a Objetos 328
Sub ChequearSueldo()
If mvarSueldo < 500 Then
RaiseEvent SueldoBajo()
ElseIf mvarSueldo > 3000 Then
RaiseEvent SueldoAlto()
End If
End Sub
Public Sub ActualizarSueldo(ByVal vNuevoSueldo As Single)
mvarSueldo = vNuevoSueldo
ChequearSueldo()
End Sub
También podemos definir en el módulo de clase constantes, campos y enumeraciones;
además, podemos añadir constructores y destructores para la clase, tal como vimos en la
sección anterior.
Técnica de Programación Orientada a Objetos 329
Probando y Usando la Librería de Clases
Probar la Librería de Clases
Para probar el funcionamiento de la Librería de Clases es necesario crear una aplicación que
use los miembros de las clases de la librería. Esta aplicación la llamaremos el “Cliente” del
componente y puede estar escrito en cualquier lenguaje del FrameWork .NET, es decir, si
creamos una librería en Visual Basic .NET, la podemos probar o usar en una aplicación Visual
Basic .NET, Visual C#, Visual C++, COBOL, Pascal, C++, etc.
Vamos a asumir que se desea crear una aplicación cliente en Visual Basic .NET que pruebe la
librería de clases creada, para esto necesitamos realizar lo siguiente:
1. Del menú “File”, elegir “Add Project”, y luego seleccionar “New Project”. Elegir una plantilla de aplicación para Windows o Web en Visual Basic .NET
2. Elegir el directorio donde se creará la aplicación, escribir el nombre y “OK”. Aparecerá un nuevo proyecto en la solución, el cual se ejecuta por defecto.
3. Para indicar que el proyecto de la aplicación es el que se ejecuta dar clic derecho sobre el nombre del proyecto en la ventana del “Solution Explorer” y elegir “Set as StartUp Project”.
Técnica de Programación Orientada a Objetos 330
4. Para usar la librería desde la aplicación creada hacer una referencia a esta, desde el menú “Project” eligiendo “Add Reference...”
5. Elegir la ficha “Projects” de la ventana de añadir referencia y se mostrará la librería creada en la misma solución, tal como se muestra en la figura anterior.
6. Dar clic al botón “Select” y luego “OK”; inmediatamente, aparecerá en la carpeta “References” del proyecto en la ventana del “Solution Explorer”.
7. Declarar una variable objeto que apunte a una clase del componente o librería, para lo cual existen 3 formas que ilustraremos con la clase empleado:
1. Primera forma: Dim objEmpleado As ACME.Empleado
objEmpleado = New ACME.Empleado()
2. Segunda forma: Dim objEmpleado As ACME.Empleado = New ACME.Empleado()
3. Tercera forma: Dim objEmpleado As New ACME.Empleado
8. Usar las propiedades y métodos del objeto, tal como se muestra en el ejemplo: objEmpleado.CrearEmpleado(123, "Luis Dueñas", 1000)
9. Si deseamos usar los eventos, entonces tendremos que declarar la variable en la sección de decalaraciones generales, de la siguiente forma:
Private WithEvents objEmpleado As New ACME.Empleado()
10. Para liberar la variable objeto realizar la siguiente asignación: objEmpleado = Nothing
Nota:
La anterior sentencia en realidad no destruye la variable, sino que la desactiva, el encargado
de destruir definitivamente al objeto es el “Garbage Collector”.
Técnica de Programación Orientada a Objetos 331
Usar la Librería de Clases
Anteriormente, habíamos visto como probar la librería junto con una aplicación en la misma
solución, lo que permite realizar depuración paso a paso, pero cuando ya está probada la
librería no es necesario tener el código fuente, sino tan solo el archivo DLL.
Para usar la librería en cualquier aplicación solo hay que hacer una referencia y en la opción
“Projects” hay que seleccionar el nombre de la DLL que se encuentra en la carpeta del
proyecto. Después se realizan los mismos pasos que para probarla.
Herencia de Clases
La parte principal de la Programación Orientada a Objetos (POO) es la herencia de clases, es
decir, la característica de definir una clase que sirva de base para otras clases derivadas, las
clases derivadas tendrán los miembros de la clase base: propiedades, métodos, eventos, etc.
Los miembros heredados por la clase derivada pueden sobre escribirse e implementarse de
otra forma, además la clase derivada puede tener sus propios miembros y servir de clase base
para otras clases, lográndose la reutilización de objetos a través de la herencia.
Otra forma de herencia es a través del polimorfismo, que es una característica de la POO que
consiste en definir una clase abstracta con propiedades y métodos que serán implementados
de diferentes formas por otras clases, es decir, con un mismo nombre de propiedad o método
se obtiene funcionalidad distinta de acuerdo al tipo de objeto.
En .NET solo existe herencia simple y no herencia múltiple, es decir, una clase derivada solo
puede heredar de una clase base. Haciendo una analogía, si a la clase base le llamamos
“padre” y a la clase derivada le llamamos “hijo” diríamos que la herencia simple consiste en que
un “hijo” solo puede tener un solo “padre”, lo que parece algo natural y coherente.
Si deseamos simular herencia múltiple en Visual Basic .NET recurrimos a las interfaces, que
permiten definir propiedades y métodos en una clase sin código, luego desde una clase se
puede implementar varias interfaces, lográndose una herencia múltiple pero a nivel de
definición y no de código, ya que la implementación será distinta en cada clase.
En general, la herencia de clases permite reutilizar código y facilitar el mantenimiento de las
aplicaciones, ya que cuando se desea modificar características de un objeto solo hay que
cambiar la clase adecuada.
Con .NET podemos implementar la herencia de cualquier clase pública de la librería de clases
base, la cual tiene una gran cantidad de clases de diferentes tipos, tales como Windows, Data,
Técnica de Programación Orientada a Objetos 332
XML, ASP .NET, System, etc. Pero, también podemos implementar herencia de clases creadas
por nosotros, sin importar el lenguaje en que fueron creadas.
Implementando Herencia en una Clase
Para crear una herencia de clases se usa la instrucción Inherits seguida de la clase base de
donde se heredarán los miembros para la clase actual (clase derivada), tal como se muestra
debajo.
Sintaxis:
Inherits <Clase Base>
Notas:
Dos observaciones importantes que hay que tener en cuenta son:
1. La instrucción Inherits debe escribirse en la primera línea de la clase derivada. 2. Solo puede existir una instrucción Inherits, ya que solo existe herencia simple.
Ejemplo:
Podemos crear una clase llamada “Vendedor” que herede de la clase “Empleado” que
habíamos creado anteriormente, y crear dos propiedades, una llamada “Venta” y otra llamada
“Comision”, tal como sigue:
Public Class Vendedor
Inherits Empleado
Private mvarVenta As Single
Private mvarComision As Single
Property Venta() As Single
Get
Venta = mvarVenta
End Get
Set(ByVal Value As Single)
mvarVenta = Value
Técnica de Programación Orientada a Objetos 333
End Set
End Property
Property Comision() As Single
Get
Comision = mvarComision
End Get
Set(ByVal Value As Single)
mvarComision = Value
End Set
End Property
End Class
Finalmente, la clase “Vendedor” tendrá
5 propiedades: 3 heredadas: “Codigo”, “Nombre” y “Basico” y 2 propias: “Venta” y “Comision”.
2 métodos heredados: “CrearEmpleado” y “ActualizarBasico”. 2 eventos heredados: “BasicoBajo” y “BasicoAlto”.
Técnica de Programación Orientada a Objetos 334
Sentencias para trabajar con Herencia
Para trabajar con herencia de clases existen varias instrucciones que hay que conocer tanto a
nivel de la clase como de sus miembros que definen las características de la herencia, las
cuales explicamos a continuación.
Declaración de Clases Base
Para declarar una clase base existen varias formas que fueron vistas en temas anteriores,
ahora afianzaremos solo los tipos de declaraciones que posibilitan o limitan el uso de herencia
de una clase base:
1. MustInherit
Permite crear una clase que solo sirva como clase base, es decir, que sirva solo para
implementar herencia en otras clases, pero no podrá crearse objetos de esta clase.
Sintaxis:
MustInherit Class <Nombre Clase Base>
<Código de la clase>
End Class
2. NotInheritable
Se usa para crear una clase que solo pueda crear objetos o aplicaciones clientes, pero que
no pueda servir para heredarse en otra clase.
Sintaxis:
NotInheritable Class <Nombre Clase>
<Código de la clase>
End Class
Técnica de Programación Orientada a Objetos 335
SobreEscribiendo Propiedades y Métodos en Clases
Derivadas
Para declarar una propiedad o método en una clase derivada o clase que hereda de una clase
base, hay que tener ciertas consideraciones de acuerdo al tipo de declaración, que se explican
a continuación.
1. Overridable
Permite crear una propiedad o método que puede ser sobre escrito en una clase derivada.
Esta declaración se hace en la propiedad o método de la clase base.
2. Overrides
Se usa para sobre escribir una propiedad o método que fue definido como “Overridable” en
la clase base. Esta declaración se hace en la propiedad o método de la clase derivada.
3. NotOverridable
Impide que una propiedad o método pueda ser sobre escrito en una clase derivada. La
definición se realiza en la propiedad o método de la clase base.
Por defecto, todas las propiedades o métodos públicos definidos en una clase base no
pueden ser sobre escritos en la clase derivada.
4. MustOverride
Permite crear una propiedad o método que será obligatorio sobre escribirlo en la clase
derivada. Esta declaración se realiza en la propiedad o método de la clase base que ha
sido definida como MustInherit.
Palabras claves MyBase y MyClass
Se puede usar las palabras clave MyBase y MyClass al trabajar con herencia, tal como se
muestra a continuación:
1. MyBase Se usa para llamar a miembros de la clase base desde la clase derivada. Es decir en vez
de usar el nombre de la clase seguido de la propiedad o método se usa la palabra clave
MyBase seguida de la propiedad o método.
Este tipo de llamada es útil cuando se trabaja con métodos sobre escritos en una clase
derivada y se necesita invocar al método de la clase base que será sobre escrito, tal como
se muestra en el siguiente ejemplo.
Técnica de Programación Orientada a Objetos 336
Ejemplo:
Suponiendo que el método “CrearEmpleado” de la clase “Empleado” haya sido creado
como “Overridable”, y se desea sobre escribir en la clase “Vendedor” para calcular
correctamente el sueldo del vendedor incluyendo las comisiones, entonces, tendriamos lo
siguiente:
Public Class Vendedor
Inherits Empleado
Public Overrides Sub CrearEmpleado(ByVal vCodigo As Integer, _
ByVal vNombre As String, ByVal vSueldo As Single)
vSueldo = vSueldo + mvarVenta * mvarComision
MyBase.CrearEmpleado(vCodigo,vNombre,vSueldo)
End Sub
End Class
2. MyClass
Se usa para llamar a métodos sobre escribibles desde la clase derivada, y diferenciarlos de
los métodos heredados desde la clase base.
Técnica de Programación Orientada a Objetos 337
Polimorfismo
El polimorfismo consiste en la funcionalidad múltiple que puede tener un miembro de una clase
para comportarse de diversas maneras de acuerdo al tipo de objeto que lo implemente.
Existen dos formas de implementar el polimorfismo en Visual Basic .NET:
1. Polimorfismo basado en Herencia
Es una nueva forma de crear multiple funcionalidad para un método de una clase base que
puede ser sobre escrito por otros métodos con el mismo nombre en las clases derivadas.
Ejemplo:
Tomemos como caso el ejemplo anterior donde habíamos sobre escrito el método
“CrearEmpleado” de la clase “Empleado” modificandose en la clase derivada “Vendedor”
para incluir lo recibido por comisiones de ventas. Crearemos el método llamado
“MostrarSueldo” que permita crear el empleado y mostrar cuanto gana, usando el
polimorfismo dependeiendo si es vendedor o no.
Sub MostrarSueldo(ByVal vEmpleado As Empleado, _
ByVal vCodigo As Integer, ByVal vNombre As String, _
ByVal vSueldo As Single)
vEmpleado.CrearEmpleado(vCodigo,vNombre,vSueldo)
MsgBox(vNombre & " gana s/. " & vSueldo)
End Sub
Sub ProbarPolimorfismo()
Dim objEmpleado As New Empleado
Dim objVendedor As New Vendedor
objEmpleado.CrearEmpleado(100, "Luis Dueñas", 1000)
objVendedor.Venta=1000
objVendedor.Comision=0.10
objVendedor.CrearEmpleado(100, "Luis Dueñas", 1000)
End Sub
Técnica de Programación Orientada a Objetos 338
En este ejemplo el resultado será para el primer caso el mensaje “Luis Dueñas gana 1000”
y en el segundo caso el mensaje “Luis Dueñas gana 1100”.
2. Polimorfismo basado en Interfaces
Este tipo de polimorfismo se usa también en Visual Basic 6 y consiste en crear una
interface donde se definan nombres de propiedades y/o métodos, y luego se implementen
con la sentencia “Implements” en varias clases, escribiendo diferentes códigos o
implementaciones para las propiedades y métodos de cada clase.
Este último tipo de polimorfismo no se va a tratar, debido a que la manera natural de
implementar polimorfismo es a través de la herencia de clases sobre escribiendo
propiedades o métodos.
Las interfaces son un elemento bastante importante en .NET Framework, ya que de hecho
se utiliza con bastante frecuencia, en esta lección veremos que son las interfaces y como
utilizarlas en nuestros proyectos, también veremos que papel juegan en .NET y cómo
aplicar algunas de las definidas en la biblioteca base.
Técnica de Programación Orientada a Objetos 339
¿Qué es una interfaz?
Las interfaces son una forma especial de una clase, aunque la diferencia principal con las
clases es que las interfaces no contienen código ejecutable, solo definen los miembros.
Las interfaces se utilizan para indicar el "comportamiento" que tendrá una clase, o al
menos qué miembros debe definir esa clase.
Para definir una interfaz en Visual Basic 2005 tenemos que usar la instrucción Interface
seguida del nombre de la interfaz y terminar la declaración con End Interface:
Public Interface IAnimal
'...
End Interface
Nota:
Según las indicaciones de nomenclatura de .NET Framework, se recomienda que todas las
interfaces empiecen con una I mayúscula seguida del nombre al que hacer referencia la
interfaz.
¿Qué contiene una interfaz?
Al principio de esta lección hemos comentado que las interfaces no contienen código, solo
define los miembros que contiene. Esa definición la haremos como cualquier otra, con la
diferencia de que no incluimos ningún código, solo la "firma" o el prototipo de cada uno de
esos miembros.
En el siguiente código definimos una interfaz que contiene los cuatros tipos de miembros
típicos de cualquier clase:
Public Interface IPrueba
Sub Mostrar()
Function Saludo(ByVal nombre As String) As String
Property Nombre() As String
Event DatosCambiados()
End Interface
Técnica de Programación Orientada a Objetos 340
El primer miembro de esta interfaz, es un método de tipo Sub que no recibe parámetros.
El siguiente método es una función que devuelve un valor de tipo String y recibe un
parámetro también de tipo cadena.
A continuación definimos una propiedad que devuelve una cadena.
Por último, definimos un evento.
Como podemos observar, lo único que tenemos que hacer es indicar el tipo de miembro y
si recibe o no algún parámetro o argumento.
Dos cosas importantes sobre las interfaces:
1- No se pueden definir campos. 2- Los miembros de las interfaces siempre son públicos, tal como indicábamos en la tabla
Una interfaz es un contrato
Siempre que leemos sobre las interfaces, lo primero con lo que nos solemos encontrar es
que una interfaz es un contrato. Veamos que nos quieren decir con esa frase.
Tal como acabamos de ver, las interfaces solo definen los miembros, pero no el código a
usar en cada uno de ellos, esto es así precisamente porque el papel que juegan las
interfaces es el de solo indicar que es lo que una clase o estructura puede, o mejor dicho,
debe implementar.
Si en una clase indicamos que queremos "implementar" una interfaz, esa clase debe definir
cada uno de los miembros que la interfaz expone. De esta forma nos aseguramos de que si
una clase implementa una interfaz, también implementa todos los miembros definidos en
dicha interfaz.
Cuando una clase implementa una interfaz está firmando un contrato con el que se
compromete a definir todos los miembros que la clase define, de hecho el propio
compilador nos obliga a hacerlo.
Las interfaces y el polimorfismo
Como comentamos anteriormente, el polimorfismo es una característica que nos permite
acceder a los miembros de un objeto sin necesidad de tener un conocimiento exacto de
ese objeto (o de la clase a partir del que se ha instanciado), lo único que tenemos que
saber es que ese objeto tiene ciertos métodos (u otros miembros) a los que podemos
acceder. También hemos comentado que las interfaces representan un contrato entre las
clases que las implementan, por tanto las interfaces pueden ser, (de hecho lo son), un
medio para poner en práctica esta característica de la programación orientada a objetos. Si
una clase implementa una interfaz, esa clase tiene todos los miembros de la interfaz, por
Técnica de Programación Orientada a Objetos 341
tanto podemos acceder a esa clase, que en principio pude sernos desconocida, desde un
objeto del mismo tipo que la interfaz.
Usar una interfaz en una clase
Para poder utilizar una interfaz en una clase, o dicho de otra forma: para "implementar" los
miembros expuestos por una interfaz en una clase debemos hacerlo mediante la
instrucción Implements seguida del nombre de la interfaz:
Public Class Prueba
Implements IPrueba
Y como comentábamos, cualquier clase que implemente una interfaz debe definir cada uno
de los miembros de esa interfaz, por eso es el propio Visual Basic el encargado de crear
automáticamente los métodos y propiedades que la interfaz implementa, aunque solo
inserta el "prototipo" de cada uno de esos miembros, dejando para nosotros el trabajo de
escribir el código.
Usando la definición de la interfaz IPrueba que vimos antes, el código que añadirá VB será
el siguiente:
Public Class Prueba
Implements IPrueba
Public Event DatosCambiados() Implements IPrueba.DatosCambiados
Public Sub Mostrar() Implements IPrueba.Mostrar
End Sub
Public Property Nombre() As String Implements IPrueba.Nombre
Get
End Get
Técnica de Programación Orientada a Objetos 342
Set(ByVal value As String)
End Set
End Property
Public Function Saludo(ByVal nombre As String) As String _
Implements IPrueba.Saludo
End Function
End Class
Como podemos apreciar, no solo ha añadido las definiciones de cada miembro de la
interfaz, sino que también añade código extra a cada uno de esos miembros: la instrucción
Implements seguida del nombre de la interfaz y el miembro al que se hará referencia.
La utilidad de que en cada uno de los miembros se indique expresamente el método al que
se hace referencia, es que podemos usar nombres diferentes al indicado en la interfaz. Por
ejemplo, si implementamos esta interfaz en una clase que solo utilizará la impresora, al
método Mostrar lo podríamos llamar Imprimir que sería más adecuado, en ese caso
simplemente cambiamos el nombre del método de la clase para que implemente el método
Mostrar de la interfaz:
Public Sub Imprimir() Implements IPrueba.Mostrar
End Sub
De esta forma, aunque en la clase se llame de forma diferente, realmente hace referencia
al método de la interfaz.
Acceder a los miembros implementados
Una vez que tenemos implementada una interfaz en nuestra clase, podemos acceder a
esos miembros de forma directa, es decir, usando un objeto creado a partir de la clase:
Dim prueba1 As New Prueba
Técnica de Programación Orientada a Objetos 343
prueba1.Mostrar()
O bien de forma indirecta, por medio de una variable del mismo tipo que la interfaz:
Dim prueba1 As New Prueba
Dim interfaz1 As IPrueba
interfaz1 = prueba1
interfaz1.Mostrar()
¿Qué ha ocurre aquí?
Como ya comentamos anteriormente, cuando asignamos variables por referencia,
realmente lo que asignamos son referencias a los objetos creados en la memoria, por tanto
la variable interfaz1 está haciendo referencia al mismo objeto que prueba1, aunque esa
variable solo tendrá acceso a los miembros de la clase Prueba que conoce, es decir, los
miembros definidos en IPrueba.
Si la clase define otros miembros que no están en la interfaz, la variable interfaz1 no podrá
acceder a ellos.
Saber si un objeto implementa una interfaz
Si las interfaces sirven para acceder de forma anónima a los métodos de un objeto, es
normal que en Visual Basic tengamos algún mecanismo para descubrir si un objeto
implementa una interfaz.
Para realizar esta comprobación podemos usar en una expresión If/Then la instrucción
TypeOf... Is, de forma que si la variable indicada después de TypeOf contiene el tipo
especificado después de Is, la condición se cumple:
If TypeOf prueba1 Is IPrueba Then
interfaz1 = prueba1
interfaz1.Mostrar()
End If
Técnica de Programación Orientada a Objetos 344
De esta forma nos aseguramos de que el código se ejecutará solamente si la variable
prueba1 contiene una definición de la interfaz IPrueba.
Implementación de múltiples interfaces
En Visual Basic 2005, una misma clase puede implementar más de una interfaz. Para
indicar que implementamos más de una interfaz podemos hacerlo de dos formas:
1- Usando nuevamente la instrucción Implements seguida del nombre de la interfaz:
Public Class Prueba
Implements IPrueba
Implements IComparable
2- Indicando las otras interfaces en la misma instrucción Implements, pero separándolas
con comas:
Public Class Prueba
Implements IPrueba, IComparable
De cualquiera de las dos formas es válido implementar más de una interfaz, aunque en
ambos casos siempre debemos definir los miembros de cada una de esas interfaces.
Múltiple implementación de un mismo miembro
Como acabamos de comprobar, una misma clase puede implementar más de una interfaz,
y esto nos puede causar una duda:
Técnica de Programación Orientada a Objetos 345
¿Qué ocurre si dos interfaces definen un método que es idéntico
en ambas?
En principio, no habría problemas, ya que el propio Visual Basic crearía dos métodos con
nombres diferentes y a cada uno le asignaría la implementación de ese método definido en
cada interfaz.
Por ejemplo, si tenemos otra interfaz que define el método Mostrar y la implementamos en
la clase Prueba, la declaración podría quedar de esta forma:
Public Interface IMostrar
Sub Mostrar()
End Interface
Public Sub Mostrar1() Implements IMostrar.Mostrar
End Sub
Aunque si ambos métodos hacen lo mismo, en este ejemplo mostrar algo, podríamos hacer
que el mismo método de la clase sirva para implementar el de las dos interfaces:
Public Sub Mostrar() Implements IPrueba.Mostrar, IMostrar.Mostrar
End Sub
Es decir, lo único que tendríamos que hacer es indicar la otra implementación separándola
con una coma.
¿Dónde podemos implementar las interfaces?
Para ir acabando este tema nos queda por saber, entre otras cosas, dónde podemos
implementar las interfaces, es decir, en que tipos de datos podemos usar Implements.
La implementación de interfaces la podemos hacer en las clases (Class), estructuras
(Structure) y en otras interfaces (Interface).
Debido a que una interfaz puede implementar otras interfaces, si en una clase
implementamos una interfaz que a su vez implementa otras, esa clase tendrá definidas
cada una de las interfaces, lo mismo ocurre con una clase que "se derive" de otra clase
que implementa alguna interfaz, la nueva clase también incorporará esa interfaz.
Técnica de Programación Orientada a Objetos 346
Nota: Cuando una interfaz implementa otras interfaces, éstas no se pueden indicar mediante
Implements, en lugar de usar esa instrucción debemos usar Inherits.
Public Interface IPrueba2
Inherits IMostrar
Si en una clase implementamos una interfaz que a su vez implementa otras interfaces, esa
clase tendrá definiciones de todos los miembros de todas las interfaces, por ejemplo, si
tenemos la siguiente definición de la interfaz IPrueba2 que "implementa" la interfaz
IMostrar:
Public Interface IPrueba2
Inherits IMostrar
Function Saludo(ByVal nombre As String) As String
Property Nombre() As String
Event DatosCambiados()
End Interface
Y la clase Prueba2 implementa IPrueba2, la definición de los miembros quedaría de la
siguiente forma:
Public Class Prueba2
Implements IPrueba2
Public Sub Mostrar() Implements IMostrar.Mostrar
End Sub
Public Event DatosCambiados() Implements IPrueba2.DatosCambiados
Public Property Nombre() As String Implements IPrueba2.Nombre
Get
Técnica de Programación Orientada a Objetos 347
End Get
Set(ByVal value As String)
End Set
End Property
Public Function Saludo(ByVal nombre As String) As String _
Implements IPrueba2.Saludo
End Function
End Class
En este código, el método Mostrar se indica mediante la interfaz IMostrar, pero también se
puede hacer por medio de IPrueba2.Mostrar, ya que IPrueba2 también lo implementa (o
hereda).
Si dejamos que Visual Basic cree los miembros, no tendremos problemas a la hora de
definirlos. Pero si lo hacemos manualmente, aunque dentro del IDE de Visual Basic, éste
nos ayuda indicándonos que interfaces implementamos y qué miembros son los que se
adecuan a la declaración que estamos usando, tal como podemos comprobar en la figura
2.16:
Técnica de Programación Orientada a Objetos 348
Un ejemplo práctico usando una interfaz de .NET
Tal como comentamos al principio, el propio .NET está "plagado" de interfaces, cada una
de ellas tiene un fin concreto, por ejemplo, si queremos definir una clase que pueda ser
clasificada por el propio .NET, esa clase debe implementar la interfaz IComparable, ya que
el método Sort, (de la clase que contiene los elementos del tipo definido por nosotros), que
es el encargado de clasificar los elementos, hará una llamada al método
IComparable.CompareTo de cada uno de los objetos que queremos clasificar, por tanto, si
la clase no ha definido esa interfaz, no podremos clasificar los elementos que contenga.
En el siguiente código tenemos la definición de una clase llamada Empleado que
implementa la interfaz IComparable y en el método CompareTo hace la comprobación de
que objeto es mayor o menor, si el de la propia clase o el indicado en el parámetro de esa
función:
Public Class Empleado
Implements IComparable
Public Nombre As String
Public Sub New(ByVal nombre As String)
Me.Nombre = nombre
End Sub
' Si el objeto es del tipo Empleado, comparamos los nombres.
' Si no es del tipo Empleado, devolvemos un cero
' que significa que los dos objetos son iguales.
Public Function CompareTo(ByVal obj As Object) As Integer _
Implements System.IComparable.CompareTo
If TypeOf obj Is Empleado Then
Dim e1 As Empleado = CType(obj, Empleado)
Return String.Compare(Me.Nombre, e1.Nombre)
Else
Return 0
Técnica de Programación Orientada a Objetos 349
End If
End Function
End Class
En el método CompareTo hacemos una comprobación de que el objeto con el que
debemos realizar la comparación es del tipo Empleado, en ese caso convertimos el objeto
pasado en uno del tipo Empleado y comparamos los nombres.
Si el objeto que recibe el método no es del tipo Empleado, devolvemos un cero, para
indicar que no haga ninguna clasificación, ya que ese valor indica que los dos objetos son
iguales.
Esta comparación no es estrictamente necesaria, ya que si no indicamos el valor que debe
devolver una función, devolverá un valor cero, al menos en este caso, ya que el tipo a
devolver es un número entero.
Esta clase la podemos usar de esta forma:
' Una colección de datos del tipo Empleado.
Dim empleados As New System.Collections.Generic.List(Of Empleado)
' Añadimos varios empleados a la colección.
empleados.Add(New Empleado("Pepe"))
empleados.Add(New Empleado("Bernardo"))
empleados.Add(New Empleado("Juan"))
empleados.Add(New Empleado("Ana"))
' Clasificamos los empleados de la colección.
empleados.Sort()
' Mostramos los datos una vez clasificados.
For Each e1 As Empleado In empleados
Console.WriteLine(e1.Nombre)
Next
Técnica de Programación Orientada a Objetos 350
Contenido.
Manejo de Colecciones o Concepto de Colecciones. Tipos. o Agregar y remover ítems de una colección. o Recorrer los ítems de una colección.
Colecciones Especializadas: ArrayList, HashTable Interfaces
o IEnumerable e IEnumerator o ICloneable o IComparable
Las Colecciones
En el tema sobre arrays hemos comprobado cómo a través de la clase Array, podemos
manipular estos elementos del lenguaje con una mayor potencia y flexibilidad que en pasadas
versiones del lenguaje. No obstante, en muchas ocasiones nos encontraremos con situaciones
en las que sería muy de agradecer que los arrays dispusieran de algunas características
adicionales, dependiendo del problema que tengamos que resolver en ese preciso momento.
Por ejemplo, sería una gran idea poder manejar un array que creciera dinámicamente, sin tener
que preocuparnos por aumentar o disminuir su tamaño; o también, disponer de un array a
cuyos valores pudiéramos acceder, a través de identificadores claves, y no por el número de
índice, que en algunas situaciones es más incómodo de manejar.
Aun así no hay que preocuparse, ya que no va a necesitar escribir complicados algoritmos para
implementar estas características en sus arrays. Todas las funcionalidades mencionadas, y
algunas más, se encuentran disponibles en un tipo especial de array denominado colección
(collection).
Una colección es un objeto que internamente gestiona un array, pero que está preparado,
dependiendo del tipo de colección, para manejar el array que contiene de una manera especial;
podríamos definirlo como un array optimizado o especializado en ciertas tareas.
Técnica de Programación Orientada a Objetos 351
El espacio de nombres System.Collections
Este espacio de nombres del entorno de .NET Framework, es el encargado de agrupar el
conjunto de clases e interfaces que nos permiten la creación de los distintos tipos de objetos
collection. Por lo que si necesitamos un array con alguna característica especial, sólo hemos
de instanciar un objeto de alguna de las clases de este espacio de nombres para disponer de
un array con esa funcionalidad. Entre las clases más significativas de System.Collections,
podemos destacar las siguientes.
ArrayList. Proporciona una colección, cuyo array es redimensionado dinámicamente.
Hashtable. Las colecciones de este tipo, contienen un array cuyos elementos se basan en una combinación de clave y valor, de manera que el acceso a los valores se facilita, al realizarse mediante la clave.
SortedList. Consiste en una colección ordenada de claves y valores.
Queue. Representa una lista de valores, en el que el primer valor que entra, es el primero que sale.
Stack. Representa una lista de valores, en el que el último valor que entra, es el primero que sale.
Para hacer uso de colecciones en una aplicación VB.NET creada desde VS.NET, no es
necesario importar este espacio de nombres, ya que como habrá observado el lector en
ejemplos anteriores, el propio IDE incluye por defecto la importación del espacio System al
proyecto.
La clave se halla en los interfaces
Las clases integrantes de System.Collections implementan en mayor o menor grado, un
conjunto común de interfaces, que proporcionan la funcionalidad para el trabajo con arrays
especializados o colecciones. Entre alguno de los interfaces de Collections, podemos
mencionar los siguientes.
IEnumerable. Proporciona el soporte para recorrer colecciones de valores.
ICollection. Proporciona las características para manipular el tamaño, gestionar enumeradores, etc., de listas de valores.
IList. Referencia a una lista de valores que puede ordenarse.
ICloneable. Permite la creación de copias exactas e independientes de objetos.
Todo ello significa, que además de las clases con las funcionalidades especiales de
Collections, podemos crear nuestras propias clases, para aquellos casos en los que
necesitemos disponer de un array con funcionalidades especiales, no contempladas por los
arrays base, y que además tampoco exista como colección. La manera de crear nuestro propio
tipo de colección sería heredando de una clase collection existente y/o la implementación de
alguno de los interfaces de Collections.
Seguidamente realizaremos una descripción general y pruebas con algunas de las colecciones
existentes en el entorno, remitiendo al lector a la documentación de la plataforma accesible
desde Visual Studio .NET para los detalles más específicos.
Técnica de Programación Orientada a Objetos 352
La clase ArrayList
Los objetos de tipo colección creados con esta clase, implementan un array cuyo número de
elementos puede modificarse dinámicamente.
Instanciación de objetos ArrayList
Podemos instanciar una colección ArrayList en alguno los modos mostrados en el Código
fuente. Observe cómo en el último ejemplo de este fuente, el constructor de ArrayList recibe
como parámetro una colección dinámica.
Sub Main()
' crear una lista sin elementos
Dim alEstaciones As New ArrayList()
' crear una lista indicando el número de elementos
' pero sin darles valor
Dim alDatos As New ArrayList(3)
' crear una lista utilizando una colección dinámica
Dim alLetras As New ArrayList(New String() {"a", "b", "c"})
End Sub
Una colección dinámica se crea de forma muy similar a un array, con la diferencia de que no es
necesario usar una variable a la que asignar la colección, ya que en su lugar, se pasa como
parámetro al constructor de ArrayList. El modo de creación de una colección dinámica consiste
en utilizar la palabra clave New, seguida del tipo de dato de la colección, los paréntesis
indicativos de array, y por último, encerrados entre llaves, los valores de la colección.
Agregar valores a un ArrayList
Una vez creado un ArrayList, podemos utilizar algunos de los métodos indicados a
continuación para añadir valores a la colección.
Add(Valor). Añade el valor representado por Valor.
AddRange(Colección). Añade un conjunto de valores mediante un objeto del interfaz ICollection, es decir, una colección dinámica creada en tiempo de ejecución.
Insert(Posición, Valor). Inserta el valor Valor en la posición Posición del array, desplazando el resto de valores una posición adelante.
InsertRange(Posición, Colección). Inserta un conjunto de valores mediante una colección dinámica, a partir de una posición determinada dentro del array.
SetRange(Posición, Colección). Sobrescribe elementos en un array con los valores de la colección Colección, comenzando en la posición Posición.
Técnica de Programación Orientada a Objetos 353
El código fuente siguiente muestra algunos ejemplos de asignación de nuevos valores a un
ArrayList.
Sub Main()
Dim alDatos As New ArrayList(10)
alDatos.Add("a")
alDatos.AddRange(New String() {"b", "c", "d"})
Console.WriteLine("ArrayList después de usar Add() y AddRange()")
RecorrerAList(alDatos)
alDatos.Insert(2, "hola")
Console.WriteLine("ArrayList después de usar Insert()")
RecorrerAList(alDatos)
alDatos.InsertRange(1, New Integer() {55, 77, 88})
Console.WriteLine("ArrayList después de usar InsertRange()")
RecorrerAList(alDatos)
alDatos.SetRange(3, New String() {"zzz", "yyy"})
Console.WriteLine("ArrayList después de usar SetRange()")
RecorrerAList(alDatos)
Console.ReadLine()
End Sub
Private Sub RecorrerAList(ByVal alValores As ArrayList)
Dim oEnumerador As IEnumerator = alValores.GetEnumerator()
While oEnumerador.MoveNext()
Console.WriteLine("Valor: {0}", oEnumerador.Current)
End While
Console.WriteLine()
End Sub
Técnica de Programación Orientada a Objetos 354
Los valores que espera recibir una colección son del tipo genérico Object, por lo que podemos
insertar valores de diferentes tipos de dato.
Recorrer y obtener valores de un ArrayList
Para recorrer un array podemos emplear la técnica habitual del bucle For...Next y la propiedad
Count del objeto ArrayList, que devuelve el número de elementos que tiene el objeto; o bien
podemos usar un objeto del interfaz IEnumerator, proporcionado por el método
GetEnumerator(), mucho más simple de recorrer.
Sub Main()
' crear ArrayList y añadir valores
Dim alLetras As New ArrayList(6)
alLetras.Add("a")
alLetras.AddRange(New String() {"b", "c", "d"})
' recorrer con un bucle For y usando la propiedad Count,
' tener en cuenta que al ser cero el primer índice del array,
' tenemos que restar uno a la propiedad Count
Console.WriteLine("Recorrer objeto ArrayList con bucle For")
Dim iContador As Integer
For iContador = 0 To (alLetras.Count - 1)
Console.WriteLine("Elemento actual {0}, valor: {1}", _
iContador, alLetras(iContador))
Next
Console.WriteLine()
' recorrer el array con un enumerador
Console.WriteLine("Recorrer objeto ArrayList con un enumerador")
Dim oEnumerador As IEnumerator
oEnumerador = alLetras.GetEnumerator()
While oEnumerador.MoveNext()
Console.WriteLine("Elemento de la lista: {0}", oEnumerador.Current())
End While
Console.ReadLine()
End Sub
Técnica de Programación Orientada a Objetos 355
Capacidad y valores en una colección ArrayList
Cuando manipulamos un objeto ArrayList debemos distinguir entre los conceptos capacidad y
valores asignados. La capacidad de un ArrayList hace referencia al número de elementos del
array subyacente que contiene este objeto, mientras que los valores asignados se refieren a
aquellos elementos del array a los que se ha asignado valor mediante métodos como Add( ) o
AddRange( ). Podemos obtener esta información a través de las propiedades Capacity y Count
del objeto colección.
Console.WriteLine("Valores asignados al array: {0}", alLetras.Count)
Console.WriteLine("Capacidad del array: {0}", alLetras.Capacity)
La capacidad es un aspecto de la clase ArrayList que mejora el rendimiento a la hora de añadir
o eliminar elementos del array. Analicemos esta característica con más detenimiento. En primer
lugar, todo objeto ArrayList dispone de una propiedad oculta llamada _items, conteniendo el
array que internamente gestiona los valores asignados. Esta es una propiedad que no puede
manipular el programador, pero que puede visualizar a través del depurador, abriendo la
ventana Locales y expandiendo el contenido de un objeto ArrayList.
Cuando creamos un objeto ArrayList con un tamaño como el del último ejemplo, la acción de
añadir un valor a la colección no redimensiona su array subyacente, puesto que ya está creado
con un tamaño determinado, sino que asigna un valor al siguiente elemento libre que no
hubiera sido previamente asignado.
Técnica de Programación Orientada a Objetos 356
Este comportamiento del objeto tiene la ventaja de que mejora el rendimiento y optimiza
recursos, puesto que cada vez que añadimos o eliminamos valores, el array _items no siempre
tiene que ser redimensionado.
¿Qué sucede, sin embargo, cuando se han añadido valores y el array está completo?, pues
que el objeto ArrayList detecta esta situación y en la siguiente ocasión en que se añade un
nuevo valor, automáticamente redimensiona el array _items, duplicando el número de
elementos inicial que contenía.
En el caso que muestra la anterior figura, después de añadir la letra m al objeto, la propiedad
Capacity devolvería 12 y la propiedad Count devolvería 9.
Técnica de Programación Orientada a Objetos 357
Un detalle muy importante que debe tener en cuenta el lector, es que al crear un objeto
ArrayList, si no especificamos el tamaño, la propiedad _items tiene una capacidad por defecto
de 16 elementos.
Obtención de subarrays a partir de un objeto ArrayList
La clase ArrayList nos proporciona métodos tanto para obtener un fragmento o rango
(subarray) de un objeto ArrayList, como para crear nuevos objetos mediante métodos shared o
compartidos. Entre este tipo de métodos, se encuentran los siguientes.
GetRange(Posición, Elementos). Obtiene un subarray comenzando en el índice Posición, y tomando el número que indica Elementos.
FixedSize(ArrayList). Método compartido que crea un array de tamaño fijo a partir de un objeto ArrayList pasado como parámetro. Sobre el nuevo array obtenido, podemos modificar los elementos existentes, pero no añadir nuevos.
Repeat(Valor, Cantidad). Método compartido que crea un ArrayList de valores repetidos, tomando como valor a repetir el parámetro Valor, y creando tantos elementos como se especifica en el parámetro Cantidad.
ToArray(). Copia los elementos del ArrayList en un objeto Array, al ser ambos arrays independientes, el objeto sobre el que se han copiado los elementos puede modificarse sin que afecte al ArrayList.
ReadOnly( ). Método compartido que crea un objeto ArrayList de sólo lectura a partir de un array existente.
Sub Main()
Dim alLetras As New ArrayList(10)
alLetras.AddRange(New String() {"a", "b", "c", "d", "e", "f", "g"})
Console.WriteLine("Array alLetras")
RecorrerAList(alLetras)
' obtener un subarray con un rango determinado
Dim alRangoLetras As ArrayList
alRangoLetras = alLetras.GetRange(4, 2)
Console.WriteLine("Array alRangoLetras")
RecorrerAList(alRangoLetras)
' obtener un subarray de tamaño fijo,
' se pueden modificar sus elementos,
' no se pueden añadir valores
Dim alLetrasFijo As ArrayList = ArrayList.FixedSize(alLetras)
Técnica de Programación Orientada a Objetos 358
'alLetrasFijo.Add("m") <-- esto provocaría error
alLetrasFijo(2) = "vvv"
Console.WriteLine("Array alLetrasFijo")
RecorrerAList(alLetrasFijo)
' ArrayList de valores repetidos
Dim alRepetidos As ArrayList
alRepetidos = ArrayList.Repeat("hola", 3)
alRepetidos.Add("otro valor")
Console.WriteLine("Array alRepetidos")
RecorrerAList(alRepetidos)
' copiar ArrayList sobre un array normal
Dim aNuevo As Array
aNuevo = alLetras.ToArray()
aNuevo(2) = "zzz"
Console.WriteLine("Array aNuevo")
RecorrerArray(aNuevo)
' crear ArrayList de sólo lectura
' a partir de un array existente
Dim alLetrasSoloLeer As ArrayList = ArrayList.ReadOnly(alLetras)
' solamente podemos recorrerlo
Console.WriteLine("ArrayList de sólo lectura")
RecorrerAList(alLetrasSoloLeer)
' las dos líneas siguientes provocarían un error
'alLetrasSoloLeer.Add("yyy")
'alLetrasSoloLeer(2) = "wwer"
Console.ReadLine()
End Sub
Técnica de Programación Orientada a Objetos 359
Private Sub RecorrerAList(ByVal alValores As ArrayList)
Dim oEnumerador As IEnumerator = alValores.GetEnumerator()
While oEnumerador.MoveNext()
Console.WriteLine("Valor: {0}", oEnumerador.Current)
End While
Console.WriteLine()
End Sub
Private Sub RecorrerArray(ByVal aValores As Array)
Dim oEnumerador As IEnumerator = aValores.GetEnumerator()
While oEnumerador.MoveNext
Console.WriteLine("Valor: {0}", oEnumerador.Current)
End While
Console.WriteLine()
End Sub
Respecto a los ArrayList de tamaño fijo, tipo FixedSize, queremos advertir al lector que a la
hora de ver su contenido en el depurador, no debe consultar la propiedad _items mencionada
anteriormente, ya que esta contendrá un array de valores vacíos.
Este punto puede crear confusión, ya que el lector al ejecutar la aplicación sí obtendrá los
valores de la colección FixedSize, por lo que se preguntará dónde han ido a parar esos valores.
El secreto reside en el siguiente lugar: al ejecutar con el depurador, debemos expandir la
propiedad [System.Collections.ArrayList.FixedSizeArrayList] del ArrayList con tamaño fijo.
Dentro de esta propiedad, que es realmente una variante del objeto ArrayList, abriremos la
propiedad _list, y de nuevo dentro de esta propiedad encontraremos otra con el nombre _items,
la cual será la que contiene realmente los valores del array de tamaño fijo.
Técnica de Programación Orientada a Objetos 360
Búsquedas en colecciones ArrayList
Además de los métodos IndexOf( ) y LastIndexOf( ), disponibles en los arrays estándar, un
ArrayList aporta el método Contains( ), que nos devuelve un valor lógico indicando si el valor
pasado como parámetro existe en el array.
Sub Main()
Dim alLetras As New ArrayList(10)
alLetras.AddRange(New String() {"jj", "oo", "aa", _
"jj", "ee", "tt", "mm", "xx"})
Dim iPosicIndexOf As Integer
' buscar un elemento de la colección desde el principio
iPosicIndexOf = alLetras.IndexOf("aa")
Console.WriteLine("Posición al buscar con IndexOf: {0}", iPosicIndexOf)
Dim iPosicLastIndexOf As Integer
' buscar un elemento de la colección desde el final
iPosicLastIndexOf = alLetras.LastIndexOf("jj")
Console.WriteLine("Posición al buscar con LastIndexOf: {0}", _
iPosicLastIndexOf)
Dim bEncontrado As Boolean
' comprobar si existe un valor en la colección
bEncontrado = alLetras.Contains("oo")
Console.WriteLine("Resultado de la búsqueda con Contains: {0}", bEncontrado)
Console.ReadLine()
End Sub
Técnica de Programación Orientada a Objetos 361
Borrado de elementos en una colección ArrayList
Para realizar un borrado de valores, la clase ArrayList proporciona los métodos descritos a
continuación.
Remove(Valor). Elimina el elemento del array que corresponde a Valor.
RemoveAt(Posicion). Elimina el elemento del array situado en el índice Posición.
RemoveRange(Posición, Elementos). Elimina el conjunto de elementos indicados en el parámetro Elementos, comenzando por el índice Posición.
Clear( ). Elimina todos los elementos del objeto.
Debido a las causas de optimización en cuanto a ejecución comentadas en un apartado
anterior, al borrar elementos de un ArrayList, el valor de la propiedad Capacity permanece
inalterable. Eso quiere decir que si añadimos muchos valores a un ArrayList para después
eliminar gran parte de ellos, el array subyacente de la propiedad _items no disminuirá su
tamaño para ahorrar recursos. Esto no es algo preocupante sin embargo, puesto que si
utilizamos el método TrimToSize( ) de esta clase, conseguiremos que el tamaño o capacidad
del ArrayList se ajuste al número real de elementos que contiene.
Sub Main()
' borra todos los elementos
Dim alLetras1 As New ArrayList(10)
alLetras1.AddRange(New String() {"a", "b", "c", "d", "e", "f", "g"})
alLetras1.Clear()
Estado("alLetras1", alLetras1)
' borra un elemento por el valor
Dim alLetras2 As New ArrayList(10)
alLetras2.AddRange(New String() {"a", "b", "c", "d", "e", "f", "g"})
alLetras2.Remove("c")
Estado("alLetras2", alLetras2)
' borra un elemento por posición
Dim alLetras3 As New ArrayList(10)
alLetras3.AddRange(New String() {"a", "b", "c", "d", "e", "f", "g"})
alLetras3.RemoveAt(5)
Estado("alLetras3", alLetras3)
Técnica de Programación Orientada a Objetos 362
' borra un rango de elementos por posición
Dim alLetras4 As New ArrayList(10)
alLetras4.AddRange(New String() {"a", "b", "c", "d", "e", "f", "g"})
alLetras4.RemoveRange(2, 3)
Console.WriteLine("Array alLetras4: estado antes de reajustar tamaño")
Estado("alLetras4", alLetras4)
' reajustar capacidad del array
alLetras4.TrimToSize()
Console.WriteLine("Array alLetras4: estado después de reajustar tamaño")
Estado("alLetras4", alLetras4)
Console.ReadLine()
End Sub
Public Sub Estado(ByVal sNombre As String, ByVal alValores As ArrayList)
Console.WriteLine("Array: {0} / Capacidad: {1} / Número de elementos: {2}",
_sNombre, alValores.Capacity, alValores.Count)
Console.WriteLine()
End Sub
Ordenar elementos en un objeto ArrayList
Al igual que en la clase base Array, los objetos ArrayList disponen del método Sort( ), que
ordena los elementos del array; y del método Reverse( ), que invierte las posiciones de un
número determinado de elementos del array. El Código fuente 374 muestra un ejemplo de cada
uno.
Sub Main()
Dim alLetras As New ArrayList(10)
alLetras.AddRange(New String() {"z", "t", "c", "a", "k", "f", "m"})
' ordenar
alLetras.Sort()
Técnica de Programación Orientada a Objetos 363
Console.WriteLine("ArrayList después de ordenar")
RecorrerAList(alLetras)
' invertir posiciones de elementos
alLetras.Reverse(3, 3)
Console.WriteLine("ArrayList después de invertir elementos")
RecorrerAList(alLetras)
Console.ReadLine()
End Sub
Private Sub RecorrerAList(ByVal alValores As ArrayList)
Dim oEnumerador As IEnumerator = alValores.GetEnumerator()
While oEnumerador.MoveNext()
Console.WriteLine("Valor: {0}", oEnumerador.Current)
End While
Console.WriteLine()
End Sub
Técnica de Programación Orientada a Objetos 364
La clase Hashtable
Esta clase tiene la particularidad de que el acceso a los valores del array que gestiona
internamente se realiza a través de una clave asociada a cada elemento, al estilo de los
objetos Dictionary de versiones anteriores de VB. Como dato significativo, esta clase
implementa el interfaz IDictionary, por lo que si hemos utilizado anteriormente objetos
Dictionary, ya conocemos gran parte de su filosofía de trabajo.
En este tipo de colección no es necesario preocuparse por la posición o índice de los
elementos, ya que accedemos a ellos a través de literales, lo cual en algunas circunstancias es
mucho más cómodo de manejar.
Manejo básico de colecciones Hashtable
Supongamos como ejemplo, que un proceso en una aplicación necesita guardar de forma
temporal, datos de un cliente en un array. Podemos naturalmente utilizar un array estándar
para tal fin, como se muestra:
Dim aCliente = Array.CreateInstance(GetType(Object), 6)
aCliente(0) = 22
aCliente(1) = "Pedro"
aCliente(2) = "Naranjo"
aCliente(3) = "C/Rio Bravo, 25"
aCliente(4) = 35
aCliente(5) = 250
En un planteamiento como el anterior, debemos acordarnos, a la hora de obtener los datos del
array, que la primera posición corresponde al código de cliente, la siguiente al nombre, etc.,.
Bien es cierto que podemos utilizar constantes numéricas para cada posición, pero sigue
siendo una solución poco flexible.
Utilizando un objeto Hashtable sin embargo, tenemos la ventaja de que no necesitamos saber
la posición en que se encuentra cada valor, ya que precisamente a cada posición le damos un
nombre clave que es mediante el que accedemos posteriormente cuando queremos obtener
los valores.
Técnica de Programación Orientada a Objetos 365
Sub Main()
' declarar colección Hashtable
Dim htCliente As Hashtable
htCliente = New Hashtable()
' añadir valores
htCliente.Add("ID", 22)
htCliente.Add("Nombre", "Pedro")
htCliente.Add("Apellidos", "Naranjo")
htCliente.Add("Domicilio", "C/Rio Bravo, 25")
htCliente.Add("Edad", 35)
htCliente.Add("Credito", 250)
' mostrar el número de elementos que contiene
Console.WriteLine("El objeto Hashtable tiene {0} elementos", _
htCliente.Count)
Console.WriteLine()
' obtener algunos valores
Console.WriteLine("Obtener algunos valores del objeto Hashtable")
Console.WriteLine("Domicilio: {0} ", htCliente.Item("Domicilio"))
Console.WriteLine("Nombre: {0} ", htCliente("Nombre"))
Console.WriteLine("Credito: {0} ", htCliente("Credito"))
Console.WriteLine()
' recorrer el array al completo
Console.WriteLine("Recorrer objeto Hashtable con un enumerador")
Dim oEnumerador As IDictionaryEnumerator
oEnumerador = htCliente.GetEnumerator()
Técnica de Programación Orientada a Objetos 366
While oEnumerador.MoveNext()
Console.WriteLine("Clave: {0} / Valor: {1}", _
oEnumerador.Key, oEnumerador.Value)
End While
Console.ReadLine()
End Sub
Para crear un nuevo objeto Hashtable hemos utilizado el constructor sin parámetros, que es el
más básico disponible. Puesto que se trata de un constructor sobrecargado, sugerimos al lector
que consulte la documentación de .NET Framework para ver una lista completa de todos los
constructores disponibles.
Respecto a la asignación de valores a la colección, esta clase utiliza el método Add( ), cuyo
primer parámetro corresponde a la clave del elemento y el segundo corresponde al valor que
vamos a asignar a la posición de su array.
Para obtener un valor del array utilizamos el método Item( ), pasando como parámetro el
nombre de la clave de la que vamos a obtener el valor correspondiente. Al tratarse del método
por defecto de esta clase no es necesario especificarlo. Como hemos podido comprobar, el
resultado es el mismo tanto si especificamos como si no el nombre del método.
Si queremos recorrer el array al completo contenido en el objeto, podemos utilizar el método
GetEnumerator( ), que nos devuelve un enumerador para poder obtener todos los valores del
objeto en un bucle. La diferencia con los otros algoritmos de recorrido que hemos visto
anteriormente, es que al estar la colección Hashtable basada en una combinación de
clave/valor, necesitamos un enumerador basado en el interfaz IDictionaryEnumerator,
especialmente adaptado para manipular arrays de este tipo.
Como habrá comprobado el lector, un enumerador IDictionaryEnumerator proporciona la
información de la colección mediante las propiedades Key y Value, a diferencia de un
enumerador simple, basado en IEnumerator, en el que usamos la propiedad Current, para
extraer los datos. La clase Hashtable no sitúa los valores que se añaden al array en posiciones
consecutivas, por lo que al obtener los valores mediante un enumerador posiblemente no
aparecerán en el mismo orden en el que los añadimos inicialmente. Dada la filosofía de
funcionamiento de este tipo de objetos, el orden en el que se graban los valores dentro del
array no debería ser un problema, ya que nosotros accedemos al array utilizando claves y no
índices, como sucede en un array estándar.
Técnica de Programación Orientada a Objetos 367
Operaciones varias con colecciones Hashtable
Antes de obtener valores de un objeto Hashtable, podemos comprobar que la clave o valor que
necesitamos están realmente en la colección, empleando respectivamente los métodos
ContainsKey( ) y ContainsValue( ). Al primero le pasamos como parámetro la clave a buscar,
mientras que al segundo le pasamos el valor. Ambos métodos devuelven un resultado de tipo
Boolean, que indica si la comprobación tuvo o no éxito.
Por otra parte, el método Remove( ), elimina un elemento del objeto, pasándole como
parámetro la clave a borrar, mientras que el método Clear( ), elimina el contenido completo de
la colección.
Sub Main()
' crear colección Hashtable y añadir valores
Dim htCliente As New Hashtable()
htCliente.Add("ID", 22)
htCliente.Add("Nombre", "Pedro")
htCliente.Add("Apellidos", "Naranjo")
htCliente.Add("Domicilio", "C/Rio Bravo, 25")
htCliente.Add("Edad", 35)
htCliente.Add("Credito", 250)
' comprobar la existencia de elementos por la clave
Dim sClave As String
Console.WriteLine("Introducir la clave a buscar")
sClave = Console.ReadLine()
If htCliente.ContainsKey(sClave) Then
Console.WriteLine("La clave {0} existe, su valor es: {1}", _
sClave, htCliente(sClave))
Else
Console.WriteLine("La clave {0} no existe", sClave)
End If
Console.WriteLine()
Técnica de Programación Orientada a Objetos 368
' comprobar la existencia de elementos por el valor
Dim oValor As Object
Console.WriteLine("Introducir el valor a buscar")
oValor = Console.ReadLine()
' antes de comprobar si existe el valor
' debemos hacer una conversión al tipo
' específico de dato del contenido de
' la variable oValor
If IsNumeric(oValor) Then
oValor = CType(oValor, Integer)
Else
oValor = CType(oValor, String)
End If
' ahora comprobamos
If htCliente.ContainsValue(oValor) Then
Console.WriteLine("El valor {0} existe", oValor)
Else
Console.WriteLine("El valor {0} no existe", oValor)
End If
' para borrar un elemento se usa la clave
htCliente.Remove("Nombre")
Console.WriteLine()
RecorrerHT(htCliente)
' ahora borramos el contenido al completo del objeto
htCliente.Clear()
Console.ReadLine()
End Sub
Técnica de Programación Orientada a Objetos 369
Public Sub RecorrerHT(ByVal htTabla As Hashtable)
Dim oEnumerador As IDictionaryEnumerator
oEnumerador = htTabla.GetEnumerator()
While oEnumerador.MoveNext()
Console.WriteLine("Clave: {0} / Valor: {1}", _
oEnumerador.Key, oEnumerador.Value)
End While
End Sub
Las propiedades Keys y Values de la clase Hashtable, devuelven un array con los nombres de
las claves y los valores de un objeto Hashtable respectivamente. Realmente devuelven un
objeto del interfaz ICollection, pero ya que un array implementa este interfaz, dicho objeto
podemos manipularlo como un array.
Observar que el modo de declarar y obtener los objetos ICollection e IEnumerator, que en
definitiva, nos llevan al mismo resultado, demostrando así, la gran flexibilidad sintáctica que la
especificación CLS proporciona al lenguaje.
Sub Main()
' crear y llenar la colección
Dim htCliente As New Hashtable()
htCliente.Add("ID", 22)
htCliente.Add("Nombre", "Pedro")
htCliente.Add("Apellidos", "Naranjo")
htCliente.Add("Domicilio", "C/Rio Bravo, 25")
htCliente.Add("Edad", 35)
htCliente.Add("Credito", 250)
' obtener un array con las claves,
' y recorrer con un enumerador
Dim aClaves As ICollection
aClaves = htCliente.Keys
Técnica de Programación Orientada a Objetos 370
Dim oEnumerador As IEnumerator
oEnumerador = aClaves.GetEnumerator()
Console.WriteLine("Claves del objeto Hashtable")
RecorrerEnumerador(oEnumerador)
' obtener un array con los valores,
' y recorrer con un enumerador
Dim aValores As ICollection = htCliente.Values
Dim oEnumVal As IEnumerator = aValores.GetEnumerator()
Console.WriteLine("Valores del objeto Hashtable")
RecorrerEnumerador(oEnumVal)
Console.ReadLine()
End Sub
Public Sub RecorrerEnumerador(ByVal oEnumerador As IEnumerator)
While oEnumerador.MoveNext
Console.WriteLine(oEnumerador.Current)
End While
Console.WriteLine()
End Sub
Traspaso de elementos desde una colección Hashtable a un array
básico
El método CopyTo( ) de la clase Hashtable, se encarga de traspasar a un array
estándar un determinado número de elementos desde un objeto Hashtable. Como ya
sablemos, cada elemento de una colección de este tipo está formado realmente por
dos componentes, clave y valor; por ello, cabe preguntarse cómo se las ingenia esta
clase para poder traspasarlos a un array normal.
La respuesta es la siguiente: lo que realmente se traspasa al array normal no son
valores independientes, sino una estructura de tipo DictionaryEntry, cuyas propiedades
son precisamente Key y Value, es decir, la clave y valor del elemento de la colección.
Técnica de Programación Orientada a Objetos 371
El código siguiente muestra un ejemplo, en el cual, después de crear un objeto Hashtable con
sus correspondientes valores, creamos un array normal de tipo Object al que traspasamos los
elementos desde el Hashtable.
Sub Main()
' crear un array Hashtable
Dim htCliente As New Hashtable()
htCliente.Add("ID", 22)
htCliente.Add("Nombre", "Pedro")
htCliente.Add("Apellidos", "Naranjo")
htCliente.Add("Domicilio", "C/Rio Bravo, 25")
htCliente.Add("Edad", 35)
htCliente.Add("Credito", 250)
' crear un array estándar
Dim aDeposito(10) As Object
aDeposito(0) = "aaa"
aDeposito(1) = "bbb"
aDeposito(2) = "ccc"
aDeposito(3) = "ddd"
' volcar elementos del Hashtable al array estándar,
' comenzando a copiar desde una posición determinada
' del array estándar
htCliente.CopyTo(aDeposito, 2)
' obtener algunos valores del objeto Hashtable
' que se han pasado al array normal
Dim oEntradaDicc As DictionaryEntry
Dim iContador As Integer
For iContador = 3 To 6
oEntradaDicc = aDeposito(iContador)
Técnica de Programación Orientada a Objetos 372
Console.WriteLine("Clave: {0} / Valor: {1}", _
oEntradaDicc.Key, oEntradaDicc.Value)
Next
Console.ReadLine()
End Sub
Como el array normal tenía valores asignados previamente, algunos de ellos se pierden,
puesto que el método CopyTo( ) no redimensiona el array normal. Tenga este hecho en cuenta
el lector, ya que el array destino deberá tener el suficiente tamaño cuando traspasamos valores
desde una colección de este tipo.
Técnica de Programación Orientada a Objetos 373
Aplicaciones
Este laboratorio pretende enseñar como se trabajan con componentes en Visual Basic .NET,
primero se verá un laboratorio de cómo crear una librería de clases y luego veremos como
trabajar con herencia de clases..
Ejercicio 1: Creando y Usando una Librería de Clases
Se va a construír una librería que permita manejar el inventario de productos en almacen y
realizar un mantenimiento de estos. Para esto realizar los siguientes pasos:
Elegir un nuevo proyecto “Visual Basic” y una plantilla “Class Library”, seleccionar en ubicación la carpeta “C:\VBNET\Labs” y como nombre escribir “Libreria_Clases”.
Escribir “Producto” como nombre físico y lógico de la clase:
Public Class Producto
End Class
Creando propiedades para la clase producto:
Private mvarCodigo As String
Private mvarNombre As String
Private mvarPrecio As Single
Private mvarStock As Integer
Public Property Codigo() As String
Get
Codigo = mvarCodigo
End Get
Set(ByVal Value As String)
mvarCodigo = Value
Técnica de Programación Orientada a Objetos 374
End Set
End Property
Public Property Nombre() As String
Get
Nombre = mvarNombre
End Get
Set(ByVal Value As String)
mvarNombre = Value
End Set
End Property
Public Property Precio() As Single
Get
Precio = mvarPrecio
End Get
Set(ByVal Value As Single)
mvarPrecio = Value
End Set
End Property
Public Property Stock() As Integer
Get
Stock = mvarStock
End Get
Set(ByVal Value As Integer)
mvarStock = Value
Técnica de Programación Orientada a Objetos 375
End Set
End Property
Creando métodos para la clase producto:
Public Sub CrearProducto(ByVal vCodigo As String, ByVal vNombre
As String, ByVal vPrecio As Single, ByVal vStock As Integer)
mvarCodigo = vCodigo
mvarNombre = vNombre
mvarPrecio = vPrecio
mvarStock = vStock
End Sub
Public Sub ActualizarPrecio(ByVal vOperacionPrecio As Byte,
ByVal vTasa As Single)
If vOperacionPrecio = 1 Then
mvarPrecio = (1 + (vTasa / 100)) * mvarPrecio
ElseIf vOperacionPrecio = 2 Then
mvarPrecio = (1 - (vTasa / 100)) * mvarPrecio
End If
End Sub
Técnica de Programación Orientada a Objetos 376
Public Sub ActualizarStock(ByVal vOperacionStock As Byte,
ByVal vCantidad As Integer)
If vOperacionStock = 1 Then
mvarStock = mvarStock + vCantidad
ElseIf vOperacionStock = 2 Then
mvarStock = mvarStock - vCantidad
End If
End Sub
Luego, añadimos una aplicación para Windows que permita realizar el mantenimiento de productos usando la librería creada.
Del menú “File” elegimos “Add Project”, y seleccionamos “New Project”. Elegimos una “Aplicación para Windows” y le damos el nombre de “Prueba_Libreria_Clases”.
Configuramos para que la aplicación sea la que inicia, dando clic derecho al nombre en la ventana del “Solution Explorer” y eligiendo “Set as StartUp Project”.
Diseñamos un formulario llamado “frmProducto” que tenga un “TabControl” con 3 fichas, una de ingreso de productos, otra de actualización de precios y stock y otra de consulta, diseñadas tal como muestran las figuras de abajo:
Técnica de Programación Orientada a Objetos 377
Ficha “Ingreso” del formulario “frmProducto”
Ficha “Actualizacion” del formulario “frmProducto”
Técnica de Programación Orientada a Objetos 378
Ficha “Consulta” del formulario “frmProducto”
Después de realizar el diseño y antes de escribir código, para usar la librería primero debemos hacer una referencia a ésta.
Del menú “Project” elegir “Add Reference...”, seleccionar la ficha “Projects”, elegir la librería creada y clic en “Select”, luego “OK”.
Declarar e inicializar una variable objeto de tipo de la clase producto, tal como sigue:
Private objProducto As New Libreria_Clases.Producto()
Programando en el botón de crear producto:
Técnica de Programación Orientada a Objetos 379
Private Sub btnCrear_Click(…) Handles btnCrear.Click
objProducto.CrearProducto(txtCodigo_Ing.Text, _
txtNombre_Ing.Text, Convert.ToSingle(txtPrecio_Ing.Text), _
Convert.ToInt16(txtStock_Ing.Text))
txtCodigo_Ing.Clear()
txtNombre_Ing.Clear()
txtPrecio_Ing.Clear()
txtStock_Ing.Clear()
End Sub
Programando los botones de actualizar precio y stock del producto:
Private Sub btnActualizarPrecio_Click(…) Handles ...
If rbnPrecioAumento.Checked = True Then
objProducto.ActualizarPrecio(1,
Convert.ToSingle(txtTasa.Text))
ElseIf rbnPrecioDisminucion.Checked = True Then
objProducto.ActualizarPrecio(2,
Convert.ToSingle(txtTasa.Text))
End If
txtTasa.Clear()
End Sub
Técnica de Programación Orientada a Objetos 380
Private Sub btnStock_Click(…) Handles btnStock.Click
If rbnStockAumento.Checked = True Then
objProducto.ActualizarStock(1,
Convert.ToInt16(txtCantidad.Text))
ElseIf rbnStockDisminucion.Checked = True Then
objProducto.ActualizarStock(2,
Convert.ToInt16(txtCantidad.Text))
End If
txtCantidad.Clear()
End Sub
Finalmente, mostrando los datos del producto:
Private Sub btnMostrar_Click(…) Handles btnMostrar.Click
With objProducto
txtCodigo_Con.Text = .Codigo
txtNombre_Con.Text = .Nombre
txtPrecio_Con.Text = .Precio.ToString
txtStock_Con.Text = .Stock.ToString
End With
End Sub
Técnica de Programación Orientada a Objetos 381
Ejercicio 2: Trabajando con Herencia de Clases
En este laboratorio vamos a construír una librería de clases para un Instituto Superior
Tecnológico que permita matricular a los alumnos en un cierto curso libre dictado por un cierto
profesor. Para lo cual realizamos los siguientes pasos:
Elegir un nuevo proyecto “Visual Basic” y una plantilla “Class Library”, seleccionar en ubicación la carpeta “C:\VBNET\Labs” y como nombre escribir “Libreria_Herencia”.
Crear la clase “Persona”, modificando el nombre de la clase “Class1” por el de “Persona”, tanto física como lógicamente; luego escribir código para crear las propiedades: nombre, fechanac, edad y direccion; y el método crearpersona:
Public Class Persona
Private mvarNombre As String
Private mvarFechaNac As Date
Private mvarEdad As Byte
Private mvarDireccion As String
Property Nombre() As String
Get
Nombre = mvarNombre
End Get
Set(ByVal Value As String)
mvarNombre = Value
End Set
End Property
Property FechaNac() As Date
Get
FechaNac = mvarFechaNac
End Get
Técnica de Programación Orientada a Objetos 382
Set(ByVal Value As Date)
mvarFechaNac = Value
End Set
End Property
ReadOnly Property Edad() As Byte
Get
Edad = mvarEdad
End Get
End Property
Property Direccion() As String
Get
Direccion = mvarDireccion
End Get
Set(ByVal Value As String)
mvarDireccion = Value
End Set
End Property
Sub CrearPersona(ByVal vNombre As String, _
ByVal vFechaNac As Date, ByVal vDireccion As String)
mvarNombre = vNombre
mvarFechaNac = vFechaNac
mvarDireccion = vDireccion
mvarEdad = Convert.ToByte(Date.Today.Year-vFechaNac.Year)
End Sub
End Class
Técnica de Programación Orientada a Objetos 383
Crear la clase “Alumno” que hereda de “Persona”, para lo cual añadimos una clase al componente; del menú “Project” elegimos “Add Class...” y escribimos como nombre “Persona.vb” y “Open”. Luego escribimos el siguiente código:
Public Class Alumno
Inherits Persona
Private mvarCodigo As String
Private mvarEspecialidad As String
Property Codigo() As String
Get
Codigo = mvarCodigo
End Get
Set(ByVal Value As String)
mvarCodigo = Value
End Set
End Property
Property Especialidad() As String
Get
Especialidad = mvarEspecialidad
End Get
Set(ByVal Value As String)
mvarEspecialidad = Value
End Set
End Property
Sub CrearAlumno(ByVal vNombre As String, _
ByVal vFechaNac As Date, ByVal vDireccion As String, _
ByVal vCodigo As String, ByVal vEspecialidad As String)
Técnica de Programación Orientada a Objetos 384
CrearPersona(vNombre, vFechaNac, vDireccion)
mvarCodigo = vCodigo
mvarEspecialidad = vEspecialidad
End Sub
End Class
Crear la clase “Profesor” que también hereda de “Persona”, para lo cual añadimos una clase al componente; del menú “Project” elegimos “Add Class...” y escribimos como nombre “Profesor.vb” y “Open”. Luego escribimos el siguiente código:
Public Class Profesor
Inherits Persona
Private mvarCodigo As String
Private mvarTipo As String
Property Codigo() As String
Get
Codigo = mvarCodigo
End Get
Set
mvarCodigo = Value
End Set
End Property
Property Tipo() As String
Get
Tipo = mvarTipo
End Get
Set
mvarTipo = Value
End Set
Técnica de Programación Orientada a Objetos 385
End Property
Sub CrearProfesor(ByVal vNombre As String, _
ByVal vFechaNac As Date, ByVal vDireccion As String, _
ByVal vCodigo As String, ByVal vTipo As String)
CrearPersona(vNombre, vFechaNac, vDireccion)
mvarCodigo = vCodigo
mvarTipo = vTipo
End Sub
End Class
Finalmente, crear la clase “Curso”, para lo cual añadimos una clase al componente; del menú “Project” elegimos “Add Class...” y escribimos como nombre “Curso.vb” y “Open”. Luego escribimos el siguiente código:
Public Class Curso
Private mvarCodigo As String
Private mvarNombre As String
Private mvarTotalHoras As Byte
Private mvarCostoTotal As Single
Private mvarCostoHora As Single
Property Codigo() As String
Get
Codigo = mvarCodigo
End Get
Set(ByVal Value As String)
mvarCodigo = Value
End Set
End Property
Property Nombre() As String
Técnica de Programación Orientada a Objetos 386
Get
Nombre = mvarNombre
End Get
Set(ByVal Value As String)
mvarNombre = Value
End Set
End Property
Property TotalHoras() As Byte
Get
TotalHoras = mvarTotalHoras
End Get
Set(ByVal Value As Byte)
mvarTotalHoras = Value
End Set
End Property
Property CostoTotal() As Single
Get
CostoTotal = mvarCostoTotal
End Get
Set(ByVal Value As Single)
mvarCostoTotal = Value
End Set
End Property
ReadOnly Property CostoHora() As Single
Get
CostoHora = mvarCostoHora
End Get
End Property
Técnica de Programación Orientada a Objetos 387
Sub CrearCurso(ByVal vCodigo As String, _
ByVal vNombre As String, ByVal vTotalHoras As Byte, _
ByVal vCostoTotal As Single)
mvarCodigo = vCodigo
mvarNombre = vNombre
mvarTotalHoras = vTotalHoras
mvarCostoTotal = vCostoTotal
mvarCostoHora = mvarCostoTotal / mvarTotalHoras
End Sub
End Class
Para probar la librería de clase añadimos un proyecto a la solución, del menú “File”, elegimos “Add Project” y luego “New Project...”, seleccionando una aplicación para Windows a la cual llamaremos “Prueba_Libreria_Herencia”.
La aplicación tendrá un formulario llamado “frmMatricula” con 3 fichas, donde se realizarán el ingreso de datos del alumno, el curso y el profesor para la matrícula, tal como se muestran en las figuras de abajo.
Ficha “Alumno” del formulario “frmMatricula”
Técnica de Programación Orientada a Objetos 388
Ficha “Curso” del formulario “frmMatricula”
Ficha “Profesor” del formulario “frmMatricula”
Lo primero que tenemos que hacer para probar la librería en la aplicación es hacer una referencia a esta, eligiendo del menú “Project”, “Add References...”, seleccionar la ficha “Projects” y elegir la librería, clic en “Select” y “OK”.
Para que la aplicación Windows que vamos a crear sea la que se ejecute dar clic derecho al nombre del proyecto en la ventana del “Solution Explorer” y elegir “Set as StartUp Project”.
En las declaraciones generales definimos variables objetos para manipular datos del alumno, curso y el profesor, así como una rutina que permita limpiar textos.
Private objAlumno As New Libreria_Herencia.Alumno()
Técnica de Programación Orientada a Objetos 389
Private objCurso As New Libreria_Herencia.Curso()
Private objProfesor As New Libreria_Herencia.Profesor()
Sub LimpiarTextos()
txtAlumno_Codigo.Clear()
txtAlumno_Nombre.Clear()
txtAlumno_FechaNac.Clear()
txtAlumno_Direccion.Clear()
txtAlumno_Edad.Clear()
txtAlumno_Especialidad.Clear()
txtCurso_Codigo.Clear()
txtCurso_Nombre.Clear()
txtCurso_TotalHoras.Clear()
txtCurso_CostoTotal.Clear()
txtCurso_CostoHora.Clear()
txtProfesor_Codigo.Clear()
txtProfesor_Nombre.Clear()
txtProfesor_FechaNac.Clear()
txtProfesor_Direccion.Clear()
txtProfesor_Edad.Clear()
txtProfesor_Tipo.Clear()
End Sub
Programamos el botón “Matricular” para que guarde los datos de los objetos creados anteriormente.
Private Sub btnMatricular_Click(…) Handles btnMatricular.Click
objAlumno.CrearAlumno(txtAlumno_Nombre.Text, _
Convert.ToDateTime(txtAlumno_FechaNac.Text), _
txtAlumno_Direccion.Text, txtAlumno_Codigo.Text, _
txtAlumno_Especialidad.Text)
objCurso.CrearCurso(txtCurso_Codigo.Text, _
Técnica de Programación Orientada a Objetos 390
txtCurso_Nombre.Text, _
Convert.ToByte(txtCurso_TotalHoras.Text), _
Convert.ToSingle(txtCurso_CostoTotal.Text))
objProfesor.CrearProfesor(txtProfesor_Nombre.Text, _
Convert.ToDateTime(txtProfesor_FechaNac.Text), _
txtProfesor_Direccion.Text, _
txtProfesor_Codigo.Text, txtProfesor_Tipo.Text)
LimpiarTextos()
End Sub
Escribimos código en el botón “Consultar” para mostrar los datos almacenados en los objetos.
Private Sub btnConsultar_Click(…) Handles btnConsultar.Click
With objAlumno
txtAlumno_Codigo.Text = .Codigo
txtAlumno_Nombre.Text = .Nombre
txtAlumno_FechaNac.Text=Format(.FechaNac, "dd/MM/yyyy")
txtAlumno_Direccion.Text = .Direccion
txtAlumno_Edad.Text = .Edad.ToString
txtAlumno_Especialidad.Text = .Especialidad
End With
With objCurso
txtCurso_Codigo.Text = .Codigo
txtCurso_Nombre.Text = .Nombre
txtCurso_TotalHoras.Text = .TotalHoras.ToString
txtCurso_CostoTotal.Text = .CostoTotal.ToString
txtCurso_CostoHora.Text = .CostoHora.ToString
End With
With objProfesor
Técnica de Programación Orientada a Objetos 391
txtProfesor_Codigo.Text = .Codigo
txtProfesor_Nombre.Text = .Nombre
txtProfesor_FechaNac.Text=Format(.FechaNac, "dd/MM/yyyy")
txtProfesor_Direccion.Text = .Direccion
txtProfesor_Edad.Text = .Edad.ToString
txtProfesor_Tipo.Text = .Tipo
End With
End Sub
Finalmente, programamos el botón de “Salir” de la aplicación.
Private Sub btnSalir_Click(…) Handles btnSalir.Click
Me.Close()
End Sub
Técnica de Programación Orientada a Objetos 392
Contenido.
Clases del File System (Sistema de Archivos) o Clase FileSystemInfo o Clase FileInfo o Clase DirectoryInfo o Clase DriveInfo o Enumerando los Drives: uso de la enumeración Drivetype o Clase Path. Cambiando la extensión de un archivo.
Acceso al Sistema de Archivos
Empezaremos viendo las las clases elementales o más usadas para manejar el sistema de
archivos desde .NET.
El espacio de nombres System.IO es el que contiene todas las clases relacionadas con los
ficheros y directorios, en ese mismo espacio de nombres están las clases dedicada a los
streams de .NET, ya que al fin y al cabo, cuando tratamos con los ficheros, estaremos tratando
con una secuencia de caracteres o bytes, secuencia a la que accederemos con las clases
especializadas.
Aquí nos centraremos principalmente en la forma de acceder a esos ficheros, a copiarlos, a
comprobar si existen, etc., en definitiva: a manipularlos.
Las clases del espacio de nombres System.IO
Entre las clases que nos podemos encontrar en este espacio de nombres, tenemos clases que
podemos agrupar dependiendo de las tareas que podemos hacer con ellas en:
o Las clases para manipular las unidades, directorios y ficheros o Las clases para crear streams
Técnica de Programación Orientada a Objetos 393
o Las clases para leer o escribir en los streams
Veamos primero una relación de esas clases y enumeraciones y después veremos algunas de
ellas con más detalle.
Clases para manipular unidades, directorios y ficheros
Entre las clases que nos permiten trabajar con los ficheros, directorios y las unidades de disco,
podemos destacar las siguientes:
o Directory, proporciona métodos estáticos para crear, mover y enumerar los ficheros de directorios y subdirectorios.
o DirectoryInfo, al igual que la clase Directory, pero los métodos son de instancia, dicha instancia se creará a partir de un directorio determinado.
o DriveInfo, proporciona métodos de instancia para crear, mover y enumerar el
contenido de unidades.
o File, proporciona métodos estáticos para crear, copiar, eliminar, mover y abrir ficheros, además de ayudar a la creación de objetos FileStream.
o FileInfo, igual que la clase File, pero los métodos son de instancia, dicha instancia se creará a partir de un fichero determinado.
o Path, proporciona métodos y propiedades para procesar cadenas relacionadas con los directorios.
También tenemos las siguientes enumeraciones:
o FileAccess, define constantes para el tipo de acceso a los ficheros: lectura, escritura o lectura/escritura.
o FileAttributes, define constantes para el atributo de los ficheros y directorios: archivo, oculto, solo lectura, etc.
o FileMode, define las constantes que podemos usar para controlar como abrimos un fichero.
o FileShare, define las constantes para controlar el tipo de acceso que otros objetos FileStream pueden tener al mismo fichero.
Técnica de Programación Orientada a Objetos 394
Clases para manipular unidades, directorios y ficheros
Entre las clases que nos permiten trabajar con los ficheros, directorios y las unidades de disco,
podemos destacar las siguientes:
o Directory, proporciona métodos estáticos para crear, mover y enumerar los ficheros de directorios y subdirectorios.
o DirectoryInfo, al igual que la clase Directory, pero los métodos son de instancia, dicha instancia se creará a partir de un directorio determinado.
o DriveInfo, proporciona métodos de instancia para crear, mover y enumerar el contenido de unidades.
o File, proporciona métodos estáticos para crear, copiar, eliminar, mover y abrir ficheros, además de ayudar a la creación de objetos FileStream.
o FileInfo, igual que la clase File, pero los métodos son de instancia, dicha instancia se creará a partir de un fichero determinado.
o Path, proporciona métodos y propiedades para procesar cadenas relacionadas con los directorios.
También tenemos las siguientes enumeraciones:
o FileAccess, define constantes para el tipo de acceso a los ficheros: lectura, escritura o lectura/escritura.
o FileAttributes, define constantes para el atributo de los ficheros y directorios: archivo, oculto, solo lectura, etc.
o FileMode, define las constantes que podemos usar para controlar como abrimos un fichero.
o FileShare, define las constantes para controlar el tipo de acceso que otros objetos FileStream pueden tener al mismo fichero.
Las clases Directory y DirectoryInfo
Técnica de Programación Orientada a Objetos 395
Cuando necesitemos acceder a un directorio, por ejemplo, para saber que subdirectorios y
ficheros contiene o para obtener otro tipo de información, incluso para saber si existe o no, en
esos casos podemos utilizar las clases Directory o DirectoryInfo.
La primera de ellas: Directory, proporciona métodos estáticos, es decir, los métodos que
contienen siempre estarán disponibles sin necesidad de crear una nueva instancia de la clase.
Por tanto, podremos usar esos métodos simplemente usando la propia clase.
La segunda: DirectoryInfo, proporciona los mismos métodos que Directory, pero en lugar de
ser métodos estáticos, son métodos de instancia, es decir, esos métodos solamente se podrán
usar después de haber creado una instancia (u objeto en memoria) de esta clase.
Cada una de las instancias de DirectoryInfo, hará referencia a un directorio en particular, ese
directorio se indicará al crear el objeto, aunque también puede ser que esté referenciado al
obtenerlo mediante otros métodos que devuelven este tipo de objetos.
Nota:
El directorio asignado al crear la instancia de DirectoryInfo no tiene porqué existir.
De esa forma podemos comprobar si existe, y en caso de que no exista, crearlo, etc.
Por ejemplo, si queremos saber si un directorio existe, utilizaremos el método Exists, en el caso
de la clase Directory, como parámetro le indicaremos el directorio del que queremos comprobar
su existencia, sin embargo, si usamos un objeto del tipo DirectoryInfo, no necesitamos indicar
ningún parámetro, ya que el directorio que está asociado con esa clase lo habremos indicado al
crear el objeto.
En el siguiente código vemos cómo usar estas dos clases:
Const dir1 As String = "E:\Pruebas" Const dir2 As String = "E:\Pruebas2" Sub Main() claseDirectory() Console.WriteLine() claseDirectoryInfo() Console.WriteLine() ' Console.ReadLine() End Sub Sub claseDirectory() ' Los métodos de la clase Directory son estáticos, ' por tanto no necesitamos crear una instancia de esta clase ' ' Comprobar si existe un directorio: If System.IO.Directory.Exists(dir1) Then
Técnica de Programación Orientada a Objetos 396
Console.WriteLine("El directorio '{0}' SI existe", dir1) Else Console.WriteLine("El directorio '{0}' NO existe", dir1) End If End Sub Sub claseDirectoryInfo() ' Los métodos de la clase DirectoryInfo son de instancia, ' por tanto tenemos que crear una instancia de la clase ' para poder usarla ' Dim di As New System.IO.DirectoryInfo(dir2) ' ' Comprobar si existe un directorio: If di.Exists Then Console.WriteLine("El directorio '{0}' SI existe", dir2) Else Console.WriteLine("El directorio '{0}' NO existe", dir2) End If End Sub
El resto de métodos de estas dos clases funcionan de forma similar, al menos en el sentido de
que si usamos la clase Directory, siempre habrá un parámetro que haga referencia al directorio
que queremos usar, mientras que con DirectoryInfo siempre estará haciendo referencia al
directorio usado al crear la instancia.
Nota:
No queremos parecer repetitivos, pero nos interesa que quede claro como funcionan este tipo
de clases, que por otro lado, será similar al de las clases File y FileInfo, al menos en el sentido
de que la clase con los métodos estáticos siempre necesitará saber a que elemento del
sistema de archivos estamos refiriéndonos, mientras que las clases que debemos instanciar,
siempre sabrán con que elemento trabajarán.
Los métodos de las clases Directory y DirectoryInfo
Estas clases siempre manejarán directorios y entre los métodos que podemos utilizar,
destacamos los siguientes, empezamos por la clase Directory:
o CreateDirectory, crear los directorios indicados en el parámetro. Si algunos de los directorios intermedios no existen, los creará.
o Exists, comprueba si el directorio indicado existe.
o GetCurrentDirectory, devuelve el directorio de trabajo de la aplicación.
o GetDirectories, devuelve un array de String con todos los subdirectorios del directorio indicado. Se puede indicar un "pattern" de búsqueda y si queremos incluir los subdirectorios que tenga el directorio indicado.
Técnica de Programación Orientada a Objetos 397
o GetDirectoryRoot, devuelve el directorio raíz del directorio indicado.
o GetFiles, devuelve un array de tipo String con los ficheros del directorio indicado. Se puede indicar un filtro de búsqueda.
o GetLogicalDrives, devuelve un array con los nombres de las unidades lógicas en el formato: "<letra>:\".
Como hemos comentado, la clase DirectoryInfo siempre hará referencia al directorio utilizado
para instanciarla, por tanto algunos de los métodos de la clase Directory se convierten en
propiedades de esta clase y otros cambian de nombre para adecuarlos mejor a la acción a
realizar con ellos.
Por ejemplo, en la clase Directory tenemos el método Exists, que en DirectoryInfo es una
propiedad. De igual forma, el método Move de la clase Directory es el método MoveTo de
DirectoryInfo.
En cuanto a los métodos de Directory para obtener o asignar la fecha de creación, acceso, etc.,
en DirectoryInfo son propiedades de lectura/escritura.
Dicho esto, no vamos a relacionar todos estos miembros de DirectoryInfo, ya que en la
documentación están bien detallados y no nos resultará difícil de saber cómo usarlos.
Lo que si queremos resaltar es que algunos de los métodos de la clase DirectoryInfo,
concretamente GetDirectories y GetFiles, no devuelven un array de tipo String, sino un array de
objetos DirectoryInfo o FileInfo respectivamente.
También debemos indicar que la clase DirectoryInfo tiene ciertas propiedades, como FullName
o Name, que nos dan información del nombre de la ruta completa o del nombre del directorio.
Y como nota final sobre Directory y DirectoryInfo, aclarar que el "filtro" (o pattern) que podemos
usar para filtrar los directorios o ficheros obtenidos con GetDirectories o GetFiles solo pueden
tener un filtro o especificación, queremos aclarar este punto, ya que en Visual Basic 6.0, si
indicábamos un filtro en los controles File o Directory, podíamos indicar varios filtros separados
por punto y coma (;), en las clases de .NET esto no se puede hacer.
Para dejar claro estos puntos, veremos un ejemplo de cómo usar GetDirectories y GetFiles, con
estas dos clases.
Técnica de Programación Orientada a Objetos 398
Imports System Imports System.IO Module Module Const dir1 As String = "E:\Pruebas" Sub Main() Console.WriteLine("Ejemplo de la clase Directory:") claseDirectory() Console.WriteLine() Console.WriteLine("Ejemplo de la clase DirectoryInfo:") claseDirectoryInfo() Console.WriteLine() ' Console.ReadLine() End Sub Sub claseDirectory() ' Recorrer los subdirectorios de un directorio Dim dirs() As String dirs = Directory.GetDirectories(dir1) mostrarFicheros(dir1, "*.txt") ' recorrer los ficheros de cada uno de estos directorios For Each dir As String In dirs mostrarFicheros(dir, "*.txt") Next End Sub Sub mostrarFicheros(ByVal dir As String, ByVal filtro As String) Console.WriteLine("Los ficheros {0} del directorio: {1}", _ filtro, dir) Dim fics() As String fics = Directory.GetFiles(dir, filtro) For Each fic As String In fics Console.WriteLine(" Fichero: {0}", fic) Next End Sub Sub claseDirectoryInfo() Dim di As New DirectoryInfo(dir1) Dim dirs() As DirectoryInfo dirs = di.GetDirectories mostrarFicheros(di, "*.*") For Each dir As DirectoryInfo In dirs mostrarFicheros(dir, "*.*") Next End Sub Sub mostrarFicheros(ByVal dir As DirectoryInfo, ByVal filtro As String) Console.WriteLine("Los ficheros {0} del directorio: {1}", _ filtro, dir.FullName) Dim fics() As FileInfo fics = dir.GetFiles(filtro) For Each fic As FileInfo In fics Console.WriteLine(" Fichero: {0}", fic.Name) Next End Sub End Module
Las clases File y FileInfo
Técnica de Programación Orientada a Objetos 399
Al igual que ocurre con las clases para manejar los directorios, tenemos dos clases diferentes
para manejar los ficheros, una de ellas (File) todos los métodos que tiene son estáticos, por
tanto podemos usarlos directamente, sin crear una nueva instancia de la clase. Por otro lado la
clase FileInfo es una clase de la que tenemos que crear un nuevo objeto para poder usarla, al
crear ese objeto (o instancia), tenemos que indicar el fichero al que hará referencia, ese fichero
no tiene porqué existir previamente.
En el siguiente código podemos ver cómo usar estas dos clases.
Imports System Imports System.IO Module Module1 Const fic1 As String = "E:\Pruebas\Prueba.txt" Const fic2 As String = "E:\Pruebas\SubDir\Prueba3.txt" Sub Main() Console.WriteLine("Ejemplo de la clase File:") claseFile() Console.WriteLine() Console.WriteLine("Ejemplo de la clase FileInfo:") claseFileInfo() Console.WriteLine() ' Console.ReadLine() End Sub Sub claseFile() ' comprobar si el fichero existe If File.Exists(fic1) Then Console.WriteLine("El fichero '{0}' SI existe", fic1) Console.WriteLine("Fecha creación: {0}", File.GetCreationTime(fic1)) Else Console.WriteLine("El fichero '{0}' NO existe", fic1) End If End Sub Sub claseFileInfo() Dim fi As New FileInfo(fic2) ' ' Comprobar si existe el fichero: If fi.Exists Then Console.WriteLine("El fichero '{0}' SI existe", fic2) Console.WriteLine("Fecha creación: {0}", fi.CreationTime) agregarTexto(fi) Else Console.WriteLine("El fichero '{0}' NO existe", fic2) ' lo creamos fi.Create() End If End Sub Sub agregarTexto(ByVal fi As FileInfo) Dim fs As StreamWriter fs = fi.CreateText fs.WriteLine("Hola, Mundo") fs.Flush() fs.Close() ' fi.Refresh()
Técnica de Programación Orientada a Objetos 400
Console.WriteLine("Tamaño : {0}", fi.Length) End Sub End Module
Cifrar y descifrar un fichero usando File o FileInfo
En los sistemas operativos Windows XP y Windows 2003, al mostrar el cuadro de diálogo de
las propiedades avanzadas de un fichero, nos permite cifrarlo, de forma que el usuario actual
sólo tenga acceso al contenido del mismo.
Tanto la clase File como FileInfo tienen métodos para realizar esta operación, así como la
inversa: descifrarlo. Cuando ciframos un fichero, solo el usuario actual podrá acceder a su
contenido (y el resto de administradores), la forma de hacerlo es bien simple: solo tenemos que
llamar al método Encrypt o Decrypt para cifrarlo o descifrarlo. Cuando está cifrado, el nombre
del fichero se mostrará en un color diferente al del resto de ficheros (de forma predeterminada
en verde).
Esta forma de cifrado es diferente a la que vimos en la lección anterior, ya que si ciframos el
contenido de un fichero de forma "manual", siempre estará cifrado, independientemente de
quién acceda al fichero.
Cuando utilizamos los métodos para cifrar o descifrar un fichero, no recibiremos ninguna
excepción si aplicamos el método de cifrar sobre un fichero ya cifrado. Pero si queremos saber
si un determinado fichero está o no cifrado, lo podemos averiguar mediante la propiedad
Attribute de la clase FileInfo, particularmente comprobando si tiene activado el atributo
FileAttributes.Encrypted.
Técnica de Programación Orientada a Objetos 401
En el siguiente código tenemos ejemplos de cómo usar las clases File y FileInfo para
comprobar si un fichero ya está cifrado, en cuyo caso lo desciframos, y si resulta que no está
cifrado, lo ciframos.
Imports System Imports System.IO Module Module1 Const fic1 As String = "E:\Pruebas\Prueba.txt" Sub Main() cifradoFile(fic1) Console.WriteLine() cifradoFileInfo(fic2) Console.WriteLine() ' Console.ReadLine() End Sub ' Cifrar / Descifrar ficheros ' y comprobar si ya están cifrados... Sub cifradoFile(ByVal fichero As String) ' comprobar si está cifrado, Dim atrib As FileAttributes atrib = File.GetAttributes(fichero) If (atrib And FileAttributes.Encrypted) = FileAttributes.Encrypted Then Console.WriteLine("El fichero {0} ya estaba cifrado.", fichero) File.Decrypt(fichero) Else File.Encrypt(fichero) Console.WriteLine("El fichero {0} no estaba cifrado.", fichero) End If End Sub Sub cifradoFileInfo(ByVal fichero As String) ' comprobar si está cifrado, Dim fi As New FileInfo(fichero) Dim atrib As FileAttributes atrib = fi.Attributes If (atrib And FileAttributes.Encrypted) = FileAttributes.Encrypted Then Console.WriteLine("El fichero {0} ya estaba cifrado.", fi.FullName) fi.Decrypt() Else fi.Encrypt() Console.WriteLine("El fichero {0} no estaba cifrado.", fi.FullName) End If End Sub End Module
Abrir ficheros para agregar o leer el contenido
Estas dos clases de manipulación de ficheros exponen una serie de métodos que nos permiten
abrir el fichero al que hace referencia la clase para leer el contenido del mismo o para escribir
en él. Dependiendo del método usado, éste devolverá un objeto de tipo FileStream o
StreamReader o StreamWriter. Esto nos permite de una forma fácil poder acceder al contenido
que tiene sin necesidad de usar otros constructores. Lo que si debemos tener en cuenta es que
en el caso de que leamos o escribamos texto, éste se guardará usando la codificación UTF-8,
por tanto si queremos usar otro tipo de codificación, tendremos que abrirlos usando los
constructores correspondientes, normalmente los de las clases StreamReader y StreamWriter.
De estas dos clases nos ocuparemos más adelante.
Técnica de Programación Orientada a Objetos 402
Veamos un par de ejemplos que nos permitan leer el contenido o agregar nuevo texto a los
ficheros.
Imports System Imports System.IO Module Module1 Const fic3 As String = "E:\Pruebas\Prueba4.txt" Const fic4 As String = "E:\Pruebas\SubDir\Prueba4.txt" Sub Main() abrirFile(fic3) Console.WriteLine() abrirFileInfo(fic4) Console.WriteLine() ' Console.ReadLine() End Sub ' Abrir ficheros para leer el contenido o escribir en él Sub abrirFile(ByVal fichero As String) If File.Exists(fichero) Then Dim fs As FileStream = File.OpenRead(fichero) Dim enc As New System.Text.UTF8Encoding() Dim datos(1024) As Byte fs.Read(datos, 0, datos.Length) fs.Close() Dim s As String = enc.GetString(datos, 0, datos.Length) Console.WriteLine("El contenido de: {0}{2} es:{2}{1}", _ fichero, s, vbCrLf) Else Console.WriteLine("Guardando algo en el fichero {0}", fichero) Dim fs As FileStream = File.OpenWrite(fichero) Dim enc As New System.Text.UTF8Encoding() Dim datos() As Byte = enc.GetBytes("¡Hola bytes!") fs.Write(datos, 0, datos.Length) fs.Close() End If End Sub Sub abrirFileInfo(ByVal fichero As String) Dim fi As New FileInfo(fichero) If fi.Exists Then ' abrir el fichero como texto y leemos el contenido Dim sr As StreamReader = fi.OpenText Dim s As String = sr.ReadToEnd Console.WriteLine("El contenido de: {0}{2} es:{2}{1}", _ fichero, s, vbCrLf) Else Console.WriteLine("Guardando algo en el fichero {0}", fichero) Dim sw As New StreamWriter(fi.OpenWrite) sw.WriteLine("Hello bytes!") sw.Close() End If End Sub End Module
En el método abrirFile utilizamos la clase File para abrir, leer y escribir en un fichero. En este
caso estamos usando un objeto del tipo FileStream para acceder al contenido de dicho fichero,
Técnica de Programación Orientada a Objetos 403
como sabemos, esta clase solo trabaja con bytes, por tanto si queremos leer el contenido del
mismo, debemos hacerlo mediante un array de bytes y para mostrar en formato texto ese
contenido, tenemos que aplicarle la codificación correspondiente para extraer el contenido en
forma de una cadena. Lo mismo hacemos para guardar una cadena en el fichero, (en caso de
que no exista previamente).
En el método abrirFileInfo, en lugar de crear un objeto FileStream para acceder al contenido,
usamos uno del tipo StreamReader, ya que esta clase si que nos devolverá una cadena sin
necesidad de hacer conversiones extras. Lo mismo ocurre a la hora de escribir algo en el
fichero, aunque en esta ocasión utilizamos un objeto del tipo StreamWriter.
En el primer caso, cuando leemos el contenido, utilizamos el método OpenText, el cual
devuelve un objeto del tipo StreamReader. Por otra parte, cuando queremos guardar texto, lo
que hacemos es pasarle al constructor de la clase StreamWriter el objeto FileStream devuelto
por el método OpenWrite.
Nota:
Como hemos podido comprobar, cuando tratamos con las clases DirectoryInfo o
FileInfo, siempre estamos tratando con instancias que pueden ser diferentes y por tanto
múltiples, esas instancias siempre manejan el directorio o fichero usado en el
constructor, por tanto, será preferible usar estas clases cuando tengamos que hacer
varias operaciones sobre el mismo directorio o fichero.
Por otro lado, si solo queremos hacer pocas operaciones, podemos usar las clases Directory o
File, ya que no necesitaremos crear un objeto en memoria para hacer las tareas que
necesitemos hacer.
Manipular cadenas relacionadas con ficheros y directorios usando Path La clase Path es una clase especial, en la que todos los métodos son estáticos, por tanto para
usarla no necesitamos crear una instancia. Lo de "especial" es porque esta clase realmente no
realiza ninguna acción "física" sobre los directorios (o ficheros), simplemente nos permite
manipular los nombres de esos directorios o ficheros.
Por ejemplo, podemos usar esta clase para obtener información sobre un fichero, como el
nombre completo, el nombre del directorio o la extensión.
En el siguiente código vemos cómo usar algunos de esos métodos:
Técnica de Programación Orientada a Objetos 404
Const fic1 As String = "E:\Pruebas\Prueba.txt" Sub clasePath() Console.WriteLine("Nombre completo: {0}", fic1) Console.WriteLine("El nombre: {0}", Path.GetFileName(fic1)) Console.WriteLine("Sin extensión: {0}", Path.GetFileNameWithoutExtension(fic1)) Console.WriteLine("La extensión: {0}", Path.GetExtension(fic1)) Console.WriteLine("El directorio: {0}", Path.GetDirectoryName(fic1)) End Sub
Nota:
Debido a que la clase Path solo maneja cadenas, podemos usar los métodos de esta
clase con nombres de ficheros o directorios que no existen, y por tanto, cualquier
cambio que hagamos en esos parámetros, no afectarán a ningún fichero ni directorio.
Debido a que los ensamblados de .NET podemos usarlos con diferentes sistemas operativos
(al menos en teoría), esta clase proporciona ciertas propiedades que nos permiten averiguar
los caracteres especiales de cada sistema, por ejemplo para saber el separador usado por los
directorios.
Con esta clase también podemos crear ficheros con nombres temporales, de forma que nos
aseguremos de que no habrá otro fichero "temporal" con el mismo nombre. Igualmente, por
medio del método GetTempPath podemos averiguar el directorio temporal del sistema.
Incluso podemos generar nombres aleatorios "seguros" para ficheros o directorios mediante el
método GetRandomFileName.
Veamos un ejemplo para generar estos nombres temporales y aleatorios:
Dim dir As String dir = Path.GetTempPath() Console.WriteLine("Directorio temporal: {0}", dir) Dim fic As String fic = Path.GetTempFileName() Console.WriteLine("Fichero temporal: {0}", fic) ' fic = Path.GetRandomFileName() Console.WriteLine("Fichero random: {0}", fic)
En los dos primeros casos, se usa el directorio %TEMP% del sistema. Y en el caso del fichero
temporal, la extensión es .tmp
En el nombre aleatorio, tanto el nombre como la extensión están formados por caracteres
"imprimibles" aleatorios.
Técnica de Programación Orientada a Objetos 405
Esta sería una "posible" salida para un usuario llamado Alguien:
Directorio temporal: C:\Documents and Settings\Alguien\Local Settings\Temp\
Fichero temporal: C:\Documents and Settings\Alguien\Local Settings\Temp\tmp257.tmp
Fichero random: rmbpgxv1.14g
Codigo fuente de algunas aplicaciones
1- Copiar archivos en un directorio
2- Crear un archivo vacío ( método Create - objeto System.IO.File )
3- Crear un archivo plano y añadirle texto (método WriteLine del objeto StreamWriter. Espacio de nombres System.IO )
Técnica de Programación Orientada a Objetos 406
4- My.Computer.FileSystem.GetFiles - Listar archivos. Ejemplo que carga los elementos en un ListBox.
5- My.Computer.FileSystem.FindInFiles - Buscar dentro de un fichero. Ejemplo que busca en un directorio archivos que contengan una cadena de texto determinada. Incluir un listbox en el formulario.
Técnica de Programación Orientada a Objetos 407
6- Comprobar si un directorio o archivo Existe. Propiedad Exist del objeto Directory y el objeto File. (Espacio de nombres System.IO)
7- Renombrar un archivo. ( My.Computer.FileSystem.RenameFile )
8- Mover. ( My.Computer.FileSystem.MoveFile )
Técnica de Programación Orientada a Objetos 408
9- Eliminar archivos y carpetas. ( My.Computer.FileSystem.DeleteFile ). ( My.Computer.FileSystem.DeleteDirectory )
Técnica de Programación Orientada a Objetos 409
10- Crear un archivo temporal. ( My.Computer.FileSystem.GetTempFileName )
11- Leer todo el contenido de un archivo de texto en una solo operación, y almacenarlo en una variable. ( My.Computer.FileSystem.ReadAllText )
12- Cargar directorios y archivos en un ListBox ( Métodos GetFiles y GetDirectories) Colocar en un formulario dos controles ListBox
Técnica de Programación Orientada a Objetos 410
13- Obtener propiedades. Ejemplo que usa la clase FileInfo de system.IO para obtener algunas propiedades y datos de archivos ( el nombre , la fecha y la hora de modificación en formato corto , el tamaño en bytes y la extensión ) Colocar un control Listview, un button y un control TextBox
Técnica de Programación Orientada a Objetos 411
Técnica de Programación Orientada a Objetos 412
Contenido.
Streams de Datos y de Archivos o Comprendiendo los Streams. o Clases que facilitan la lectura y escitura de datos o La Clase File o La Clase Directory o Accediendo a un archivo: uso de la enumeración FileAccess. o Creación de archivos usando la enumeración FileMode. o Manejo de Clases: Stream, FileStream, MemoryStream. Uso del Writer
y Reader
Streams de Datos y de Archivos
Al empezar a trabajar con .NET, uno de los "grandes" cambios que notaremos los que estamos
habituados a desarrollar con otros lenguajes es todo lo relacionado con el acceso al contenido
de los ficheros.
En .NET, y por tanto en Visual Basic 2005, el acceso a ficheros se realiza por medio de los
streams (o usando la traducción de la documentación: las secuencias).
Con los streams no solo podemos acceder a los ficheros de disco, sino que también podemos
acceder a otros tipos de "secuencias" o flujos de datos, desde streams de memoria a streams
para enviar información a través de Internet.
Toda esta transmisión o flujo de información se realiza mediante una serie de métodos de
lectura y escritura que están básicamente encapsulados en la clase abstracta Stream.
Esta clase será la clase base de todas aquellas que de alguna forman tienen que transmitir
cierta información entre la fuente de datos y nuestra aplicación.
En este capítulo trataremos de las clases basadas en Stream que con más frecuencia
utilizaremos, sobre todo en lo relacionado con el acceso a ficheros, que es al fin y al cabo la
utilidad principal de este tipo de "secuencias".
Técnica de Programación Orientada a Objetos 413
Streams en .NET
Según hemos comentado en la introducción, los streams (o secuencias o flujos) nos permiten
abstraernos de la forma en que están implementados los procesos de acceso a los ficheros u
otros recursos. Todas las clases que manejan este tipo de flujos de datos están basadas
(directa o indirectamente) en la clase Stream, la cual nos ofrece ciertos métodos que nos
permiten, entre otras cosas, leer y escribir en esos flujos de información.
Además de poder leer o escribir, también podemos realizar búsquedas o, dicho de otro modo,
podemos movernos a través de esa secuencia de datos. Pero debido a que no todos los flujos
de datos nos permiten realizar todas las operaciones de la clase Stream, existen ciertas
propiedades por medio de las cuales podemos saber si se permiten todas las operaciones
"básicas" que normalmente podremos hacer con los streams. Por ejemplo, es posible que no
podamos leer o escribir en una secuencia o que no podamos cambiar la posición del "puntero"
de lectura o escritura. Para todas estas comprobaciones podremos usar las propiedades
CanRead, CanWrite o CanSeek, pero creo que antes de entrar en detalles, deberíamos ver
algunos de las clases que .NET pone a nuestra disposición para poder realizar este tipo de
operaciones con "las secuencias" de datos.
Las clases basadas en Stream
Entre las clases que están basadas en esta clase abstracta tenemos las siguientes:
o BufferedStream, clase abstracta que representa un buffer de almacenamiento para operaciones de lectura y escritura de otro stream.
o DeflateStream, permite la compresión y descompresión de streams usando el algoritmo Deflat.
o GZipStream, usada para comprimir y descomprimir streams.
o FileStream, nos permite una forma básica de acceder y manipular ficheros.
o MemoryStream, crear un stream que se almacena en la memoria como una secuencia de bytes.
o NetworkStream, proporciona una secuencia de datos para el acceso a la red.
o CryptoStream, un stream usado para encriptar otros streams.
Nota:
Las clases DeflateStream y GZipSteam están incluidas en el espacio de nombres
System.IO.Compression.
La clase CryptoStream está incluida en el espacio de nombres
System.Security.Cryptography.
La clase NetworkStream está incluida en el espacio de nombres System.Net.Sockets.
Técnica de Programación Orientada a Objetos 414
Además de estas clases que se derivan directamente de la clase Stream, y que normalmente
se usan como "secuencias" a usar por otras clases de entrada/salida, tenemos otras que nos
permitirán acceder a esas secuencias de datos de una forma más directa, (algunas de estas
las veremos con algo de más detalle en el próximo capítulo dedicado al sistema de archivos de
.NET), por ejemplo:
o BinaryReader / BinaryWriter, lee o escribe tipos primitivos como valores binarios utilizando una codificación específica.
o StreamReader / StreamWriter, clases para leer y escribir caracteres en ficheros utilizando una codificación determinada.
o StringReader / StringWriter, implementa TextReader o TextWriter para leer o escribir en una cadena.
o TextReader / TextWriter, clases abstractas para leer o escribir en una secuencia de caracteres.
Cuando trabajamos con los streams debemos olvidarnos de las "cosas simples" y debemos
tener en cuenta que trataremos casi siempre con secuencias de bytes, ya que al fin y al cabo
esa es la forma de almacenar la información en los streams. Por tanto cuando veamos los
ejemplos que la documentación de Visual Basic 2005 nos proporciona no debemos extrañarnos
de que haya que hacer tantas "cosas" para acceder o manipular la información almacenada en
esas "secuencias" de datos. Si bien, esa "complicación" nos da mayor control sorbe el formato
de la información contenida en los streams. Por suerte, para los que nos gustan las cosas
"simples" las clases específicas nos facilitan mucho las cosas.
A continuación veremos un par de ejemplos en los que manipularemos cierta información tanto
en la memoria usando un objeto del tipo MemoryStream, como en un fichero de disco usando
FileStream y las clases que casi con seguridad usaremos habitualmente para acceder al
contenido de los ficheros: StreamReader y StreamWriter.
Manejar un fichero usando FileStream En este primer ejemplo veremos lo complicado que pude parecer acceder a un fichero usando
la clase FileStream y por extensión cualquier método de otras clases que devuelvan este tipo
de secuencia, como por ejemplo los métodos OpenRead, OpenWrite, etc. de la clase File.
La "complejidad" de esta clase es que realmente obtiene o guarda la información por medio de
un array de tipo Byte, cuando a lo que estamos acostumbrados es a usar cadenas.
Nota: Realmente, esta forma "binaria" de acceder a la información de un fichero no la tenemos que ver como un inconveniente, ya que nos puede servir para acceder de forma "binaria" a ese fichero, en caso de que nuestra intención sea acceder de forma "normal" para, por ejemplo, leer solo texto, deberíamos usar otras clases más especializadas para esa tarea, como lo es StreamReader.
Técnica de Programación Orientada a Objetos 415
En el siguiente código tenemos dos métodos, uno que guarda una cadena en el fichero
indicado:
Private Sub guardarDatos(ByVal fichero As String, ByVal cadena As String)
' Abrimos o creamos el fichero, para escribir en él Dim fs As New System.IO.FileStream(fichero, _ System.IO.FileMode.OpenOrCreate, _ System.IO.FileAccess.Write) ' Escribimos algunas cadenas, ' el problema es que solo podemos escribir arrays de bytes, ' por tanto debemos convertir la cadena en un array de bytes Dim datos() As Byte ' pero usando la codificación que creamos conveniente ' de forma predeterminada es UTF-8, ' aunque la codificación de Windows es ANSI (Encoding.Default) Dim enc As New System.Text.UTF8Encoding ' convertimos la cadena en un array de bytes datos = enc.GetBytes(cadena) ' lo escribimos en el stream fs.Write(datos, 0, datos.Length) ' nos aseguramos que se escriben todos los datos fs.Flush() ' cerramos el stream fs.Close() End Sub
En el constructor de la clase FileStream indicamos el fichero en el que queremos guardar la
información, también le indicamos que queremos crearlo o abrirlo, es decir, si ya existe lo abre
y si no existe lo crea, de cualquiera de las formas, en el siguiente parámetro del constructor le
indicamos que nuestra intención es escribir en ese fichero.
Como hemos comentado, la clase FileStream (y en general todos los streams) trabaja con
bytes, por tanto para poder almacenar algo en ese fichero debemos hacerlo mediante un array
de tipo Byte.
En el caso de las cadenas, éstas siempre deben estar codificadas, es decir, deben usar el
juego de caracteres que creamos conveniente, en el mundo de .NET ese juego de caracteres
es Unicode, más concretamente usando la codificación UTF-8, la cual permite trabajar con
cualquier carácter de cualquier cultura.
Como lo que nos interesa es convertir una cadena en un array de bytes, usamos el método
GetBytes de un objeto UTF8Encoding, el cual convierte la cadena en una "ristra" de bytes con
el formato adecuado, en este caso UTF-8.
Si en lugar de usar UTF-8 quisiéramos usar otro "codificador", por ejemplo el predeterminado
de Windows, con idea de que los ficheros sean compatibles con otras aplicaciones que utilizan
el formato predeterminado de Windows, tendremos que declarar la variable enc de la siguiente
forma:
Técnica de Programación Orientada a Objetos 416
Dim enc As System.Text.Encoding = System.Text.Encoding.Default
A continuación, simplemente le pasamos el array de bytes al método Write del FileStream
indicando desde que posición de dicho array debe escribir y cuantos bytes.
Por último nos aseguramos de que todos los bytes del "buffer" se guarden en el fichero y lo
cerramos.
Y otra función que devuelve el contenido de un fichero en formato cadena:
Private Function leerDatos(ByVal fichero As String) As String ' Los bloques leídos los almacenaremos en un StringBuilder Dim res As New System.Text.StringBuilder ' Abrimos el fichero para leer de él Dim fs As New System.IO.FileStream(fichero, _ System.IO.FileMode.Open, _ System.IO.FileAccess.Read) ' los datos se leerán en bloques de 1024 bytes (1 KB) Dim datos(1024) As Byte Dim enc As New System.Text.UTF8Encoding() ' leemos mientras hay algo en el fichero While fs.Read(datos, 0, 1024) > 0 ' agregamos al stringBuilder los bytes leídos ' (convertidos en una cadena) res.Append(enc.GetString(datos)) End While ' cerramos el buffer fs.Close() ' devolvemos todo lo leído Return res.ToString End Function
En esta función vamos a leer los datos del fichero indicado, como ya hemos vistos, la clase
FileStream trabaja con bytes y esos bytes los convertimos a caracteres por medio de las clases
de codificación especializadas.
Por regla general, esas lecturas las haremos de forma parcial, es decir leyendo bloques de
bytes y como tenemos que convertir esos bytes en caracteres, y puede ser que el fichero sea
muy grande, en lugar de concatenar una cadena para almacenar las lecturas parciales, vamos
a usar un objeto del tipo StringBuilder en el que iremos "agregando" cada trozo leído, de forma
que el rendimiento no se vea penalizado por la forma de ser de las cadenas, ya que cada vez
que hacemos una concatenación en una variable de tipo String, realmente estamos creando
nuevos objetos en la memoria y si son muchos, pues la verdad es que tendremos al recolector
de basura (GC) trabajando a tope, y si usamos un objeto StringBuilder el rendimiento mejora
una barbaridad.
La lectura de cada bloque de bytes lo hacemos en un bucle While, también podríamos haberlo
hecho en un bucle Do While, pero en estos casos, el rendimiento de While es un "poquitín"
mayor.
Técnica de Programación Orientada a Objetos 417
Los datos leídos los agregamos al objeto StringBuilder por medio del método Append que se
encarga de agregarlo a la cadena interna.
Finalmente cerramos el stream y devolvemos la cadena leída.
Para usar estas dos funciones lo podemos hacer de la siguiente forma:
' un fichero de ejemplo (el directorio debe existir) Const fichero As String = "E:\Pruebas\prueba.txt" ' guardamos una cadena en el fichero guardarDatos(fichero, "Hola, Mundo de FileStream") ' ' Leemos el contenido del fichero y lo mostramos Console.WriteLine(leerDatos(fichero))
Este código no necesita mayor explicación.
Manejar un fichero usando StreamReader y StreamWriter
A continuación veremos cómo crear las dos funciones del ejemplo anterior para que utilicen las
clases "especializadas" para leer y escribir cadenas en un fichero.
Como podremos comprobar, esta es una forma muchísimo más simple y, por tanto
recomendada para este tipo de acceso a los ficheros. Aunque debemos recordar que solo
servirá para leer la información de forma secuencial y en formato cadena.
La función para guardar una cadena en un fichero:
Private Sub guardarDatos(ByVal fichero As String, ByVal cadena As String) ' Abrimos el fichero para escribir, (no añadir), ' usando la codificación predeterminada: UTF-8 Dim sw As New System.IO.StreamWriter(fichero, False) ' guardamos toda la cadena sw.WriteLine(cadena) ' Cerramos el fichero sw.Close() End Sub
Como podemos apreciar, esta es una forma mucho más "compacta" que la anterior, ya que
solo tenemos que indicar en el constructor lo que queremos hacer y usar el método Write o
WriteLine para guardar lo que queramos en el fichero.
Para guardarlo usando la codificación predeterminada del Sistema Operativo en el que se
utilice la aplicación, (en Windows será ANSI), simplemente usamos este constructor:
Dim sw As New System.IO.StreamWriter(fichero, False, System.Text.Encoding.Default)
Para leer los datos podemos hacerlo de dos formas: línea a línea o todo el contenido de una
sola vez.
Técnica de Programación Orientada a Objetos 418
En el código siguiente se muestra línea a línea, y al final, (comentado), cómo hacerlo en una
sola pasada.
Private Function leerDatos(ByVal fichero As String) As String ' Abrimos el fichero para leer ' usando la codificación UTF-8 (la predeterminada de .NET) Dim sr As New System.IO.StreamReader(fichero, True) ' si queremos usar la predeterminada de Windows 'Dim sr As New System.IO.StreamReader(fichero, System.Text.Encoding.Default) ' Podemos leer cada una de las líneas del fichero o todo el contenido ' Forma larga: ' si vamos a leer el fichero línea por línea, mejor usar un StringBuilder Dim ret As New System.Text.StringBuilder ' recorremos el fichero hasta que no haya nada que leer While sr.Peek <> -1 ret.Append(sr.ReadLine) End While ' cerramos el fichero sr.Close() ' devolvemos lo leído Return ret.ToString ' '' Forma corta: '' leemos todo el contenido del fichero 'Dim ret As String = sr.ReadToEnd() '' lo cerramos 'sr.Close() '' devolvemos lo leído 'Return ret End Function
Si nos decidimos a leer el contenido del fichero línea a línea, podemos usar el método Peek, el
cual devolverá el siguiente carácter del buffer del stream, o -1 si no hay nada que leer. Peek no
"consume" el carácter, simplemente comprueba si hay algo que leer.
Si hay algo que leer, leemos la línea completa y la añadimos al objeto StringBuilder, el bucle se
repetirá mientras haya información pendiente de leer.
Pero si optamos por la vía rápida, porque realmente no nos interese procesar cada línea,
podemos usar el método ReadToEnd, que en nuestro ejemplo, el valor devuelto será todo el
contenido del fichero, el cual asignamos a una variable de tipo String para usarla como valor
devuelto por la función, después de cerrar el fichero.
Asegurarnos que el fichero se cierra
Si queremos ahorrarnos el paso intermedio de asignar el valor en una variable y después
devolverlo, también podemos hacerlo de esta forma:
Try Return sr.ReadToEnd() Finally sr.Close() End Try
Técnica de Programación Orientada a Objetos 419
Ya que el bloque Finally siempre se ejecutará, se produzca o no un error, por tanto nos
aseguramos de que el fichero se cierra.
Liberar recursos: Using... End Using
O si lo preferimos, podemos usar la nueva forma de asegurarnos de que los recursos usados
se liberan:
' Podemos usar Using para asegurarnos de que el recurso se libera Private Function leerDatos(ByVal fichero As String) As String Dim sr As New System.IO.StreamReader(fichero, True) Using sr Return sr.ReadToEnd() End Using End Function
En este código, cuando usamos Using sr, al ejecutarse End Using, el CLR se encargará de
llamar al método Dispose de la clase, de forma que se liberen los recursos que estemos
usando, en este ejemplo: el fichero abierto.
Estos dos últimos ejemplos serían equivalentes a los anteriores, más seguros, pero también
con más "trabajo" para el CLR.
Nota:
Using... End Using solo se puede usar con clases que implementen la interfaz
IDisposable, que es la que asegura que el objeto implementa el método Dispose.
Por tanto, si implementamos el método IDisposable.Dispose en nuestras clases, en ese
método nos tenemos que asegurar que liberamos los recursos que nuestra clase esté
utilizando.
Ejemplo de para cifrar y descifrar un fichero
En el siguiente ejemplo (adaptado de uno de la documentación), veremos cómo usar algunas
de las clases basadas en Stream, particularmente las clase MemoryStream, FileStream,
CryptoStream además de las clases StreamReader y StreamWriter.
Este código tiene dos funciones:
La primera encripta (cifra) una cadena y la guarda en un fichero.
La segunda desencripta (descifra) el contenido de un fichero y lo guarda en otro.
Ambas funciones devuelven la cadena cifrada o descifrada respectivamente.
Imports System Imports System.IO Imports System.Text Imports System.Security.Cryptography Module Module1 Const fic1 As String = "E:\Pruebas\Prueba CryptoStream.txt" Const fic3 As String = "E:\Pruebas\Prueba CryptoStream des.txt" Const sKey As String = "El password a usar" Sub Main()
Técnica de Programación Orientada a Objetos 420
Dim ret As String ' ret = cifrarFichero("Hola, Mundo encriptado", fic1) Console.WriteLine("Cadena encriptada : {0}", ret) ' ret = descifrarFichero(fic1, fic3) Console.WriteLine("Cadena desencriptada: {0}", ret) ' Console.ReadLine() End Sub
Function cifrarFichero( _
ByVal texto As String, _ ByVal ficSalida As String) As String ' Creamos un MemorySream con el texto a cifrar Dim enc As New UTF8Encoding Dim datos() As Byte = enc.GetBytes(texto) Dim ms As New MemoryStream(datos) ' El fichero de salida Dim fs As New FileStream(ficSalida, FileMode.Create, FileAccess.Write) ' El proveedor criptográfico Dim r As New DESCryptoServiceProvider 'Establecer la clave secreta r.Key = Encoding.Default.GetBytes(sKey.Substring(0, 8)) r.IV = Encoding.Default.GetBytes(sKey.Substring(0, 8)) ' Crear una secuencia de cifrado Dim cs As New CryptoStream(fs, _ r.CreateEncryptor(), _ CryptoStreamMode.Write) 'Escribir el fichero cifrado cs.Write(datos, 0, datos.Length) cs.Close() 'devolver el texto cifrado Return Convert.ToBase64String(ms.ToArray()) End Function
Function descifrarFichero( _
ByVal fichero As String, _ ByVal ficSalida As String) As String ' el proveedor del cifrado y las claves usadas para cifrar Dim r As New DESCryptoServiceProvider r.Key() = Encoding.Default.GetBytes(sKey.Substring(0, 8)) r.IV = Encoding.Default.GetBytes(sKey.Substring(0, 8)) ' crear la secuencia para leer el fichero cifrado Dim fs As New FileStream(fichero, FileMode.Open, FileAccess.Read) Dim cs As New CryptoStream(fs, _ r.CreateDecryptor(), _ CryptoStreamMode.Read) ' guardar el contenido de fichero descifrado Dim sw As New StreamWriter(ficSalida) Dim sr As New StreamReader(cs) sw.Write(sr.ReadToEnd) sw.Flush() sw.Close() ' ' devolver el texto sr = New StreamReader(fic3) Dim ret As String = sr.ReadToEnd() sr.Close() ' Return ret End Function
End Module
Técnica de Programación Orientada a Objetos 421
Bibliografía
JOYANES AGUILAR, Luis. Fundamentos de Programación, Estructura de Datos y Programación Orienta Objetos. 3era Edición McGraw-Hill/Interamericana de España
Manuales Oficiales de Preparación para los Exámenes de Certificación Microsoft Curso 2546: Core Windows Application Development with Visual Studio 2005
MCTS Self-Paced Training Kit (Exam 70-536): Microsoft .NET Framework 2.0 – Application Development Foundation
Programming Microsoft Visual Basic 2005: The Language