Académique Documents
Professionnel Documents
Culture Documents
INFORMTICO
El desarrollo de un programa o de un conjunto de aplicaciones se basa en un concepto
llamado ciclo de vida. Son una serie de etapas o fases que hay que seguir
secuencialmente.
Las fases o etapas son:
Anlisis.
Diseo.
Codificacin o construccin.
Implantacin o explotacin.
Mantenimiento.
ANLISIS
En esta fase se establece el producto a desarrollar, siendo necesario especificar los
procesos y estructuras de datos que se van a emplear. Debe existir una gran
comunicacin entre el usuario y el analista para poder conocer todas las necesidades que
precisa la aplicacin. En el caso de falta de informacin por parte del usuario se puede
recurrir al desarrollo de prototipos para saber con ms precisin sus requerimientos.
En el anlisis estructurado se pueden emplear varias tcnicas como:
Diagramas de flujo de datos: Sirven para conocer el comportamiento del sistema
mediante representaciones grficas.
Modelos de datos: Sirven para conocer las estructuras de datos y sus caractersticas.
(Entidad relacin y formas normales)
Diccionario de datos: Sirven para describir todos los objetos utilizados en los grficos,
as como las estructuras de datos.
Definicin de los interfaces de usuario: Sirven para determinar la informacin de
entrada y salida de datos.
Al final de esta fase tenemos que tener claro las especificaciones de la aplicacin.
DISEO
En esta fase se alcanza con mayor precisin una solucin ptima de la aplicacin,
teniendo en cuenta los recursos fsicos del sistema (tipo de ordenador, perifricos,
comunicaciones, etc) y los recursos lgicos. (sistema operativo., programas de utilidad,
bases de datos, etc)
En el diseo estructurado se pueden definir estas etapas:
Diseo externo: Se especifican los formatos de informacin de entrada y salida.
(pantalla y listados)
Diseo de datos: Establece las estructuras de datos de acuerdo con su soporte fsico y
lgico. (estructuras en memoria, ficheros y hojas de datos)
Diseo modular: Es una tcnica de representacin en la que se refleja de forma
descendente la divisin de la aplicacin en mdulos. Est basado en diagramas de flujo
de datos obtenidos en el anlisis.
Diseo procedimental: Establece las especificaciones para cada mdulo, escribiendo el
algoritmo necesario que permita posteriormente una rpida codificacin. Se emplean
tcnicas de programacin estructurada, normalmente ordinogramas y pseudocdigo.
Al final de esta etapa se obtiene el denominado cuaderno de carga.
CODIFICACIN
EXPLOTACIN
En esta fase se realiza la implantacin de la aplicacin en el sistema o sistemas fsicos
donde van a funcionar habitualmente y su puesta en marcha para comprobar el buen
funcionamiento.
Actividades a tener en cuenta o realizar:
MANTENIMIENTO
Esta es la fase que completa el ciclo de vida y en ella nos encargaremos de solventar los
posibles errores o deficiencias de la aplicacin. Existe la posibilidad de que ciertas
aplicaciones necesiten reiniciar el ciclo de vida.
Tipos de mantenimiento:
Mantenimiento correctivo: Consiste en corregir errores no detectados en pruebas
anteriores y que aparezcan con el uso normal de la aplicacin. Este mantenimiento puede
estar incluido en la garanta o mantenimiento de la aplicacin.
Mantenimiento adaptativo: Consiste en modificar el programa a causa de cambio de
entorno grfico y lgico en el que estn implantados. (nuevas generaciones de
ordenadores, nuevas versiones del sistema operativo, etc.)
Mantenimiento perfectivo: Consiste en una mejora sustancial de la aplicacin al recibir
por parte de los usuarios propuestas sobre nuevas posibilidades y modificaciones de las
existentes.
Los tipos de mantenimiento adaptativo y perfectivo reinician el ciclo de vida, debiendo
proceder de nuevo al desarrollo de cada una de sus fases para obtener un nuevo
producto.
INSTALANDO NETBEANS
HOLA MUNDO:
IDE
CREANDO
EL
All vern qu es lo van a instalar. En este caso se lista todo lo que vimos hoy porque yo
baj el paquete completo. Si le dan en Personalizar podrn elegir qu instalar y qu no.
Damos en Siguiente:
Nos aparece el hermoso contrato de licencia que todos morimos por leer detenidamente
sin perdernos una sola palabra. No creo que exista alguien en el ancho mundo que solo
de clic en Acepto los trminos del acuerdo de licencia y de Siguiente si leer
absolutamente nada o s? ;)
Dependiendo de los componentes elegidos para instalar podran aparecer ms hermosos
contratos as que estaremos felices de tener tanto que leer.
Llegamos a esta ventana:
Aqu tienen dos cuadros, uno para elegir donde instalar NetBeanas (les recomiendo que
dejen el que viene por defecto) y otro para indicarle a NetBeans donde encontrar el JDK.
En mi caso aparece ya por defecto porque la variable PATH est bien configurada, sin
embargo, si no les aparece le dan clic en Examinar y buscan ustedes a mano el lugar
donde esta su JDK y listo, NetBeans lo detecta y no nos hace problema. Damos clic en
Siguiente. Dependiendo de las opciones elegidas para instalar podra aparecernos
alguna otra ventana para elegir donde instalar los otros componentes.
Les recomiendo que toqueteen esta pgina y exploren, hay varias cosas interesantes. Si
no quieren verla ms cada vez que abren el IDE desmarquen la opcin Mostrar al Inicio.
Bien, creemos nuestro primer proyecto. Al igual que en Modula, Java funciona con
proyectos, as que vamos a Archivo --> Proyecto Nuevo:
Debemos elegir dos cosas: Categora y Proyecto. Las categoras disponibles dependern
de lo que hayan instalado. Lo que a m me interesa ahora es Java Estndar as que
elegimos categora Java y luego Java Application.
Las Java Application son aplicaciones Java comunes, es decir, programas de escritorio.
Damos en Siguiente:
Proyectos: NetBeans nos muestra todos los proyectos que tenemos creados,
como ahora solo tenemos uno es el nico que podemos visualizar de momento. Ya
tendremos ms.
Archivos: Nos permite visualizar todos los archivos que componen a nuestro
proyecto.
Prestaciones: Son herramientas que amplan un proyecto, como por ejemplo,
conexin a base de datos. De momento no lo usaremos.
Como ven a la izquierda ahora podemos ver la nueva clase (archivo .java) agregada al
proyecto. A la derecha vemos una pestaa con el nombre de la clase y la opcin Source
(fuente) marcada. NetBeans ya nos genera algo de cdigo fuente en la clase. Lo que est
en gris son comentarios (ya hablaremos de ellos luego porque Java tiene tres tipos de
comentarios y aqu ya tenemos dos).
Borren los comentarios.
La otra forma es hacer clic derecho sobre el cono del proyecto (la tazita de caf roja),
eligen Nuevo --> Java Class. Los dems pasos son iguales que para la manera anterior.
Veamos el cdigo fuente que tenemos:
Cdigo:
Para empezar NetBeans pinta en azul las palabras reservadas del lenguaje. All tenemos:
veremos ms adelante, por ahora simplemente saben que tiene que ir.
class: Indica que lo que estamos declarando es una clase. En Modula usabamos la
palabra MODULE. Las clases siempre se declaran con esta palabra.
En Pascal el programa estaba escrito dentro de los bloques BEGIN y END y en Modula el
mdulo principal llevaba el bloque BEGIN/END. En Java nos olvidamos de las palabras
BEGIN y END y las sustituimos por las llaves { y } respectivamente. De este modo, en el
ejemplo, la llave { indica el inicio de la clase y la llave } indica el final de la misma. Lo
que tenemos entonces all ahora es una clase pblica que se llama HolaMundo y est
vaca
porque
no
tiene
cdigo
ninguno
dentro
de
las
llaves.
Escriban a mano entonces dentro de las llaves este cdigo:
Cdigo:
Como vern NetBeans va corrigiendo sintaxis en tiempo real. Adems, cuando escribimos
la llave { y damos enter, NetBeans nos agrega la llave de cierre } ya indentada y todo.
Otra cosa til es que si nos paramos en una llave de apertura el IDE nos pinta en amarillo
cul es la que la cierra y viceversa. Lo mismo con los parntesis y todo tipo de smbolo de
apertura y cierre.
Qu es eso que acabamos de escribir? De momento les digo que es un procedimiento
que se llama main (principal en ingls). Todo programa Java tiene una sola clase principal
(al igual que los programas en Modula tenan un solo mdulo principal). La clase principal
es la nica que tiene el procedimiento main que acabamos de escribir. Justamente eso es
lo que la marca como clase principal. De momento no me detendr a explicar mucho ms
de este procedimiento, asuman que es as y a medida que avancemos todo se ir viendo
claramente.
Algo importante es que el procedimiento tambin tiene llave de apertura y cierre. En
Pascal y Modula llevaban un bloque BEGIN/END.
Bien, dentro de este procedimiento escribiremos el cdigo:
Cdigo:
System.out.println("Hola Mundo");
Esto ltimo es una tpica sentencia de Java. Como ven termina en punto y coma (;). Al
igual que en Pascal y Modula, el smbolo de punto y coma tiene la funcin de separador,
es decir, es el que separa una sentencia (instruccin) de otra. Las llaves de cierre no
llevan punto y coma al final.
Antes de pasar al detalle de lo que significan estas palabras, veamos el cdigo completo:
Cdigo:
Ahora van al men Ejecutar --> Limpiar y generar Main Project. Luego van a
Ejecutar --> Ejecutar Main Project. El IDE les pedir que indiquen cul es la clase
principal del proyecto. Seleccionen la suya y den Aceptar.
Tendrn esta pantalla:
Vern que debajo apareci la pestaa Salida HolaMundo (run). Esa es la salida de la
consola del IDE, es decir, lo que antes vean en una pantalla negra con letras blancas
horribles, ahora lo ven en esta pantalla dentro del IDE. Como ven, apareci el mensaje
Hola Mundo.
Las opciones del men Ejecutar las tienen tambin en la barra de herramientas.
Noten tambin que ahora en la pestaa Proyectos apareci un cono verde de Play
(reproducir) en el cono de la clase que tenemos. Eso indica que ahora NetBeans la
reconoce como clase principal y que es desde ella que ejecutar el programa. Esto lo
veremos enseguida; primero analicemos un poquito ms lo que tenemos en nuestro
cdigo:
class HolaMundo
Cdigo:
System.out.println("Hola Mundo");
Continuaremos trabajando con esto en la leccin que sigue. Vern que poco a poco Java
se ir mostrando super sencillo. Al principio hay cosas que cuestan pero es, como
siempre
ha
sido,
solo
acostumbrarse
jeje.
NOTAS:
Como ven no hay diferencia. Lo nico es que si ustedes corren el cdigo Pascal y el
cdigo Java las salidas sern diferentes ya que el de Pascal mostrar las comillas en
Hola Mundo y el de Java no lo har. Es decir, tendremos esto en la salida de Pascal:
Cdigo:
es
en
en
en
SECUENCIAS DE ESCAPE:
Justamente por el problema que seal recin con las comillas y por otros tantos, adems
de lograr simplificarnos varias cosas, Java nos provee de ciertos caracteres especiales
para utilizar en los literales de Strings. Como primer ejemplo veremos como lograr la
misma salida anterior en una sola lnea de cdigo:
Cdigo:
Vern que solo hay un System.out.print. Sin embargo si ustedes corren ese programa
saldr el texto en dos lneas, tal como si hubiera usado println y print como en el ejemplo
anterior. Si prestan atencin, justo donde hay un salto de lnea en la salida estndar
tenemos en nuestro literal el smbolo \n. Este smbolo representa justamente el fin de
lnea. De este modo este cdigo
Cdigo:
1. System.out.println("Hola Mundo");
puede ser sustituido por
Cdigo:
1. System.out.print("Hola Mundo\n");
La barra diagonal inversa (\) se conoce como carcter de escape. Esta barra indica a
print y a println que se va a imprimir un carcter especial, de modo que dicho carcter
va justo luego de la barra. En este caso, la n minscula indica que lo que se quiere
imprimir es un salto de lnea. De esta manera, si yo quiero que salga en pantalla este
texto:
Cdigo:
He logrado crear
mi primer programa
en el lenguaje Java.
As, cada vez que usamos \ Java imprime comillas dobles () en pantalla.
Tenemos un total de cinco secuencias de escape:
\n Nueva lnea. Imprime un carcter de fin de lnea, o sea, baja el cursor una lnea.
\t Tabulacin. Imprime una tabulacin horizonal.
\r Retorno de carro. Vuelve el cursor al inicio de la lnea actual. Todo lo que se imprima
Cdigo:
1.
import java.util.Scanner;
2.
3.
4.
5.
//Declaracin de variables.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Bueno, se ha complicado un poquito as que como siempre, veamos lnea por lnea lo que
tenemos a fin de que no queden dudas de nada. As que vamos por la lnea 01 donde hay
una importacin. Como dije hoy necesitbamos usar la clase Scanner. En java las
libreras constan de varias clases las cuales se agrupan en paquetes. Un paquete consta
entonces de varias clases y subpaquetes. Bien, la clase Scanner est dentro de un
paquete llamado util que est dentro de un paquete llamado java. Las importaciones en
Java se hacen, al igual que en Modula, al inicio del cdigo fuente antes de declarar la
clase. Usamos la palabra reservada import para decir que queremos importar una clase
o un paquete de clases. La declaracin es entonces as
Cdigo:
1.
import nombreDelPaquete.nombreDelSubpaquete.nombreDelSubpaquete.nombreDeLaClase;
Como ven, lo que se hace es separar por puntos (no espacios) cada nombre de cada
paquete hasta llegar a la clase. Como Scanner est en el paquete util el cual est
dentro del paquete java, tenemos que escribir
Cdigo:
1. import java.util.Scanner;
De momento solo deben saber eso, luego veremos como el IDE nos facilitar la vida con
las importaciones, pero primero tienen que aprender a hacerlas ustedes a mano.
Sigamos. En la lnea 03 tenemos la declaracin de la clase HolaMundo. Como vern, us
la misma clase que ya tenamos solo porque no tena ganas de hacer otro proyecto. En la
lnea 04 tenemos la declaracin del procedimiento main. En la lnea 05 tenemos un
comentario de fin de lnea. Estos comentarios los habamos visto en Pascal y se abren con
el mismo smbolo que en aquel lenguaje (//). Se cierran automticamente con el fin de la
lnea en que se escriben. Como ven, el IDE pinta en gris los comentarios.
En la lnea 06 aparece por primera vez la declaracin de una variable, que encima no es
de un tipo primitivo sino que es de tipo Scanner, es decir, es una variable del tipo de una
clase (como si nosotros nos declarramos una variable del tipo de un mdulo en Modula
2), o sea que es una referencia a un objeto. No me concentrar en este hecho todava
porque no quiero llegar a la programacin orientada a objetos en Java tan rpido, hay
mucho por ver antes.
En Pascal y en Modula 2, a la hora de declarar una variable primero escribamos el
nombre de la variable, luego dos puntos y luego el tipo de datos que almacenara. En
Java va primero el tipo de datos y luego el nombre de la variable sin poner dos puntos.
Por ejemplo, en Pascal una variable nombre del tipo String se declarara as:
Cdigo:
1. nombre: String;
En Java sera
Cdigo:
1. String nombre;
Algo nuevo es que no necesitamos poner una palabra reservada para declarer variables
en Java como suceda en Pascal y en Modula donde tenamos que poner VAR y luego
declarar las variables. Ahora podemos declararnos una variable en cualquier
momento donde se nos antoje. Si vamos programando y nos damos cuenta que
necesitamos tal o cual variable la declaramos en el momento y ya. No es prolijo, a pesar
de que Java nos permite hacer eso, se suele declarar todas las variables al inicio del
cdigo para que este sea ms legible por otras personas y por uno mismo.
Bien, me declar una variable llamada entradaEstandar del tipo Scanner. Esta variable
ser la que nos devuelva los textos de ingresados por el usuario. En la misma lnea donde
est declarada entradaEstandar la he inicializado asignndole un valor por defecto
mediante
Cdigo:
1. new Scanner(System.in)
Esta asignacin quedar colgada por ahora. Lo importante es que para poder obtener
resultados de la entrada estndar debemos declararnos una variable Scanner tal como yo
lo he hecho.
El smbolo de asignacin en Pascal y Modula era (:=), ahora en Java es simplemente el
(=).
En la lena 07 me declaro una variable llamada nombre del tipo String. En Java volvemos
a tener el tipo String y nos olvidamos del ARRAY OF CHAR de Modula 2. Este tipo es casi
como si fuera un tipo primitivo de Java aunque en realidad no lo es. Por el momento
nosotros lo usaremos como un tipo primitivo ya que podemos hacerlo sin ningn
problema. Luego en la lnea 09 imprimimos un simple mensaje al usuario.
La lnea 10 es la que hace la lectura de la entrada estndar. Vemoslo de forma simple:
Scanner nos provee de una funcin llamada nextLine que no recibe argumentos y
retorna un String que es justamente lo ledo de la entrada estndar. La funcin nextLine
lee toda la lnea completa, como si fuera READLN. A diferencia de READ o READLN,
donde ponamos la variable que recibira los datos como argumento de estos
procedimientos, nextLine lo retorna como funcin, por tanto tenemos que asignar ese
retorno a la variable nombre. Es como si en Pascal en vez de hacer
Cdigo:
1. ReadLn(nombre);
hiciramos
Cdigo:
nombre:= ReadLn();
Sin embargo, nextLine al ser una operacin de Scanner debe usarse mediante un objeto
de esta clase (eso es parte de POO en Java y lo veremos luego). De este modo debo usar
el
objeto
entradaEstandar
para
usar
nexLine
simplemente
escribiendo
entradaEstandar.nextLine().
Entonces, la lnea 10 lo nico que hace es asignar a nombre lo ledo en la entrada
estndar.
La lnea 12 simplemente muestra el mensaje Hola con un espacio al final y la lnea 13
imprime el contenido de la variable nombre. Como ven, println y print puede recibir
variables como argumentos para ser mostrados en pantalla tal como suceda con WriteLn
y Write de Pascal.
Las lneas 14 y 15 cierran los bloques de main y HolaMundo respectivamente con
comentarios que lo aclaran. Dejar comentarios que aclaren qu cierra cada llave ayuda a
mejorar el cdigo, ms all de que NetBeans marca en amarillo las llaves que abren y
cierran un bloque.
1. System.out.print("Hola ");
2. System.out.print(nombre);
1. System.out.print(Hola + nombre);
Esto no era permitido en Pascal y mucho menos en Modula 2. Java nos permite utilizar el
operador + en los literales y hace la unin automticamente. En Pascal tenamos la
salvedad de que un mismo procedimiento Write o WriteLn poda recibir varios
argumentos separados por comas, pero esto en Java y Modula no es posible. De este
modo Java nos provee una forma elegante de solucionarlo.
Si quisiramos que el mensaje final fuera:
Cdigo:
1. System.out.println(Hola );
2. System.out.println(nombre);
3. System.out.println(. Es un placer conocerte);
Escribimos este cdigo:
Cdigo:
Si ponemos el cursor sobre una variable, NetBeans pinta todas las partes del
cdigo donde dicha variable aparece. Adems nos muestra en la barra vertical a la
derecha de la pantalla todos los lugares de modo que si hacemos clic all vamos
directo a la parte del cdigo que queremos.
Si al escribir el nombre de la variable del tipo Scanner ponemos luego un punto,
NetBeans nos muestra todas las operaciones disponibles detallando informacin al
respecto. Podemos subir y bajar por todas ellas a fin de elegir la que necesitamos.
Con cualquiera de esas opciones tendrn la ventana que usamos al crear el HolaMundo.
Pongan a su proyecto el nombre AreasYPerimetros. Desmarquen la opcin Crear Main
Class.
Ahora, debajo de la pestaa Proyectos, vemos que aparece el nuevo proyecto creado
marcado en letra negrita. Esto es porque al momento de crearlo estaba marcada la casilla
Set as Main Project (establecer como proyecto principal). Esta casilla est debajo de
Crear Main Class.
Qu significa que un proyecto est marcado como proyecto principal? Pues que al
compilar y/o ejecutar estaremos ejecutando el proyecto principal establecido. De este
modo si ustedes dan clic en el botn Ejecutar Main Project o bien presionan F6, no
estarn corriendo HolaMundo aunque estn mirando su cdigo fuente, sino que
NetBeans intentar correr AreasYPermetros y no podr porque no tiene ninguna clase
principal.
Para cambiar el proyecto establecido como principal simplemente deben hacer clic
derecho sobre su nombre y elegir la opcin Establecer como Proyecto Principal
(puede aparecer Set as Main Project). Con eso ya est. Igualmente ustedes pueden
correr o compilar un proyecto sin establecerlo como proyecto principal; para ello hacen
clic derecho sobre l y elijen Ejecutar (si es que quieren correrlo) o Limpiar y Construir
(si
solo
quieren
compilarlo).
Creemos entonces la clase principal de nuestro proyecto AreasYPerimetros. Es usual
colocar a la clase principal el mismo nombre que tiene el proyecto (tal como yo lo hice
con HolaMundo). No es requerido, es decir que, si yo ahora le pongo a mi clase principal
el nombre Abuela, el programa funcionar sin problemas (en Modula no era as), pero a
la hora de leer el cdigo fuente, sobre todo si hay muchas clases, se facilita encontrar la
clase principal por el nombre. Ms all de eso, NetBeans nos marca con el cono verde de
Play la clase establecida como clase principal.
La ejecucin de nuestro programa debe como quedar la que muestro a continuacin.
Pinto en azul lo que corresponde a la entrada ingresada por el usuario. Los datos
ingresados sern nmeros enteros.
Cita:
Bienvenid@ a reas y Permetros.
Calcularemos el rea y el permetro de:
*Un tringulo.
*Un rectngulo.
*Una circunferencia.
Vamos con el rea del tringulo.
La base ser el primer lado ingresado.
Ingresa la medida de sus lados y su altura: 10 5 7 3
Lado a= 10
Lado b= 5
Lado c= 7
Altura= 3
rea= 15.0
Permetro= 22
Usando una variable rea y una variable permetro para estos clculos.
Cdigo:
01 import java.util.Scanner;
02
03 public class AreasYPerimetros {
04
public static void main(String[] args){
05
//Declaramos las variables a usar.
06
Scanner entradaEstandar= new Scanner(System.in);
07
int a, b, c, altura, permetro;
08
double rea;
09
10
/*Mostramos el mensaje inicial al usuario. Har todo en una misma lnea
11
* de salida para que se vallan acostumbrando.
12
*/
13
System.out.print("Bienvenid@ a reas y Permetros.\n\n"
14
+ "Calcularemos el rea y el permetro de:\n\n"
15
+ "*Un tringulo.\n*Un rectngulo.\n*Una circunferencia.\n\n"
16
+ "Vamos con el rea del tringulo.\nLa base ser el primer lado"
17
+ " ingresado.\nIngresa la medida de sus lados y su altura: ");
18
19
//Leemos uno a uno los valores ingresados:
20
a= entradaEstandar.nextInt();
21
b= entradaEstandar.nextInt();
22
c= entradaEstandar.nextInt();
23
altura= entradaEstandar.nextInt();
24
25
/*Consumimos el fin de lnea, tal como hacamos con ReadLn en Pascal y
26
* con SkipLine en Modula 2. En Java es usar nextLine solo.
27
*/
28
entradaEstandar.nextLine();
29
30
rea= a*altura/2.0;
31
permetro= a + b + c;
32
33
System.out.println("\nLado a= " + a + "\nLado b= " + b + "\nLado c= " + c
34
+ "\nAltura= " + altura + "\n\nrea= " + rea + "\nPermetro= "
35
+ permetro);
36
}//Fin del procedimiento main.
37 }//Fin de la clase AreasYPerimetros.
Este cdigo es apenas ms complejo que lo que hemos venido viendo, pero no ms
complejo que lo que ustedes ya saben utilizar. Veamos las lneas importantes de este
cdigo
nada
ms
ya
que
hay
mucho
que
ya
he
explicado.
Vamos entonces directo a la lnea 07 donde tenemos una declaracin de varias variables
del tipo int, el cual es un tipo primitivo de Java y se corresponde con el tipo INTEGER de
Pascal y Modula con la enorme diferencia de que admite valores mucho mayores
(veremos esto luego). Como ya saben, en Java para declarar variables primero va el tipo
de datos y luego la variable. Al igual que en los lenguajes anteriores, en Java podemos
declarar varias variables de un mismo tipo separndolas por coma. As, las variables del
tipo int declaradas son a, b, c, altura y permetro.
En la lnea 08 tenemos otra declaracin de variable para una llamada rea del tipo
primitivo double. Este tipo se corresponde con el tipo REAL de Modula y Pascal, salvo
tambin
que
admite
valores
muchsimo
mayores.
Como vern, sigo usando la vieja prctica de declarar todas las variables al inicio del
cdigo. Por el momento siempre estoy haciendo las declaraciones de variables dentro del
propio procedimiento main, es decir que son variables locales a l. Como por ahora
siempre estaremos trabajando dentro de dicho procedimiento no nos complicaremos con
variables globales ni mucho menos.
Entre las lneas 10 y 12 tenemos un bloque de comentarios multilnea. Este es el tipo de
comentarios que usbamos en Modula el cual comenzaba con (* y cerraba *). En Pascal
tambin se abran y cerraban con dichos smbolos o bien con las llaves {}. En Java los
comentarios multilnea se abren con /* y se cierran con */. Este es el segundo tipo de
comentarios que posee Java y el segundo tipo de comentarios que ustedes conocen. Este
lenguaje integra un nuevo tipo de cometarios conocidos como javadoc, pero los veremos
ms
adelante.
Luego entre las lneas 13 y 17 tenemos una impresin en pantalla de todo el texto que se
debe mostrar al usuario tal como lo describ en el ejemplo. Podra haber usado varios
println para lograr la misma salida, sin embargo quiero que vean cmo podemos escribir
una salida muy larga en un solo print o println uniendo los trozos de texto con signos de
suma (+). Eso es lo ms comn en Java. Modula no nos permita esto y Pascal tampoco.
La facilidad que nos da la secuencia de escape \n es muy valorable, ahorramos mucho
tiempo.
Ahora viene la parte en que leemos los datos. Esta vez no us nexLine ya que no quera
leer toda la lnea completa y adems no quera recibir algo de tipo String, sino que quera
leer de a uno los nmeros ingresados por el usuario. Para esto en vez de usar nexLine
usamos nexInt, que justamente lee un entero (algo del tipo primitivo int) en la entrada y
nos lo devuelve. No consume toda la lnea, sino que lee un entero y luego deja el cursor
justo adelante del siguiente espacio. Cabe destacar que para usar nextInt lo que el
usuario ingres debe ser justamente un nmero del tipo int, de lo contrario Java nos
lanzar una excepcin del tipo InputMismatchException que significa Excepcin de
falta de coincidencia en la entrada (veremos excepciones ms adelante) y nos mostrar
un mensaje como este en la salida de la consola:
Cita:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:840)
at java.util.Scanner.next(Scanner.java:1461)
at java.util.Scanner.nextInt(Scanner.java:2091)
at java.util.Scanner.nextInt(Scanner.java:2050)
at AreasYPerimetros.main(AreasYPerimetros.java:20)
Java Result: 1
GENERACIN CORRECTA (total time: 5 seconds)
Estos informes de errores nos ayudan mucho a la hora de detectar problemas. Lo que
est en rojo indica, en cada rengln, el paquete, la clase y la operacin en la que se ha
producido el error separando cada dato por un punto porque justamente est indicando
paquetes. Lo que est en azul es un enlace hacia la clase indicada en la lnea exacta
donde sucedi el problema (si hacemos clic en l nos lleva justo a donde se detect el
error). Esto hay que leerlo desde abajo hacia arriba (por un tema de herencia). Si se fijan,
el ltimo error indicado est en la clase AreasYPerimetros en la operacin main, ms
explcitamente en la lnea 20. Justo la lnea 20 es donde se lee el primer entero y se le
asigna el valor a la variable a. El problema fue que el usuario no ingres algo del tipo int
y por eso nuestro programa cay. Luego el error nos lleva a la lnea 2050 de la clase
Scanner y as podemos navegar hasta la lnea 840 de dicha clase que es donde se lanz
la excepcin. De momento sabemos que el problema es el ingreso de datos y con eso nos
basta
para
proseguir.
Debajo de todo el informe indica GENERACIN CORRECTA ya que el programa compila
bien y por tanto el archivo .class fue creado; el problema que hubo fue en tiempo de
ejecucin.
Hasta la lnea 23 de nuestro cdigo tenemos las asignaciones de los nmeros ingresados
por el usuario. Dichos nmeros pueden ingresarse de a uno separando por espacios o
bien presionando ENTER. Es como cuando utilizbamos READ en Pascal con una variable
INTEGER para leer de a uno los enteros.
Al igual que suceda en Pascal, tenemos que consumir el fin de lnea luego de leer algo
que no lo consume. Esto en aquel lenguaje lo hacamos colocando un READLN solito. En
Modula lo hacamos con SkipLine. Pues en Java lo hacemos colocando nextLine
solamente. Recuerden que las operaciones que estamos utilizando para leer son de la
clase Scanner y por eso se hacen a travz del objeto Scanner que nosotros nos creamos.
En la lnea 28 consumimos el fin de lnea.
En la lnea 30 tenemos una sentencia de asignacin donde le damos a la variable rea el
valor de multiplicar la variable a por la variable altura y dividir esto entre 2. En Pascal o
Modula esta asignacin sera:
Cdigo:
area:= a*altura/2.0;
En Java lo nico que cambia es que el signo de asignacin (:=) cambia por (=). Algo que
cabe destacar es que poda haber puesto 2 en vez de 2.0. La diferencia es que uno es un
nmero entero y el otro es un nmero real. En Pascal y Modula la operacin / era
estrictamente del tipo REAL. En Java eso no es as, al menos no en las versiones actuales.
Si todos los operandos de la operacin matemtica son del tipo int pues Java
transformar el resultado de la operacin / a tipo int. Por ejemplo, sabemos que la
variable rea es del tipo double (casi equivalente al tipo REAL de Pascal y Modula) y que
a y altura son del tipo int. Si yo hago aquella asignacin de esta manera
Cdigo:
rea= a*altura/2;
estoy dejando todos los operandos del tipo int. Como no hay ninguno del tipo double Java
hace la operacin / retornando un int tal como si fuera DIV en Modula o Pacal. Luego
asigna eso a la variable rea; como esta es double Java transforma el resultado int a
double agregando un 0 luego de la coma. El problema de esto es que perdemos precisin.
Veamos un ejemplo:
Supongamos que:
a= 7
altura= 3
Si hacemos la operacin de la segunda forma (todos int) tenemos que:
Cdigo:
7*3/2= 10
Luego Java asignar el valor entero 10 a la variable rea pero dejndolo como 10.0
para que sea double. Eso claramente est mal, aquella cuenta debe dar 10.5. Para
que / funcione como divisin real debe haber algn real en los operandos, por eso
pongo el 2 como 2.0.
Resumiendo, en Pascal y Modula tenamos DIV para divisin entera y / para divisin
REAL. En Java tenemos solo /, y esta funciona como divisin entera si todos los
operandos son enteros y como divisin real si hay al menos un operando que del tipo
real (double para Java).
El resultado es 25
En Pascal podamos hacer esto en una instruccin ya que Write y WriteLn permitan una
lista variable de argumentos de diversos tipos. En Modula tenamos que utilizar mltiples
instrucciones para imprimir los datos en funcin del tipo al que pertenecan. Java nos da
una mayor soltura incluso que Pascal al sobrecargar el smbolo (+).
Hay un pequeo detalle con esto. El programa anterior se poda hacer sin utilizar las
variables rea y permetro ya que podamos realizar los clculos directamente en la
instruccin de salida:
Cdigo:
a*altura/2.0
no es problema porque al tener smbolos de multiplicacin (*) y/o divisin (/) y/o resta (-),
Java detecta que es una operacin matemtica, la resuelve, y luego concatena el
resultado a la cadena de salida. Sin embargo, la ltima operacin que corresponde al
clculo del permetro DEBE llevar los parntesis para que le den precedencia. El tema es
que como es una operacin que solo tiene el smbolo (+) y en este caso dicho smbolo
tiene dos funcionalidades (sumar nmeros y concatenar cadenas de caracteres), Java
necesita saber cul de las dos funcionalidades queremos usar.
Supongamos esta instruccin:
Cdigo:
El permetro es 101113
Al tener los parntesis, Java detecta la precedencia de la operacin y, como todo lo que
hay entre parntesis corresponde a variables numricas, realiza la cuenta matemtica y
luego concatena el resultado al String que est a la izquierda.
Con esto cerramos el ejemplo del rea del tringulo no sin dejar un ejercicio:
NOTAS: El objeto del tipo Scanner tiene una operacin next casi para cualquier tipo
primitivo que queramos leer:
No tenemos una operacin para leer datos del tipo char. Esto tiene una solucin sencilla
mediante el trabajo con el tipo String, pero la veremos ms adelante.
Ejercicio: Completar el programa anterior para que adems del rea y el permetro del
tringulo calcule tambin el rea y el permetro de un rectngulo y de una circunferencia.
Les dejo a continuacin un ejemplo de ejecucin, pintando en azul lo que corresponde a
la entrada ingresada por el usuario:
Cita:
Bienvenid@ a reas y Permetros.
Calcularemos el rea y el permetro de:
*Un tringulo.
*Un rectngulo.
*Una circunferencia.
Vamos con el rea del tringulo.
La base ser el primer lado ingresado.
Ingresa la medida de sus lados y su altura: 10 5 7 3
Lado a= 10
Lado b= 5
Lado c= 7
Altura= 3
rea= 15.0
Permetro= 22
Ahora vamos con el rea y el permetro del rectngulo:
Ingresa la medida de la base y la altura: 10 5
Base= 10
Altura= 5
rea= 50
Permetro= 30
Solo falta la circunferencia.
Ingresa la medida del radio: 10
Radio= 10
rea= 314
Permetro= 62.8
Gracias por usar AreasYPerimetros.
NOTAS:
La salida de su programa debe ser idntica a la mostrada en el ejemplo. Esto ser una
enorme prctica para ustedes con la cual comenzarn a manejar varios aspectos de Java.
LECCIN
65:
TIPOS,
DECLARACIONES Y SELECCIN
OPERADORES,
En esta leccin veremos las palabras reservadas de Java, un poco ms sobre declaracin
de variables aadiendo adems las constantes, tipos primitivos y sus rangos de datos,
operadores aritmticos y relacionales para as llegar a la seleccin, es decir, a los if y a
algo parecido al CASE.
Asimismo tenemos tambin los tipos primitivos de datos de los cuales conocemos dos
hasta ahora: int y double. Los tipos primitivos son aquellos tipos de datos predefinidos
por el lenguaje. Estos datos se almacenan directamente en memoria ocupando un cierto
espacio ya establecido. Normalmente estos tipos de datos refieren a nmeros, caracteres
y booleanos. Veamos entonces qu tipos de datos primitivos nos da Java para trabajar:
boolean: El tpico booleano. Puede valer true o false. Ocupa 1 bit de memoria.
char: Un carcter Unicode, como los que ya conocemos. Ocupan 16 bits de
memoria.
byte: Un nmero entero con signo. Va desde -128 hasta 128. Ocupan 8 bits de
memoria.
short: Un nmero entero con signo. Este tipo es idntico al tipo INTEGER de
Pascal y Modula ya que tiene el mismo rango de valores y cada variable de este
tipo ocupa tambin 16 bits de memoria. Va desde -32768 hasta 32767.
int: Un nmero entero con signo. Va desde -2147483648 hasta 214748647.
Ocupan 32 bits de memoria. Como ven, ya tenemos un rango mucho mayor que
en Pascal o Modula.
long: Un nmero entero con signo. Va desde -9223372036854775808 hasta
92233720368547707. Ocupan 64 bits de memoria. Un super rango numrico.
float: Un nmero de coma flotante. Este tipo es idntico al tipo REAL de Pascal o
Modula. Tienen un rango comprendido entre +-3.40282347E+38 y +1.40239846E-45. Tiene una precisin simple. Ocupa 32 bits de memoria.
double: Un nmero de coma flotante con doble precisin. Va desde
+-1.79769313486231570E+308 hasta +-4.94065645841246544E-324. Ocupan 64
bits de memoria.
Como ven, los tipos numricos nos dan mayores rangos con los que trabajar respecto a
los que tenamos antes con Pascal y Modula. Hay que tener cuidado con la compatibilidad
de estos tipos, pero me gustara que ustedes mismos hicieran pequeas pruebas
declarando variables de distintos tipos y asignen a unas los valores de otras.
Por ejemplo, si yo me declaro una variable llamada real del tipo double y otra llamada
entero del tipo int, puedo hacer esto:
Cdigo:
real= entero;
Tenemos una forma de que Java vea una variable double como int para poder hacer
una asignacin que en Pascal o Modula era simplemente incompatible. Esta forma se
conoce como casteo, pero la veremos ms adelante.
Algo a destacar es que el tipo String no aparece como tipo primitivo de datos y
justamente es porque no lo es. Un String es una concatenacin de caracteres, es decir
que, un String es la unin de varios datos de tipo char, el cual s es un dato primitivo.
numero % 10;
(numero % 100)/10;
(numero % 1000) / 100;
numero / 1000;
El cdigo es casi exacto al de Pascal y creo yo que muy fcil de comprender. Comparen
ambos y saquen sus propias conclusiones.
TipoDeDatos identificadorVariable;
Podemos adems declarar muchas variables del mismo tipo separadas por comas
adems de que Java nos permite declarar las variables por cualquier parte del cdigo
siempre que las declaremos antes de usarlas. Bien, como ya saben siempre que vamos a
usar una variable para alguna operacin y no sabemos qu valor tendr ya que no lo
leeremos de la entrada (por ejemplo un contador para iterar) debemos inicializarlas.
Veamos un ejemplo donde me declaro una variable del tipo int llamada i y la inicializo en
0:
Cdigo:
int i;
i= 0;
Bien, eso no tiene nada de nuevo, primero me declar la variable y luego la inicialic.
Java tambin me permite hacer esto para simplificar el cdigo:
Cdigo:
int i=0;
Como ven he declara la variable y a la vez le he dado un valor inicial. Supongamos que
quiero declarar muchas variables del tipo int y quiero inicializar algunas s y otras no.
Podemos hacer todo por separado o todo junto as:
Cdigo:
Java nos da una libertad total a la hora de declarar variables. All tenemos tres que han
sido inicializadas y dos que no. No tenemos que respetar ningn orden ni mucho menos.
Se suele declarar a las variables que no inicializamos por un lado, y por otro lado a las
que s para dejar el cdigo ms claro, es decir, algo como esto:
Cdigo:
Esto es muy relativo ya que se pueden agrupar las variables segn el uso que se les dar.
En fin, cada uno escribe sus programas como ms le guste. Dejen buenos comentarios y
ya.
Algo importante es que a veces suele ser necesario en Java inicializar variables del tipo
String dada la soltura de este lenguaje para el trabajo con cadenas de caracteres. Con
qu valor inicializo un String? Pues a menos que fuese lo que necesitamos podemos
inicializar un String con algn valor que elijamos, pero Java nos provee la posibilidad de
inicializar un String con un valor nulo el cual es . S, el String nulo es abrir y cerrar
comillas. Por ejemplo:
Cdigo:
String palabra= ;
NOTA: El tipo char de Java utiliza comillas simples (como los Strings de Pascal) y no
dobles porque sino seran Strings. Ejemplo:
Cdigo:
char letra= A;
DECLARACIN DE CONSTANTES:
Como ya saben, las constantes son variables que no cambian de valor, por eso est mal
llamarlas variables. En Pascal y Modula las declarbamos debajo de la palabra CONST.
Como no variaban haca falta inicializarlas en la misma declaracin. Algo interesante es
que no le asignbamos el tipo ya que este quedaba implcito en el valor que le dbamos
a la constante.
En Java, al igual que no existe VAR tampoco existe CONST y al igual que con las variables
podemos declarar las constantes en cualquier lado. Es necesario poner el tipo de datos
que contendr. La declaracin de constantes es igual a la de variables solo que
anteponemos la palabra reservada final:
Cdigo:
1 PROGRAM preciosIVA;
2
3 Const
4 iva= 23;
5
6 Var
7 harina, leche, azucar, sal, arroz: real;//Precios de los productos.
8 porcentaje: real; //Para calcular cunto se debe sumar al precio.
9
10 BEGIN
11
12 //Mostramos mensajes al usuario y leemos los datos desde la entrada.
13 write('Precio HARINA : ');
14 readln(harina);
15 write('Precio LECHE : ');
16 readln(leche);
17 write('Precio AZUCAR : ');
18 readln(azucar);
19 write('Precio SAL : ');
20 readln(sal);
21 write('Precio ARRZ : ');
22 readln(arroz);
23
24 //Dejamos una lnea en blanco.
25 writeln;
26
27 //Calculamos el porcentaje de IVA para harina.
28 porcentaje:= harina*iva/100;
29 //Mostramos el nuevo precio al usuario.
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Como ven solo han cambiado los operadores de igualdad y diferencia con respecto a los
que tenamos en Pascal y Modula.
if (condicin)
instruccin;
Ese es un if super sencillo, es decir, con una sola instruccin. Si hacen memoria, en
Pascal podamos tener IF con una sola instruccin al que no tenamos que ponerle BEGIN
y END porque no haca falta. En Java es igual, si el if tiene una sola instruccin podemos
poner un bloque de llaves {} o no, es decir que aquel if poda haber sido
Cdigo:
if (condicin){
instruccin;
}
if (condicin){
Instruccin1;
Instruccin2;
...
InstruccinN
}
Algo super importante en Java es que la condicin SIEMPRE va entre parntesis, no hay
excepcin a eso, de otro modo tendrn un error de sintaxis.
Veamos un ejemplo sencillo:
Cdigo:
import java.util.Scanner;
public class EjemploIF {
public static void main(String[] args){
Scanner entrada= new Scanner(System.in);
int n1, n2;
System.out.print("Ingrese dos nmeros enteros: ");
n1= entrada.nextInt();
n2= entrada.nextInt();
entrada.nextLine();
if(n1<n2)
System.out.println("El primero es menor que el segundo.");
if(n1==n2)
System.out.println("Ambos nmeros son iguales.");
if(n1>n2)
System.out.println("El primero es mayor que el segundo.");
}//Fin de main.
}//Fin de EjemploIF.
Cdigo:
if(n1<n2)
System.out.println("El primero es menor que el segundo.");
else if(n1==n2)
System.out.println("Ambos nmeros son iguales.");
else
System.out.println("El primero es mayor que el segundo.");
Cdigo:
CASE variable OF
Constante1: BEGIN
Instrucciones;
END;
...
ConstanteN: BEGIN
Instrucciones;
END;
ELSE
BEGIN
Instrucciones;
END;
END;
Debemos recordar que en cada etiqueta (constante) podamos omitir los bloques
BEGIN/END si tenan solo una instruccin. La variable deba ser de un tipo ordinal, por
tanto no servan Strings, nmeros reales ni tipos definidos por nosotros mismos a menos
que
fueran
enumerados.
En Modula 2:
Cdigo:
CASE variable OF
Constante1: Instruccion1;
...
InstruccinX|
...
ConstanteN: Instruccin1;
...
InstruccinY|
ELSE
Instruccin1;
...
InstruccinZ|
END;
Igual que el CASE de Pascal salvo que ya no existen los bloques BEGIN/END. Para cada
etiqueta las instrucciones se separaban por punto y coma salvo la ltima que se cerraba
con la barra vertical |. Por lo dems funcionaba igual.
En ambos casos la etiqueta ELSE no era obligatoria sino que serva para hacer algo en
caso de que la variable no tomara el valor de ninguna de las etiquetas. Podamos omitir
perfectamente el ELSE y en caso de que sucediera lo anteriormente dicho el CASE no
haca nada.
La instruccin switch de Java hereda un aspecto del CASE de Modula: tenemos algo que
cierra todas las etiquetas. En Modula era la barra |, en Java ser la palabra reservada
break. Veamos la declaracin genrica de switch y luego transformaremos un CASE para
que quede claro:
Cdigo:
switch (variable){
case etiqueta1: Instruccin(es);
break;
case etiqueta2: Intruccin(es);
break;
...
}
Como ven es casi lo mismo. La variable va entre parntesis s o s. Antes de cada etiqueta
debe ir la palabra case y luego los dos puntos. Por cada etiqueta podemos tener tantas
instrucciones como queramos, incluyendo if y sentencias de repeticin. Cada etiqueta
debe (en realidad puede) finalizar con break.
Ejemplo:
Supongamos que la variable num es de tipo INTEGER en Pascal y Modula y de tipo int en
Java:
CASE Pascal:
Cdigo:
CASE num OF
1: WriteLn(El nmero es el 1.);
2: Begin
WriteLn(El nmero es el 2.);
Write(No me gusta mucho ese nmero.);
End;
3: WriteLn(El tres tambin me gusta.);
END;
CASE Modula:
Cdigo:
CASE num OF
1: WriteString(El nmero es el 1.)|
2: WriteString(El nmero es el 2.); WriteLn;
WriteString(No me gusta mucho ese nmero.)|
3: WriteString(El tres tambin me gusta.)|
END;
Switch:
Cdigo:
switch (num){
case 1: System.out.println(El nmero es el 1.); break;
case 2: System.out.println(El nmero es el 2.);
System.out.println(No me gusta mucho ese nmero.);
break;
case 3: System.out.println(El tres tambin me gusta.); break;
}
Y el ELSE donde queda con switch? Pues switch en vez de ELSE tiene una instruccin
llamada default que es exactamente lo mismo. Si la variable no toma el valor de ninguna
de las etiquetas case entonces entramos en el default. Con el mismo ejemplo tendramos:
Cdigo:
switch (num){
case 1: System.out.println(El nmero es el 1.); break;
case 2: System.out.println(El nmero es el 2.);
System.out.println(No me gusta mucho ese nmero.);
break;
case 3: System.out.println(El tres tambin me gusta.); break;
default: System.out.println(No se eligi ni 1, ni 2, ni 3.);
System.out.println(Default y ELSE son lo mismo.);
break;
}
switch(num){
case 1: System.out.print(1 );
case 2: System.out.print(2 );
case 3: System.out.print(3); break;
default: System.out.println(No se eligi nada entre 1 y 3.);
}
Ejercicio:
Escriban un programa que muestre un men al usuario donde pueda elegir si quiere
calcular el rea y el permetro de un tringulo, un rectngulo o una circunferencia. Si el
usuario no elije una de las opciones dadas entonces se le mostrar un mensaje de error.
Las opciones sern numricas y se leern como enteros Veamos un ejemplo:
Cita:
Seleccin: 3
Ingrese el radio de la circunferencia: 2
El rea es: 12.56
El permetro es: 12.56
Es un programa super sencillo, pero servir mucho de prctica para afianzar Java y dejar
de lado los viejos vicios arraigados de Pascal y Modula.
Precio de IGV
Cdigo:
import java.util.Scanner;
Cdigo:
import java.util.Scanner;
public class AreasyPerimetros {
public static void main(String[] args){
Scanner entradaEstandar= new Scanner(System.in);
int a,b,c,altura,perimetro,opcion;
double area,per;
System.out.print("Bienvenid@ a Areas y Perimetros.\n\n" + "Elige una Opcion:\n\n"
+ "1.Un triangulo. \n2.Un rectangulo.\n3.Una circunferencia\n\n"
+ "\n\nSeleccion:" );
opcion=entradaEstandar.nextInt();
switch(opcion){
case 1: System.out.print("\n\nVamos con el area del triangulo.\nLa base sera el primer lado
ingresado \nIngresa la medida de sus lados y su altura:"
);
a= entradaEstandar.nextInt();
b= entradaEstandar.nextInt();
c= entradaEstandar.nextInt();
altura= entradaEstandar.nextInt();
entradaEstandar.nextLine();
System.out.print("\nLado a=" + a + "\nLado b=" + b + "\nLado c=" + c
+ "\nAltura=" + altura);
area= a*altura/2.0;
perimetro= a+b+c;
entradaEstandar.nextLine();
System.out.print("\nArea= "+ area + "\nPerimetro=" + perimetro); break;
case 2: System.out.print("\n\nVamos con el area y el perimetro del rectangulo."
+ "\nIngresa la medida de la base y altura: "
);
a= entradaEstandar.nextInt();
b= entradaEstandar.nextInt();
System.out.print("\n\nBase=" + a + "\nAltura=" + b);
area=a*b;
perimetro=2*(a+b);
System.out.print("\n\nArea="+ area + "\nperimetro=" + perimetro); break;
case 3: System.out.print("\n\nVamos con la circunferencia.\nIngresa la medida del radio: ");
a= entradaEstandar.nextInt();
area=a*a*3.14;
per= a*2*3.14;
System.out.print("\n\nRadio=" + a + "\n\nArea=" + area +"\nPerimetro=" + per);
break;
}
}
}
FOR i:= 1 TO n DO
La variable de control (en este caso i) deba estar definida previamente. Bien, en Java la
sentencia for tiene un encabezado ms complejo. Lo escribir de forma genrica y luego
veremos ejemplos:
Cdigo:
FOR i:= 1 TO 10 DO
WriteString(*);
END;
Estamos de acuerdo en que este FOR imprime 10 asteriscos verdad? Bien, vemoslo en
Java:
Cdigo:
for (i = 1; i<=10 ; i= i + 1)
System.out.print(*);
Como ven el encabezado del for tiene tres argumentos que se separan por punto y coma.
El primero indica la variable de control a utilizar y con qu valor se inicializa. El segundo
argumento indica la condicin de fin del for (s, el for de Java tiene condicin). El tercer
argumento indica el aumento de la variable de control o bien, el decremento de la misma.
En este caso aumentamos i en 1, pero podra haber sido 2 o ms, depende de la
necesidad.
La asignacin de acumulacin es ya bien conocida por ustedes, es decir que algo como
i= i + 1 no debera resultarles extrao. Java sabe que es usual hacer eso y por tanto nos
provee de esta forma de escribirlo:
Cdigo:
i++;
i= i + 1;
Si ustedes buscan informacin del for de Java en Google lo vern siempre de esta forma.
Como el for del ejemplo tiene una nica instruccin puedo elegir si poner llaves o no,
pero cuando tiene ms de una instruccin s o s hay que poner llaves:
Cdigo:
La nica restriccin para este uso es que la variable declarada dentro del for no debe
estar declarada antes, de otro modo no tendra sentido redeclararla. Asimismo, la
variable declarada en el for no ser visible fuera de l (como si fuera local), por tanto, si
se quiere usar luego s debemos declararla.
while(condicin)
instruccin;
Cita:
while(condicin){
instruccin;
}
All tienen dos ejemplos de while con una sola instruccin. Como ya debera ser natural,
en Java siempre que tenemos una sola instruccin podemos optar por no poner las llaves
de cierre y apertura al igual que en Pascal podamos optar por no poner BEGIN y END. La
forma general de un while entonces es:
Cdigo:
while (condicin){
instruccin1;
instruccin2;
...
instruccin;
}
Debera ser obvio que la condicin puede ser una condicin compuesta por operadores
NOT, AND, OR, etc. Debe estar siempre entre parntesis.
No me detendr ms con esta instruccin porque no tiene caso, es lo que ya conocen.
do{
instrucciones;
}while (condicin);
Primero vuelvo a aclarar que si hay una sola instruccin podemos omitir las llaves (no lo
recomiendo). Bien, como se darn cuenta enseguida, este bloque chequea la condicin al
final y no al inicio como while, de modo que al igual que REPEAT se ejecutar al menos
una vez. El tema es que REPEATUNTIL es como decir Repite hasta que y DOWHILE
es Haz mientras que.
Mientras que REPEAT tena la condicin inversa al WHILE, ahora en Java tanto while
como dowhile tienen la misma condicin. Veamos ejemplos sencillos:
Como acabo de decir, la condicin en Java siempre es la misma tanto para while como
para dowhile. Esto no es menor ya que de este modo la nica diferencia entre una
estructura y otra es que while puede no ejecutarse nunca y dowhile se ejecuta siempre
al menos una vez.
Ejercicio:
Realicen el programa Adivinador propuesto en Pascal pero ahora en Java. A continuacin
les dejar la letra propuesta en aquel momento, pero antes debemos ver cmo generar
nmeros aleatorios en Java. Esto ser un simple acercamiento al tema ya que Java nos
provee varias opciones a la hora de generar un nmero al azar.
Existe una clase llamada Random la cual est en el paquete java.util. Debemos
declarar un objeto de esta clase e inicializarlo para luego, a travs de l, generarnos
nmeros al azar. Veamos un ejemplo sencillo de un programa que genera nmeros
aleatorios entre el 0 y el 5:
Cdigo:
import java.util.Random;
public class Aleatorio {
public static void main(String[] args){
Random generador= new Random(); //Mi objeto de tipo Random.
int numeroAleatorio; //Mi variable para guardar el nmero generado.
numeroAleatorio= generador.nextInt(6); //Obtengo el nmero generado.
System.out.println(numeroAleatorio);
}//Fin de main.
}//Fin de Aleatorio.
Como ven tenemos una operacin de Random llamada nexInt que toma un entero como
argumento y nos devuelve otro entero entre 0 y el valor pasado menos 1 (igual que
Pascal). En este caso pas un literal entero como argumento pero bien poda ser una
variable entera.
Presten atencin a la letra que les dejar porque hay una pequea variante.
Ejemplos de ejecucin:
Ejemplo 1:
Cita:
Ejemplo 2:
Cita:
El usuario puede ingresar como rango mximo cualquier nmero mayor que 10,
de lo contrario el programa le avisar como en el programa anterior.
El nmero mximo de intentos no puede ser menor que el rango mximo divido
10. Por ejemplo, si el rango mximo es 500, el nmero de intentos no puede ser
menor que 50. Si el usuario ingresa un rango menor al mnimo el programa se lo
notificar de este modo:
Cita:
Enumerados.
Subrangos.
Arreglos.
Registros.
Conjuntos (Set no lo utilizamos).
Punteros.
Los enumerados en Java no existan hasta hace muy poco. Su uso igualmente difiere
bastante del que les dbamos, pero lo veremos poco a poco. Igualmente, de los tipos
listados arriba, en Java solo quedan estos:
Enumerados.
Arreglos.
Cmo? Pues s, la forma en que funciona Java hace que cosas como registros, conjuntos
o subrangos no se hagan necesarias como tipo predefinido por el lenguaje, sino que
nosotros mismos con las clases podemos lograr incluso mejores resultados que con los
registros (por ejemplo). De esta manera, veremos estos dos tipos a definir para luego
pasar a la declaracin de funciones y procedimientos y as llegar a la orientacin a
objetos en Java donde empezaremos a ver realmente el potencial de este lenguaje, ya
que hasta ahora solo hemos repasado conceptos ya asimilados traducindolos a la
sintaxis de Java.
ENUMERADOS:
Como dije, los enumerados no existan en Java hasta hace poco. Esto indica que
podamos lograr sin ellos los mismos resultados que logrbamos con ellos en Pascal o
Modula. Sin embargo su existencia nos facilita muchas tareas y su uso en Java an ms.
En principio veremos un uso idntico al que ya conocemos y ms adelante, con la
Programacin Orientada a Objetos veremos ms.
En Java un enumerado se declara as:
Cdigo:
}
}
Este programa no hace nada, solo muestra como he declarado un enumerado llamado
Meses con los meses del ao y luego, dentro del main, como he declarado una variable
del tipo Meses llamada mes a la cual he inicializado con el valor Enero. Es importante
que noten la diferencia entre el uso de los enumerados en Pascal y Modula al de Java. En
los anteriores lenguajes podamos dar a una variable de un tipo enumerado un valor de l
simplemente escribindolo, por ejemplo:
Cdigo:
Type
Meses= (Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio,
Agosto, Setiembre, Octubre, Noviembre, Diciembre);
Var
mes: Meses;
Begin
Mes:= Enero;
End;
En Java tenemos que anteponer el tipo de la variable, un punto y luego el valor a asignar
tal como ven en el ejemplo anterior:
Cdigo:
mes= Meses.Enero;
CASE mes OF
Enero: WriteString(Enero)|
Febrero: WriteString(Febrero)|
...
Diciembre: WriteString(Diciembre)|
END;
System.out.println(mes);
Con eso saldr en pantalla el valor de la variable mes tal cual lo declaramos en el
enumerado. Hagan ustedes mismos la prueba para comprobarlo. Esto es debido a la
forma de funcionar que tiene Java, acerca de la cual iremos aprendiendo poco a poco.
Esto es una simple aclaracin ya que no es intuitivo. Si quisiramos por algn motivo
utilizar una variable de tipo enumerado en una instruccin switch, al escribir las etiquetas
no debemos anteponer el nombre del tipo enumerado tal como lo hacemos con las
asignaciones, sino que ponemos el literal del valor como lo hacamos en Pascal y Modula.
Por ejemplo:
Cdigo:
switch(mes){
case Enero: //Algo para hacer.
break;
case Febrero: //Algo para hacer.
break;
. . .
}
En este ejemplo he puesto break, pero ya saben que no es obligatorio y qu es lo que sucede en
caso de no colocarlo.
ARREGLOS:
La palabra ARRAY ya deja de existir dentro del lenguaje. La declaracin de arreglos en
Java es bastante diferente a lo que conocemos de Pascal o Modula teniendo adems ms
de una forma de hacerlo. No hace falta declarar un tipo ARRAY ni mucho menos. Si lo que
yo quiero, por ejemplo es un arreglo de enteros simplemente me declaro una variable as:
Cdigo:
int[] miArreglo;
Con eso ya tengo un arreglo de enteros. En este caso todava no tiene ni celdas,
simplemente hemos dicho que la variable miArreglo es un arreglo de enteros. Cmo?
Pues poniendo los corchetes luego de int. Si yo quisiera declarar una variable que sea un
arreglo de nmeros reales, por ejemplo, double, lo hago as:
Cdigo:
double[] reales;
TipoDeDatos[] identificador;
Ahora bien cmo hacemos para decir cuntas celdas tiene el arreglo? Es fcil, por
ejemplo, quiero que el arreglo miArreglo tenga seis celdas:
Cdigo:
La declaracin e inicializacin se puede hacer de forma conjunta como con todo en Java,
de este modo, podamos haber declarado e inicializado el arreglo de enteros miArreglo
de esta manera:
Cdigo:
En la cantidad de celdas yo he puesto un literal, en este caso 6, pero podemos poner una
variable entera. Esto es algo que haban preguntado para Pascal y Mdula, es decir,
poder generar un arreglo de un tamao indeterminado inicialmente ya que estara dado
por una variable. De este modo, veamos un programa muy bsico que pida un valor al
usuario
y
genere
un
arreglo
con
esa
cantidad
de
celdas:
Cdigo:
import java.util.Scanner;
public class EjemploArreglos {
public static void main(String[] args){
Scanner entrada= new Scanner(System.in);
int cantCeldas;
int[] misNumeros;
System.out.print("Cuntos nmeros desea guardar?: ");
cantCeldas= entrada.nextInt();
misNumeros= new int[cantCeldas];
}
}
import java.util.Random;
public class EjemploArreglos {
public static void main(String[] args) {
final int LARGO_ARREGLO= 10;
Random generadorAleatorio= new Random();
int[] arreglo= new int[LARGO_ARREGLO];
for(int i=0; i<LARGO_ARREGLO; i++)
arreglo[i]= generadorAleatorio.nextInt(10);
for(int i=0; i<LARGO_ARREGLO; i++)
System.out.print(arreglo[i]+" ");
}
}
Algo a destacar es que Java siempre numera las celdas de los arreglos a partir del 0.
Un cdigo muy sencillo y corto. Lanlo con tranquilidad.
Inicializacin explcita de arreglos:
Java nos provee de una forma de declarar arreglos poniendo explcitamente los valores de
sus celdas. Por ejemplo, si quiero un arreglo de tres celdas con los valores 10, 28 y 77
puedo hacer esto:
Cdigo:
All la variable miArreglo es un simple arreglo de tres celdas. Luego podemos hacer con
l lo que queramos.
Arreglos multidimensionales:
Bien, en Java declarar un arreglo, por ejemplo, de dos dimensiones (una tabla) no tiene
ms ciencia que esto:
int [][] miTabla= new int[10][5];
Ah tenemos un arreglo de 10 filas por 5 columnas. Como ven, es solo poner tantos []
como dimensiones queramos y ya. Luego, al hacer new debemos poner los valores para
cada
dimensin
del
arreglo
y
listo.
Del mismo modo se accede a un arreglo multidimensional:
Cdigo:
miTabla[1][2]= 25;
Qu pasa si yo quiero tener una tabla pero inicializarla explcitamente como con un
arreglo normal? Pues Java nos permite hacerlo tranquilamente. Supongamos que
queremos un arreglo de 2x2:
Cdigo:
Los arreglos en Java son objetos propiamente dichos y, aunque an no los usamos como
tales, tienen ciertas caractersticas importantes a tener en cuenta, sobre todo si se desea
usarlo
en
funciones
y
procedimientos.
Lo nico que veremos ahora es que existe una constante llamada length que nos da el
largo de un arreglo como int. Si por ejemplo yo quiero guardarme en una variable el largo
del arreglo puedo hacerlo as:
Cdigo:
Noten que no estamos usando una operacin, por eso no hay parntesis. Estamos
accediendo a una constante. De momento esto no est claro ya que corresponde a la
orientacin a objetos de Java. Los arreglos son objetos de una clase llamada Array. Si
ustedes la buscan con NetBeans, de todas las que aparecen debern cliquear sobre la
que est en el paquete java.lang.reflect. All tienen el cdigo fuente del funcionamiento
de los arreglos. No entendern nada por tres principales motivos:
NOTA: Para arreglos multidimensionales, length solo nos devolver el largo de la primera
dimensin declarada. Por ejemplo:
Cdigo:
miTabla[1].length
Hagan pruebas ustedes mismos. Java permite arreglos con columnas de largos diferentes.
Nmax=Entrada.nextInt();
if (Nmax>10) a=true; else a=false;
}while(a==false);
a=true;
do{
if (a==false){ System.out.print("ERROR - muy pocos intentos."
+ " Los intentos deben ser mayor o igual que " + (Nmax/10) );}
System.out.print("\n\nIngresa el numero maximo de intentos:");
Imax=Entrada.nextInt();
if (Imax>=(Nmax/10)) a=true; else a=false;
}while(a==false);
Nadivinar= Generador.nextInt(Nmax);
System.out.print("\n\nDispones de "+ Imax + " Intentos \n
iactuales=1;
irestantes=Imax;
do{
System.out.print("\n\nDispones de "+ irestantes + "\n" + iactuales
+ ")--> ");
obtenido= Entrada.nextInt();
if(obtenido==Nadivinar){ ganado=true; irestantes=0; }else{
if (obtenido>Nadivinar) System.out.print("\nEl numero a adivinar es menor"); else{
System.out.print("\nEl numero a adivinar es mayor");
}
ganado=false; iactuales=iactuales+1; irestantes=irestantes-1;
}
} while((irestantes!=0)||(ganado=false) ) ;
if (ganado=true)System.out.print("!!HAS GANADO FELICIDADES!!"); else{
System.out.print("Has perdido , el numero era "+ Nadivinar);
}
break;
case 2: break;
default: System.out.print("Has introducido una opcion incorrecta");
}
}
SOLUCION2 ADIVINADOR
Cdigo:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
package adivinador;
import java.util.Random;
import java.util.Scanner;
public class Adivinador {
public static void main(String[] args) {
Random generador= new Random();//Creo el objeto Random
Scanner entradaEstandar= new Scanner(System.in); //Creo el objeto de entrada
por teclado
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
LECCIN
67:
OPERACIONES
INTRODUCCIN A LA POO.
EN
JAVA
Cdigo:
3.
4.
5. }
Creamos una clase llamada Persona. Su cdigo fuente ser simplemente este:
Cdigo:
Es decir que solo est declarada como clase pblica y nada ms. Recuerden que para
declarar una clase simplemente va la palabra class, luego el identificador y las llaves de
apertura { y cierre } que forman el cuerpo de la clase. En este caso agregamos adems
el modificador public para que la clase sea accesible desde otros mdulos del programa .
En Modula tenamos aquello de archivo de definicin y archivo de implementacin. Como
dije antes, en Java todo est en el mismo archivo, es decir, en la clase. Las clases definen
por s mismas tipos de objetos que podemos crear con ellas. De este modo, al definir una
clase Persona, ya estamos definiendo una futura creacin de objetos de tipo Persona.
En Modula tenamos que definir en el archivo de definicin que bamos a usar un tipo de
objetos de ese mdulo. Eso lo hacamos con los tipos opacos. Ahora olvidamos ese
aspecto porque la propia declaracin de la clase define que se crearn objetos de ese
tipo.
Luego, en Mdula debamos ir al archivo de implementacin y dar una representacin
para el tipo de objetos que bamos a crear. Esto lo hacamos con un puntero a un registro
que definamos en el mismo mdulo. Por ejemplo, el tipo Persona del sistema
NominaPersonas era as:
Cdigo:
1. TYPE
2. Persona= POINTER TO DatosPersona
3.
4. DatosPersona= RECORD
5.
6.
7.
SueldoPorHora: REAL;
8.
HorasTrabajadas: REAL;
9. END;
10.
Antes dije que en Java no podemos manejar punteros y tambin dije que no tenemos
registros. As que esa definicin de arriba solo nos servir como modelo. Tomemos de ese
tipo simplemente los datos Nombre y Apellido, es decir, de momento nuestros objetos
Persona tendrn solo un nombre y un apellido. Cmo definimos eso en Java? Pues fcil,
declaramos dos variables para esos datos y ya:
Cdigo:
3.
4. }
Como ven solo declare dos variables del tipo String, pero qu es eso de public en las
variables?
Esa palabra la han visto ya al declarar la clase. Se trata de un modificador de acceso;
en este caso quiere decir que esas variables son pblicas de la clase Persona, es decir,
podemos acceder a ellas desde otra clase cualquiera. Es casi como si fueran variables
declaradas en el DEF de un mdulo de Modula 2. Vamos un ejemplo:
Ya tenemos entonces nuestra clase Persona declarada la cual tiene dos variables
pblicas para almacenar un nombre y un apellido. Vamos entonces a la clase principal y
nos declaramos una variable llamada p del tipo Persona:
Cdigo:
3.
Persona p;
4.
5.
6. }
Sabiendo ustedes que p entonces ser un objeto de tipo Persona, deberan ya deducir
entonces que p en realidad es una referencia a un objeto de tipo Persona. La variable p
contendr la direccin de memoria en donde estar el objeto Persona con su nombre y su
apellido.
Ahora p est simplemente declarada por lo cual no sabemos qu valor posee, incluso si
quisiramos usarla ahora NetBeans no dara un error de sintaxis porque la variable no
est inicializada.
Cmo la inicializo? Pues en Modula tenamos una operacin constructora llamada
CrearPersona, la cual se encargaba de solicitar memoria y apuntar al puntero a dicho
lugar de memoria. Esta operacin adems se encargaba de asignar los valores de los
atributos ya que los reciba como argumentos. Recordmosla:
Cdigo:
1. p= new Persona();
El operador new, al igual que en Pascal y Modula solicita memoria para almacenar un
objeto y la reserva. Mediante la operacin constructora se encarga, luego de haber
pedido memoria, de inicializar los atributos del objeto retornando finalmente la direccin
de memoria hacia l. A nosotros no nos importa la direccin de memoria ni cmo se
escribe, nos importa que p es una referencia a un objeto y ya; o sea, seguiremos viendo a
p como una flecha hacia una entidad de memoria que contiene muchos datos
manipulables.
Cmo sabe la operacin constructora cmo inicializar los atributos del objeto?
Seguramente ahora eso de una operacin constructora por defecto suena raro. Pues bien,
como no hemos escrito nada sobre esta operacin, sino que nos apegamos a la que Java
nos da, debemos saber que los atributos se inicializarn entonces con valores
predeterminados:
En este caso, nuestra clase Persona tiene solo dos atributos: nombre y apellido. Estos
atributos son del tipo String, por tanto no son tipos primitivos sino que son referencias a
objetos as que se inicializarn en null. Esto significa que son Strings nulos, lo cual no es
lo mismo que Strings vacos representados por el valor .
EL VALOR NULL:
As como yo poda definir en Pascal y Modula un puntero que no apuntara a nada
asignndole el valor NIL, en Java puedo hacerlo tambin. Sabiendo que las referencias a
objetos son punteros a esos objetos, puedo asignar a un puntero el valor NIL, solo que en
Java se llama null. Por tanto yo puedo hacer algo como esto :
Cdigo:
1. p= null;
Cdigo:
1. if (p==null)
2.
. . .
2.
3.
4.
5.
p.nombre= "Kyshuo";
6.
p.apellido= "Ayame";
7.
8.
9.
10. }
Como pueden ver, para acceder a las variables del objeto simplemente ponemos el
nombre de la referencia, un punto y luego el nombre de la variable. Es ms, si ustedes
escriben el nombre de la referencia al objeto de tipo Persona y un punto vern que
NetBeans despliega un listado de lo que tenemos disponible. All vern las variables que
definimos y luego alguna otra cosa ms que de momento no sabemos de dnde sale. Ya
investigaremos sobre el tema.
Si al escribir una referencia a un objeto seguida de un punto no ven el listado de opciones
o bien, NetBeans lo cerr, simplemente presionen ALT Gr + ESPACIO y lo tendrn a su
disposicin. Resulta muy til, sobre todo cuando tengamos muchas clases con muchas
variables y dems.
De este modo hemos accedido directamente a las variables (atributos) de la clase
Persona. Esto nicamente fue posible porque estas variables fueron declaradas como
pblicas y por tanto podemos acceder a ellas desde otra clase que no sea la clase
Persona.
2.
3.
4. }
Ahora ya no tenemos dos variables String sino que tenemos un arreglo de Strings de dos
celdas. La primera celda contendr el nombre y la segunda contendr el apellido. Si un
usuario pretende utilizar mi nueva clase Persona tendr que, adems de sustituir su
antigua clase Persona, modificar el cdigo fuente de su clase principal porque ya no hay
una variable nombre y una variable apellido. Si ustedes cambian el cdigo fuente en sus
PCs y compilan vern que NetBeans les marcar muchos errores.
Para solucionarlos pueden, o bien dejar la clase Persona como estaba, o bien modificar la
clase principal. En este caso no sera un trabajo arduo, pero en un sistema grande ya
pueden imaginar que s.
Esto muestra en un ejemplo prctico que declarar los atributos de una clase como
pblicos hace que se pierda individualidad en el cdigo, de modo que un cambio en una
clase impacta directamente sobre el cdigo fuente de otras. Esto no es para nada lo que
queremos. Por eso ya Modula ocultaba la representacin del tipo de objetos que
implementbamos y nos valamos de las operaciones para manipular la informacin.
Volvamos entonces a tener nuestro atributo nombre y nuestro atributo apellido pero
ahora declarados como private y no como public:
Cdigo:
3.
4.
5. }
Declaracin de operaciones:
En Java toda operacin se declara de la misma manera sin importar si es funcin o procedimiento:
Cdigo:
Esto es una operacin llamada ModificarNombrePersona que retorna algo del tipo void
y recibe como argumento algo de tipo String en un parmetro llamado nom. En Java el
tipo void es un tipo nulo, es decir que, una operacin que retorna void justamente no
retorna nada y por eso sabemos que es un procedimiento. Noten que para los parmetros
va primero el tipo y luego el identificador, tal como es para las variables.
Y qu pas con el parmetro por referencia que en Modula era justamente el objeto
Persona cuyo nombre modificaramos? Pues ya veremos que esto no es necesario en
Java, adems de que ya no existe el pasaje de parmetros por referencia.
La operacin ModificarNombrePersona quedara entonces as:
Cdigo:
nombre= nom;
3. }
Cmo sabe Java a qu objeto Persona modificar el nombre? Pues, qu mejor manera
que verlo con un ejemplo? Veamos, desde la clase principal, teniendo dos objetos
Persona distintos, cmo asignamos un nombre a cada uno:
Cdigo:
2.
3.
4.
5.
6.
7.
8.
9.
10. }
1. p1.ModificarNombrePersona(Kyshuo);
queda totalmente explcito que lo haremos con el objeto p1. Las operaciones que se hacen a travs
de un objeto de una clase siempre se realizan con esta sintaxis:
Cdigo:
1. referenciaDelObjeto.operacionARealizar(argumentos);
Java. Para dejarlo claro, en Mdula debamos pasar por referencia un objeto del tipo en
cuestin como suceda con esta operacin
Cdigo:
1. ModificarNombrePersona(Kyshuo,p1);
1. p1.ModificarNombrePersona(Kyshuo);
Esto traer algunas cositas interesantes a tener en cuenta de ahora en ms.
Referencia this:
En Mdula, al tener la referencia como nombre de un argumento (en la operacin
ModificarNombrePersona la habamos llamado p) nos referamos a ese parmetro para
modificar los valores necesarios. Por ejemplo, en ModificarNombrePersona hacamos:
Cdigo:
1. p^.nombre= nombre;
En Java, no tenemos un argumento explcito del tipo en cuestin. Cmo nos referimos
entonces al objeto que nos han pasado en el llamado a la operacin? Veamos esto con un
simple problema:
En el ejemplo anterior llam al argumento que pasaba el nombre de la persona nom,
pero mejor sera llamarlo nombre, de este modo la firma de la operacin
ModificarNombrePersona sera
Cdigo:
nombre= nombre;
3. }
Dentro de la operacin el parmetro nombre funciona como variable local, eso ustedes
ya lo tienen clarsimo. Por tanto opaca a la variable nombre global que tenemos
declarada como atributo de los objetos Persona, as que la asignacin
nombre=nombre es asignar al parmetro nombre su propio valor y por tanto la
variable global nombre queda intacta. Incluso si ustedes paran el cursor sobre la palabra
nombre que usan dentro de la operacin ModificarNombrePersona vern que
NetBeans les pinta en todo el cdigo a quin estn haciendo referencia.
Este problema no lo tenamos en Modula porque al tener el argumento p de tipo Persona
hacamos:
Cdigo:
1. p^.nombre= nombre;
Y si hacemos algo parecido en Java? Pues, como el objeto con el que hacen el llamado a
la operacin es pasado de forma implcita no tenemos un nombre con qu referenciarlo,
pero afortunadamente los creadores de Java tenan esto presente y nos dan una
referencia para el objeto en cuestin, la cual se llama this. De este modo el cdigo casi
completamente correcto de la operacin es:
Cdigo:
this.nombre= nombre;
Entonces, Java nos provee SIEMPRE, queramos o no, una referencia al objeto con el que
hemos llamado a una operacin. Esta referencia se utiliza con la palabra reservada this.
De este modo, si el llamado a la operacin fue
Cdigo:
1. p1.ModificarNombrePersona(Kyshuo);
dentro de la operacin, la referencia this tendr el mismo valor que p1, es decir this y p1
sern alias. Espero que esto se entienda, porque es crucial en Java y, aunque de pronto
ahora podemos prescindir del uso de this, luego no habr manera de avanzar sin esta
referencia, por tanto les pedir que pregunten todo lo que les haga falta.
Yo creo que una buena forma de adaptarse a esto es pensar que ya no necesitamos para
nada declarar en nuestras operaciones un parmetro que sea del tipo del objeto que
estamos tratando porque Java siempre lo recibir de forma implcita y lo llamar this. Es
como si en Modula la operacin ModificarNombrePersona tuviera esta firma:
Cdigo:
Java entonces SIEMPRE declara por nosotros un parmetro del tipo objeto en cuestin y lo
llama this. Con eso nos ahorramos tener que pasar los objetos como argumentos de las
operaciones y adems no tenemos que declararlos ms en los encabezados de las
mismas.
No est de ms aclarar que el objeto pasado a la operacin se pasa por copia (por valor),
por eso digo que this y p1 son alias. De este modo realmente es como si en Modula la
firma fuera esta:
Cdigo:
FUNCIONES EN JAVA:
Como ya dije, las operaciones en Java se declaran siempre de la misma manera sin
importar si son procedimientos o funciones:
Cdigo:
Ustedes ya tienen bien claro que un procedimiento no retorna nada y en cambio una
funcin s lo hace. De este modo, para declarar un procedimiento le damos el tipo de
retorno void, que justamente es el tipo nulo de Java para retornos. Claramente entonces,
si ponemos otro tipo de retorno distinto de void estamos declarando una funcin.
Veamos, ahora que nuestra clase Persona tiene sus atributos como privados, cmo
utilizar una funcin para que nos retorne el nombre. Recordmosla primero en Modula:
Cdigo:
RETURN p^.Nombre;
4. END ObtenerNombrePersona;
En Java ser:
Cdigo:
1. String ObtenernombrePersona(){
2.
return this.nombre;
3. }
Seguimos un poco con el tema de la referencia this. Vern que en Modula haca falta
pasar el objeto Persona como argumento pero, como ya dije, Java siempre lo pasa de
forma implcita y le llama this, por tanto no necesitamos declarar ningn argumento para
esta operacin.
Noten que es una funcin que retorna algo del tipo String, por tanto podemos usarla a la
izquierda de una asignacin, cosa que no podemos con un procedimiento.
En Java, las funciones tambin tienen una sentencia return que s o s es requerida, la
cual funciona exactamente igual que en Modula, es decir que, llegada a la sentencia
return salimos de la operacin sin importar si haba cdigo por ejecutarse debajo. Mucho
ojo con eso.
Los procedimientos, o funciones nulas como los llaman algunos (para m esa
nomenclatura es errnea), no requieren sentencia return porque justamente no retornan
nada. Sin embargo podemos poner si queremos una sentencia return vaca:
Cdigo:
1. return;
Si la usamos, NetBeans la subrayar en amarillo y nos dir que es innecesaria, sin
embargo compilar y funcionar correctamente si la dejamos ah.
No colocar al menos una sentencia return en una funcin es un error de sintaxis y
NetBeans nos lo indicar enseguida. Cuando una funcin se vuelve compleja y tiene
muchos if y bucles tendemos a tener distintas sentencias return de modo que se realizar
la una o la otra. NetBeans chequear que las condiciones aseguren que siempre habr
alguna sentencia return que se ejecutar, si no es as nos dir que hay un error de
sintaxis. Por ejemplo:
Cdigo:
1. if (X>=0) then
2.
3. else
4.
X= 0;
En ese caso si X es mayor o igual que 0 retornamos un String (suponiendo que ese
cdigo corresponde a una funcin de tipo String), pero si no es as le asignamos a X el
valor 0 y ya. En ese caso NetBeans detecta que hay posibilidad de llegar a un momento
en que no haya un return posible (cuando entramos en el else) y nos marcar un error. De
este modo tenemos dos opciones:
1. . . .
2. String ret; //La variable para retornar algo.
3.
4. if(X>=0)
5.
6. else{
7.
X=0;
8.
ret= Asignado a 0;
9. }
10.
11. . . .
12. return ret;
nombre= nombre;
3. }
4.
5. public String ObtenernombrePersona(){
6.
return this.nombre;
7. }
Vamos a hacer entonces el TAD Persona que tenamos en Modula pero ahora en Java.
Recordemos primero el archivo DEF de este TAD:
Cdigo:
1. (*****************************************************************************
*
2. Un objeto Persona estar representado por los siguientes datos:
3.
4.
DOCUMENTO
5.
NOMBRE
6.
APELLIDO
7.
EDAD
8.
9.
HORAS TRABAJADAS
10. Esta interfz describe las operaciones que se pueden realizar con un objeto
del
11. tipo Persona.*)
12.
13. DEFINITION MODULE Persona;
14. CONST
15.
MAX_LARGO_NOMBRE= 50;
16. TYPE
17.
18.
19.
20.
(************************************)
21.
(*
CONSTURCOTRAS
*)
22.
(************************************)
23.
24.
25.
26.
27.
28.
(************************************)
29.
(*
30.
(************************************)
SELECTORAS
*)
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
(*Retorna el sueldo ganado por una persona segn el sueldo que gana por
51.
52.
53.
54.
(************************************)
55.
(*
56.
(************************************)
MODIFICADORAS
*)
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
(************************************)
77.
(*
78.
(************************************)
INFORMACIN
*)
79.
80.
81.
Documento: ValorDelDocumento
82.
Nombre: NombrePersona
83.
Apellido: ApellidoPersona
84.
Edad: EdadPersona
85.
86.
87.
88.
89.
(************************************)
90.
(*
91.
(************************************)
DESTRUCTORAS
*)
92.
93.
94.
CONSTRUCTORES EN JAVA:
Hasta ahora solo sabemos que Java nos provee un constructor por defecto el cual posee
el mismo nombre de la clase en cuestin y no recibe argumentos. Nosotros, sin tan
siquiera declararlo en la clase podemos invocarlo para solicitar memoria y crear el nuevo
objeto. El hecho es que este constructor inicializa todos los atributos con un valor por
defecto lo cual ya expliqu. Y si no quiero que los atributos se inicialicen por defecto sino
que yo quiero darles un valor o hacer tareas en la construccin del objeto? Y si quiero
pasar argumentos al constructor para directamente construir un objeto con datos
definidos
u
obtenidos
de
alguna
parte?
El constructor que tenamos en Modula reciba todos los datos necesarios para dar
valores a todos los atributos del TAD Persona, a esto se le conoce como constructor
completo. Sin embargo podramos haber definido algn constructor con menos
argumentos, por ejemplo, solo con el nombre y el apellido, dejando lo dems a la deriva
de una inicializacin predefinida.
En este ejemplo concreto no tiene mucho sentido hacer tareas en el constructor por
defecto, pero a medida que los sistemas a desarrollar se vuelven complejos la forma de
inicializar un objeto al crearlo se complicar. Java nos permite entonces:
Para inicializar los atributos de un objeto con un valor por defecto a nuestro gusto
tenemos dos opciones:
La primera forma sera como muestro a continuacin, suponiendo que el cdigo fuente de
la clase Persona es este:
Cdigo:
3.
4.
5.
6.
7.
this.nombre= nombre;
}
8.
9.
10.
return this.nombre;
11.
12. }
Como ven, los atributos estn inicializados ya en la declaracin. Podemos tambin
declarar eso mismo en una sola lnea. Lo he hecho por separado para que todo se
visualice lo mejor posible.
Ahora escribamos el constructor por defecto y demos los valores all:
Cdigo:
3.
4.
5.
public Persona(){
6.
this.nombre= "ninguno";
7.
this.apellido= "ninguno";
8.
9.
10.
11.
12.
this.nombre= nombre;
}
13.
14.
15.
16.
return this.nombre;
}
17. }
Agregamos a la clase entonces una nueva operacin. Esta operacin es extraa por dos
cosas:
Los constructores de Java tienen reglas bien especficas las cuales son justamente las de
arriba:
[*]Deben llevar el mismo nombre de la clase a la que pertenecen.
[*]No deben tener ningn tipo de retorno asociado, ni siquiera void.
Un constructor en Java, que no recibe argumento ninguno, es justamente el constructor
por defecto. Si nosotros declaramos, como hice ahora, un constructor sin argumentos nos
estamos definiendo nuestro propio constructor por defecto. Cuando desde fuera se hace,
por ejemplo:
Cdigo:
1. TYPE
2.
3.
4.
DatosPersona= RECORD
5.
6.
7.
SueldoPorHora: REAL;
8.
HorasTrabajadas: REAL;
9.
END;
Declaremos entonces el resto de los atributos en nuestro TAD Persona de Java, tras lo
cual completaremos el cdigo del constructor por defecto para inicializar todos los valores
de manera correcta y declararemos adems un constructor completo. Hasta ahora la
clase Persona es esta:
Cdigo:
3.
4.
5.
6.
public Persona(){
7.
this.nombre= "ninguno";
8.
this.apellido= "ninguno";
9.
10.
11.
12.
13.
this.nombre= nombre;
14.
this.apellido= apellido;
15.
this.edad= edad;
16.
this.documento= documento;
17.
this.sueldoPorHora= sueldoPorHora;
18.
this.horasTrabajadas= horasTrabajadas;
19.
20.
21.
22.
23.
this.nombre= nombre;
}
24.
25.
26.
27.
return this.nombre;
}
28. }
Bien, tenemos entonces dos constructores, es decir, dos operaciones constructoras. Algo
que tal vez a ustedes les llame mucho la atencin es que tenemos dos operaciones con el
mismo nombre. Esto es algo nuevo y se conoce como Polimorfismo, es decir, una
misma operacin puede tener muchas formas. En este caso tenemos el constructor
Persona con dos formas diferentes. Cmo sabr Java a cual constructor estamos
llamando? Pues por la cantidad y el tipo de argumentos. Veamos un ejemplo:
Cdigo:
Claramente all tenemos dos declaraciones distintas, sin embargo ambas tienen dos
argumentos cuyos tipos coinciden. Al momento de la invocacin Java no puede saber a
qu constructor de ambos estamos queriendo llamar y pues por este motivo no nos
dejar hacer estas declaraciones. Imaginen esto:
Cdigo:
1. private Persona(){}
Como ven, he abierto y cerrado las llaves {}, es decir, ni siquiera puse cdigo fuente en
el cuerpo del constructor porque no lo usaremos. Podra haberlo hecho si pretendiera
usarlo internamente, pero para la clase Persona podramos querer que siempre se
inicialice con el constructor completo a fin de garantizarnos que siempre se crear un
nuevo objeto con datos sustanciales. De este modo ya tenemos esa garanta, los clientes
de mi clase no tendrn ms que usar el constructor completo.
Ejercicio:
Dado el TAD Persona que usamos en Modula 2 tal como lo he mostrado anteriormente,
reescrbanlo en Java exceptuando la operacin DestruirPersona. Esto ltimo viene a
que la destruccin de objetos en Java es muy distinta a la que conocen (lo veremos
luego).
Modifiquen el mtodo main de modo que pida al usuario un entero para la cantidad de
personas a almacenar y cree con ese valor un arreglo de personas llamado
nominaPersonas. Luego deber pedir para cada persona los datos ingresados por el
usuario e ir guardando dichas personas en el arreglo. Al final debe imprimir los datos de
todas las personas cargadas en el formato que mostrar. Veamos un ejemplo de
ejecucin donde pinto en azul la entrada ingresada por el usuario:
Cita:
Este ejercicio ser una gran prctica para ustedes. Por favor, hganlo.
1. p= CrearPersona(Kyshuo,Ayame);
2. p= CrearPersona(Mengano,Menganoso);
Claro debera ser para ustedes el error all. Primero hemos creado un objeto Persona
referenciado por p y luego hemos creado otro objeto Persona referenciado tambin por p.
Esto hace que p deje de apuntar al primer objeto creado y quede apuntando al segundo.
De este modo, el objeto con nombre Kyshuo Ayame queda perdido en memoria,
inaccesible y ocupando espacio. Lo correcto habra sido destruir el objeto Persona Kyshuo
Ayame antes de crear el nuevo, o bien, referenciar dicho objeto con otra variable.
Asimismo, suponiendo que p y q son punteros a enteros, cosas como estas estn mal:
En esos los dos primeros casos estamos dejando memoria colgada, y en el tercer caso
tenamos que p y q eran alias y luego, al disponer uno de ellos el otro queda indefinido
tambin lo cual era muy peligroso si el programador no se daba cuenta porque al intentar
acceder a un puntero indefinido tendra un error en tiempo de ejecucin.
En Java para liberar memoria justamente tenemos que dejarla colgada. !!!QU???
S, tenemos que dejar memoria colgada porque Java ser quin se encargue de liberarla
luego, nosotros no tenemos control sobre eso. De este modo, si yo hago en Java algo
como esto:
Cdigo:
1. p= new Persona(Kyshuo,Ayame);
2. p= null;
estoy dejando el objeto creado en la primera lnea colgado en memoria e inaccesible.
Justamente eso es lo que Java necesita saber para liberar esa memoria luego. O sea que,
para liberar memoria tengo que, a propsito, dejarla colgada. As, todo lo que estaba mal
en Modula y Pascal ahora en Java no nos da problemas.
Por ejemplo, el tercer caso visto recin en Modula en Java sera:
Cdigo:
1. p= new Persona(Kyshuo,Ayame);
2. q= p;
3. p= null;
All hemos dejado la referencia p en null pero no hemos afectado a q por tanto el objeto
creado no est inaccesible y por ende no est colgado en memoria.
Entonces cmo funciona realmente esto de la gestin de memoria en Java?
RECOLECCIN DE BASURA
Como estamos viendo, para liberar memoria tenemos que dejarla colgada, no tenemos
otro modo. Esto es porque en Java existe un proceso llamado Garbage Collector
(recolector de basura) que cada tanto tiempo se ejecuta y busca en memoria los objetos
que estn inaccesibles desde el programa principal liberando la memoria ocupada por
ellos, es decir, este proceso se encarga justamente de buscar y liberar todo lo que hemos
dejado colgado y que por tanto se considera basura. Entonces, el recolector de basura
elimina de memoria todo aquello que no est referenciado por nadie o bien, que no es
accesible desde el programa principal (veremos esto en detalle).
Cundo pasa el recolector de basura? Este proceso es ejecutado por la mquina virtual
de Java y nosotros como programadores no tenemos ningn control sobre l, por tanto se
ejecuta espordicamente o cuando el sistema necesita memoria para otra cosa. Nunca se
sabe entonces cuando ser ejecutado este proceso. Otro punto importante es que la
ejecucin del recolector de basura no implica necesariamente que se eliminen todos los
objetos que son considerados basura. Por tanto, si hemos dejado cinco objetos colgados,
cuando el recolector pase no tiene por qu eliminar los cinco objetos. Nosotros tampoco
tenemos
un
control
sobre
eso.
Existe una instruccin que podemos utilizar para indicar a la mquina virtual de Java que
queremos que el recolector de basura pase para limpiar la memoria la cual es:
Cdigo:
1. System.gc();
Sin embargo enfatizar especficamente la parte de que con esto indicamos a la mquina
virtual que QUEREMOS que el recolector pase, pero no implica que la mquina virtual lo
ejecute y por tanto esa decisin depender de ella. De este modo, por mucho nfasis que
pongamos en querer liberar memoria nunca sabremos efectivamente cuando ser
ejecutado el recolector de basura.
Este proceso es muy inteligente, en el siguiente sentido:
Esto implica entonces que el recolector de basura puede determinar cuando toda una
enorme estructura llena de punteros que referencian a objetos de todos lados son basura
o no. Si a es una referencia a un rbol binario de bsqueda que contiene miles de nodos y
yo hago a=null, el recolector de basura podr determinar que no es posible llegar a
ningn nodo del rbol desde el programa principal y por tanto lo eliminar todo, ya no
tenemos que programarlo nosotros.
La contraparte de esto es que la recoleccin de basura es entonces un proceso muy
pesado y que consume recursos, por este motivo es la mquina virtual la que decide
cuando es necesario ejecutarlo, lo cual depender de la necesidad del sistema operativo
por usar la memoria ocupada, la carga del procesador en el momento actual (si el
procesador est muy ocupado no conviene ejecutar el recolector), la necesidad de
nuestro programa por obtener nueva memoria, etc. Toda esta complicacin queda por
parte de los programadores de Java y por tanto nosotros solo la utilizamos.
Ejemplo:
Crearemos entonces cuatro objetos de tipo Persona y luego los eliminaremos, es decir, los
desreferenciaremos con el fin de que queden como basura, inaccesibles por nosotros y
por tanto nos desentenderemos de ellos porque sabemos que Java los eliminar en algn
momento:
Cdigo:
3.
4.
5.
6.
7.
8.
System.out.println(Persona.obtenerCantidadPersonas());
9.
10.
p1= null;
11.
p2= null;
12.
p3= null;
13.
p4= null;
14.
15. }
Hasta ah todo bien, sin embargo si ustedes vuelven a mostrar en pantalla el valor de la
variable cantidadPersonas vern que vuelve a salir el nmero 4. Entonces en realidad
esta variable lleva un conteo de los objetos instanciados desde el inicio del programa sin
tomar en cuenta los eliminados. De este modo si a lo largo del tiempo de ejecucin de mi
programa creo en total 1500 objetos, sea que hayan convivido en memoria todos a la vez
o no, la variable marcar el valor 1500; ms claramente, suma 1 cada vez que creamos
un objetos, jams disminuye.
Cmo hacemos para restar 1 a la variable cuando se destruya un objeto? Deberamos
saber cuando el recolector de basura elimina efectivamente a un objeto en memoria que
es considerado basura. Cmo logramos esto? Pues Java nos provee de una operacin ya
definida que se ejecuta cuando un objeto va a ser eliminado, es decir, cuando el
recolector de basura va a reclamar la memoria ocupada por un objeto que es basura este
tiene la posibilidad de ejecutar una ltima operacin antes de ser borrado. Esta operacin
se conoce con el nombre finalize.
La razn de la existencia de esta operacin es darle al programador la posibilidad de
liberar algn posible recurso que el objeto pueda estar usando antes de ser eliminado con
el fin de tener una buena gestin sobre ese recurso; un ejemplo podra ser la conexin
con una base de datos que debera ser cerrada antes de eliminar al objeto que la
representa. En este caso puntual nosotros usaremos la operacin finalize para restar 1 a
la variable cantidadPersonas a fin de que represente realmente la cantidad de objetos
de la clase Persona que existen en memoria en un momento dado.
La declaracin de la operacin finalize es:
Cdigo:
Entonces vallamos a nuestra clase Persona y declaremos esta operacin dndole adems
un mtodo como el que muestro ahora:
Cdigo:
Persona.cantidadPersonas--;
3. }
Vern que NetBeans les subrayar en amarillo a esta operacin. En unos momentos
veremos por qu. Vallamos ahora a la clase principal de DatosPersonas y agreguemos
estas dos lneas a lo que ya tenamos:
Cdigo:
1. System.gc();
2.
3. System.out.println(Objetos en memoria
+Persona.obtenerCantidadPersonas());
All ven que tenemos subrayada la palabra finalize y adems vemos la lamparita que
est en lugar del nmero 130. Si hacemos clic en la lamparita veremos que NetBeans
nos da opciones acerca de la sugerencia. En este caso particular tendremos tres:
Si hacemos clic en alguna veremos que NetBeans aadir algn cdigo o nos abrir
algn cuadro de dilogo.
Mas all de eso, las sugerencias son sugerencias y si no las aceptamos todo
funcionar.
http://www.foro.lospillaos.es/curso-gratuito-de-programacion-aprende-desde-0vt7888.html