Sunteți pe pagina 1din 93

Tecnolgico Nacional de Mxico

Tecnolgico de Saltillo
Departamento de Sistemas
Apuntes de Programacin Orientada a Objetos
Dr. Scrates Torres Ovalle
Enero de 2016

Programa
Contenidos especficos
1. Arreglos de una dimensin
(vectores)

2. Arreglos de dos dimensiones


(Matrices)

3. Mtodos y parmetros de tipo


objeto

4. Extensin de clases

5. Excepciones

6. Flujos y archivos

Temas de aprendizaje
1.1 Definicin del concepto de vector
1.2 Declaracin de una referencia de tipo
vector
1.3 Creacin de un objeto vector
1.4 Seleccin de los componentes
2.1 Definicin del concepto de matriz (Vector
de vectores)
2.2 Declaracin de una referencia de tipo
matiz
2.3 Creacin de un objeto matriz
2.4 Seleccin de los componentes
2.5 Diseo de una clase instanciable con una
matriz como atributo
3.1 Declaracin y uso de parmetros de tipo
objeto
3.2 Declaracin y uso de mtodos de tipo
objeto
3.3 Vector de objetos
4.1 Inner clases (clases dentro de clases)
4.2 Concepto de herencia
4.3 Jerarqua de clases y atributos protected
4.4 Compatibilidad de tipos (uso de downcasting y up-casting)
4.5 La super clase Object
4.6 Polimorfismo
4.7 Vector de objetos de tipo Object
4.8 Herencia forzada y clases abstractas
4.9 Declaracin y uso de una interface
5.1 Definicin del concepto de excepcin
5.2 Tipos de excepciones predefinidas
5.3 Propagacin
5.4 Manejo y lanzamiento de excepciones
5.5 Excepciones definidas por el usuario
6.1 Concepto de flujo
6.2 Tipos de flujos
6.3 Lectura y escritura en un archivo
6.4 La clase File
6.5 Archivos de acceso aleatorio
6.6 Lectura y escritura de objetos

NDICE

1.- Arreglos de una dimensin

2.- Arreglos de dos dimensiones

35

3.- Mtodos y parmetros de tipo objeto

45

4.- Extensin de clases

49

5.- Excepciones

62

6.- Flujos y Archivos

73

Referencias

82

Anexo A

83

Anexo B

89

Unidad 1.- Arreglos de una dimensin


Objetivo: Comprender el uso de la coleccin de datos arreglo y resolver
problemas basados en arreglos unidimensionales.
CONCEPTOS BSICOS
Debemos considerar que cada tema que se suma al conocimiento y
habilidad del programador, es con la finalidad de darle mayor poder
programtico o hacerle ms fcil la tarea de programacin. Por lo
anterior es que debemos conocer y dominar el manejo de la coleccin
de datos ms usada: arreglos. Iniciemos.
Por qu usar un arreglo o cundo debo usar un arreglo? Si
tuviramos la necesidad de manejar el nmero de nmina y salario de
un empleado, la siguiente declaracin sera suficiente:
int nomina;
double salario;
Pero, si el universo de empleados se extiende a cinco empleados,
la declaracin de variables sera:
String nomina1, nomina2, nomina3, nomina4, nomina5;
double salario1, salario2, salario3, salario4, salario5;
Imagina la mega declaracin de variables necesaria para manejar
todos los empleados de una empresa real, digamos de, cincuenta
empleados o ms. Seguramente que tal declaracin y uso se tornara
inmanejable. Es momento entonces, de utilizar un arreglo: Declaremos
arreglos de cinco elementos para nomina y salario:
int nominas[] = new int[5];
//Se declara nmina como un arreglo de 5 enteros.
double salarios[] = new double[5];
//Se declara salarios como un arreglo de 5 dobles.
De esta manera, ser suficiente el manejo de un solo nombre el
nombre del arreglo (nominas o salarios) para acceder a cualquiera de
sus elementos cinco. Lo anterior se logra mediante el uso de un ndice:
nominas[0]
nominas[1]
nominas[2]
nominas[3]
nominas[4]

=
=
=
=
=

100;
200;
400;
700;
800;

//asignar 100 al primer elemento


//asignar 200 al segundo elemento
//...
//...
//asignar 800 al ltimo elemento

Debemos anotar, que en Java, los elementos en un arreglo siempre


inician en el ndice cero y siempre son numricos. El ltimo valor del
ndice ser igual al tamao del arreglo (nmero total de elementos en el
arreglo) menos uno (debido a que el ndice inicia en cero). Es ms fcil
manejar solamente el nombre del arreglo que cinco variables diferentes.
Como dijimos, se trata de facilitar la tarea del programador.
Otra razn, ms bien tcnica, por la que se debe utilizar un arreglo es
debido a una de las tres caractersticas que lo distinguen:
MEMORIA FSICAMENTE CONTIGUA
Los arreglos se almacenan en localidadades de memoria RAM (Memoria
de Acceso Aleatorio) que son fsicamente contiguas. Se dice que es ms
rpido acceder a localidades de memoria que se encuentran en
localidades contiguas en lugar de localidades de memoria dispersas. En
la siguiente declaracin, consideremos la manera en que se disponen las
variables en memoria: 1) cuando se utilizan cinco variables cuando, y
2) cuando se utiliza un arreglo de dobles.
double salario1, salario2, salario3, salario4, salario5;
double salarios[] = new double[5];
Las Figuras 1.1 y 1.2 muestran la localizacin de las variables en
memoria. La primera declaracin produce cinco variables distintas, que
estn dispersas en la memoria; la segunda, localiza el arreglo en
direcciones RAM contiguas. La asignacin de direcciones es trabajo y
decisin del Sistema Operativo, no depende del programa ni del
programador. Podemos ver que la variable salario1 se localiza en la
direccin 2000h, salario2 en la memoria siguiente (2001h), pero la
variable salario3 en la direccin 2200h. El sufijo h indica que las
direcciones corresponden con nmeros hexadecimales. Se dice que es
mucho ms rpido acceder memoria contigua que dispersa. Utilizar un
arreglo entonces, produce aplicaciones Java, que en su ejecucin, son
ms rpidas. De hecho, el sueo de todo programador es que todo
programa por ms complicado que sea, pueda ser implementado
utilizando un arreglo. Sin embargo, habr aplicaciones que demanden el
uso de colecciones de datos ms elaboradas como la famosa lista,
pila, cola pero el estudio de stas es motivo de un curso de
programacin avanzada.

Figura 1.1.- Localizacin de cinco variable dispersas


El primer elemento del arreglo qued localizado en la direccin 2000h, el
resto de los elementos se localizan en direccin contiguas (ver Figura
1.2). Esta disposicin de memoria, no es casual, el proceso de
asignacin de memoria para un arreglo est obligado a realizar este tipo
de memoria fsicamente contigua.

Figura 1.2.- Localizacin de un arreglo cuyos elementos son


fsicamente contiguos
Contrastemos este concepto de memoria fsicamente continua
propio de los arreglos, con el concepto de memoria lgicamente
contigua propio de las listas. La Figura 1.3 muestra como los elementos
de una lista (nodos) se localizan en memorias no contiguas (dispersas),
sin embargo, se tiene control de la lista a travs de una referencia al
primer nodo (CABEZA). El usuario de la lista podr percibir que los
elementos en la lista estn fsicamente contiguos, pero no lo estn.
Cabeza es la referencia que sabe dnde se localiza el primer nodo de la
lista; de all en adelante, cada nodo sabe dnde se encuentra el
siguiente nodo; el ltimo nodo de la lista no tiene nodo consecuente, eso
se indica con el smbolo ground (tierra, la flecha que termina en tres
lneas).
6

Figura 1.3.- Localizacin de una lista cuyos elementos son lgicamente


contiguos
MEMORIA DE ACCESO ALEATORIO
Memoria de acceso aleatorio es otra caracterstica de los arreglos.
Nuevamente, es preferido este tipo de acceso sobre el acceso secuencial
que manifiesta una lista. Acceso aleatorio no quiere decir nmeros
aleatorios, ms bien, indica que puedes acceder cualquier elemento de
la lista de forma directa, a travs de un ndice. Mientras que en una lista,
si quieres asignarle un valor al tercer nodo, tendrs que visitar el primer
nodo (a travs de la referencia cabeza), de all pasar al segundo nodo,
para finalmente arribar al tercero (cada nodo conoce la localizacin del
siguiente nodo). A esto se le conoce como acceso secuencial. Por simple
observacin, es ms rpido el acceso de tipo aleatorio que el secuencial.
Nuevamente el uso de un arreglo es ms eficaz que el de una lista.
nominas[2] = 900;
nominas[4] = 300;
El ndice de un arreglo puede ser una variable, de hecho se
acostumbra que sea una variable. As, todo consiste en cambiar o ms
bien controlar el valor del ndice para acceder a otro miembro del
arreglo. La Tabla 1.1 muestra un intento grfico para ilustrar la mecnica
de un ndice.
int indice = 2;
nominas[indice]= 900;

indice = 4;
nominas[indice]= 300;

Tabla 1.1.- Cambia el valor del ndice y se accede a otro miembro del
arreglo
Nota: cuando aplicas el operador unario incremento (++) o decremento
(--) a un ndice, el efecto es diferente si lo usas como prefijo o sufijo del
ndice. La Tabla 1.2 muestra dos fragmentos de cdigo: La primer
columna asigna un cien al elemento 5 del arreglo, mientras que en la
columna de la derecha se asigna un cien al elemento 6 del arreglo. El
operador incremento situado como prefijo del ndice indica que primero
se realiza el incremento y luego la asignacin. Caso contrario cuando el
operadore incremento es un sufijo de ndice.
int
arreglo
int[10];
int indice = 5;

new int
arreglo
int[10];

new

int indice = 5;

arreglo[indice++] = 100;
arreglo[++indice] = 100;
Tabla 1.2.- Efecto de usar el operador unario como prefijo o sufijo de un
ndice
MEMORIA ESTTICA
Por ltimo, una tercera caracterstica de los arreglos tiene que ver con el
uso de memoria esttica: una vez dimensionado el arreglo, una vez que
se declar cuantos elementos tiene, no habr forma de cambiarlo. Si lo
contrastamos con la memoria dinmica propia de una lista, veremos que
en esta ltima se podr insertar o borrar tantos nodos como sea
necesario, pero al arreglo no se le podr agregar o quitar un elemento.
Esto en s es una desventaja. Aunque tambin existe la clase ArrayList
contenida en el paquete java.util (package).
Sintaxis en la declaracin de un arreglo
Lo fro de la sintaxis, nadie quiere lidiar con esto, pero si te acostumbras,
vers que son como asntotas que te guan en la buena escritura y uso
de un arreglo. Sintaxis:
tipo [] nombreArreglo = new tipo[tamao];
tipo nombreArreglo[] = new tipo[tamao];
8

Los corchetes pueden ir como prefijo o sufijo antes o despus de


nombreArreglo. Tamao deber ser una expresin entera: nmero,
variable o expresin. Una vez que tamao dimensiona (en tiempo de
ejecucin) al arreglo no podr ser re-dimensionado. El tipo expresa la
naturaleza de los elementos en el arreglo. Si se trata de un arreglo de
tipos primitivos, tipo podr ser: cualquier entero, como int; cualquier
real, como double; boolean o char.
Expuesto lo anterior podemos construir nuestra propia definicin
de lo que es un arreglo en el mbito de Java:
Un arreglo es una coleccin de datos del mismo tipo, arreglo
de enteros por ejemplo; el acceso a cada uno de los
elementos en el arreglo se realiza de forma directa (acceso
aleatorio) a travs de un ndice; una vez dimensionado el
arreglo no se puede modificar en tamao (memoria esttica);
y, todos los elementos en el arreglo se encuentran en
direcciones contiguas (memoria fsicamente contigua).
El ndice de un arreglo, si lo sabes controlar, si lo sabes manipular,
tendrs total dominio del ste. Cambia el valor del ndice y tienes acceso
a otro elemento en el arreglo. Adems, siempre tendrs acceso directo a
cualquier elemento en el arreglo. La Figura 1.4 muestra la declaracin de
un arreglo (edades) de diez elementos tipo entero. An no se asignan
valores a los elmentos, mientras esto sucede, se dice que Java inicializa
en cero cada elemento, ya que es el valor por defecto (default) que se
asigna a un tipo entero.

Figura 1.4.- Declaracin de un arreglo de diez enteros


En la Figura 1.5, tenemos, tanto la declaracin de un arreglo
(precios) de dobles, como la inicializacin de los mismos. De forma

implcita el tamao
dimensionamiento).

del

arreglo

se

fij

en

cuatro

(auto-

Figura 1.5.- auto-dimensionamiento mediante inicializacin


Tcnicamente, un arreglo es una referencia, una a la que luego se
le asigna un bloque de memoria con todos los elementos del arreglo. Si
lo vemos de esta manera, la declaracin de un arreglo puede realizarse
en dos partes o ms bien en dos momentos (dos lneas de cdigo
diferente). Esto hace ms rica la declaracin: Podemos declarar la
primera parte como una referencia de lo que va a ser el arreglo, luego
preguntar al usuario cuntos elementos necesita para el arreglo, y con
esto dimensionar al arreglo en tiempo de corrida, utilizar los elementos
de ste para al finalizar liberar la memoria del arreglo. Esto es en parte,
el concepto de memoria dinmica: Pides memoria, la utilizas y luego la
liberas o regresas al Sistema.
Scanner s = new Scanner(System.in);
int[] miArreglo; //se declara la referencia (1er tiempo)
System.out.println("cuntos elementos son: ");
int n = s.nextInt();
miArreglo = new int[n]; //se dimensiona (2 tiempo)
//aqu se realizan operaciones sobre el arreglo
miArreglo = null; //se libera memoria del arreglo
s.close();
Si suponemos que durante la ejecucin del programa anterior n es
4, y que en el segmento de operaciones sobre el arreglo se le asignan
los siguientes datos:
miArreglo[0]
miArreglo[1]
miArreglo[2]
miArreglo[3]

=
=
=
=

12;
37;
21;
24;
10

La disposicin del arreglo en RAM sera como se muestra en la


Figura 1.6. Estamos suponiendo que el Sistema Operativo asign, en
primera instancia, la direccin RAM 2000h, a la referencia miArreglo
una referencia a un arreglo de enteros. Despus de preguntar al usuario
cuntos elementos necesita en el arreglo, y suponiendo que dijo cuatro,
nuevamente suponemos que el Sistema operativo asign un bloque de
memoria contigua para alojar los 4 elementos del cuerpo del arreglo (de
la direccin 2003h a la 2006h). Podemos notar que, la referencia y el
cuerpo del arreglo, no son alojados en memorias contiguas, esto no es
necesario. Tambin, y dadas las direcciones supuestas, el contenido de
la direccin 2000h, donde se encuentra la referencia, es un 2003.
Decimos que la referencia miArreglo tiene el valor de 2003 porque
precisamente indica el inicio del cuerpo del arreglo que el controla o al
que hace referencia. Despus de todo miArreglo es una referencia a un
arreglo de enteros.

Figura 1.6.- Referencia y cuerpo de un arreglo


Qu pasa si trato de usar un arreglo que no he declarado ni
dimensionado?
arreglo[2] = 100; //no declaro no dimensiono el arreglo
El error resultante es: cannot find symbol: variable arreglo (no puedo
encontrar el smbolo arreglo). Es el error clsico que se genera cuando
tratas de usar una variable que no has declarado.
Qu pasa si declaro el arreglo pero no lo dimensiono, luego trato de
usarlo?
int[] arreglo; //declaro el arreglo
arreglo[2] = 100; //trato de usarlo sin dimensionar
Ahora se reporta el siguiente error: variable arreglo might not have
been initialized. Indica la posibilidad de que la variable arreglo podra
11

no haber sido inicializada. Tenemos declarada la referencia (nombre) del


arreglo, pero no existe el cuerpo del arreglo. Si lo dimensionamos el
error desaparece:
int[] arreglo = new int[7]; //un arreglo de 7 enteros
arreglo[2] = 100;
Se pueden tener ndices que no sean enteros: double o String?
int[] arreglo = new int[7];
arreglo[2] = 100;
arreglo["1"] = 500; //error por tipos incompatibles
arreglo[3.0] = 400; //posible prdida de precisin
//requerido int; encontrado double
Los ndices de los arreglos deben ser de tipo entero.
Se puede acceder un elemento despus del ltimo elemento del
arreglo?
int[] arreglo = new int[7];
arreglo[7] = 100;
Al estilo de BlueJ, el cdigo anterior no tiene errores, pero esto es en
tiempo de compilacin. Al momento de ejecutar la aplicacin, suceden
los denominados errores en tiempo de corrida. En este caso el error
arrojado es: java.lang.ArrayIndexOutOfBoundsException: 7. Este tipo
de errores se conocen como Excepciones (Exception). La excepcin
arrojada para el cdigo anterior indica que se ha salido de los lmites
marcados para el ndice del arreglo. Ms adelante abordaremos
ampliamente el manejo de excepciones.
Puedo acceder un elemento del arreglo que este situado en una
posicin (ndice) negativa?
int[] arreglo = new int[7];
arreglo[-1] = 100;
Otra vez la Excepcin lanzada o reportada en tiempo de ejecucin es:
java.lang.ArrayIndexOutOfBoundsException: -1.
Puede tener un arreglo ms de una referencia?
//declaracin y dimensin de una referencia
//a arreglo de enteros.
double[] unaReferencia = new double[10];
//declaracin de otra referencia a arreglo de enteros
12

double[] otraReferencia;
//se asigna la primer referencia a la segunda
otraReferencia = unaReferencia;
//ahora el arreglo tiene dos nombres (referencias)
Un arreglo, entonces, s puede tener ms de una referencia, los
elementos del arreglo pueden ser manipulados a travs de cualquiera de
estas referencias. No se trata de dos arreglos, son dos referencias que
tienen control de los mismos elementos en un arreglo.
unaReferencia[5] = 21.7;
otraReferencia[5] = 14.18;
El valor final para el elemento cinco es 14.18. Se puede pensar que,
tener dos referencias (nombres) para un arreglo es de poca utilidad,
pero su utilizacin es bastante frecuente al menos de forma indirecta
: El caso de enviar como argumento un objeto cualquiera (un arreglo
por ejemplo), el cual es recibido por una referencia. Al primero se le
relaciona con un argumento actual, al segundo como argumento formal.
De esta manera los cambios que el objeto sufra a su paso por el mtodo
que lo recibe (mediante la referencia formal) son los mismos que se
reflejan en el objeto enviado (referencia actual).
Es cierto que puedo liberar la memoria del arreglo?
Cuando se asigna a una referencia el valor de null, se dice que la
referencia pierde el control del arreglo. Esto tambin es cierto cuando la
referencia controla un objeto. De hecho un arreglo es considerado un
objeto.
Tambin, cuando un arreglo ya no lo controla ninguna referencia, se dice
que la memoria que ocupan todos los elementos del arreglo queda
disponible para asignarse a otras variables. Lo anterior sucede mediante
el trabajo del recolector de basura de Java. Para el ejemplo del arreglo
que es controlado por dos referencias, si se asigna null a ambas
referencias:
unaReferencia = null;
otraReferencia = null;
Estamos indicando que el recolector de basura (Garbage Collector) de
Java puede regresar el bloque de memoria que ocupaba el arreglo.
Cuando el colector acta, el Sistema Operativo marca este bloque de
memoria como disponible.

13

Qu es el recolector de basura de Java?


Es un proceso (programa) que se ejecuta junto con las aplicaciones Java,
este proceso siempre est buscando bloques de memoria que las
referencias dejaron de usar. El colector de basura se ejecuta con menor
prioridad que las aplicaciones Java, esto con la finalidad de no interferir
con el buen funcionamiento de las mismas. Pero, tan pronto como
pueda, entra en accin y colecta esos bloques de memoria en desuso.
Tambin se puede ordenar la ejecucin de este recolector de basura,
mediante el siguiente cdigo:
System.gc();

Figura 1.7.- Llamada al recolector de basura


http://rodrigocprates.blogspot.mx/2010/07/o-que-e-e-para-que-serve-ogarbage.html

Figura 1.8.- Objetos sin referencia listos para ser recolectados


http://www.guru99.com/images/uploads/2012/07/GarbageCollection4.jpg
Es cierto que un arreglo es un objeto? Si esto es cierto, un arreglo debe
poseer campos (variables) y/o mtodos. El siguiente cdigo imprime el
14

valor de la variable length asociada a todo arreglo. Para este caso 10


indica el tamao con el que se dimension el arreglo.
double[] unaReferencia = new double[10];
System.out.println(Longitud: +unaReferencia.length);
Corrida:
Longitud: 10
El siguiente cdigo utiliza el mtodo clone() que posee todo arreglo
(aunque el mtodo lo hereda de la clase Object) para obtener una copia
de si mismo:
int[] primerArreglo = {1,2,3,4,5};
int[] segundoArreglo = primerArreglo.clone();
System.out.println(segundoArreglo.length);
if(Arrays.equals(primerArreglo, segundoArreglo))
{
System.out.println("Copiado exitoso");
}
System.out.println(Arrays.toString(segundoArreglo));
El resultado de la ejecucin sera:
Copiado exitoso
[1, 2, 3, 4, 5]
Problema propuesto 1.1
Programar una aplicacin que permita la lectura de n (ene) nmeros y
calcule su promedio: a) utilizar una variable entera para recibir los datos
de entrada, b) utilizar un arreglo de enteros para recibir los datos de
entrada. Determinar en qu casos es recomendable el uso de un arreglo.
En ambos casos deber mostrar una corrida como se muestra a
continuacin:
Cuntos son? 3
Dato 1.- 10
Dato 2.- 20
Dato 3.- 30
Promedio = 20.0
Sin arreglo: Los ene datos se sobre escriben en la misma variable
(dato). Despus del ciclo (for) que lee los datos, la variable dato slo
conserva el ltimo valor ledo. Esto no causa ningn problema porque es
el promedio lo nico que se pide como salida.
import java.util.*;
15

public class SinArreglo


{
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
System.out.print("Cuntos son? ");
int n = s.nextInt();
double sumaAcumulada = 0.0;
double dato = 0.0;
for (int i = 1; i <= n; i++)
{
System.out.print("Dato " + i + ".- ");
dato = s.nextInt();
sumaAcumulada = sumaAcumulada + dato;
}
double promedio = sumaAcumulada / n;
System.out.println("Promedio = " + promedio);
s.close();
}
}
Con arreglo: Todos los datos de entrada se guardan como elementos
del arreglo datos. Despus del ciclo (for) que lee los datos, el arreglo
conserva todos los datos de entrada. Sin embargo, despus de calcular e
imprimir el promedio, no me piden hacer algo con estos datos. Decimos
que, de nada me sirvi conservarlos. A no ser que despus del clculo
del promedio me pidan seguir procesando estos datos para realizar otro
tipo de operaciones: Podramos luego, pedir otro arreglo y calcular la
suma de ambos, por ejemplo.
import java.util.*;
public class ConArreglo
{
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
double[] numeros;
System.out.print("Cuntos son? ");
int n = s.nextInt();
numeros = new double[n];
double sumaAcumulada = 0.0;
16

for (int i = 0; i < n; i++)


{
System.out.print("Dato " + (i+1) + ".- ");
numeros[i] = s.nextDouble();
sumaAcumulada = sumaAcumulada + numeros[i];
}
double promedio = sumaAcumulada / n;
System.out.println("Promedio = " + promedio);
s.close();
}
}
En conclusin: Para el ejemplo anterior, era suficiente manejar una
sola variable para recibir los datos de entrada, pero, si hubiera la
necesidad de un post-procesamiento de estos datos, sera necesario
manejar un arreglo.
Problema propuesto 1.2
Acerca de los generadores de nmeros aleatorios, se considera que son
buenos cuando un nmero tiene la misma probabilidad de ser generado.
Probemos la calidad de generacin aleatoria que sostiene la clase
Random. Programa una aplicacin que permita la generacin de 10,000
(diez mil) nmeros aleatorios en el rango del 1 al 10, y muestre como
salida la frecuencia de aparicin de cada uno de ellos. Se espera una
corrida ideal como se muestra:
Frecuencia de nmeros generados:
1.- 1000
2.- 1000
3.- 1000
4.- 1000
5.- 1000
6.- 1000
7.- 1000
8.- 1000
9.- 1000
10.- 1000
Primer idea: Utilizar slo variables de tipo primitivo. Se utilizan diez
variables enteras como contadores de las incidencias generadas
(nmeros del 1 al 10). El programa funciona pero es mucho cdigo para
tan simple problema.
import java.util.*;
17

public class Aleatorio1


{
public static void main(String [] args)
{
Random r = new Random();
int uno, dos, tres, cuatro, cinco, seis,
siete, ocho,nueve, diez;
uno = dos = tres = cuatro = cinco = seis =
siete = ocho = nueve = diez =
0;
int num = 0;
for (int i = 1; i <= 10000; i++)
{
num = r.nextInt(10) + 1;
switch(num)
{
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
}//switch
}//for

uno++;
dos++;
tres++;
cuatro++;
cinco++;
seis++;
siete++;
ocho++;
nueve++;
diez++;

break;
break;
break;
break;
break;
break;
break;
break;
break;
break;

System.out.println("Frecuencia de nmeros
generados:");
System.out.println("1.- " + uno);
System.out.println("2.- "
+ dos);
System.out.println("3.- "
+ tres);
System.out.println("4.- "
+ cuatro);
System.out.println("5.- "
+ cinco);
System.out.println("6.- "
+ seis);
System.out.println("7.- "
+ siete);
System.out.println("8.- "
+ ocho);
System.out.println("9.- "
+ nueve);
System.out.println("10.- " + diez);
}//main
}//class

18

Segunda idea: Utilizar un arreglo de diez contadores. El programa se


simplifica a la hora de entregar los resultados con la frecuencia de
aparicin.
import java.util.*;
public class Aleatorio2
{
public static void main(String [] args)
{
Random r = new Random();
int[] contador = new int[11];
for (int i = 0; i < 11; i++ ) contador[i] = 0;
int num = 0;
for (int i = 1; i <= 10000; i++)
{
num = r.nextInt(10) + 1;
switch(num)
{
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
}//switch
}//for

contador[1]++;
contador[2]++;
contador[3]++;
contador[4]++;
contador[5]++;
contador[6]++;
contador[7]++;
contador[8]++;
contador[9]++;
contador[10]++;

break;
break;
break;
break;
break;
break;
break;
break;
break;
break;

System.out.println("Frecuencia de nmeros
generados:");
for(int i = 1; i <= 10; i++)
{
System.out.println(i + ".- " + contador[i]);
}
}//main
}//class
Tercer idea: Utilizar un arreglo de contadores. De la segunda idea, se
puede observar que el caso dentro del estatuto switch siempre
corresponde con el ndice del contador que se incrementa. Entonces el
dato generado aleatoriamente se utiliza como ndice del contador que se
19

incrementa. Siempre se incrementar el contador que corresponde con


el dato generado. Esto no slo simplifica la entrega de resultados sino
tambin el ciclo que determina la frecuencia de aparicin de dichos
nmeros.
import java.util.*;
public class Aleatorio3
{
public static void main(String [] args)
{
Random r = new Random();
int[] contador = new int[11];
for (int i = 0; i < 11; i++ ) contador[i] = 0;
int num = 0;
for (int i = 1; i <= 10000; i++)
{
num = r.nextInt(10) + 1;
contador[ num ]++;
}//for
System.out.println("Frecuencia de nmeros
generados:");
for(int i = 1; i <= 10; i++)
{
System.out.println(i + ".- " + contador[i]);
}
}//main
}//class
Conclusin: Como dijimos, sumar el poder programtico que resulta al
estudiar el manejo de arreglos tambin simplifica el cdigo del
programador. La siguiente corrida muestra que la frecuencia de los
nmeros generados se encuentra alrededor del ideal (mil).
Frecuencia de nmeros generados:
1.- 1001
2.- 1007
3.- 1050
4.- 971
5.- 1037
6.- 985
7.- 1012
8.- 964
9.- 959
20

10.- 1014
Los arreglos, se pasan por referencia como los objetos, de hecho, un
arreglo es un objeto. Dado que los arreglos son referencias a objetos,
stos, cuando se pasan como parmetros en un mtodo, no son paso de
parmetros por valor sino por referencia. Considera el siguiente cdigo:
int[] unArreglo = {15, 21, 0, -72, 100};
System.out.println("Contenido del arreglo");
System.out.println( Arrays.toString( unArreglo ) );
Arrays.sort(unArreglo);
System.out.println("Contenido del arreglo despus de ser
enviado como parmetro");
System.out.println( Arrays.toString( unArreglo ) );
La ejecucin nos muestra que el arreglo cambi despus de haber sido
enviado como parmetro, lo cual indica que los arreglos, siendo objetos,
siempre son enviados por referencia y no por valor como sucede cuando
enviamos variables de tipo primitivo.
Contenido del arreglo
[15, 21, 0, -72, 100]
Contenido del arreglo despus de ser enviado como parmetro
[-72, 0, 15, 21, 100]
Sumarizando: Debemos tener cuidado cuando enviamos un arreglo
como parmetro o argumento de un mtodo, ya que si el mtodo
cambia algn elemento del arreglo, ste se ve reflejado en nuestro
arreglo original.
Cmo puedo hacerle para que mi arreglo original no cambie? La
respuesta consiste en hacer una copia (o clone) del arreglo original, y
enviar la copia como parmetro, al trmino de la ejecucin del mtodo,
la copia podra haber cambiado, pero el arreglo original permanece
intacto. En general est regla aplica para cualquier objeto (referencia)
que es enviado como parmetro. La idea anterior se ilustra en el
siguiente cdigo:
int[] unArreglo = {15, 21, 0, -72, 100};
System.out.println("Contenido del arreglo original");
System.out.println( Arrays.toString( unArreglo ) );
int[] copiaDelArreglo = unArreglo.clone();
Arrays.sort(copiaDelArreglo);
System.out.println("Contenido ordenado del arreglo copia");
21

System.out.println( Arrays.toString( copiaDelArreglo ) );


System.out.println("Otra
vez,
contenido
del
original");
System.out.println( Arrays.toString( unArreglo ) );

arreglo

Ejecucin de programa:
Contenido del arreglo original
[15, 21, 0, -72, 100]
Contenido ordenado del arreglo copia
[-72, 0, 15, 21, 100]
Otra vez, contenido del arreglo original
[15, 21, 0, -72, 100]
Conclusin: Debemos recordar que los arreglos si se envan como
parmetro en la llamada de un mtodo, siempre se envan por
referencia.
La clase Arrays, una clase contenida en el paquete java.util del API de
Java, permite la manipulacin de arreglos. Utiliza de la clase Arrays los
mtodos tipo static, fill() y toString(), para programar la aplicacin
anterior que generaba 10,000 nmeros aleatorios y mostraba la
frecuencia de aparicin:
import java.util.*;
public class AleatorioConArrays
{
public static void main(String args[])
{
Random r = new Random();
int[] contador = new int[11];
//contadores se inician en cero
Arrays.fill(contador, 0);
//generacin y conteo
for (int i = 1; i <= 10000; i++)
{
contador[ (r.nextInt(10) + 1) ]++;
}//for
System.out.println("Frecuencia de nmeros
generados:");
//se copia el arreglo de once elementos a uno de
//de diez elementos
int[]contadorConDiezElementos =
22

Arrays.copyOfRange(contador,1,11);
//seimprime el arreglo de contadores
System.out.println(Arrays.toString(
contadorConDiezElementos));
}
}
Resultado de la ejecucin:
Frecuencia de nmeros generados:
[984, 979, 982, 1017, 1009, 991, 993, 1057, 964, 1024]
Clases instanciables que contienen (has_a) arreglos como
campos
Los arreglos tambin pueden fungir como campos (variables en una
clase instanciable).
Problema propuesto 1.3
Podemos entonces realizar la suma de dos arreglos (vectores)
programando directamente sobre los arreglos o mediante una clase
definida por nosotros de nombre, digamos, Arreglo. Veamos las dos
opciones:
Para aumentar el grado de complejidad realicemos la suma punto que
permite la suma de arreglos an cuando sean de diferente tamao
(dimensin). La corrida se espera como sigue:
Tamao del arreglo a
3
Dato 0
1
Dato 1
2
Dato 2
3
Tamao del arreglo b
5
Dato 0
1
Dato 1
2
Dato 2
3
Dato 3
4
23

Dato 4
5
a = [1, 2, 3]
b = [1, 2, 3, 4, 5]
c = a +. b = [2, 4, 6, 4, 5]
Sin clase instanciable
import java.util.*;
public class SumaPunto
{
public static void main(String args[])
{
Scanner s = new Scanner(System.in);
System.out.println("Tamao de a");
int n = s.nextInt();
int a[] = new int[n];
for(int i=0; i<n; i++)
{
System.out.println("Dato "+i);
a[i] = s.nextInt();
}
System.out.println("Tamao de b");
int m = s.nextInt();
int b[] = new int[m];
for(int i=0; i<m; i++)
{
System.out.println("Dato "+i);
b[i] = s.nextInt();
}
int c[]=null;
if(n == m)
{
c = new int[n];
for(int i=0; i<n; i++)
{
c[i] = a[i] + b[i];
}
}
if(n > m)
{
c = new int[n];
//b es ms pequeo
for(int i=0; i < m; i++)
{
c[i] = a[i] + b[i];
}
for(int j = m; j < n; j++)
24

{
c[j] = a[j] + 0;
}
}
if(m > n)
{
c = new int[m];
//b es ms pequeo
for(int i=0; i < n; i++)
{
c[i] = a[i] + b[i];
}
for(int j = n; j < m; j++)
{
c[j] = b[j] + 0;
}
}
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
System.out.println(Arrays.toString(c));
}//main
}//class
Con clase instanciable
Una opcin del proyecto podra ser como se muestra en la Figura 1.9:

Figura 1.9.- Proyecto SumaPuntoInstanciable


La clase instanciable Arreglo sera:
import java.util.*;
public class Arreglo
{
25

Scanner s = new Scanner(System.in);


private int arr[]=null;
public Arreglo()
{
System.out.println("Tamao de arreglo");
int n = s.nextInt();
arr = new int[n];
}
public Arreglo(int n)
{
arr = new int[n];
}
public void leerDatos()
{
System.out.println(arr.length);
for(int i=0; i<arr.length; i++)
{
System.out.println("Dato "+i);
arr[i] = s.nextInt();
}
}
public Arreglo sumarArregloCon(Arreglo ax)
{
int a[]=this.arr;
int b[]=ax.arr;
int c[]=null;
Arreglo cx = null;
int m = ax.arr.length;
int n = this.arr.length;
if(n == m)
{
cx = new Arreglo(n);
c = cx.arr;
for(int i=0; i<n; i++)
{
c[i] = a[i] + b[i];
}
}
if(n > m)
{
cx = new Arreglo(n);
26

c = cx.arr;
//b es ms pequeo
for(int i=0; i < m; i++)
{
c[i] = a[i] + b[i];
}
for(int j = m; j < n; j++)
{
c[j] = a[j] + 0;
}
}
if(m > n)
{
cx = new Arreglo(m);
c = cx.arr;
//b es ms pequeo
for(int i=0; i < n; i++)
{
c[i] = a[i] + b[i];
}
for(int j = n; j < m; j++)
{
c[j] = b[j] + 0;
}
}
return cx;
}//sumar
public void mostrarArreglo()
{
System.out.println(Arrays.toString(arr));
}
}//class
El cdigo para la aplicacin PruebaArregloParaSumaPunto sera:
public class PruebaArregloParaSumaPunto
{
public static void main (String args[])
{
Arreglo a = new Arreglo();
a.leerDatos();
Arreglo b = new Arreglo();
b.leerDatos();
Arreglo c = a.sumarArregloCon(b);
27

a.mostrarArreglo();
b.mostrarArreglo();
c.mostrarArreglo();
}//main
}//class

28

Ejercicio propuesto para Suma Punto:

Figura 1.10.- Proyecto propuesto alterno para Suma Punto


La aplicacin PruebaSumaPunto deber tener el siguiente cdigo:
public class PruebaSumaPunto
{
public static void main()
{
TresArreglos ta = new TresArreglos();
ta.leerA();
ta.leerB();
ta.sumarAyB();
ta.mostrar();
}
}
El diagrama UML de la clase TresArreglos deber ser:
TresArreglos
- a: Arreglo
- b: Arreglo
- c: Arreglo
+
TresArreglos( )
+ leerA( ): void
+ leerB( ): void
+ sumarAyB( ) :
void
+ mostrar( ):
void
Tabla 1.3.- Diagrama UML para TresArreglos
29

El diagrama UML de la clase Arreglo deber ser:


Arreglo
- a: int []
+ Arreglo( )
+ Arreglo(n: int)
+ leerArreglo( ):
void
+ toString( ):
String
Tabla 1.4.- Diagrama UML para Arreglo
Y la corrida deber ser similar a la del anterior proyecto.
Arreglos de objetos
El tipo de dato de los elementos en un arreglo no tiene que ser de tipo
primitivo, puede ser cualquier objeto instancia de cualquier clase.
Ejemplo:
//Declaracin de un arreglo de
String
String args[]= new String[10];

diez

elementos

tipo

Los arreglos de String son la excepcin dado que un arreglo de objetos


siempre necesitar, adems de declarar y dimensionar, construir cada
uno de los elementos del arreglo.
Ejemplo:
//Declaracin y dimensin de un arreglo de tres puntos
Punto puntos[] = new Punto[3];
//Creacin de cada uno de los elementos en el arreglo
for(int i=0; i<3; i++)
{
puntos[i] = new Punto();
}
Para los arreglos de tipo primitivo no se necesitar la etapa de creacin
de los elementos, y como dijimos, tampoco se necesitan en el caso de
arreglos de String, aunque si se pueden crear cada uno de los elementos
de este tipo. Para el ejemplo anterior:
for(int i=0; i<10; i++)
{
args[i] = new String();
}
30

De hecho, este arreglo es usado como argumento del mtodo main en


toda aplicacin de Java. Esto tiene relacin con el uso de parmetros en
la lnea de comandos que muchos lenguajes soportan (e. g. C, C++,
Java, entre otros).

Problema propuesto 1.4

Figura 1.11.- Proyecto Tienda (Arreglo de objetos)


La corrida del proyecto deber ser como sigue:
Men principal
[1] Alta
[2] Baja
[3] Consulta
[4] Cambio
[5] Listado
[6] Salvar
[7] Cargar
[9] Salir
Tu opcin?
Para la opcin de Alta:
Tu opcin?
1
Ests en altas
Nmero de parte:
100
Descripcin:
Cereal
Costo:
23.50
Cantidad:
31

25
Para la opcin de Listado:
Tu opcin?
5
Ests en listado
Producto No. parte: 100
Descripcin: Cereal
costo: 23.5
Cantidad: 25
Producto No. parte: 200
Descripcin: Detergente
costo: 17.5
Cantidad: 122
Producto No. parte: 300
Descripcin: Refresco
costo: 9.5
Cantidad: 90
Para la opcin de Consulta:
Tu opcin?
3
Ests en consultas
Cul nmero de parte:
200
Producto No. parte: 200
Descripcin: Detergente
costo: 17.5
Cantidad: 122
Tu opcin?
3
Ests en consultas
Cul nmero de parte:
500
Producto no existe
Para la opcin de Baja:
Tu opcin?
2
Ests en bajas
Cul nmero de parte:
500
Producto no existe

32

Tu opcin?
2
Ests en bajas
Cul nmero de parte:
200
Tu opcin?
5
Ests en listado
Producto No. parte: 100
Descripcin: Cereal
costo: 23.5
Cantidad: 25
Producto No. parte: 300
Descripcin: Refresco
costo: 9.5
Cantidad: 90
Para la opcin de Cambio:
Tu opcin?
4
Ests en cambios
Cul nmero de parte:
100
Producto No. parte: 100
Descripcin: Cereal
costo: 23.5
Cantidad: 25
Qu campo (variable) deseas cambiar
Descripcin [D]
Costo [C]
Cantidad [Ca]
Tu opcin
c
Nuevo costo
20.50
Tu opcin?
3
Ests en consultas
Cul nmero de parte:
100
Producto No. parte: 100
Descripcin: Cereal
costo: 20.5
Cantidad: 25
33

Las opciones Salvar [6] y Cargar [7] relacionadas con el manejo de


archivos se desarrollarn en el unidad seis (Flujos y Archivos). Ver
detalle de las clases que conforman este problema propuesto en el
anexo A.

Ejercicios propuestos:
1. Leer n nmeros y contar cuntos son pares, negativos y ceros.
2. Leer n calificaciones y contar cuntos estn arriba de la media, y
cuntos por debajo de ella.
3. Encontrar el mayor y el menor de un arreglo de n nmeros.
4. Leer n nombres de personas y determinar cul es la moda.
5. Crear un arreglo de 40 nmeros aleatorios binarios.
6. Crear un arreglo de 10 nmeros aleatorios hexadecimales irrepetibles.
7. Programar los siguientes mtodos de la clase Arrays (consulta el API de
Java para ver detalle de los mtodos):
Copiar un arreglo
Llenar un arreglo
Ordenar un arreglo
Convertir a String un arreglo.
Buscar un elemento dado en un arreglo.
copiaDe() y todas las sobrecargas.
busqueda()
copiaDeRango()
equals()
deepEquals()
fill()
hashCode()
deepHashCode()
sort()
toString()
deepToString()
8. Programar los mtodos que permitan operaciones bsicas sobre

arreglos [2]:
Bsqueda
Ordenamiento
Insercin
Eliminacin
9. Programar aplicaciones para los siguientes ejercicios bsicos entre
vectores:
Suma de vectores
Resta de vectores
Producto escalar o producto punto
Producto vectorial

34

Transpuesta de un arreglo
10. Programar una clase instanciable Triangulo Irregular que contenga,

a su vez, un arreglo de tres objetos de la clase Punto, y permita el


clculo del permetro y rea de un triangulo de este tipo. Nota: no
aplica la formula a = ( b * h ) / 2 propia de los tringulos
rectngulos.
El clculo del semi permetro es:
sp=(a+b +c) /2
donde:
a, b, y c son las distancias entre vrtices.
El clculo de rea es;

a= sp( spa ) ( spb )( spc )

35

Unidad 2.- Arreglos de dos dimensiones


Objetivo: Comprender el uso de la coleccin de datos bidimensional.
Utilizar matrices para resolver problemas. Comprender el concepto de
arreglo ene dimensional.
Definicin del concepto de matriz
Los arreglos de dos dimensiones tambin conocidos como arreglos
bidimensionales o matrices son soportados mediante la programacin
Java. A continuacin veamos la forma en que se puede declarar una de
estas colecciones bidimensionales de datos.
Sintaxis para la declaracin:
tipo_dato nombre_arreglo[][];
Ejemplo, declarar de un arreglo (datos) de dos dimensiones:
int datos[][];
Al igual que los arreglos unidimensionales se deber dimensionar el
arreglo bidimensional pero usando dos dimensionadores:
Ejemplo, dimensionar el arreglo anterior con 4 columnas y 5 filas:
datos = new int[4][5];
Se pude declarar y dimensionar al mismos tiempo:
double matriz[][] =

new double[64][128];

Tambin se pude declarar y dimensionar en dos tiempos:


double matriz[][];
System.out.println(Cuntas columnas ? );
int x = s.nextInt();
System.out.println(Cuntas filas ? );
int y = s.nextInt();
matriz =

new double[x][y];

36

A continuacin se declara una matriz k de 4 x 3 (cuatro columnas, tres


filas) que se auto dimensiona y se inicializa con los valores indicados:
int k [][] = { {1,3,5,7}, {5,4,1,16}, {7,9,61,13} };
En la Tabla 2.1 podemos ver la disposicin de columnas y filas en la
matriz k.
Columnas
0 1 2 3
0 1 3 5 7
Fil 1 5 4 1 1
as
6
2 7 9 6 1
1 3
Tabla 2.1.- Arreglo bidimensional (matriz)
Declaracin de una referencia de tipo matriz
Cuando se utilizan referencias a matrices debemos tener en cuenta que
no son copias sino accesos a los datos originales. As, si consideramos
que tenemos un mtodo que muestra todos los elementos contenidos en
una matiz:
public void muestraMatriz(int arr[][])
{
for(int i; i<arr.length; i++)
{
for(int j=0; arr[i].length; j++)
{
System.out.println(arr[i][j]);
}
}
}
Decimos que los arreglos bidimensinales al igual que los
unidimensionales siguen siendo objetos, por lo que al pasarlos como
argumentos se comportarn como de tipo por referencia y no de tipo por
valor.
La Figura 2.1 muestra el diagrama para una matriz bidimensional.
Podemos observar que puede ser considerada de dos formas: como una
matriz de 5 columnas 3 filas (ver Figura 2.1), o como un arreglos de tres
arreglos de 5 enteros cada uno (ver Figura 2.2).

37

Figura 2.1.- arreglos de 5 columnas y tres filas


http://4.bp.blogspot.com/3bmtKVAW5Yw/UMZdPs7mbpI/AAAAAAAAAG0/3pUhN64QLI/s1600/matriz-java-1.jpg

Figura 2.2.- Arreglo de tres arreglos de 5 enteros cada uno


http://3.bp.blogspot.com/4D4u4fWzklU/UMZgIWNL0CI/AAAAAAAAAHU/pdhefsibOiY/s1600/matrice
s-java.jpg
Tambin se pueden tener matrices irregulares, por ejemplo:
int [][]m = new int[3][];
//crea una matriz m de 3 filas.
A cada fila se le puede asignar un nmero distinto de columnas:
m[0] = new int[3];
m[1] = new int[5];
m[2] = new int[2];
La Figura 2.3 muestra la disposicin de una matriz irregular que algunos
denominan tipo diente en sierra.

Figura 2.3.- Matriz irregular


http://4.bp.blogspot.com/-pQGQ1RaERQ/UMZfa4r5NgI/AAAAAAAAAHM/fceBm9gzEYA/s1600/arrays-irregularesjava.jpg

38

Podrs encontrar otros ejemplos ilustrativos en la referencia [3].


Creacin de un objeto matriz
Como dijimos, la creacin de un objeto tipo matriz o tipo arreglo de dos
dimensiones consiste en la declaracin y doble dimensionamiento de un
arreglo.
int

matriz [][] = new int [10][20];

Despus de la declaracin y dimensionamiento debers leer cada uno de


los datos en la matriz, para esto debers usar un for anidado. El primero
deber permitir todas las columnas y el segundo todas las filas, o
viceversa.
for(int i=0; i<matriz.length; i++)
{
for(int j=0; matriz[i].length; j++)
{
System.out.println(matriz [+i+][+j+]);
matriz[i][j] = s.nextInt();
}
}
Seleccin de los componentes
Para seleccionar los elementos debers acceder va los dos ndices, esto,
tanto para acceder al valor del elemento en la columna i y fila j, o para
modificar su valor.
Acceder al elemento columna i y fila j y modificarlo aadiendo el valor
de desviacin:
matriz[i][j] = matriz[i][j] + desviacion;
Diseo de una clase instanciable con una matriz como atributo
As como una clase instanciable puede contener un arreglo
unidimensional, tambin puede contener un arreglo de dos o ms
dimensiones.
Problema propuesto 2.1
Disear una clase instanciable Arreglo2D definida por el diagrama UML
descrito en la Tabla 2.2 y una aplicacin como se muestra en la Figura
2.4:

39

Figura 4.- Diagrama de clases para el problema propuesto


Arreglo2D
- mx [][] : int
+ Arreglo2D()
+ Arreglo2D(col:int, fil: int)
+ leerDatos(): void
+ getElemento(col:int, fil:int) : int
+ setElemento(col: int, fil: int,
dato:int) : void
+ toString() : String
Tabla 2.2.- Diagrama UML para la clase Arreglo2D
El cdigo para la aplicacin AppMatrices es:
public class AppMatrices
{
public static void main(String args[])
{
Arreglo2D ma = new Arreglo2D();
System.out.println("Matriz A");
ma.leerDatos();
System.out.println(ma.toString());
Arreglo2D mb = new Arreglo2D(2,4);
System.out.println("Matriz B ");
mb.leerDatos();
System.out.println(mb.toString())
}//main
40

}//class
El cdigo para la clase instanciable Arreglo2D es:
import java.util.*;
public class Arreglo2D
{
private int mx[][];
Scanner s = new Scanner(System.in);
public Arreglo2D()
{
System.out.println("Columnas? ");
int n = s.nextInt();
System.out.println("Filas? ");
int m = s.nextInt();
mx = new int[n][m];
}
public Arreglo2D(int col, int fil)
{
mx = new int[col][fil];
}
public void leerDatos()
{
for(int i=0; i<mx.length; i++)
{
for(int j=0; j<mx[i].length; j++)
{
System.out.println("matriz
["+i+"]["+j+"]");
mx[i][j] = s.nextInt();
}
}
}
public int getElemento(int col, int fil)
{
return mx[col][fil];
}
public void serElemento(int col, int fil, int dato)
{
mx[col][fil] = dato;
}
public String toString()
{
String aux = "Matriz de "+ mx.length+ "x"+
41

mx[0].length +"\n";
for(int i=0; i<mx.length; i++)
{
aux = aux + Arrays.toString(mx[i])+"\n";
}
return aux;
}
}
La ejecucin de la aplicacin es:
Columnas?
2
Filas?
2
Matriz A
matriz [0][0]
1
matriz [0][1]
2
matriz [1][0]
3
matriz [1][1]
4
Matriz de 2x2
[1, 2]
[3, 4]
Matriz
matriz
1
matriz
2
matriz
3
matriz
4
matriz
5
matriz
6
matriz
7
matriz
8

B
[0][0]
[0][1]
[0][2]
[0][3]
[1][0]
[1][1]
[1][2]
[1][3]
42

Matriz de 2x4
[1, 2, 3, 4]
[5, 6, 7, 8]
Problema propuesto 2.2
Disear una clase instanciable Matrices que permita realiza la operacin
suma de dos matrices. Deber utilizar la clase anterior (Arreglo2D) y
deber contener las variables y mtodos descritos por el diagrama UML
de la tabla 2.3.
Matrices
- a: Arreglo2D
- b: Arreglo2D
- c: Arreglo2D

+ Matrices()
+Matrices(col:int, fil: int)
+ leerMatrices(): void
+ sumarMatrices(): void
+ toString() : String
Tabla 2.3 Diagrama UML para la clase Matrices
El diagrama de clases puede verse en la Figura 2.5.

Figura 2.5 Diagrama de clases para el problema propuesto 2.2


El cdigo para la aplicacin AppMatrices es:
import java.util.*;
43

public class AppMatrices


{
public static void main(String args[])
{
Scanner s = new Scanner(System.in);
System.out.println("Columnas? ");
int n = s.nextInt();
System.out.println("Filas? ");
int m = s.nextInt();
Matrices ms = new Matrices(n,m);
ms.leerMatrices();
ms.sumarMatrices();
System.out.println(ms.toString());
}
}
El cdigo para la clase instanciable Matrices es:
public class Matrices
{
private Arreglo2D a;
private Arreglo2D b;
private Arreglo2D c;
public Matrices(int col, int fil)
{
a = new Arreglo2D(col,fil);
b = new Arreglo2D(col,fil);
c = new Arreglo2D(col,fil);
}
public void leerMatrices()
{
a.leerDatos();
b.leerDatos();
}
public void sumarMatrices()
{
44

for(int i=0;i<a.getColumnas();i++)
{
for(int j=0; j<a.getColumnas(); j++)
{
c.setElemento(i,j, a.getElemento(i,j) +
b.getElemento(i,j));
}
}
}
public String toString()
{
String aux = a.toString() + "\n" +
b.toString() + "\n" +
c.toString() ;
return aux;
}
}
La corrida es:
Columnas?
2
Filas?
2
matriz [0][0]
1
matriz [0][1]
2
matriz [1][0]
3
matriz [1][1]
4
matriz [0][0]
1
matriz [0][1]
2
matriz [1][0]
3
matriz [1][1]
4
Matriz de 2x2
[1, 2]
[3, 4]
Matriz de 2x2
[1, 2]
[3, 4]

45

Matriz de 2x2
[2, 4]
[6, 8]

Para ms detalles sobre el manejo de arreglos podrs visitar la pgina


de Oracle [4].
Ejercicios propuestos:
1.
2.
3.
4.
5.

Programar una aplicacin que permita realizar la suma de matrices.


Mismo problema anterior pero usando clases instanciables.
Programar una aplicacin que permita realizar la resta de matrices.
Mismo problema anterior pero usando clases instanciables.
Programar una aplicacin que permita realizar el producto escalar o
producto punto matrices.
6. Mismo problema anterior pero usando clases instanciables.
7. Programar una aplicacin que permita realizar el producto vectorial de
matrices.
8. Mismo problema anterior pero usando clases instanciables.
9. Programar una aplicacin que permita realizar la transpuesta de una
matriz.
10.Mismo problema anterior pero usando clases instanciables.
11.Programar una aplicacin que permita realizar la inversa de una matriz.
12.Mismo problema anterior pero usando clases instanciables.
13.Programar una aplicacin que permita calcular el determinante de una
matriz.
14.Mismo problema anterior pero usando clases instanciables.
15.Programar una aplicacin que permita calcular la pseudo inversa de
Moore de una matriz.
16.Mismo problema anterior pero usando clases instanciables.

46

Unidad 3.- Mtodos y parmetros de tipo objeto


Objetivo: Comprender el uso de parmetros por referencia. Programar
mtodos de instancia que reciben objetos. Comprender y utilizar los
arreglos de objetos.
Desarrollo de contenido:
De acuerdo al libro Aprobar Java [6] existen cinco tipos de mtodos. Esta clasificacin
obedece ms bien a las diferentes combinaciones que puede presentar la firma de un
mtodo. La firma consiste en la estructura de diseo formal que define a un mtodo. Las
partes que incluye la firma son:

Nombre del mtodo.


Tipo de regreso
Argumentos de entrada o formales
Modificador de acceso
Modificador tipo clase o de instancia

Como en todos los lenguajes un mtodo no podr ser duplicado (poseer la misma firma).
Dos o ms mtodos si podrn llamarse iguales (concepto de Sobrecarga overload ),
siempre y cuando posean diferente firma. Esto se logra diferendo en la cantidad y/o tipo de
sus argumentos.
Sintaxis:
modificador-acceso clase_o_instancia tipo_retorno nombre (argumentos_formales)
{
estatutos que dan funcionalidad particular al mtodo;
}
Cinco tipos de mtodos descritos en [6]:
Mtodos que reciben parmetros de entrada y retornan un valor, el mtodo
charAt, recibe un argumento de entrada, este es de tipo int (el nombre index
no es importante), y retorna un char. La funcin que desempea se anota
abajo. Adems el mtodo es de acceso pblico y de tipo instancia. Este mtodo
pertenece a la clase String que se encuentra en el package java.lang.
public char

charAt(int index)
Returns the char value
the specified index.

at

Tabla 3.1.- Mtodo charAt


Mtodos que reciben parmetros de entrada y no retornan valor, el
mtodo println, recibe un argumento de entrada, este es de tipo int (el
nombre x no es importante), y retorna void. La funcin que desempea se

47

anota abajo. Adems el mtodo es de acceso pblico y de tipo instancia. Este


mtodo pertenece a la clase PrintStream que se encuentra en el package
java.io.
public void

println(int x)
Prints an integer and then
terminate the line.
Tabla 3.2.- Mtodo println

Mtodos que no reciben parmetros de entrada y retornan un valor, el


mtodo nextInt, recibe cero argumentos de entrada (no se escribe void), y
retorna un int. La funcin que desempea se anota abajo. Adems el mtodo
es de acceso pblico y de tipo instancia. Este mtodo pertenece a la clase
Scanner que se encuentra en el package java.util.
public int

nextInt()
Scans the next token of the
input as an int.
Tabla 3.3.- Mtodo nextInt

Mtodos que no reciben parmetros de entrada y no retornan valor, el


mtodo init, recibe cero argumentos de entrada (no se escribe void), y
retorna void. La funcin que desempea se anota abajo. Adems el mtodo es
de acceso pblico y de tipo instancia. Este mtodo pertenece a la clase Applet
que se encuentra en el package java.applet.
public void

init()
Called by the browser or
applet viewer to inform this
applet that it has been
loaded into the system.
Tabla 3.4.- Mtodo init

Mtodos que en sus parmetros reciben objetos, stos como son


referencias, pueden ser usados como un parmetro de entrada o de salida, el
mtodo sort, recibe un argumento de entrada de tipo arreglo de enteros (int),
y retorna void. La funcin que desempea se anota abajo. Adems el mtodo
es de acceso pblico y de tipo clase. Este mtodo pertenece a la clase Arrays
que se encuentra en el package java.util.
static void

sort(int[] a)

Sorts the specified array into


ascending numerical order.

Tabla 3.5.- Mtodo sort


Cuando uno de los argumentos del mtodo es un objeto (los arreglos son
objetos), se dice que el paso de parmetros es por referencia, contrario al paso

48

de parmetros por valor (cuando el argumento es una variable de tipo


primitivo).
El paso de parmetros por valor copia el argumento actual en el
argumento formal, si se modifica el argumento formal, el argumento actual
queda
intacto.
Por
ejemplo:
int
altura
=
101;
System.out.println(valor);, el valor 101 del argumento actual (variable
valor) se copia en el argumento formal (variable x, segn API), si la variable x
cambia, el valor de la variable altura queda intacto. Esto es el paso de
parmetros por valor.
El paso de parmetros por referencia sucede cuando uno de los
argumentos es un objeto, stos por default son pasados por referencia. En este
caso el argumento formal tiene la referencia del argumento actual, si el
argumento formal cambia, el argumento actual tambin cambia.
En este sentido, el mtodo sort recibe en su argumento formal un arreglo
de enteros, dado que el mtodo retorna void, se puede pensar que regresa
nada, pero en realidad, al trmino del mtodo, el arreglo retorna ordenado,
aunque realmente no retorna, ms bien el ordenamiento se realiza
directamente sobre el argumento local que fue pasado como referencia al
argumento formal. Parece un juego de palabras, pero podemos encerrar esta
enseanza de la siguiente manera: Cada vez que pasamos un objeto, este se
pasa por referencia, por lo tanto el mtodo tiene acceso a los campos y
mtodos propios del objeto original. Dicho de otra manera, si no quieres que
un mtodo tenga acceso a los campos y mtodos del objeto original, saca una
copia y psala como argumento del mtodo en cuestin; si la copia sufre algn
cambio, el objeto original permanece intacto.
Este es el quinto tipo de mtodo de acuerdo a su prototipo. No es el tipo
de mtodo ms raro sino el ms utilizado. Ms adelante aprenderemos que los
modificadores de acceso public, protected, y private se utilizan para dar
diferentes tipos de acceso a los campos y mtodos en una clase. Tambin, la
presencia del modificador static indica que el campo o mtodo es tipo clase.
La ausencia de este indica que es ms bien de tipo instancia.
Queremos recordar nuestra aseveracin, si aprendemos a leer cdigo y su
documentacin, obtendremos poder programtico que nos facilitar la tarea de
disear y programar nuestras propias clases y proyectos de software.

El quinto tipo corresponde con el motivo de esta unidad.


Ejercicios propuestos:
1. Disear un mtodo de clase que recibe un arreglo de enteros y
el mayor.
2. Disear un mtodo de clase que recibe un arreglo de enteros y
el menor.
3. Disear un mtodo de clase que recibe un arreglo de enteros y
el promedio.
4. Disear un mtodo de clase que recibe un arreglo de enteros y
la desviacin estndar.
5. Disear un mtodo de clase que recibe un arreglo de dobles y
sus datos de forma ascendente.

regresa
regresa
regresa
regresa
ordena

49

6. Disear un mtodo de clase que recibe un arreglo de dobles y ordena


sus datos de forma descendente.
7. Disear un mtodo de clase que recibe un tres arreglos de dobles: el
primero lo concatena con el segundo y produce el tercero.
8. Disear un mtodo de clase que recibe un arreglo de dobles y coloca en
un arreglo todos los datos menores que el promedio, y en otro, los
mayores.
9. Disear un mtodo de clase que recibe un arreglo de chars y verifica si
se trata de un palndromo.
10.Disear un mtodo de clase que recibe un arreglo de chars y busca
fechas textuales descritas por DD/MM/AAAA. Tip: usar la clase
StringTokenizer [7].

50

Unidad 4.- Extensin de clases


Objetivo: Comprender el concepto de reutilizacin de cdigo mediante
herencia. Solucin de problemas usando herencia. Utilizacin del
polimorfismo.
Acerca de la reutilizacin de cdigo, una es la instanciacin de una clase,
y otra es la extensin de ella.
Instanciacin: En el ejemplo que sigue, se puede ver la declaracin de
dos objetos, uno instancia de la clase String, y otro de la clase
StringTokenizer. Dado que puedes tener tantos objetos instancia de
cualquier clase (instanciable) como sean necesarios, podemos decir que
este es un tipo de reutilizacin de cdigo. Cabe mencionar que para las
clases String y StringTokenizer no es necesario tener el cdigo fuente
(.java) sino el byte (.class).
String palabra = new String(Programando en Lenguaje Java);
StringTokenizer st = new StringTokenizer(palabra, );
while(st.hasMoreTokens())
{
System.out.println(st.nextToken());
}
La ejecucin es:
Programando
en
Lenguaje
Java
Otro tipo de reutilizacin de cdigo es mediante la extensin de una
clase existente. Esto se logra mediante el uso del estatuto extends,
como se ilustra en el siguiente ejemplo. Para este tipo de reutilizacin
tampoco se necesita el cdigo fuente slo el byte.
Sintaxis para lograr la extensin de una clase:
public class NombreClaseExtendida extends NombreClaseBase
{
//variables que se suman a las heredadas
//mtodos que se suman a los heredados
}

51

Si tenemos una
JugadorDeTenis:

clase

Jugador

podemos

extender

la

clase

public class JugadorDeTenis extends Jugador


{
//variables
//mtodos
}
De hecho, aunque nunca lo habamos mencionado, la herencia el
mecanismo de herencia ya estaba al alcance de nuestra mano. En Java,
se dice que ninguna clase puede subsistir por s sola. Toda clase debe
ser extendida de otra clase existente, al menos de la clase ms bsica
de Java, la clase Object.
El API de Java, es entonces un nico rbol de clases con raz en la clase
Object. Se dice que tan alejado est una clase de la raz ms
especializada ser, lo mismo en sentido contrario, la clase ms cercana
a la raz es ms bsica.
As como el compilador aade cierto cdigo a la hora de la compilacin:
importar el paquete java.lang, convertir tipos de datos tambin agrega
la parte que permite a una clase extenderse de la clase Object.
La clase Tringulo que habamos programado en un curso bsico
anterior:
public class Triangulo
{
//variables
//mtodos
}
En el proceso de compilacin realmente queda as:
import java.lang.*;
public class Triangulo extends Object
{
//variables
//mtodos
}
El diagrama de clases queda:
Object
es un
Triangulo

52

Figura 4.1 Diagrama de clases con relacin es_un


La relacin de las clases (denotada por la flecha contigua) es del tipo
es_un, e indica que la clase Triangulo es un Objeto. La direccin de la
flecha indica cul es la clase que se extiende de la clase base.
Despus de todo, Java, siendo un Lenguaje Orientado a Objetos, todo es
un objeto. Todo excepto las variables de tipo primitivo. Aunque para eso
existen las clases del tipo wrapper class. Existe una clase Double, por
ejemplo, para emular el tipo doubl, pero a nivel objeto. Ahora s, todo
es objeto en Java.
Si toda clase al menos se extiende de la clase Object, entonces en cada
clase que hemos programado tuvimos el poder programtico que provee
esta clase, pero nunca lo utilizamos. Cules son algunos de estos
mtodos o variables que la clase Object nos provea desde siempre?
Vayamos al API de Java y consultemos.
Se provee para la clase Object el constructor de la Figura 4.2:

Figura 4.2.- Constructor para la clase Object


Se provee para la clase Object los mtodos de la Figura 4.3:

53

Figura 4.3.- Alguno mtodos para la clase Object


Clases que no podrn extenderse
El nico tipo de clases que no podrn ser extendidas son las que fueron
definidas con el modificador final:
public final class nombreClase
{
//variables
//mtodos
}
Clases como la String son del tipo anterior. Jams se podr extender una
clase a partir de String. Esto se realiza cuando no deseas que existan
variaciones de clases tan clsicas como Math, y String, entre otras.
Los modificadores de acceso se ven en la Tabla 4.1:
private
public
protected

Ninguna clase podr utilizar


variables o mtodos privados.
Todas las clases podrn ver o
utilzar variable o mtodos con
este modificador.
Slo las clases derivadas podrn
ver y utilizar elementos de este
tipo.
54

no
modificador

Las clases en el mismo paqute


tienen acceso a este tipo de
variables o mtodos.
Tabla 4.1 Modificadores de acceso

En suma, slo las variable de tipo publico o protegido podrn ser


reutilizadas mediante el mecanismo de herencia. Para las variables de
tipo privado siempre tendremos la opcin de agregar un accesor del tipo
get o set.
Problema propuesto 4.1
Disear una clase base PuntoUnaDimension que se extienda de la clase
Object, deber contener las variables y mtodos descritos en el
diagrama UML de la Tabla 4.4.
PuntoUnaDimension
# x: int

+ PuntoUnaDimension()
+setX(a: int): void
+ getX(): int
+ leerX(): void
+ toString() : String
Tabla 4.4 Diagrama UML para la clase PuntoUnaDimension
Segn [8], en UML los diferentes modificadores de acceso son como se
muetra en la Tabla 4.5.
+

private
Public
Packag
e
# Protect
ed
Tabla 4.5 Diferentes modificadores de acceso segn UML
El cdigo para la clase PuntoUnaDimensin es:
import java.util.*;
public class PuntoUnaDimension extends Object

55

{
protected int x; //x es heredable
public PuntoUnaDimension()
{
x = 0;
}
public void setX(int abs)
{
x = abs;
}
public int getX()
{
return x;
}
public void leerX()
{
Scanner s = new Scanner(System.in);
System.out.println("valor de x= ");
x = s.nextInt();
}
@Override
public String toString()
{
return "Soy un punto en 1D x = "+x;
}
}

Podemos notar que se antepuso al mtodo toString() la directiva


@Override, que le indica al compilador que el programador est
consciente que dicho mtodo anula el mismo mtodo heredado de la
clase Object. Lo anterior debido a que el mtodo original no aplica en el
mbito de un Punto en una dimensin. A esto se le llama ocultamiento
(override). Decimos que la mejor forma de ocultar un mtodo heredado
es ocultarlo de forma accidental. La directiva en cuestin indica que el
ocultamiento es a propsito.
Ahora, utilizando el mecanismo de herencia, extender la clase
PuntoUnaDimension para programar la clase PuntoDosDimensiones. Ver
Tabla 4.6 para el detalle de la clase.
PuntoDosDimensiones
# y: int

+ PuntoDosDimensiones()
+setY(a: int): void

56

+ getY(): int
+ leerY(): void
+ toString() : String
Tabla 4.6.- Diagama UML para la clase PuntoDosDimensiones
Al extendernos de la clase PuntoUnaDimension, heredamos la variable x
(abscisa), y slo aadimos el cdigo alrededor de la variable y
(ordenada).
import java.util.*;
public class PuntoDosDimensiones extends
PuntoUnaDimension
{
//la variable x la hereda
protected int y; //y es heradable
public PuntoDosDimensiones()
{
super();
//x=0;
y=0;
}
public void setY(int ord)
{
y = ord;
}
public int getY()
{
return y;
}
//leerX() lo hereda
public void leerY()
{
Scanner s = new Scanner(System.in);
System.out.println("valor de y= ");
y = s.nextInt();
}
@Override
public String toString()
{
return "Soy un punto en 2D x = "+x+" y= "+y;
}
}

Si queremos programar la clase PuntoTresDimensiones podemos


empezar de cero, programando tres variables de instancia (x, y, y z),
pero si nos extendemos de la clase PuntoDosDimensiones nos
ahorraremos mucho cdigo. Slo debemos aadir la parte del eje z, la
57

denominada cota. El diagrama UML para esta clase se pude ver en la


Tabla 4.7.
PuntoTresDimensiones
# z: int

+ PuntoTresDimensiones()
+setZ(a: int): void
+ getZ(): int
+ leerZ(): void
+ toString() : String
Tabla 4.7.- Diagrama UML para la clase PuntoTresDimensiones
El cdigo par la clase PuntoTresDimensiones es:
import java.util.*;
public class PuntoTresDimensiones extends
PuntoDosDimensiones
{
//la variable x la hereda
//la variable y la hereda
private int z;
PuntoTresDimensiones()
{
super();//x=0, y=0
z=0;
}
public void setZ(int aux)
{
z = aux;
}
public int getZ()
{
return z;
}
//leerX() lo hereda
//leerY() lo hereda
public void leerZ()
{
Scanner s = new Scanner(System.in);
System.out.println("valor de z= ");
z = s.nextInt();
}
@Override

58

public String toString()


{
return "Soy un punto en 3D x = "+x+" y= "+
y+" z= "+z;

}
}

El diagrama de clases para este problema propuesto se pude apreciar en


la Figura 4.4:

Figura 4.4.- Diagrama de clases para el problema propuesto 4.1


El cdigo para la aplicacin PruebaPuntos es:
public class PruebaPuntos
{
public static void main(String args[])
{
PuntoUnaDimension p1;
PuntoDosDimensiones p2;
PuntoTresDimensiones p3;
p1 = new PuntoUnaDimension();
p1.leerX();
System.out.println(p1.toString());
p2 = new PuntoDosDimensiones();
p2.leerX();
p2.leerY();
System.out.println(p2.toString());
p3 = new PuntoTresDimensiones();
p3.leerX();

59

p3.leerY();
p3.leerZ();
System.out.println(p3.toString());

La corrida para este proyecto es:


valor de x=
2
Soy un punto en 1D x = 2
valor de x=
4
valor de y=
5
Soy un punto en 2D x = 4 y= 5
valor de x=
7
valor de y=
8
valor de z=
9
Soy un punto en 3D x = 7 y= 8 z= 9
Polimorfismo:
Polimorfismo hace referencia al principio biolgico en el cual un
organismo o especie puede manifestar diferentes formas o estadios. El
ejemplo clsico es usar el operador suma del contexto aritmtico como
operador de concatenacin en en contexto cadenas de caracteres.
Ejemplo:
System.out.println(10+20);
System.out.println("suma = "+10+20);
Debido a que uno de los operandos es String, el operador suma se
convierte en concatenacin. La ejecucin es:
30
suma = 1020
Ejemplo con clases:
Object ob = new String("Programacin");
System.out.println(ob);
La ejecucin es:

60

Programacin
Si invertimos el orden, es decir que un objeto instancia de una subclase
se trate de construir usando una superclase:
String nombre = new Object();
System.out.println(nombre);
El error arrojado es:
incompatible types: java.lang.Object cannot be converted to
java.lang.String
En conclusin: Un objeto slo puede ser construido con cualquiera de las
subclases de la cual fue instanciado. Esto es el concepto de
polimorfismo
Clases abstractas:
Una clase abstracta es una clase que es declarada abstract. Puede tener
o no tener mtodos abstractos. No puede ser instanciada pero si puede
ser extendida. Tambin puede ser extendida por otra clase abstracta.
Como dijimos, ninguna clase abstracta superclase o subclasejams
podr ser instanciada.
La sintaxis de una clase abstracta es:
public abstract class UnaClase {
// declarar campos
// declarar mtodos no abstractos
abstract void draw(); //ejemplo de mtodo abstracto
}
Un mtodo abstracto es declarado sin su implementacin. No tendr
asociado un bloque de cdigo. Ejemplo:
abstract void desplazarseA(double incX, double incY);
Considera el uso de clases cuando, en el ambiente de herencia, deseas
que un conjunto de subclases compartan un cierto cdigo base. Con los
mtodos abstractos aseguras que todas las clases implementen su
propia versin de cdigo. Si la clase derivada no implementa el cdigo
de los mtodos abstractos entonces deber ser tambin una clase
abstracta. Las clases derivadas, sino son abstractas de nuevo, podrn
ser instanciadas.
Interfaces:
61

Una interface, al igual que una clase, es una referencia que puede tener
constantes, firmas de mtodos, mtodos tipo default, mtodos estticos,
y tipos anidados.
Ejemplo:
public interface Carro {
// declaracin de constantes, si son necesarias
// firmas de mtodos
int encender(Direccion direccion,
double radio,
double velInicial,
double velFinal);
int cambiarEngranes(Direccion direccion,
double velInicial,
double velFinal);
int encenderSeal(Direccion direccion,
boolean sealEncendido);
int getRadarFrontal(double distanciaACarro,
double velDeCarro);
int getRadarAtras(double distanciaACarro,
double velDeCarro);
...
// ms firmas de mtodos
}
Usa una interface cuando deseas que clases no relacionadas
implementen tu interface.
Las interfaces son usadas para tratar de emular la herencia mltiple que
en Java est prohibido. Se dice que una clase slo puede extenderse de
una clase pero implementar tantas interfaces como sea necesario:
public class TelefonoInteligente extends
DispositivoElectronico implements Calendario,
Calculadora, Agenda, Mensajera
{
//campos o variables
//mtodos
}
62

Ejercicios propuestos:
1. Disear el proyecto que se muestra en la Figura 4.5:

Figura 4.5 Proyecto empresa


2. Programar la siguiente aplicacin:

Figura 4.6 Proyecto Circulo-Cilindro


3. Agrega lo necesario al proyecto anterior para que se reutilice el cdigo
de la Clase Cilindro y se derive la clase Tubo:

63

Figura 4.7 Proyecto Circulo-Cilindro-Tubo


4. Desarrolla el cdigo para el siguiente proyecto:

Figura 4.8 Proyecto Jugadores

64

Unidad 5.- Excepciones


Objetivo: Programar la parte que valida los datos de un programa.
Deteccin de excepciones existente. Utilizacin y atrapado de
excepciones existentes. Programacin de clases definidas por el
programador.
Definicin del concepto de excepcin
Una excepcin es un evento que ocurre durante la ejecucin de un
programa y que interrumpe el flujo normal de ejecucin. Los lenguajes
de programacin usan excepciones (exceptions) para administrar el
manejo de errores
Tipos de excepciones predefinidas
Siempre hemos dicho que el API de Java es un conjunto de clases
predefinidas provistas por Java para que el programador no inicie desde
cero. A su vez, hemos aseverado que subconjutnos de clases
relacionadas se organizan a manera de paquetes (packages). Entonces,
un paquete, es un conjunto de clases relacionadas. Debemos ampliar
esta definicin diciendo que, un paquete, no slo contiene clases sino
excepciones relacionadas. Ver Figura 5.1 para el detalle de clases y
excepciones contenidas en el paquete java.util.

Figura 5.1.- Paquete java.util


65

De hecho cada paquete contiene no slo clases y excepciones, sino


tambin enumerados (enum) e interfaces (interface) relacionadas.
Algunas de las excepiones ms conocidas son:
Exception, una clase que se extiende de la clase Throwable, de la cual
adquiere la caracterstica de ser Lanzabe. Ninguna clase normal podr
ser lanzable a no ser que sea una excepcin. Esta excepcin est
contenida en el paquete java.lang.
IOException, se lanza de forma automtica cuando el formato de
entrada no coinicide con el esperado. Si tratar de leer un tipo entero y el
usuario teclea un double se lanzar este tipo de excepcin. Excepcin
contenida en java.io.
NumbreFormatException, se lanza cuando al parsear un tipo hacia
otro no se logra realizar la conversin. Est contenida en el paquete
java.lang.
ArrayIndexOutOfBoundsException, una excepcin clsica en el
mbito de los arreglos. Cuando el programa trata de acceder un
elemento del arreglo fuera del mismo se lanza esta excepcin. Esta
excepcin tambin est contenida en el paquete java.lang.
Cuando una excepcin se lanza provocar que el programa sea
abortado. Lo interesante en este caso es programar cdigo que atrape y
maneje la excepcin. Como dijimos, el manejo de excepciones est ms
bien relacionado con la validacin de datos. Un poco lo que revisara un
Software Tester. Recordemos que existen dos tipos de usuarios naturales
que enfrentarn nuestros progamas de computadors: a) el usuario
inexperto que sin malicia introduce entradas no naturales, y b) el usuario
experto que tratar de vulnerar nuestro cdigo.
Propagacin
La propagacin de las excepciones se logra a travs de anunciar en el
mtodo que las contiene el suceso de lanzamiento.
public void miMetodo() throws ExcepcionTipo1, ExcepcionTipo2
{
// Algn cdigo que puede lanzar (throw)
// alguna de las excepciones anunciadas
}
Manejo y lanzamiento de excepciones
Las excepciones se puden lanzar o son lanzadas por cdigo en las
clases. El punto es atrapar estas excepciones para dar un tratamiento,
66

que va desde emitir un mensaje hasta interactuar con el usuario para


corregir el error.
La sintaxis para el manejo de una excepcin es:
Try
{
//cdigo que puede lanzar la excepcin UnaException
//cdigo que puede lanzar la excepcin OtraException
}
catch (UnaException ue)
{
//mensaje de error
//imprimir la excepcin
System.err.println("UnaExceptionn atrapada: " +
ue.getMessage());
}
catch (OtraException oe)
{
System.err.println("OtraException atrapada: " +
oe.getMessage());
}
finally
{
//cerrar archivos
//eliminar objetos
//etc.
}

Nota: si se programan ms de un bloque catch, se deber tener cuidado


con las excepciones que estn relacionadas por herencia, ya que por
efecto de polimorfismo una excepcin ms general (superclase) atrapar
todas las excepciones que se extendieron a partir de ella (subclases). Es
decir, las excepcin ms especializadas jams entrarn en accin. No te
preocupes, el compilador no dejar que hagas este tipo de disposicin
de excepciones. Debers tener cuidado de programar la ms especfica
primero y as sucesivamente hasta llegar a la ms general.
Excepciones definidas por el usuario (programador) excepciones
propias.
Ilustremos este tema mediante un ejemplo:
class EntradaEquivocadaException extends Exception
{
EntradaEquivocadException(String s)
{
super(s);

67

}
}
class Entrada
{
void metodo() throws EntradaEquivocadaException
{
throw new EntradEquivocadaException("Entrada invlida");
}
}
class PruebaEntrada
{
public static void main(String[] args)
{
try {
new Entrada().metodo();
}
catch(EntradaEquivocadaException eee) {
System.out.println(eee.getMessage());
}
}
}

Como puedes ver, debido al mecanismo de herencia, lograr que una


clase se comporte como una excepcin es tan fcil como extenderse de
la clase Exception. Listo. Ahora, algn mtodo podr lanzar una instancia
de la excepcin definida por el usuario programador. Pongamos todo lo
expuesto junto y desarrollemos el cdigo para resolver el problema
propuesto a continuacin.
Problema propuesto 5.1:
Disear una clase Entrada que provea mtodos tipo clase (static) para
leer los tipos de datos primitivos: double, String, int, char, y boolean. La
entrada deber ser validada para no permitir tipos de datos invlidos. El
programa deber detectar la Excepcin lanzada, y despus de atraparla
hacer dos cosas: Mandar un mensaje del error, y obligar al usuario a dar
otra entrada.
La corrida deseada para el tipo int es:
Dame la edad:
hola
Te equivocaste...
Dame la edad:
1.5
Te equivocaste...
Dame la edad:
18
68

Tu edad es 18
El cdigo para el mtodo leerInt() es:
public static int leerInt(String msg)
{
Scanner s = new Scanner(System.in);
int num = 0;
while(true)
{
System.out.println(msg);
String aux = s.next();
try
{
num = Integer.parseInt(aux);
break;
}
catch(NumberFormatException nfe)
{
System.out.println("Te equivocaste...");
}
}
return num;
}

La corrida deseada para el tipo double es:


Dame el precio:
mucho
Te equivocaste...
Dame el precio:
17.50
El precio es 17.5
El cdigo para el mtodo leerDouble() es:
public static double leerDouble(String msg)
{
Scanner s = new Scanner(System.in);
double num = 0.0;
while(true)
{
System.out.println(msg);
String aux = s.next();
try
{
num = Double.parseDouble(aux);
break;
}

69

}
}

catch(NumberFormatException nfe)
{
System.out.println("Te equivocaste...");
}

return num;

La corrida deseada para el tipo char es:


Tu pocin?
M
Tu opcin es M
El cdigo para el mtodo leerChar() es:
public static char leerChar(String msg)
{
Scanner s = new Scanner(System.in);
char ch;
System.out.println(msg);
String aux = s.next();
ch = aux.charAt(0);
return ch;
}

Nota: No fue necesario manejar excepciones en el mtodo leerChar(),


esto debido a que siempre podr extraerse el primer char de un String, a
no ser que el String venga vaco. Probemos. No hay error ya que se lee
primero un String mediante el mtodo s.next(), y este no permite String
vacos.
La corrida deseada para el tipo String es:
Dame tu nombre:
Pedro
Tu nombre es Pedro
El cdigo para el mtodo leerString() es:
public static String leerString(String msg)
{
Scanner s = new Scanner(System.in);

70

System.out.println(msg);
String aux = s.next();
return aux;
}

Nota: Para el tipo String tampoco fue necesario manejar excepciones.


La corrida deseada para el tipo boolean es:
Responde si/no [true/false]
true
Tu respuesta true
El cdigo para el mtodo leerBoolean() es:
public static boolean leerBoolean(String msg)
{
Scanner s = new Scanner(System.in);
boolean b;
System.out.println(msg);
String aux = s.next();
b = Boolean.parseBoolean(aux);
return b;
}

Nota: Igual para el tipo boolean, no fue necesario manejar las


excepciones. Por regla cualquier String parseado hacia boolean ser
falso (false) excepto cuando sea la palabra true.
El cdigo total de la clase entrada lo puedes ver en el anexo B.
Problema prouesto 5.2
En el problema propuesto 1.4 se utiliza un men de opciones. Este es el
cdigo actual contenido en la clase AppTienda:
...
System.out.println("[1]
System.out.println("[2]
System.out.println("[3]
System.out.println("[4]
System.out.println("[5]
System.out.println("[6]
System.out.println("[7]
System.out.println("[9]

Alta");
Baja");
Consulta");
Cambio");
Listado");
Salvar");
Cargar");
Salir");
71

System.out.print("\nTu opcin? ");


op = s.nextInt();
switch(op)
...
Utilizar la clase entrada para validar la entrada en op = s.nextInt(), de
tal manera que slo deje teclear nmeros enteros. Si suponemos que la
clase Entrada diseada en problema propuesto 5.1. El cambio es
sencillo:
...
System.out.println("[1]
System.out.println("[2]
System.out.println("[3]
System.out.println("[4]
System.out.println("[5]
System.out.println("[6]
System.out.println("[7]
System.out.println("[9]

Alta");
Baja");
Consulta");
Cambio");
Listado");
Salvar");
Cargar");
Salir");

op = Entrada.leerInt("Tu opcin? ");


switch(op)
...
Problema propuesto 5.3
Otra vez, para el problema propuesto 5.1, en la opcin 4 (Cambio), se
solicita el nmero de parte del producto, se busca en el arreglo de
Productos, si se encuentra, se muestra un submen:
System.out.println("Qu campo (variable) deseas cambiar");
System.out.println("Descripcin [D]");
System.out.println("Costo [C]");
System.out.println("Cantidad [Ca]");
System.out.println("Tu opcin");
String subop = s.next();
Programar una excepcin FueraRangoException que ayude en el proceso
de detectar entradas String fuera del rango expuesto por el men.
public class FueraRangoException extends Exception
{
public FueraRangoException()
{
72

super();
}
@Override
public String toString()
{
return "Tecleaste un rango invlido...";
}
}
Agragar cdigo a la clase Producto para que utilice esta excepcin y
logre la validacin de entradas String invlidas:
private boolean checarRangoInvalido(String sp)
{
if(! (sp.toLowerCase().equals("d") ||
sp.toLowerCase().equals("c")||
sp.toLowerCase().equals("ca")) )
{
return true;
}
return false;
}
public void cambiar() throws FueraRangoException
{
System.out.println("Qu campo (variable) deseas
cambiar");
System.out.println("Descripcin [D]");
System.out.println("Costo [C]");
System.out.println("Cantidad [Ca]");
System.out.println("Tu opcin");
String subop = s.next();
if(
{

checarRangoInvalido(subop) )
throw new FueraRangoException();

}
...
Ejercicios propuestos:
1. La opcin de entrada del problema propuesto 5.2 ha sido validada para
recibir slo nmeros enteros. De lo contrario lanza un mensaje de
formato invlido. Sin embargo todava existen un gran nmero de
posibles entradas numricas enteras equivocadas. Se nos ocurre que
podemos programar una Excepcin definida por el programador para

73

que no slo valide a entrada de nmeros enteros sino que estn tambin
en el rango de nmeros enteros vlidos (1,2,3,4,5,6,7 y 9).
Programar la Excepcin RangoEnteroInvalidoException que pueda ser
lanzada cuando se tenga una de estas entradas invlidas.
Agregar al men el cdigo necesario que utiliza la excepcin
programada.
2. Programar la excepcin DivisionPorCerpException que colabore en la
deteccin de denominadores con valor de cero.
3. Si deseamos leer los datos para rellenar un arreglo normalmente
utilizamos un ciclo for, esto, dado que sabemos el numeor de elementos
que hay en la coleccin: arr.length, pero, deseamos hacerlo utilizando un
while, ciclo que sirve de forma natural cuando no sabemos el nmero de
ciclos a realizar. Entonces estaremos forzados a usar Manejo de
excepciones.
Implementa los primeros cinco ejercios propuestos en la Unidad uno
pero mediane excepciones.
4. Programar las excepciones que se muestran en la Figura 5.2.

Exceptio
nA
Exceptio
nB
Exceptio
n

Exceptio
nC
Exceptio
nD
Exceptio
nE

Figura 5.2 Excepiones en paralelo


5. Progamar las excepciones que se muestran en la Figura 5.3.

Exceptio
n

Exceptio
nA

Exceptio
nB

Exceptio
nC

Exceptio
nD

Exceptio
nE

Figura 5.3.- Excepciones en Serie

74

Unidad 6.- Flujos y Archivos


Objetivo: Comprender el uso de los diferentes tipos de archivos.
Programar soluciones de almacenamiento y recuperacin mediante
archivos.
Concepto de flujo
La Figura 6.1 muestra el concepto de Flujo en el mbito de Java. Se dice
que un programa puede leer (LEE) la fuente de datos a travs de un flujo
(stream), y puede escribir (ESCRIBE) los datos a travs de otro flujo.
Fi

Fuente de
Datos

Fluj
o

Programa

Fluj
o

Destino de Datos

gur 6.1 Flujo de datos en JAva


Tipos de flujos
Los diferente tipos de datos que Java maneja son:

Flujos de caracteres y flujos de bytes.


Flujos de entrada y flujos de salida.
Flujos primarios y flujos secundarios.

Flujos binarios, flujos de texto:

Flujos
o
o
Flujos
o
o

binarios:
InputStream(read())
OutputStream(write(int b))
de texto:
Reader(read(char [] b, int o, int l ))
Writer(write(char[] b), int o, int l))

Ejemplo de uso de flujo de caracteres:


Uso de la clase StringReader:
import java.io.*;
public class Flujo
{
public
static
void
main(String
args[])
IOException
{
String st = Esto es un String;
StringReader sr = new StringReader(st);
int c = sr.read();
while(c != -1)

throws

75

{
System.out.println((char)c);
c = sr.read();
}//while
}//main
}//class
Notas:

La clase StringReader est contenida en el paquete java.io.


Debemos reportar en el mtodo main el posible lanzamiento de la
excepcin IOException, o agregar un try-catch.

Ahora uso de la clase StringWriter:


StringWriter sw = new StringWriter();
sw.write(Hola mundo);
sw.write(\nSaludos);
System.out.println(sw.getBuffer());
Lectura y escritura en un archivo
Lectura de un archivo:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class FlujoDesdeArchivo
{
public static void main(String args[]) throws IOException
{
FileInputStream fis = null;
InputStreamReader isr =null;
char c;
int i;
try
{
fis = new
FileInputStream("/Users/Mac/Documents/test.txt");
isr = new InputStreamReader(fis);
while((i=isr.read())!=-1)
{
c=(char)i;
System.out.println("Caracter ledo: "+c);
}
}
catch (Exception e)

76

{
e.printStackTrace();
}
finally
{
// cierra el flujo (stream)
if(fis!=null)
fis.close();
//libera recursos asociados con el flujo
if(isr!=null)
isr.close();
}
}//main
}//class

La ejecucin del archivo es:


Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter

ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:

H
o
l
a

Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter

ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:

E
s
t
o

j
a
v
a

e
s
u
n
a
p
r
u
e
b
a

77

Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter
Caracter

ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:
ledo:

S
a
l
u
d
o
s

Caracter ledo:
Caracter ledo:
Escritura en un archivo:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class FlujoHaciaArchivo
{
public static void main(String[] args)
{
FileOutputStream fop = null;
File file;
String contenido = "Este es el contenido";
try {
file = new File("/Users/Mac/Documents/salida.txt");
fop = new FileOutputStream(file);
// si el archivo no existe, se crea
if (!file.exists())
{
file.createNewFile();
}
// obtener el contenido en bytes
byte[] contenidoEnBytes = contenido.getBytes();
//escribir en el flujo asociado al archivo
fop.write(contenidoEnBytes);
fop.flush();
fop.close();
System.out.println("Realizado");
}
catch (IOException e)
{
e.printStackTrace();

78

}
finally
{
try {
if (fop != null) {
fop.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}//main
}//class

La ejecucin produce el archivo salida.txt localizado en la carpeta


MisDocumentos. Ver Figura 6.2.

Figura6.2 Archivo salida.txt creado en la carpeta MisDocumentos


La clase File
Una clase provista por Java para:

Manipular informacin referente a Archivos y Carpetas.


Tambin permite crear y borrar Arrchivos y Carpetas.

Un objeto instancia de la clase File siempre representar un archivo o


carpeta.
Los constructores que provee la clase File son:
public File(String nombreArchivo|path);
public File(String path, String nombreArchivo|path);
public File(File path, String nombreArchivo|path);
Un ejemplo de uso de la clas File se muestra a continuacin:
import java.io.File;
import java.io.IOException;
public class PruebaFile
{
public static void main(String[] args)
{
79

try
{
File file = new File("C:/myfile.txt");
if(file.createNewFile())
System.out.println("xito!");
else
System.out.println("Error, archivo ya existe.");
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}//main
}//class
Archivos de acceso aleatorio
Los archivos de acceso aleatorio permiten un acceso no secuencial al
contenido de un archivo.
Las acciones naturales para manipular el contenido de un archivo de
acceso aleatorio son:
1. Abrir el archivo.
2. Buscar una posicin en particular dentro del archivo.
3. Leer desde o escribir hacia el archivo.

Para esto se utiliza una clase denominada FileChannel que implementa


la interface SeekableByteChannel con lo cual puede utilizar los
siguientes mtodos:

position Regresa la posicin actual del canal


position(long) Actualiza la posicin del canal
read(ByteBuffer) Lee bytes del canal
write(ByteBuffer) Escribe bytes en el canal
truncate(long) Trunca el canal conectado al canal

Lectura y escritura de objetos

Abordemos este apartado mediante un problemas propuestos:


Problema propuesto 6.1
Primero, disear la clase instanciable Cliente que contenga los campos:
nombre, calle y pas. Incluir getters y setters, sin faltal el mtodo
toString. Debemos implementar la interface Seralizable, esto en Java, es
obligatorio a la hora de escribir o leer objetos hacia o desde un archivo.
Aqu el cdigo:
80

import java.io.Serializable;
public class Cliente implements Serializable
{
String nombre;
String calle;
String pais;
public void setNombre(String nombre)
{
this.nombre = nombre;
}
public String getNombre()
{
return this.nombre;
}
public void setCalle(String calle)
{
this.calle = calle;
}
public void setPais(String pais)
{
this.pais = pais;
}
public String getCalle()
{
return this.calle;
}
public String getPais()
{
return this.pais;
}
@Override
public String toString() {
return new StringBuffer("Nombre : ")
.append(this.nombre).append(" Calle : ")
.append(this.calle)
.append(" Pas : ")
.append(this.pais).toString();
}
}
81

Segundo, programar una aplicacin que permita la escritura de archivos


instancia de la clase Cliente en un archivo. Aqu el cdigo:
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class PruebaEscrituraArchivoObjeto
{
public static void main (String args[])
{
String nombre = "Jos Alfredo";
String calle = "Abasolo 611";
String pais = "Argentina";
Cliente cliente = new Cliente();
cliente.setNombre(nombre);
cliente.setCalle(calle);
cliente.setPais(pais);
try
{
FileOutputStream fout = new
FileOutputStream("/Users/Mac/Documents/Agenda.dat");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(cliente);
oos.close();
System.out.println("Listo...");
}
catch(Exception ex)
{
ex.printStackTrace();
}
}//main
}//class

El efecto ser la simple aparicin en la carpeta MisDocumentos de un


archivo denominado Agenda.dat, el cual no podr ser ledo por un editor
de texto.
Problema propuesto 6.2
Programar una aplicacin que permita realizar el proceso inverso: Leer
del archivo Agenda.dat el objeto que se guard en el problema
propuesto anterior.
Aqu el cdigo:
import java.io.FileInputStream;

82

import java.io.ObjectInputStream;
import java.io.Serializable;
public class PruebaLecturaArchivoObjeto
{
public static void main (String args[])
{
Cliente cliente = null;
try{
FileInputStream fin = new
FileInputStream("/Users/Mac/Documents/Agenda.dat");
ObjectInputStream ois = new ObjectInputStream(fin);
cliente = (Cliente) ois.readObject();
ois.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
System.out.println(cliente);
}

La ejecucin deber mostrar el contenido del objeto que ley del archivo
Agenda.dat.
Aqu la salida:
Nombre : Jos Alfredo Calle : Abasolo 611 Pas : Argentina
Ambas aplicaciones utilizaron la clase instanciable Cliente. El proyecto
se puede apreciar en la Figura 6.3.

83

Figura 6.3 Proyecto de escritura-lectura de objetos en un archivo


Ejercicios propuestos
1. En el proyecto propuesto 1.4 qued pendiente la opcin Salvar.
Programar esta opcin para que en un archivo se puedan guardar todos
los Productos que se dieron de alta en el da, de tal manera que pueda
salvarse el estatus de la Tienda y no empezar desde cero al siguiente
da.
2. En el mismo proyecto 1.4, programar lo referente a la opcin de Cargar,
la cual permitir que el usuario cargue desde Archivo todos los Productos
previamente salvados.
3. Disear un sistema completo que te permita realizar un sistema ABC
para el siguiente proyecto:

Figura 6.4 Proyecto video centro


El sistema ABC deber tener los siguientes parmetros:

Controlar los usuarios mediante un campo clienteNumero.


Los clientes no pueden repetirse. No permitir nmeros de cliente
repetidos. Una opcin es autogenerar los nmeros de cliente al
momento de dar de alta.
Controlar las pelculas por un nmero de parte.
Los nmeros de parte tampoco podrn ser duplicados.
No se podr rentar una pelcula que no existe. Primero deber darse de
alta.
No se le podr rentar una pelcula a un cliente que no existe. Primero
deber darse de alta.

84

Referencias
[1] Oracle Help Center. Class Arrays. Recuperado de:
https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html
[2] Informtica 11. Taller 5.3. Operaciones bsicas con arreglos.
Recuperado de:
https://informatica11cor.wordpress.com/2012/05/16/taller-5-3operaciones-basicas-con-arreglos/
[3] Stack overflow. Sintax for creating a two dimensional array.
Recuperado de: http://stackoverflow.com/questions/12231453/syntaxfor-creating-a-two-dimensional-array
[4] Oracle Help Cener. Capter 10. Arrays. Recuperado de:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html
[5] Oracle Help Center. Class ArrayList. Recuperado de:
https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html
[6] Aprobar Java, Dr. Scrates Torres Ovalle. UAdeC. 2014.
[7] Oracle Help Center. Class StringTokenizer. Recuperado de:
https://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html
[8] UML. Visibility in UML. Recuperado de: http://www.umldiagrams.org/visibility.html
[9] Joyanes Aguilar, Luis., Programacin en Java 2 : algoritmos,
estructuras de datos y programacin orientada a objetos / Luis Joyanes
Aguilar, Ignacio Zahonero Martnez., 1a ed., Madrid ; Mxico : McGrawHill, c2002., Spain 2002.
[10] Sierra, Kathy., Head first Java / Kathy Sierra, Bert Bates., 2nd ed.,
Sebastopol, CA : O'Reilly, 2005, California, 2005.
[11] Deitel, Harvey M., 1945-, Java : how to program / H.M. Deitel, P.J.
Deitel., 6th ed., Upper Saddle River, N.J. : Pearson/Prentice Hall, c2005.,
New Jersey, c2005.
[12] Cohoon, James P., Programacin en Java 5.0 / James P. Cohoon, Jack
W. Davidson ; traduccin, Jess Snchez Allende ... [et al.], 1a ed.,
Madrid ; Mxico : McGraw-Hill/Interamericana, 2006., Spain, 2006.

85

Anexo A
Detalle de cdigo para el problema propuesto 1.4.
Clase Producto:
import java.util.*;
public class Producto
{
private int numParte;
private String descripcion;
private double costo;
private int cantidad;
Scanner s = new Scanner(System.in);
public Producto()
{
numParte = 0;
descripcion = null;
costo = 0.0;
cantidad = 0;
}
public Producto(int np, String d, double c, int ca)
{
numParte = np;
descripcion = d;
costo = c;
cantidad = ca;
}
public int getNumParte(){return numParte;}
public void setNumParte(int np){numParte=np;}
public String getDesc(){return descripcion;}
public void setDesc(String d){descripcion=d;}
public double getCosto(){return costo;}
public void setCosto(double c){costo=c;}
public int getCant(){return cantidad;}
public void setCant(int ca){cantidad=ca;}
public void leerProducto()
{
System.out.println("Nmero de parte: ");
numParte = s.nextInt();
System.out.println("Descripcin: ");
descripcion = s.next();
System.out.println("Costo: ");
costo = s.nextDouble();
86

System.out.println("Cantidad: ");
cantidad = s.nextInt();
}
private boolean checarRangoInvalido(String sp)
{
if(! (sp.toLowerCase().equals("d") ||
sp.toLowerCase().equals("c")||
sp.toLowerCase().equals("ca")) )
{
return true;
}
return false;
}
public void cambiar()
{
System.out.println("Qu campo (variable) deseas
cambiar");
System.out.println("Descripcin [D]");
System.out.println("Costo [C]");
System.out.println("Cantidad [Ca]");
System.out.println("Tu opcin");
String subop = s.next();
switch( subop.toLowerCase() )
{
case "d":
System.out.println("Nueva descripcin");
String d = s.next();
setDesc(d);
break;
case "c":
System.out.println("Nuevo costo");
double c = s.nextDouble();
setCosto(c);
break;
case "ca":
System.out.println("Nueva cantidad");
int ca = s.nextInt();
setCant(ca);
break;
default: System.out.println("Opcin
invlida"); break;
}
}
public String toString()
87

{
return "Producto No. parte: " + numParte +"\n"+
"Descripcin: " + descripcion +"\n"+
"costo: " + costo +"\n"+
"Cantidad: " + cantidad;
}
}
Clase Tienda:
public class Tienda extends Object
{
private Producto pros[];
private int centinela;
public Tienda(int n)
{
pros = new Producto[n];//dimensin
for (int i=0; i<n; i++)
{
pros[i] = new Producto();
}
centinela = 0;
}
public void alta()
{
if(centinela < pros.length)
{
pros[centinela].leerProducto();
centinela++;
}
else
{
System.out.println("Arreglo lleno");
}
}
public void baja(int np)
{
if ( encontrado(np) )
{
int pos = buscar(np);
for(int i = pos; i<(centinela-1); i++)
{
pros[i].setNumParte( pros[i+1].
getNumParte() );
pros[i].setDesc( pros[i+1].getDesc() );
pros[i].setCosto( pros[i+1].getCosto());
88

pros[i].setCant( pros[i+1].getCant() );
}
centinela--;
}
else
{
System.out.println("Producto no existe");
}
}
private boolean encontrado(int np)
{
for(int i=0; i<centinela; i++)
{
if (pros[i].getNumParte() == np)
return true;
}
return false;
//for(Producto p:pros)
//{
//
if(p.getNumParte() == np)
//
return true;
//}
//return false;
}
private int buscar(int np)
{
int pos=0;
for(int i=0; i<centinela; i++)
{
if(pros[i].getNumParte() == np)
{
pos = i;
break;
}
}
return pos;
}
public void consulta(int np)
{
if( encontrado(np) )
{
int pos = buscar(np);
System.out.println( pros[pos].toString() );
}
else
{
System.out.println("Producto no existe");
89

}
}
public void cambio(int np)
{
if( encontrado(np) )
{
int pos = buscar(np);
System.out.println( pros[pos].toString() );
pros[pos].cambiar();
}
else
{
System.out.println("Producto no existe");
}
}
public String toString()
{
String aux = "";
for(int i=0; i< centinela; i++)
{
aux = aux + pros[i].toString() + "\n";
}
return aux;
}
}//class
Clase AppTienda
import java.util.*;
public class AppTienda
{
public static void main(String args[])
{
Scanner s = new Scanner(System.in);
Tienda t = new Tienda(3);
int op=0;
do
{
System.out.println("[1] Alta");
System.out.println("[2] Baja");
System.out.println("[3] Consulta");
System.out.println("[4] Cambio");
System.out.println("[5] Listado");
System.out.println("[6] Salvar");
System.out.println("[7] Cargar");
System.out.println("[9] Salir");
90

System.out.print("\nTu opcin? ");


op = s.nextInt();
switch(op)
{
case 1: System.out.println("Ests
en altas");
t.alta();
break;
case 2: System.out.println("Ests
en bajas");
System.out.println("Cul nmero
de parte: ");
int np = s.nextInt();
t.baja(np);
break;
case 3: System.out.println("Ests
en consultas");
System.out.println("Cul nmero
de parte: ");
np = s.nextInt();
t.consulta(np);
break;
case 4: System.out.println("Ests en
cambios");
System.out.println("Cul nmero
de parte: ");
np = s.nextInt();
t.cambio(np);
break;
case 5: System.out.println("Ests en
listado");
System.out.println(t.toString());
break;
case 6: System.out.println("Ests
cargando el archivo");break;
case 7: System.out.println("Ests
salvando el archivo");break;
case 9: System.out.println("Ests
saliendo");break;
default: System.out.println("Entrada
invlida");break;
}//switch
}while(op!=9);
}//main
}//class
91

Anexo B
Detalle de cdigo para la clase Entrada.
import java.util.*;
public class Entrada
{
public static int leerInt(String msg)
{
Scanner s = new Scanner(System.in);
int num = 0;
while(true)
{
System.out.println(msg);
String aux = s.next();
try
{
num = Integer.parseInt(aux);
break;
}
catch(NumberFormatException nfe)
{
System.out.println("Te equivocaste...");
}
}
return num;
}
public static double leerDouble(String msg)
{
Scanner s = new Scanner(System.in);
double num = 0.0;
while(true)
{
System.out.println(msg);
String aux = s.next();
try
{
num = Double.parseDouble(aux);
break;
}
catch(NumberFormatException nfe)
{
System.out.println("Te equivocaste...");
92

}
}
return num;
}
public static char leerChar(String msg)
{
Scanner s = new Scanner(System.in);
char ch;
System.out.println(msg);
String aux = s.next();
ch = aux.charAt(0);
return ch;
}
public static String leerString(String msg)
{
Scanner s = new Scanner(System.in);
System.out.println(msg);
String aux = s.next();
return aux;
}
public static boolean leerBoolean(String msg)
{
Scanner s = new Scanner(System.in);
boolean b;
System.out.println(msg);
String aux = s.next();
b = Boolean.parseBoolean(aux);
return b;
}
}

93

S-ar putea să vă placă și