Sunteți pe pagina 1din 409

UNIVERSIDAD NACIONAL DEL

CENTRO DEL PER

PROGRAMACION CON JAVA 2

ABRAHAM GAMARRA MORENO


JOB DANIEL GAMARRA MORENO
JUAN GAMARRA MORENO

CONTENIDO
INTRODUCCION........................................................................................................................................... 1
CAPITULO UNO ............................................................................................................................................ 3
FUNDAMENTOS DEL JAVA ....................................................................................................................... 3
1.1.
QUE ES JAVA?............................................................................................................................ 3
1.2.
HISTORIA DE JAVA .................................................................................................................... 4
1.3.
POR QU APRENDER JAVA?................................................................................................... 5
1.4.
JAVA(TM) 2 SDK, STANDARD EDITION VERSION 1.4.0. ..................................................... 6
1.4.1. INSTALACION DEL JAVA(TM) 2 SDK, STANDARD EDITION VERSION 1.4.0.................... 6
1.4.2. ESTRUCTURA DE ARCHIVOS DEL JAVA 2 SDK .................................................................. 6
1.5.
EL EDITOR JCREATOR............................................................................................................. 10
1.5.1. REQUERIMIENTOS DEL SISTEMA ...................................................................................... 10
1.5.2. INSTALACION DE JCREATOR.............................................................................................. 10
1.6.
ESTRUCTURA DE UN PROGRAMA EN JAVA....................................................................... 11
1.7.
COMO CREAR UN PROGRAMA .............................................................................................. 12
1.7.1. CREACION DE UNA APLICACIN EN EL JCREATOR....................................................... 12
1.8.
USO DE COMENTARIOS .......................................................................................................... 14
1.9.
PALABRAS CLAVES................................................................................................................. 15
1.10.
IDENTIFICADORES .................................................................................................................. 16
1.11.
VARIABLES ............................................................................................................................... 16
1.12.
TIPOS DE DATOS....................................................................................................................... 17
1.12.1.
TIPOS DE DATOS PRIMITIVOS ....................................................................................... 17
1.12.2.
TIPOS DE DATOS REFERENCIA ..................................................................................... 18
1.13.
LITERALES................................................................................................................................. 19
1.14.
OPERADORES............................................................................................................................ 20
1.14.1.
OPERADORES ARITMTICOS......................................................................................... 21
1.14.2.
Operadores Relacionales.................................................................................................... 21
1.14.3.
Operadores Condicionales ................................................................................................. 22
1.14.4.
Operadores Lgicos y de Corrimiento (shift) ..................................................................... 22
1.14.5.
Operadores de Asignacin.................................................................................................. 23
1.14.6.
Otros Operadores ............................................................................................................... 23
1.15.
ENTRADA Y SALIDA BASICA ................................................................................................ 24
1.15.1.
FLUJOS DE ENTRADA DE BYTE Y CHAR (ENTRADA POR EL TECLADO) ................ 27
1.15.2.
FLUJOS DE SALIDA DE BYTE Y CHAR (SALIDA POR EL MONITOR)......................... 28
1.15.3.
USO DE EXCEPCIONES EN LA ENTRADA Y SALIDA DE DATOS................................ 30
1.16.
ENTRADA Y SALIDA UTILIZANDO TIPOS DE DATOS PRIMITIVOS ............................... 32
1.16.1.
FLUJOS DE ENTRADA A TRAVES DE BUFFEREDREADER (ENTRADA POR EL
TECLADO)33
1.16.2.
FLUJOS DE SALIDA A TRAVS DE LA SUBCLASE PRINTSTREAM (SALIDA POR EL
MONITOR)34
1.16.3.
MANEJO DE LOS TIPOS DE DATOS PRIMITIVOS ........................................................ 35
1.17.
LA CLASE MATH....................................................................................................................... 44
1.18.
EXPRESIONES, SENTENCIAS Y BLOQUES ....................................................................................... 48
1.19.
SENTENCIAS DE CONTROL DE FLUJO ................................................................................. 49
1.19.1.
Sentencia if.......................................................................................................................... 49
1.19.2.
Anidamiento de sentencias if .............................................................................................. 52
1.19.3.
Sentencia switch.................................................................................................................. 61
1.19.4.
Sentencia while ................................................................................................................... 68
1.19.5.
Sentencia do-while.............................................................................................................. 85
1.19.6.
SENTENCIA for.................................................................................................................. 93
1.19.7.
SENTENCIA break ........................................................................................................... 101
1.19.8.
SENTENCIA continue....................................................................................................... 102
1.19.9.
break etiquetado ............................................................................................................... 104

CAPITULO DOS .........................................................................................................................................107


ARREGLOS (ARRAY) Y CADENAS .......................................................................................................107
2.1.
DECLARAR Y CREAR UN ARRAY ........................................................................................107
2.2.
INICIALIZAR Y USAR LOS ELEMENTOS DEL ARRAY .....................................................108
2.3.
ARRAYS MULTIDIMENSIONALES.......................................................................................111
2.4.
GESTIN DE CADENAS..........................................................................................................114
2.4.1. Constructores .........................................................................................................................116
2.4.2. Sintaxis de cadenas especial ..................................................................................................116
2.4.3. Extraccin de caracteres........................................................................................................119
2.4.4. Comparacin..........................................................................................................................120
2.4.5. otros mtodos .........................................................................................................................122
2.4.6. LA CLASE String....................................................................................................................123
CAPITULO THREE....................................................................................................................................131
MTODOS CREADOS POR EL USUARIO............................................................................................131
3.1.

DEFINICIN DE UN MTODO ...............................................................................................132

CAPITULO CUATRO ................................................................................................................................139


CLASES Y PROGRAMACION ORIENTADO A OBJETOS ................................................................139
4.1.
ATRIBUTOS ..............................................................................................................................140
4.2.
COMPORTAMIENTO ......................................................................................................................140
4.3.
UNA CLASE EN JAVA .............................................................................................................141
4.3.1. LOS MIEMBROS DATO ........................................................................................................141
4.3.2. LAS FUNCIONES MIEMBRO ...............................................................................................142
4.3.3. Los conStructores...................................................................................................................147
4.4.
LOS OBJETOS ...............................................................................................................................149
4.4.1. Acceso a los miembros ...........................................................................................................150
4.5.
LA VIDA DE UN OBJETO ................................................................................................................151
4.6.
IDENTIFICADORES ........................................................................................................................155
4.7.
MODIFICADORES DE ACCESO A LOS MIEMBROS DE UNA CLASE ........................................156
4.7.1. Miembros pblicos .................................................................................................................157
4.7.2. Miembros privados.................................................................................................................157
4.7.3. Por defecto (a nivel de paquete).............................................................................................157
4.8.
EJEMPLOS DEL USO DE CLASES..........................................................................................165
4.9.
SOBRECARGA DE UN MTODO ..........................................................................................184
4.10.
REFERENCIA THIS ....................................................................................................................187
4.10.1.
UTILIZACION DE this EN UN CONSTRUCTOR ............................................................189
4.10.2.
this Y MLTIPLE CONSTRUCTORES.............................................................................189
4.10.3.
Otra vez this.......................................................................................................................192
4.11.
ARREGLO DE OBJETOS..........................................................................................................196
4.12.
VARIABLES DE CLASE (VARIABLE ESTTICA) ...............................................................199
4.12.1.
ACCEDIENDO A LAS VARIABLES DE CLASE...............................................................200
4.13.
Y LAS VARIABLES GLOBALES ???.......................................................................................202
4.14.
CONSTANTES: OTRO EJEMPLO DE VARIABLES DE CLASE ...........................................203
4.15.
EJEMPLOS DE VARIABLES DE CLASE ................................................................................203
4.16.
MTODOS DE CLASE (MTODOS ESTTICOS).................................................................206
4.16.1.
Sin this ...............................................................................................................................206
4.16.2.
Un mtodo de clase para Circulo .................................................................................206
4.17.
DESTRUCCIN DE LOS OBJETOS ........................................................................................214
4.17.1.
El recolector de basura (Garbage Collector)....................................................................214
4.18.
LA REFERENCIA NULL .............................................................................................................215
4.19.
HERENCIA ................................................................................................................................217
4.19.1.
La clase base .....................................................................................................................220
ii

Mg. ABRAHAM GAMARRA MORENO

4.19.2.
Objetos de la clase base.................................................................................................... 222
4.19.3.
La clase derivada.............................................................................................................. 223
4.19.4.
Objetos de la clase derivada............................................................................................. 225
4.20.
MODIFICADORES DE ACCESO Y HERENCIA .................................................................... 227
4.21.
LA JERARQUA DE CLASES QUE DESCRIBEN LAS FIGURAS PLANAS ............................................... 229
4.21.1.
La clase Figura................................................................................................................. 230
4.21.2.
La clase Rectangulo.......................................................................................................... 230
4.21.3.
La clase Circulo................................................................................................................ 231
4.22.
USO DE LA JERARQUA DE CLASES ............................................................................................... 232
4.23.
ENLACE DINMICO ...................................................................................................................... 232
CAPITULO CINCO.................................................................................................................................... 235
GESTION DE EXCEPCIONES ................................................................................................................ 235
5.1.
LAS EXCEPCIONES ESTNDAR........................................................................................... 235
5.1.1. Las excepciones ..................................................................................................................... 236
5.1.2. Captura de las excepciones ................................................................................................... 238
5.1.3. Manejando varias excepciones.............................................................................................. 239
5.2.
LAS EXCEPCIONES PROPIAS ......................................................................................................... 241
5.2.1. La clase que describe la excepcin........................................................................................ 241
5.2.2. El mtodo que puede lanzar una excepcin........................................................................... 242
5.2.3. Captura de las excepciones ................................................................................................... 242
5.2.4. Una funcin que que puede lanzar varias excepciones ......................................................... 244
CAPITULO SEIS ........................................................................................................................................ 247
PAQUETES ................................................................................................................................................. 247
6.1.
PAQUETES ............................................................................................................................... 247
6.1.1. La sentencia package (paquete) ............................................................................................ 248
6.1.2. Compilacin de clases en paquetes ....................................................................................... 248
6.1.3. La sentencia import ............................................................................................................... 250
6.1.4. Proteccin de accesos ........................................................................................................... 251
6.1.5. Los paquetes estndar ........................................................................................................... 253
6.2.
EJEMPLOS DE USO DE PAQUETES ...................................................................................... 253
CAPITULO SIETE ..................................................................................................................................... 257
INTERFACES ............................................................................................................................................. 257
7.1.
QU ES UN INTERFACE? ..................................................................................................... 257
7.2.
DIFERENCIAS ENTRE UN INTERFACE Y UNA CLASE ABSTRACTA................................................... 258
7.3.
LOS INTERFACES Y EL POLIMORFISMO ......................................................................................... 259
7.3.1. Herencia simple..................................................................................................................... 260
7.3.2. Interfaces ............................................................................................................................... 261
CAPITULO OCHO..................................................................................................................................... 267
ENTRADA/SALIDA PARA EL MANEJO DE ARCHIVOS.................................................................. 267
8.1.
ARCHIVOS Y DIRECTORIOS................................................................................................. 267
8.1.1. La clase File .......................................................................................................................... 267
8.1.2. Creacin de un filtro.............................................................................................................. 270
8.2.
FLUJOS DE DATOS........................................................................................................................ 273
8.2.1. Las jerarquas de clases ........................................................................................................ 274
8.2.2. Lectura................................................................................................................................... 276
8.2.3. Escritura ................................................................................................................................ 277
8.3.
ENTRADA/SALIDA ESTNDAR...................................................................................................... 277
8.3.1. Los objetos System.in y System.out........................................................................................ 277
8.3.2. La clase Reader ..................................................................................................................... 278
iii

8.4.
ENTRADA/SALIDA A UN ARCHIVO EN DISCO .................................................................................281
8.4.1. Lectura de un archivo ............................................................................................................281
8.4.2. Lectura/escritura....................................................................................................................283
8.5.
LEER Y ESCRIBIR DATOS PRIMITIVOS ...........................................................................................285
8.5.1. Los flujos de datos DataInputStream y DataOutputStream ...................................................285
8.5.2. Ejemplo: un pedido ................................................................................................................287
8.5.3. El final del archivo.................................................................................................................290
8.6.
LEER Y ESCRIBIR OBJETOS ..................................................................................................292
8.6.1. El interface Serializable .........................................................................................................293
8.6.2. Lectura/escritura....................................................................................................................294
8.6.3. El modificador transient.........................................................................................................298
8.6.4. Objetos compuestos................................................................................................................302
8.6.5. La herencia ............................................................................................................................306
8.6.6. Serializacin personalizada ...................................................................................................311
CAPITULO NUEVE....................................................................................................................................313
APPLETS......................................................................................................................................................313
9.1.
DEFINICIN DE APPLET ........................................................................................................313
9.2.
EL APPLET MNIMO................................................................................................................314
9.3.
EL PRIMER APPLET .......................................................................................................................314
9.4.
INSERTANDO UN APPLET EN UNA PGINA WEB .............................................................................316
9.5.
FUNCIONES GRFICAS..........................................................................................................319
9.5.1. El contexto grfico .................................................................................................................324
9.5.2. Establecer un color ................................................................................................................326
9.5.3. Dibujar una lnea ...................................................................................................................326
9.5.4. Dibujar un rectngulo............................................................................................................326
9.5.5. Dibujar un arco......................................................................................................................327
9.5.6. Dibujar un polgono...............................................................................................................327
9.5.7. Dibujar una imagen ...............................................................................................................328
9.6.
LAS CLASES COLOR, FONT Y FONTMETRICS ................................................................................331
9.6.1. La clase Color ........................................................................................................................331
9.6.2. La clase Font..........................................................................................................................335
9.6.3. La clase FontMetrics..............................................................................................................336
9.7.
INTERFAZ GRAFICA CON EL USUARIO (GUI) Y COMPONENTES BASICOS................344
9.7.1. COMPONENTES ...................................................................................................................345
9.7.2. ROTULOS (Label) .................................................................................................................346
9.7.3. ADMINISTRADOR DE DISEOS GRIDLAYOUT................................................................365
9.7.4. BOTONES PARA PULSAR (BUTTON) .................................................................................369
9.8.
LOS GESTORES FLOWLAYOUT, BORDERLAYOUT Y GRIDLAYOUT ..............................................375
9.8.1. El gestor FlowLayout.............................................................................................................375
9.8.2. El gestor BorderLayout..........................................................................................................377
9.8.3. El gestor GridLayout..............................................................................................................379
9.9.
EL GESTOR DE DISEO GRIDBAGLAYOUT ...................................................................................381
9.9.1. Ejemplo: diseo de una ficha .................................................................................................381
9.9.2. El panel ..................................................................................................................................382
9.9.3. El applet .................................................................................................................................383
9.9.4. El gestor de diseo GridBagLayout .......................................................................................384
9.9.5. Aadir los componentes al applet ..........................................................................................384
CAPITULO DIEZ........................................................................................................................................389
HILO Y SINCRONIZACIN ....................................................................................................................389
10.1.
EL MODELO DE HILO DE JAVA ......................................................................................................389
10.1.1.
Prioridades de hilo ............................................................................................................390
10.1.2.
Sincronizacin ...................................................................................................................390
10.1.3.
Intercambio de mensajes ...................................................................................................391
iv

Mg. ABRAHAM GAMARRA MORENO

10.2.
THREAD ...................................................................................................................................... 391
10.3.
RUNNABLE .................................................................................................................................. 391
10.4.
PRIORIDADES DE LOS HILOS ........................................................................................................ 393
10.5.
SINCRONIZACIN ........................................................................................................................ 393
10.5.1.
La sentencia synchronized ................................................................................................ 394
10.6.
COMUNICACIN ENTRE HILOS ..................................................................................................... 395
10.6.1.
Bloqueos ........................................................................................................................... 397
10.7.
RESUMEN DE LA INTERFAZ DE PROGRAMACIN (API) DE HILOS ................................................. 397
10.7.1.
Mtodos de clase............................................................................................................... 397
10.7.2.
Mtodos de instancia ........................................................................................................ 398

INTRODUCCION

La evolucin de los lenguajes de programacin y la capacidad


de procesamiento de los ordenadores en la actualidad ha dado
origen a la Programacin orientada Objetos. La bsqueda de
una mejor portabilidad de los programas de aplicacin, as
como la necesidad del desarrollo de programas para Internet
ha hecho que el Lenguaje Java sea uno de los ms utilizados.
El lenguaje Java es un lenguaje de programacin FreeWare, es
decir no se requiere comprar la licencia del software por lo
que nos facilita la implementacin de neutro cdigo sin costo
alguno.
Este libro trata sobre el desarrollo de programas combinando
las tcnicas de programacin tradicionales y las nuevas tcnicas de programacin orientada a objetos.
Para el desarrollo de los programas se utilizara el editor
integrado JCreator Pro y Lenguaje de Programacin Java 2 SDK,
Standard Edition, versin 1.4.0.03 de la Empresa Sun Microsystems(TM), Inc.
El primer Capitulo I trata sobre las caractersticas del lenguaje de programacin Java: la descripcin de los directorios
del lenguaje de programacin, la estructura de un programa,
los tipos de datos usados, entrada y salida bsica, las sentencias de control, y. En el Capitulo II detalla sobre los
arreglos y la gestin de de cadenas. El Capitulo III se detalla las caractersticas de la Programacin Orientada a ObjePROGRAMACION CON JAVA 2

tos. El Captulo IV contempla el tratamiento de errores en


tiempo de compilacin conocido tambin como gestin de excepciones. El Captulo V tratao sobre el uso de paquetes en Java. El Captulo VI muestra el uso de interfaces. El captulo
VII muestra la entrada/salida para el manejo de archivos. En
el Capitulo VIII se trata sobre la elaboracin de programas
para Internet utilizando Applets y la interfase grfica del
lenguaje de programacin Java. En el Capitulo IX se detallan
las caractersticas de la programacin multihilos que permitirn usar concurrentemente los recursos de un ordenador.

Mg. ABRAHAM GAMARRA MORENO

CAPITULO UNO
FUNDAMENTOS DEL JAVA
1.1.

QUE ES JAVA?
Java es un lenguaje de programacin de alto nivel con
el que se pueden escribir tanto programas convencionales como para Internet.
Una de las ventajas significativas de Java sobre otros
lenguajes de programacin es que es independiente de
la plataforma tanto en cdigo fuente como en binario.
Esto quiere decir que el cdigo producido por el compilador Java puede transportarse a cualquier plataforma (Intel, Sparc. Motorola, etc.) que tenga instalada
una mquina virtual Java y ejecutarse. Pensando en internet esta caracterstica es crucial ya que esta red
conecta ordenadores muy distintos. En cambio, C++, por
ejemplo, es independiente de la plataforma slo en cdigo fuente, lo cual significa que cada plataforma diferente debe proporcionar el compilador adecuado para
obtener el cdigo mquina que tiene que ejecutarse.
Segn lo expuesto. Java incluye dos elementos: un compilador y un intrprete. El compilador produce un cdigo de bytes que se almacena en un fichero para ser
ejecutado por el intrprete Java denominado mquina
virtual de Java.

PROGRAMACION CON JAVA 2

Programa
escrito
en Java

Compilador

Cdigo de
bytes

Mquina
virtual
de Java

Los cdigos de bytes de Java son un conjunto de instrucciones correspondientes a un lenguaje mquina que
no es especfico de ningn procesador, sino de la mquina virtual de Java. Dnde se consigue esta mquina
virtual? Hoy en da casi todas las compaas de sistemas operativos y de navegadores han implementado mquinas virtuales segn las especificaciones publicadas
por Sun Microsystems, propietario de Java, para que
sean compatibles con el lenguaje Java. Para las aplicaciones de Internet (denominadas applets) la mquina
virtual est incluida en el navegador y para las aplicaciones Java convencionales, puede venir con el sistema operativo, con el paquete Java, o bien puede obtenerla a travs de Internet.

1.2.

HISTORIA DE JAVA
El lenguaje de programacin Java fue desarrollado por
Sun Microsystems en 1991. Nace como parte de un proyecto de investigacin para desarrollar software para
comunicacin entre aparatos electrnicos de consumo
como vdeos, televisores, equipos de msica. etc. Durante la fase de investigacin surgi un problema que
dificultaba enormemente el proyecto iniciado: cada
aparato tena un microprocesador diferente y muy poco
espacio de memoria: esto provoc un cambio en el rumbo
de la investigacin que desemboc en la idea de escribir un nuevo lenguaje de programacin independiente
del dispositivo que fue bautizado inicialmente como
Oak.
La explosin de internet en 1994, gracias al navegador
grfico Mosaic para la Word Wide Web (WWW), no pas
desapercibida para el grupo investigador de Sun. Se
dieron cuenta de que los logros alcanzados en su proyecto de investigacin eran perfectamente aplicables a
Internet. Comparativamente, Internet era como un gran
conjunto de aparatos electrnicos de consumo, cada uno
con un procesador diferente. Y es cierto bsicamente,
Internet es una gran red mundial que conecta mltiples
ordenadores con diferentes sistemas operativos y diferentes arquitecturas de microprocesadores, pero todos
tienen en comn un navegador que utilizan para comuni-

Mg. ABRAHAM GAMARRA MORENO

carse entre s. Esta idea hizo que el grupo investigador abandonara el proyecto de desarrollar un lenguaje
que permitiera la comunicacin entre aparatos electrnicos de consumo y dirigiera sus investigaciones hacia
el desarrollo de un lenguaje que permitiera crear
aplicaciones que se ejecutaran en cualquier ordenador
de Internet con el nico soporte de un navegador.
A partir de aqu va todo es conocido. Se empez a
hablar de Java y de sus aplicaciones, conocidas como
applets. Un applet es un programa escrito en Java que
se ejecuta en el contexto de una pgina Web en cualquier ordenador, independientemente de su sistema operativo y de la arquitectura de su procesador. Para
ejecutar un applet slo se necesita un navegador que
soporte la mquina virtual de Java como, por ejemplo.
Microsoft Internet Explorer o Netscape. Utilizando un
navegador de stos, se puede descargar la pgina Web
que contiene el applet y ejecutarlo. Precisamente en
este campo, es donde Java como lenguaje de programacin no tiene competidores. No obstante, con Java se
puede programar cualquier cosa, razn por la que tambin puede ser considerado como un lenguaje de propsito general: pero desde este punto de vista, hoy por
hoy, Java tiene muchos competidores que le sobrepasan
con claridad; por ejemplo C++.

1.3.

POR QU APRENDER JAVA?


Una de las ventajas ms significativas de Java es su
independencia de la plataforma. En el caso de que tenga que desarrollar aplicaciones que tengan que ejecutarse en sistemas diferentes esta caracterstica es
fundamental.
Otra caracterstica importante de Java es que es un
lenguaje de programacin orientado a objetos (POO).
Adems de ser transportable y orientado a objetos. Java es un lenguaje fcil de aprender. Tiene un tamao
pequeo que favorece el desarrollo y reduce las posibilidades de cometer errores: a la vez es potente y
flexible.
Java est fundamentado en C++. Quiere esto decir que
mucha de la sintaxis y diseo orientado a objetos se
tom de este lenguaje. Por lo tanto, a los lectores
que estn familiarizados con C++ y la POO les ser muy
fcil aprender a desarrollar aplicaciones con Java. Se

PROGRAMACION CON JAVA 2

advierte a los potenciales usuarios de Java que en este lenguaje no existen punteros ni aritmtica de punteros, las cadenas de caracteres son objetos y la administracin de memoria es automtica, lo que elimina
la problemtica que presenta C++ con las lagunas de
memoria al olvidar liberar bloques de la misma que
fueron asignados dinmicamente.

1.4.
JAVA(TM)
VERSION 1.4.0.

SDK,

STANDARD

EDITION

1.4.1. INSTALACION DEL JAVA(TM) 2 SDK, STANDARD EDITION VERSION 1.4.0.


Ejecutar
el
archivo
JAVA\j2sdk-1_4_0_03windows-i586.exe desde el CD-ROM para instalar el Java2 y prosiga con el asistente de
instalacin.

1.4.2. ESTRUCTURA DE ARCHIVOS DEL JAVA 2 SDK


El siguiente grfico muestra los directorios
ms importantes para el desarrollo de aplicaciones de la plataforma Java (se asume que el
Java esta instalado en c:\j2sdk1.4.0).

c:\j2sdk1.4.0
El directorio raz del software SDK. Contiene
copyright, licencia y archivos README. Tambin contiene el archivo src.jar del cdigo
fuente para la plataforma Java 2.
6

Mg. ABRAHAM GAMARRA MORENO

c:\j2sdk1.4.0\bin
Los archivos ejecutables para el desarrollo
de programas contenidos en el Kit de desarrollo de Java (Java Development Kit).
La variable de entorno PATH debe contener una
entrada para este directorio:
path=%path%;c:\jdk1.3\bin
c:\j2sdk1.4.0\lib
Los archivos utilizados por las herramientas
de desarrollo. Estos incluyen tools.jar, que
contiene clases no esenciales como apoyo de
las herramientas y utilidades dentro del SDK.
Tambin incluye dt.jar que llaman al entorno
de desarrollo interactivo (IDE).
c:\j2sdk1.4.0\jre
El directorio raz del entorno en tiempo de
ejecucin del Java (Java Runtime Environment)
utilizado por las herramientas de desarrollo
SDK. El entorno en tiempo de ejecucin es una
implementacin de la plataforma Java 2. Este
es el directorio representado por la posesin
del java.home.
c:\j2sdk1.4.0\jre\bin
Archivos ejecutables y DLLs para herramientas
y libreras utilizadas por la plataforma Java. Los archivos ejecutables son idnticos a
los archivos en /j2sdk1.4.0/bin. La herramienta java launcher sirve coo una aplicacin
de lanzamiento, en lugar de el Viejo jre que
se enviaba con la versin 1.1 del software
SDK. Este directorio no necesita estar dentro
de la variable de entorno PATH.
c:\j2sdk1.4.0\jre\bin\classic
Contiene los archivos DLL utilizados por la
Mquina Virtual Clsica Java 2 (Java 2 Classic Virtual Machine). Estos archivos estn
presentes slo en el Java 2 SDK. Ellos no esPROGRAMACION CON JAVA 2

tn incluidos con el Java 2 Runtime Environment.


c:\j2sdk1.4.0\jre\bin\hotspot
Contiene los archivos DLL utlizados por el
Java HotSpotTM Client Virtual Machine, que es
implementado con la tecnologa Java HotSpot.
c:\j2sdk1.4.0\jre\lib
Libreras, configuracin de propiedades y archivos de recursos utilizados por el Java
runtime environment. Incluye:

rt.jar las clases de la secuencia de


arranque (bootstrap).

las clases de conversin de


caracteres y otros archivos asociados
con la localizacin e internacionalizacin.
i18n.jar

Aparte del subdirectorio ext (descrito antes)


hay varios subdirectorios de recursos adicionales no descritos aqu.
c:\j2sdk1.4.0\jre\lib\ext
Directorio de instalacin por defecto de las
extensiones para la plataforma Java. Por
ejemplo este es el directorio donde el archivo JavaHelp jar va cuando este es instalado.
c:\j2sdk1.4.0\jre\lib\security
Contiene archivos utilizados para la administracin de la seguridad. Estos incluyen las
polticas de seguridad (java.policy) y los
archivos de las propiedades de seguridad (java.security).
c:\j2sdk1.4.0\jre\lib\applet
Los archivos Jar conteniendo clases de apoyo
para applets pueden ser colocados en el directorio lib/applet/. Este reduce el tiempo de
inicio para applets grandes, permitiendo a
las clases applet ser pre cargados desde el
8

Mg. ABRAHAM GAMARRA MORENO

sistema de archivos local teh, con el cargador de clases applet, proporcionando las mismas protecciones tal como si ellos han sido
descargados desde la red.
A continuacin se describen los archivos y
directorios adicionales: demos, codigo fuente
Java y archivos de cabecera C.

c:\j2sdk1.4.0\src.jar
Archivos conteniendo cdigo fuente para la
plataforma Java 2.
c:\j2sdk1.4.0\demo
Ejemplos con cdigo fuente que muestran como
programar en la plataforma Java.
c:\j2sdk1.4.0\demo\applets
Applets que pueden utilizarse en una pgina
Web.
c:\j2sdk1.4.0\demo\jfc
Ejemplos que utilizan Java 2DTM y fiuncionalidad JFC\Swing.
c:\j2sdk1.4.0\demo\jpda
Ejemplos de uso del Java Platform Debugging
Architecture. Incluye cdigo fuente para las
utilidades javadt y jdb.
c:\j2sdk1.4.0\demo\sound
PROGRAMACION CON JAVA 2

Contiene cdigo fuente con demos de sonido


Java.
c:\j2sdk1.4.0\include
Archivos de cabecera del lenguaje C que apoyan la programacin de cdigo nativo utilizando el Java Native Interface y el Java Virtual Machine Debugger Interface.
c:\j2sdk1.4.0\include-old
Archivos de cabecera que apoyan la programacin de cdigo nativo utilizando interfaces
antiguas. Estos archivos de cabecera son proporcionados slo por compatibilidad hacia
atrs. Estas interfaces son desaprobadas, inseguras y no disponibles en todas las mquinas virtuales Java.

1.5.

EL EDITOR JCREATOR
JCreator Pro Release V2.00 build 004 (32 bit) for Win
95/98/NT/2000.
Jcreator es un poderoso Entorno de Desarrollo Integrado (Integrated Development Environment: IDE), para Java, que proporciona al usuario un amplio rango de funcionalidades tales como: Administracin de proyectos,
plantillas, navegador para clases, elaboracin de cdigo, interfaz de depuracin, resaltado de sintaxis,
asistente y una interfaz de usuario configurable.
JCreator esta escrito enteramente en C++, el cual lo
hace a este rpido y eficiente comparado con los IDEs
basados en Java.

1.5.1. REQUERIMIENTOS DEL SISTEMA

Windows 95/98/NT4/2000 o superior.

Internet Explorer 4 o superior (opcional)

1.5.2. INSTALACION DE JCREATOR


Descomprimir el fichero de instalacin JCREATORPRO2\JCREATORSETUP.EXE en un directorio
10

Mg. ABRAHAM GAMARRA MORENO

temporal y correr el ejecutable. El asistente


de instalacin realizar el resto.

1.6.

ESTRUCTURA DE UN PROGRAMA EN JAVA


Un programa es un conjunto de instrucciones, escritas
en un lenguaje de programacin, que sirven para resolver un tipo determinado de problema o para cumplir metas bien definidas. Un programa de Java contiene una o
ms clases. stas describen objetos, entidades de
software que interactan al momento de la ejecucin
para realizar tareas especficas. Los objetos se utilizan para modelar entidades reales o lgicas en el
dominio del problema. Un aspecto importante de la POO
es identificar estas entidades y sus interacciones en
el proceso de solucin.
Por lo general una clase contiene miembros que pueden
ser campos y mtodos. Los primeros son variables que
almacenan datos y objetos. Los segundos son funciones
que codifican operaciones. Es as que ellos reciben
argumentos, realizan clculos predefinidos y devuelven
resultados.
La estructura de un programa se puede representar de
la siguiente manera:
Class . . .
{
< campos o atributos >
.

< mtodos >


}
Se debe tener un mtodo main para que se pueda ejecutar la aplicacin
En Java, las clases contienen a todos los mtodos, no
se les permite no estar anexados y eso tambin sucede
con las funciones. Un mensaje enviado a un objeto activa (o invoca) un mtodo de ese objeto, le pasa argumentos y obtiene el valor que devuelve. Los objetos
interactan al enviar y recibir mensajes.
PROGRAMACION CON JAVA 2

11

Una clase proporciona el nombre bajo el que se renen


los miembros para formar una unidad de clculo que
puede operar con independencia de otras partes del
programa. Con objetos, puede construirse un programa
grande con muchas unidades pequeas, independientes y
que interactan entre si. La orientacin a objetos
puede reducir significativamente la complejidad del
programa, aumentar su flexibilidad y mejorar las posibilidades de volver a usarlo. Un programa de Java puede definir sus propias clases, utilizarlas ya integradas y emplear las que han sido creadas por otros.
Las clases pueden estar organizadas en paquetes con un
nombre. Cada paquete puede contener uno o ms archivos
de cdigo fuente.

1.7.

COMO CREAR UN PROGRAMA


Un programa es una aplicacin o un applet y puede
crearse con algn editor de textos (Block de notas o
el Edit) el programa. Pero se recomienda utilizar un
IDE, tal como el JCreator.

1.7.1. CREACION
JCREATOR

DE

UNA

APLICACIN

EN

EL

Para mostrar este ejemplo, utilizaremos el


IDE JCreator para crear nuestras aplicaciones.
Escriba el siguiente cdigo en el IDE JCreator:
Ejemplo ( 1): Programa que imprime un mensaje.
class programa1
{
public static void main (String[] args)
{
System.out.println("Mi
primer
programa!!!");
}
}

Para crear el programa elija File (Men principal), New, elija la ficha Files , Java File, ingrese el nombre del archivo en Filename, elija la carpeta donde se alojar el ar12

Mg. ABRAHAM GAMARRA MORENO

chivo en Location y presione el clic en Aceptar, tal como se muestra en la figura:

El cdigo en el IDE JCreator queda:

Para compilar el programa presione clic sobre

el icono
, luego
ejecutar el programa.

presione

para

Usted ahora tiene el siguiente resultado:

PROGRAMACION CON JAVA 2

13

El programa anterior muestra en pantalla el mensaje Mi


primer programa!!!, el cual se imprime debido al uso
de la clase System, ampliaremos este tema en las siguientes secciones. Ntese que el nombre de la clase
debe ser igual al nombre del archivo, pero el archivo
tiene la extensin .java.

1.8.

USO DE COMENTARIOS
En Java hay tres tipos de comentarios:
// comentarios de una sola lnea
/*
comentarios de una o ms lneas
*/
/**
comentario de documentacin, que pueden ser de una
o ms lneas y pueden contener palabras claves que comienzan con @ para destacar cierta informacin, por
ejemplo:
@version 1.0 (06/11/2000)
@author Gustavo A. Scrigna
@author Lisandro A. Palermo
*/
Los dos primeros tipos de comentarios son los ms
conocidos, ya que son los heredados del lenguaje C y
C++, y se utilizan del mismo modo. Los comentarios de
documentacin indican que ese comentario ha de ser
colocado
en
la
documentacin
que
se
genera
automticamente cuando se utiliza la herramienta del
JDK,
javadoc.
Dichos
comentarios
sirven
como
descripcin del elemento declarado permitiendo generar
una
documentacin
de
las
clases
que
se
van
construyendo al mismo tiempo que se genera el cdigo
de la aplicacin. En este tipo de comentario para
documentacin, se permite la introduccin de algunas
palabras claves, que harn que la informacin aparezca

14

Mg. ABRAHAM GAMARRA MORENO

destacada, permitiendo la incorporacin de informacin


til, que luego se podr ver en formato HTML sobre
cualquier navegador. Aunque posteriormente se vern en
detalle algunas de las palabras claves que soporta
javadoc, hay que tener en cuenta a la hora de utilizar
este tipo de comentarios, que javadoc solamente
procesarn la documentacin para miembros public y
protected, los comentarios para miembros private y
package sern ignorados.
Algunas de las palabras claves ms utilizadas son:

1.9.

@author: Informacin del autor

@param: Parmetro y descripcin

@exception: Nombre de la clase y descripcin

@version: Informacin de la versin

@see: Referencia a otra clase

@return: Significado del valor de retorno

@deprecated: Aviso de clase obsoleta

PALABRAS CLAVES
Las siguientes son las palabras claves que estn definidas en el lenguaje Java y que no pueden utilizarse
como identificadores:

abstract

double

int

strictfp **

boolean

else

interface

super

break

Extend

long

switch

byte

final

native

synchronized

case

finally

new

this

PROGRAMACION CON JAVA 2

15

catch

float

package

throw

char

for

private

throws

class

goto *

protected

transient

const *

if

public

try

continue

implements

return

void

default

import

short

volatile

do

instanceof

static

while

* indica una palabra clave que no esta siendo utilizada en la actualidad


** indica una palabra clave que fue agregada desde Java 2
Tambin son palabras reservadas (aunque no son palabras claves) las siguientes: true, false y null, y por
lo tanto no pueden ser utilizadas como identificadores.

1.10.

IDENTIFICADORES
Los identificadores se utilizan como nombres de clase,
mtodo y variable. Un identificador puede ser cualquier sentencia descriptiva de letras en mayscula o
minscula, nmeros y los caracteres subrayado (_) y
signo de dlar ($). No se deban comenzar por nmero.
Java diferencia entre maysculas/minsculas, lo que
significa que VALOR es un identificador diferente de
Valor.

1.11.

VARIABLES
Una variable es un tem de datos nombrado por un identificador. Debemos explcitamente suministrar un nom-

16

Mg. ABRAHAM GAMARRA MORENO

bre y un tipo para cada variable que quisiramos usar


en nuestro programa. El nombre de la variable debe ser
un identificador vlido --una serie de caracteres Unicode que comienzan con una letra. Utilizamos el nombre
de la variable para referirnos al dato que la variable
contiene. El tipo de la variable determina el conjunto
de valores que se pueden almacenar en esa variable y
el tipo de operaciones que se pueden realizar con
ella. Para dar a una variable un tipo y un nombre, escribimos una declaracin de variable, que en general
se ver de la siguiente forma:
tipo nombre;
o tambin:
tipo nombre1 [ = valor][,nombre2 [= valor] ...];
en este ltimo caso mostramos como podemos inicializar
una variable en el momento de su declaracin.
Adems del nombre y tipo que explcitamente le damos a
la variable, una variable tiene un alcance (scope). La
seccin de cdigo donde puede ser utilizado el nombre
de la variable es el alcance de la variable. El alcance de la variable es determinado implcitamente por la
ubicacin de la declaracin de la variable, es decir,
donde aparece la declaracin en relacin a otros elementos del cdigo. Se ampliar cuando se utilice funciones.

1.12.

TIPOS DE DATOS
Cada variable debe tener un tipo de datos. El lenguaje
de programacin Java tiene dos categoras de tipos de
datos: primitivo y referencia.

1.12.1.

TIPOS DE DATOS PRIMITIVOS

Una variable de tipo primitivo contiene un


nico valor de tamao y formato apropiados
para su tipo: un nmero, un carcter, un valor booleano. Por ejemplo, el valor de un entero (int) es de 32 bits de datos en un formato conocido como complemento a 2, el valor
de un carcter (char) es de 16 bits de datos
formateados como un carcter Unicode, etc.
PROGRAMACION CON JAVA 2

17

En la tabla siguiente listamos todos los tipos de datos primitivos soportados por Java,
junto con sus tamaos y formatos, y una breve
descripcin de cada uno de ellos.
Tipo

Descripcin

boolean Tiene dos valores true o false.


Caracteres Unicode de 16 bits. Los caracteres alfanumricos son los mismos que los ASCII con el bit alto
char
puesto a 0. El intervalo de valores va desde 0 hasta
65535 (valores de 16-bits sin signo).
Tamao 8 bits. El intervalo de valores va desde -27 hasbyte
ta 27 -1 (-128 a 127)
Tamao 16 bits. El intervalo de valores va desde -215
short
hasta 215-1 (-32768 a 32767)
Tamao 32 bits. El intervalo de valores va desde -231
int
hasta 231-1 (-2147483648 a 2147483647)
Tamao 64 bits. El intervalo de valores va desde -263
long
hasta 263-1 (-9223372036854775808 a 9223372036854775807)
Tamao 32 bits. Nmeros en coma flotante de simple prefloat
cisin. Estndar IEEE 754-1985
(de 1.40239846e45f a
3.40282347e+38f)
Tamao 64 bits. Nmeros en coma flotante de doble precidouble sin. Estndar IEEE 754-1985. (de 4.94065645841246544e
324d a 1.7976931348623157e+308d.)
Los tipos bsicos que utilizaremos en la mayor parte de los programas sern boolean, int
y double.

1.12.2.

TIPOS DE DATOS REFERENCIA

Los arreglos, las clases y las interfaces son


tipos referencia. El valor de una variable de
tipo referencia, en contraste con la de tipo
primitivo, es una referencia a (la direccin
de) el valor o conjunto de valores representados por la variable.
Una referencia es denominada un puntero, o
una direccin de memoria en otros lenguajes.
18

Mg. ABRAHAM GAMARRA MORENO

El lenguaje de programacin Java no soporta


el uso explcito de direcciones como en otros
lenguajes. Utilizamos en cambio el nombre de
la variable:
Referencia

Nombre del
objeto

1.13.

Un objeto o
un array

LITERALES
Un valor constante en Java se crea utilizando una representacin literal de l. Java utiliza cinco tipos
de elementos: enteros, reales en coma flotante, booleanos, caracteres y cadenas, que se pueden poner en
cualquier lugar del cdigo fuente de Java. Cada uno de
estos literales tiene un tipo correspondiente asociado
con l.
A continuacin se tiene el ejemplo de valores literales y sus tipos de datos:
Literal

Tipo de Datos

178

Int

8864L

Long

37.266

Double

37.266D

double

87.363F

float

26.77e3

double

'c'

char

true

boolean

false

boolean

"Hola"

String

PROGRAMACION CON JAVA 2

19

1.14.

OPERADORES
Un operador realiza una funcin en uno, dos o tres
operandos. Un operador que requiere un solo operando
se denomina operador unario. Por ejemplo, ++ es un
operador unario que incrementa el valor de su operando
en 1. Un operador que requiere de dos operandos es un
operador binario. Por ejemplo, = es un operador binario que asigna el valor del operando de la derecha al
operando de la izquierda. Y, finalmente, el operador
ternario el que requiere tres operandos. El lenguaje
de programacin Java tiene un operador ternario, ?:,
que es un atajo de la sentencia if-else, el cual se
analizar ms adelante .
Los operadores unarios soportan tanto la notacin prefija como postfija. La notacin prefija significa que
el operador aparece antes que el operando:
operador op

//notacin prefija

La notacin postfija significa que el operador aparece


despus que el operando:
op operador

//notacin postfija

Todos los operadores binarios utilizan notacin infija, que significa que el operador aparece entre sus
operandos:
op1 operador op2

//notacin infija

El operador ternario es tambin infijo; cada componente del operador aparece entre operandos:
op1 ? op2 : op3

//notacin infija

Adems de realizar la operacin, el operador devuelve


un valor. El valor de retorno y su tipo depende del
operador y del tipo de sus operandos. Por ejemplo, el
operador aritmtico, que realiza operaciones aritmticas bsicas como suma y resta, devuelve nmeros (el
resultado de la operacin aritmtica). El tipo de dato
devuelto por un operador aritmtico depende del tipo
de sus operandos: Si sumamos dos enteros, obtenemos un
entero. Una operacin se dice que se evala a su resultado.
20

Mg. ABRAHAM GAMARRA MORENO

1.14.1.
Operador

OPERADORES ARITMTICOS

Uso

Descripcin

op1 + op2

Suma op1 y op2

op1 - op2

Resta op2 de op1

op1 * op2

Multiplica op1 por op2

op1 / op2

Divide op1 por op2

op1 % op2

Calcula el resto de la divisin de op1 por op2

Operador

Uso

Descripcin

++

op++

Incrementa op en 1; se evala el valor de op antes de


ser incrementado

++

++op

Incrementa op en 1; se evala el valor de op despus


de ser incrementado

--

op--

Decrementa op en 1; se evala el valor de op antes


de ser decrementado

--

--op

Decrementa op en 1; se evala el valor de op despus de ser decrementado

1.14.2.
Operador

OPERADORES RELACIONALES
Uso

Devuelve true si

>

op1 > op2

op1 es mayor que op2

>=

op1 >= Op2

op1 es mayor o igual que op2

<

op1 < op2

op1 es menor que op2

<=

op1 <= op2

op1 es menor o igual que op2

==

op1 == op2

op1 y op2 son iguales

!=

Op1 != op2

op1 y op2 son distintos

PROGRAMACION CON JAVA 2

21

1.14.3.
Operador

OPERADORES CONDICIONALES
Devuelve true si

Uso

&&

op1
op2

&&

op1 y op2 son ambos true, evala condicionalmente


op2

||

op1
op2

||

Cualquiera de op1 u op2 es true, evala condicionalmente op2

! op

&

op1
op2

&

op1 y op2 son ambos true, siempre evala op1 y op2

op1
op2

Cualquiera de op1 u op2 es true, siempre evala


op1 y op2

op1
op2

Si op1 y op2 son diferentes. Esto es si uno u otro


de los operandos es true, pero no ambos.

op es false

1.14.4.
(SHIFT)

OPERADORES LGICOS Y DE CORRIMIENTO

Operador

Uso

Operacin
"AND" de Bits

&

op1 & op2

op1 | op2

"OR" de Bits

op1 ^ op2

"XOR" de Bits

~op2

Complemento Binario

Operador

Uso

Operacin

>>

op1
op2

>>

Corrimiento de bits de op1 hacia la derecha por la


distancia de op2

<<

op1
op2

<<

Corrimiento de bits de op1 hacia la izquierda por


la distancia de op2

>>>

op1 >>>
op2

Corrimiento de bits de op1 hacia la derecha por la


distancia de op2 (sin signo)

22

Mg. ABRAHAM GAMARRA MORENO

1.14.5.

OPERADORES DE ASIGNACIN

Operador

Uso

Equivalente a

+=

op1 += op2

op1 = op1 + op2

-=

op1 -= op2

op1 = op1 - op2

*=

op1 *= op2

op1 = op1 * op2

/=

op1 /= op2

op1 = op1 / op2

%=

op1 %= op2

op1 = op1 % op2

&=

op1 &= op2

op1 = op1 & op2

|=

op1 |= op2

op1 = op1 | op2

^=

op1 ^= op2

op1 = op1 ^ op2

<<=

op1 <<= op2

op1 = op1 << op2

>>=

op1 >>= op2

op1 = op1 >> op2

>>>=

op1 >>>= op2

op1 = op1 >>> op2

1.14.6.
Operador

OTROS OPERADORES

Uso

Descripcin

?:

op1 ? op2 : op3

Si op1 es verdadero, devuelve op2. De lo


contrario, devuelve op3.

[]

tipo []

Declara un array de tamao desconocido,


que contiene elementos tipo.

tipo[ op1 ]

Crea un array de op1 elementos. Debe ser


declarado con el operador new.

op1[ op2 ]

Accede al elemento de la posicin op2 dentro del array op1. El ndice comienza en 0
y se extiende hasta la longitud del array
menos uno.

op1.op2

Es una referencia al miembro op2 de op1.

Declara o llama al mtodo denominado


()

op1(parmetros)

PROGRAMACION CON JAVA 2

op1 con los parmetros especificados. La

lista de parmetros puede ser una lista


vaca. La lista esta separada por comas.
23

(tipo)

(tipo) op1

Convierte (cast) op1 a tipo. Una excepcin


ser lanzada si el tipo de op1 es incompatible con tipo.

new

new op1

Crea un nuevo objeto o array. op1 puede


ser una llamada a un constructor o la especificacin de un array.

Instanceof

op1
op2

Devuelve verdadero si op1 es una instancia de op2

1.15.

instanceof

ENTRADA Y SALIDA BASICA


Con frecuencia los programas necesitan ingresar informacin desde una fuente externa o enviar informacin
hacia un destino externo. La informacin puede estar
en cualquier lado: en un archivo, en disco, en algn
lugar de la red, en memoria, o en otro programa. Tambin puede ser de cualquier tipo: objetos, caracteres,
imgenes, o sonidos.
Para ingresar informacin, un programa abre un flujo
en una fuente de informacin (source: un archivo, memoria, un socket) y lee la informacin en serie, de
esta manera:

De la misma forma, un programa puede enviar informacin a un destino externo abriendo un flujo hacia el
destino y escribiendo la informacin en serie, de esta
manera:

24

Mg. ABRAHAM GAMARRA MORENO

No importa de donde viene la informacin o hacia donde


va y no importa que tipo de datos se est leyendo o
escribiendo, los algoritmos para leer y escribir datos
son en general siempre iguales.

Reading (Lectura)

Abrir el flujo
Mientras haya ms informacin
escribir informacin
cerrar el flujo

Writing (Escritura)
Abrir el flujo
Mientras haya ms informacin
leer la informacin
cerrar el flujo

El paquete java.io contiene una coleccin de clases de


flujos que soportan estos algoritmos para lectura y
escritura. Estas clases estn divididas en dos jerarquas de clases basados en el tipo de datos (si son
caracteres o bytes) con el que operan.
Flujo de carcter

Flujo de byte

Hay veces que es ms conveniente agrupar a las clases


por su propsito en vez de por el tipo de datos que
PROGRAMACION CON JAVA 2

25

leen o escriben. As, podemos cruzar los grupos de


flujos de acuerdo a como leen y escriben hacia almacenes de datos o procesan la informacin a medida que se
va leyendo o escribiendo.
Flujo de carcter

Flujo de byte

Flujo sumidero de
datos

Flujo de procesamiento

Las clases del paquete java.io estn divididas en dos


grupos distintos, ambos derivados de la clase Object
del paquete java.lang, segn se muestra en la figura
siguiente. El grupo de la izquierda ha sido diseado
para trabajar con datos de tipo byte y el de la derecha con datos de tipo char. Ambos grupos presentan
clases anlogas que tienen interfaces casi idnticas,
por lo que se utilizan de la misma manera (Fig.1.1.).

Figura 1.1 La clase Object y sus derivados

Las clases en negrita son clases abstractas. Una clase


abstracta no permite que se creen objetos de ella. Su
26

Mg. ABRAHAM GAMARRA MORENO

misin es proporcionar miembros comunes que sern compartidos por todas sus subclases.

1.15.1.
FLUJOS DE ENTRADA DE BYTE Y CHAR
(ENTRADA POR EL TECLADO)
La clase InputStream es una clase abstracta
que es superclase de todas las clases que representan un flujo en el que un destino lee
bytes de un origen. Cuando una aplicacin define un flujo de entrada, la aplicacin es
destino de ese flujo de bytes, y es todo lo
que se necesita saber.
El mtodo ms importante de esta clase es
read. Este mtodo se presenta de tres formas:
public abstract int read() throws IOException

public int read(byte[] b) throws IOException

public int read(byte[] b, int off, int len) throws


IOException

La primera versin de read simplemente lee


bytes individuales de un flujo de entrada;
concretamente lee el siguiente byte de datos
disponible. Devuelve un entero (int) correspondiente al valor ASCII del carcter ledo.
La segunda versin del mtodo read lee un nmero de bytes de un flujo de entrada y los
almacena en una matriz b (ms adelante analizaremos las matrices de datos). Devuelve un
entero correspondiente al nmero de bytes
ledos, o bien l si no hay bytes disponibles
para leer porque se ha alcanzado el final del
flujo.
La tercera versin del mtodo read lee un
mximo de len bytes a partir de la posicin
off de un flujo de entrada y los almacena en
una matriz b.

PROGRAMACION CON JAVA 2

27

La biblioteca de Java proporciona el


flujo estndar de entrada, manipulado
por la clase system del paquete java.lang, que es automticamente abierto cuando se inicia un programa y cerrado cuando este finaliza; este es
denominado system.in.

Se puede utilizar el mtodo read a travs de


clase system de la siguiente forma:

Variable = System.in.read()

Anlogamente, la clase Reader es una clase


abstracta que es superclase de todas las clases que representan un flujo para leer caracteres desde un origen. Sus mtodos son anlogos a los de la clase InputStream, con la diferencia de que utilizan parmetros de tipo
char en lugar de byte.
En nuestros ejemplos utilizaremos la clase
InputStream a travs de System.

1.15.2.
FLUJOS DE SALIDA
(SALIDA POR EL MONITOR)

DE

BYTE

CHAR

La clase OutputStream es una clase abstracta


que es superclase de todas las clases que representan un flujo en el que un origen escribe bytes en un destino. Cuando una aplicacin
define un flujo de salida, la aplicacin es
origen de ese flujo de bytes (es la que enva
los bytes).
El mtodo ms importante de esta clase es
write, Este mtodo se presenta de tres formas:
public abstract void write(int b) throws IOException
28

Mg. ABRAHAM GAMARRA MORENO

public void write(byte[] b) throws IOException

public void write(byte[] b, int off, int len) throws


IOException

La primera versin de write simplemente escribe el byte especificado en un flujo de salida. Puesto que su parmetro es de tipo int,
lo que se escribe es el valor correspondiente
a los 8 bits menos significativos, el resto
son ignorados.
La segunda versin del mtodo write escribe
los bytes almacenados en la matriz b en un
flujo de salida (ms adelante analizaremos
las matrices de datos).
La tercera versin del mtodo write escribe
un mximo de len bytes de una matriz b a partir de su posicin off, en un flujo de salida.
Cada uno de estos mtodos ha sido escrito para que bloquee la ejecucin del programa que
los invoque hasta que toda la salida solicitada haya sido escrita.
De manera anloga a read utilizaremos la clase System para llamar al mtodo write, de la
siguiente forma:

System.out.write(parametro)

Anlogamente, la clase Writer (tal como se


muestra en la Fig 1.1.) es una clase abstracta que es superclase de todas las clases que
representan un flujo para escribir caracteres
a un destino. Sus mtodos son anlogos a los
de la clase OutputStream, con la diferencia
de que utilizan parmetros de tipo char en
lugar de byte.
PROGRAMACION CON JAVA 2

29

1.15.3.
USO DE EXCEPCIONES EN LA ENTRADA Y
SALIDA DE DATOS
Cuando durante la ejecucin de un programa
ocurre un error que impide su continuacin,
por ejemplo, una entrada incorrecta de datos
o una divisin por cero. Java lanza una excepcin, que cuando no se captura da lugar a
un mensaje acerca de lo ocurrido y detiene su
ejecucin (las excepciones se lanzan, no ocurren). Ahora, si lo que deseamos es que la
ejecucin del programa no se detenga, habr
que capturarla y manejarla adecuadamente en
un intento de reanudar la ejecucin.
Las excepciones en Java son objetos de subclases de Throwable. Por ejemplo, el paquete
java.io define una clase de excepcin general
denominada IOException para excepciones de
entrad y salida.
Puesto que en Java hay muchas clases de excepciones, un mtodo puede indicar los tipos
de excepciones que posiblemente puede lanzar.
Por ejemplo, puede observar que los mtodos
read y write que acabamos de exponer lanzan
excepciones del tipo IOException. Entonces,
cuando utilicemos alguno de esos mtodos hay
que escribir el cdigo necesario para capturar las posibles excepciones que pueden lanzar. Esto es algo a lo que nos obliga el compilador Java, del mismo modo que l verifica
si una variable ha sido iniciada antes de ser
utilizada, o si el nmero y tipo de argumentos utilizados con un mtodo son correctos,
con la nica intencin de minimizar los posibles errores que puedan ocurrir.
La forma bsica de evitar escribir el cdigo,
cuando se produce una excepcin, es utilizar
la siguiente lnea en el main:

public static void main (String[] args) throws IOException


30

Mg. ABRAHAM GAMARRA MORENO

En secciones posteriores analizaremos con ms


detenimiento las excepciones.
A continuacin se presenta un ejemplo del uso
del read y write para leer y escribir un byte
respectivamente.
Ejemplo ( 2):
//archivo: lecturabytes.java
import java.io.*;
class lecturabytes
{
public static void main (String[] args)
throws IOException
{
// declaracin de las variables
int n;
//lee un byte
n=System.in.read();
//escribe un byte
System.out.write(n);
//escribe un salto de lnea
System.out.write('\n');
}
}

La ejecucin del programa se muestra de la


siguiente manera:

Una caracterstica an no mencionada es:


import java.io.*;

el cual le indica al compilador que importe


las clases necesarias
del paquete java.io,
para poder utilizar la entrada y salida de
Java. El comodn * sustituye a cualquier nombre del paquete.

PROGRAMACION CON JAVA 2

31

Nota: Cuando ejecute el programa usted debe


ingresar el carcter por el teclado y luego
presionar [ENTER].

1.16. ENTRADA Y SALIDA UTILIZANDO TIPOS DE


DATOS PRIMITIVOS
La seccin anterior permita la entrada y salida de un
byte o un carcter; pero ahora mostraremos como se
puede manejar la entrada y salida de los tipos de datos primitivos mostrados en la seccin 1.12.1.
Antes de mencionar el uso de los datos primitivos ubiqumonos en la jerarqua de clases que se muestra en
la figura 1.2.

InputStream

OutputStream

Reader

Writer

Figura 1.2 Clases y subclases derivados de la clase Object

En la figura anterior se pueden observar las clases


abstractas en los recuadros con lneas diagonales y
sus derivadas; una lnea discontinua indica que esa
clase no se deriva directamente de Object; esto es,
entre Object y la clase hay otras clases.
Adems debemos observar que para la lectura se puede
utilizar la subclase BufferedInputStream (derivada de
InputStream) para leer bytes; esta clase hereda el mtodo read, ya explicado anteriormente, el cual no es
muy conveniente para trabajar con tipos de datos pri32

Mg. ABRAHAM GAMARRA MORENO

mitivos; por lo tanto sugerimos utilizar las subclases


derivadas de Reader, que leen cadena de caracteres.
Para leer una cadena de caracteres del flujo in y almacenarlo en un objeto String, lo tenemos que hacer
desde un flujo de la clase BufferedReader y para escribir en el flujo out tenemos los mtodos proporcionados por la clase PrintStream o bien PrintWriter, que
permiten escribir cualquier valor de cualquier tipo
primitivo o referenciado.

1.16.1. FLUJOS DE ENTRADA A TRAVES DE BUFFEREDREADER


(ENTRADA POR EL TECLADO)
Para realizar la lectura utilizaremos
combinacin
de
InputStreamReader
BuffereadReader, de la siguiente forma:
InputStreamReader
isr
InputStreamReader(System.in);

una
y
new

BufferedReader flujoE = new BufferedReader(isr);

La clase InputStreamReader establece un puente para pasar flujos de bytes a flujos de caracteres tal como se muestra en la figura
1.3. Para ello debemos definir el flujo que
hemos denominado isr como se muestra en el
cdigo anterior.
Adems el cdigo anterior indica que el
flujoE dirigir todas las invocaciones de sus
mtodos al flujo subyacente isr; este flujo,
en el caso de que el origen sea el teclado
(dispositivo vinculado con System.in), deber
convertir los bytes ledos del teclado en
caracteres. De esta forma flujoE podr
suministrar
un
flujo
de
caracteres
al
programa destino de los datos.

PROGRAMACION CON JAVA 2

33

Programa

flujoE

isr

caracteres

in

Teclado

bytes

Figura 1.3

Para realizar la lectura de las cadenas utilizaremos el mtodo readLine, el cual nos
permite leer una lnea de texto. El mtodo
readLine tiene la siguiente sintaxis:
public String readLine() throws IOException

1.16.2. FLUJOS DE SALIDA A TRAVS DE LA SUBCLASE


PRINTSTREAM (SALIDA POR EL MONITOR)
La clase PrintStream se deriva indirectamente
de OutputStream, por lo tanto hereda todos
los miembros de sta: por ejemplo el mtodo
write expuesto anteriormente. Otros mtodos
de inters que aporta esta clase son: print y
println. La sintaxis para estos mtodos es la
siguiente:
print (tipo argumento);

println ([tipo argumento]);

Los mtodos print y println son esencialmente


los mismos; ambos escriben su argumento en el
flujo de salida. La nica diferencia entre
ellos es que println aade un carcter \n
(avance a la lnea siguiente) al final de su
salida, y print no.
34

Mg. ABRAHAM GAMARRA MORENO

Ejemplo ( 3): Programa que lee e imprime una


cadena.
//archivo: lecturacadenas.java
import java.io.*;
class lecturacadenas
{
public static void main (String[] args)
throws IOException
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader
isr
=
new
InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una
//lnea de texto
System.out.print("Introduzca un texto: ");
sdato = flujoE.readLine(); // leer una lnea de
//texto

System.out.print("el texto leido es: ");


System.out.println(sdato);
// escribir la
//lnea leda

La ejecucin muestra la siguiente pantalla:

1.16.3.
MANEJO
PRIMITIVOS

DE

LOS

TIPOS

DE

DATOS

Evidentemente, cualquier operacin aritmtica


requiere de valores numricos; pero, segn lo
expuesto en el mejor de los casos slo se
PROGRAMACION CON JAVA 2

35

puede obtener una cadena de bytes. Ahora


bien, para que esa cadena de caracteres pueda
ser utilizada en una expresin aritmtica,
tiene que adquirir la categora de valor numrico, lo que implica convertirla a un valor
de alguno de los tipos primitivos. Esto puede
hacerse utilizando los mtodos proporcionados
por las clases que encapsulan los tipos primitivos.
Class Integer
La clase Integer cubre un valor del tipo de
dato primitivo int dentro de un objeto.
Adems, esta clase proporciona varios mtodos
para convertir un int a String y un String a
int, as como otras constantes y mtodos tiles cuando tratan con un int.
A continuacin se tiene algunos atributos y
mtodos principales de la clase Integer:
Atributos
Static int MAX_VALUE

Una constante que contiene el mximo valor en un int: 231-1.


Static int MIN_VALUE

Una constante que contiene el minimo valor en un int: -231.

Constructores
Integer(int value)

Construye un objeto Integer que representa el valor especifico del int.


Integer(String s)

Construye un objeto Integer que representa el valor int indicado por el parmetro String.
Ahora mostramos en el idioma original los Mtodos de la clase Integer1
Mtodos
1

Fuente: JDK HELP


36

Mg. ABRAHAM GAMARRA MORENO

byte byteValue()

Returns the value of this Integer as a


byte.
int compareTo(Integer anotherInteger)
Compares two Integer objects numeri-

cally.

int compareTo(Object o)

object.

Compares this Integer object to another

static Integer decode(String nm)

Decodes a String into an Integer.


double doubleValue()
double.

Returns the value of this Integer as a

boolean equals(Object obj)

object.

Compares this object to the specified

float floatValue()
float.

Returns the value of this Integer as a

static Integer getInteger(String nm)

Determines the integer value of the


system property with the specified name.
static Integer getInteger(String nm, int val)

Determines the integer value of the


system property with the specified name.
static Integer getInteger(String nm, Integer val)

Returns the integer value of the system property with the specified name.
int hashCode()

Returns a hash code for this Integer.


int intValue()
int.

Returns the value of this Integer as an

long longValue()
long.

Returns the value of this Integer as a

static int parseInt(String s)

Parses the string argument as a signed


decimal integer.
static int parseInt(String s, int radix)

Parses the string argument as a signed


integer in the radix specified by the second argument.
PROGRAMACION CON JAVA 2

37

short shortValue()

Returns the value of this Integer as a


short.
static String toBinaryString(int i)

Returns a string representation of the


integer argument as an unsigned integer in base 2.
static String toHexString(int i)

Returns a string representation of the


integer argument as an unsigned integer in base 16.
static String toOctalString(int i)

Returns a string representation of the


integer argument as an unsigned integer in base 8.
String toString()

Returns a String object representing


this Integer's value.
static String toString(int i)

Returns a String object representing


the specified integer.
static String toString(int i, int radix)

Returns a string representation of the


first argument in the radix specified by the second argument.
static Integer valueOf(String s)

Returns an Integer object holding the


value of the specified String.
static Integer valueOf(String s, int radix)
Returns an Integer object holding the
value extracted from the specified String when

parsed with the radix given by the second argument.


Class Float
La clase Float cubre un valor del tipo de dato primitivo float dentro de un objeto.
Adems, esta clase proporciona varios mtodos
para convertir un float a String y un String
a float, as como otras constantes y mtodos
tiles cuando tratan con un float.

38

Mg. ABRAHAM GAMARRA MORENO

A continuacin se tiene algunos atributos y


mtodos principales de la clase Float2:
Atributos
static float MAX_VALUE

A constant holding the largest positive


finite value of type float.
static float MIN_VALUE

A constant holding the smallest positive


nonzero value of type float.
static float NaN

A constant holding a Not-a-Number (NaN)


value of type float.
static float NEGATIVE_INFINITY

A constant holding the negative infinity


of type float.
static float POSITIVE_INFINITY

A constant holding the positive infinity


of type float.
static Class TYPE

The Class instance representing the primitive type float.

Constructores
Float(double value)

Constructs a newly allocated Float object that represents the argument converted to type float.
Float(float value)

Constructs a newly allocated Float object that represents the primitive float argument.
Float(String s)

Constructs a newly allocated Float object that


represents the floating-point value of type float represented by the string.

Mtodos
byte byteValue()

Returns the value of this Float as a

byte (by casting to a byte).


static int compare(float f1, float f2)

Compares the two specified float val2

Fuente: HELP JDK 2 Ver 1.4 (Idioma Original)


PROGRAMACION CON JAVA 2

39

ues.
int compareTo(Float anotherFloat)
Compares two Float objects numerically.
int compareTo(Object o)

object.

Compares this Float object to another

double doubleValue()

object.

Returns the double value of this Float

boolean equals(Object obj)

Compares this object against the specified object.


static int floatToIntBits(float value)

Returns a representation of the specified floating-point value according to the IEEE


754 floating-point "single format" bit layout.
static int floatToRawIntBits(float value)

Returns a representation of the specified floating-point value according to the IEEE


754 floating-point "single format" bit layout,
preserving Not-a-Number (NaN) values.
float floatValue()

Returns the float value of this Float


object.
int hashCode()

Returns a hash code for this Float object.


static float intBitsToFloat(int bits)

Returns the float value corresponding


to a given bit represention.
int intValue()

Returns the value of this Float as an

int (by casting to type int).


boolean isInfinite()

Returns true if this Float value is infinitely large in magnitude, false otherwise.
static boolean isInfinite(float v)

Returns true if the specified number is


infinitely large in magnitude, false otherwise.
boolean isNaN()

Returns true if this Float value is a


Not-a-Number (NaN), false otherwise.
static boolean isNaN(float v)

Returns true if the specified number is


40

Mg. ABRAHAM GAMARRA MORENO

a Not-a-Number (NaN) value, false otherwise.


long longValue()

Returns value of this Float as a long


(by casting to type long).
static float parseFloat(String s)

Returns a new float initialized to the


value represented by the specified String, as
performed by the valueOf method of class Float.
short shortValue()

Returns the value of this Float as a

short (by casting to a short).


String toString()

Returns a string representation of


this Float object.
static String toString(float f)

Returns a string representation of the

float argument.

static Float valueOf(String s)

Returns a Float object holding the float


value represented by the argument string s.
Ejemplo( 4): Programa que lee y visualiza un
entero y un float.
//archivo: lecturanumeros.java
import java.io.*;
//import java.lang.*;
class lecturanumeros
{
public static void main (String[] args)
throws IOException
{
// Definir un flujo de caracteres de entrada: flujoE

InputStreamReader
isr
=
new
InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una
// lnea de texto
int nume; //variable que almacena un nmero
//entero
float numf; //variable que almacena un nmero
//float

");
PROGRAMACION CON JAVA 2

// lectura e impresion de un numero entero


System.out.print("Introduzca un numero entero:
41

sdato = flujoE.readLine(); // leer una lnea de


// texto
nume=Integer.parseInt(sdato);//convierte cadena a
// entero
nume=nume+5;
System.out.println("el numero + 5 es : "+nume);
// lectura e impresion de un numero float
System.out.print("Introduzca un numero real: ");
sdato = flujoE.readLine(); // leer una lnea de
//texto
numf=Float.parseFloat(sdato);//convierte cadena a
//float
numf=numf+5;
System.out.println("el numero + 5 es : "+numf);
}

La salida del programa es:

42

Mg. ABRAHAM GAMARRA MORENO

Ejemplo ( 5): Programa que calcula el rea de


un tringulo.
//archivo: operarit.java
import java.io.*;
class operarit
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada:


flujoE
InputStreamReader
isr
=
new
InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una
//lnea de texto
float b,h; //base y altura
float area;
System.out.print("Introduzca base: ");
sdato = flujoE.readLine(); // leer una lnea
// texto
b=Float.parseFloat(sdato);//convierte cadena
//float
System.out.print("Introduzca altura: ");
sdato = flujoE.readLine(); // leer una lnea
//texto
h=Float.parseFloat(sdato);//convierte cadena
//float

de
a
de
a

//calcula el area del triangulo


area=b*h/2;
System.out.println("el area es : "+area);

La salida del programa es:

PROGRAMACION CON JAVA 2

43

1.17.

LA CLASE MATH
java.lang.Object
|
+--java.lang.Math
La clase Math contiene mtodos para desarrollar operaciones numricas bsicas tal como la potenciacin, logaritmo, raz cuadrada y las funciones trigonomtricas.
A continuacin se muestran los atributos y mtodos de
la clase Math (versin original).

Atributos
static double E

The double value that is closer than any


other to e, the base of the natural logarithms.
static double PI

The double value that is closer than any


other to pi, the ratio of the circumference of a
circle to its diameter.

Mtodos
static double abs(double a)

value.

Returns the absolute value of a double

static float abs(float a)

value.

Returns the absolute value of a float

static int abs(int a)

value.

Returns the absolute value of an int

static long abs(long a)

lue.

Returns the absolute value of a long va-

static double acos(double a)

Returns the arc cosine of an angle, in


the range of 0.0 through pi.
static double asin(double a)

Returns the arc sine of an angle, in


the range of -pi/2 through pi/2.
44

Mg. ABRAHAM GAMARRA MORENO

static double atan(double a)

Returns the arc tangent of an angle, in


the range of -pi/2 through pi/2.
static double atan2(double y, double x)

Converts rectangular coordinates (x, y)


to polar (r, theta).
static double ceil(double a)

Returns the smallest (closest to negative infinity) double value that is not less than
the argument and is equal to a mathematical integer.
static double cos(double a)

angle.

Returns the trigonometric cosine of an

static double exp(double a)

Returns Euler's number e raised to the


power of a double value.
static double floor(double a)

Returns the largest (closest to positive infinity) double value that is not greater
than the argument and is equal to a mathematical
integer.
static double IEEEremainder(double f1, double f2)

Computes the remainder operation on two


arguments as prescribed by the IEEE 754 standard.
static double log(double a)

Returns the natural logarithm (base e)


of a double value.
static double max(double a, double b)

Returns the greater of two double values.


static flota max(float a, float b)

Returns the greater of two float values.


static int max(int a, int b)

Returns the greater of two int values.


static long max(long a, long b)

Returns the greater of two long values.


static double min(double a, double b)

Returns the smaller of two double values.


static flota min(float a, float b)

Returns the smaller of two float values.


static int min(int a, int b)

Returns the smaller of two int values.


PROGRAMACION CON JAVA 2

45

static long min(long a, long b)

Returns the smaller of two long values.


static double pow(double a, double b)

Returns of value of the first argument


raised to the power of the second argument.
static double random()

Returns a double value with a positive


sign, greater than or equal to 0.0 and less than
1.0.
static double rint(double a)

Returns the double value that is closest


in value to the argument and is equal to a mathematical integer.
static long round(double a)

Returns the closest long to the argument.


static int round(float a)

Returns the closest int to the argument.


static double sin(double a)

angle.

Returns the trigonometric sine of an

static double sqrt(double a)

Returns the correctly rounded positive


square root of a double value.
static double tan(double a)

angle.

Returns the trigonometric tangent of an

static double toDegrees(double angrad)

Converts an angle measured in radians


to an approximately equivalent angle measured in
degrees.
static double toRadians(double angdeg)

Converts an angle measured in degrees


to an approximately equivalent angle measured in
radians.

46

Mg. ABRAHAM GAMARRA MORENO

Ejemplo ( 6): Escriba un programa que convierta coordenadas polares a coordenadas cartesianas.

(X,Y)

x = r * cos ( )
y = r * sen ( )
//archivo: cartepola.java
import java.io.*;
import java.lang.Math;
class cartepola
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
float r,teta; //radio, angulo
double x,y; // (x,y) coordenada cartesiana
System.out.println("Ingrese coordenada polar : ");
System.out.print("Introduzca radio: ");
sdato = flujoE.readLine(); // leer una lnea de texto
r=Float.parseFloat(sdato);//convierte cadena a float
System.out.print("Introduzca angulo: ");

PROGRAMACION CON JAVA 2

47

sdato = flujoE.readLine(); // leer una lnea de texto


teta=Float.parseFloat(sdato);//convierte cadena a float
//convertimos el angulo a radianes
teta=(float) Math.toRadians(teta);
//transformamos las coordenadas
x=r*Math.cos(teta);
y=r*Math.sin(teta);

System.out.print("la coordenada cartesiana es : ");


System.out.println("("+x+","+y+")");

La salida es:

1.18.

EXPRESIONES, SENTENCIAS Y BLOQUES


Los programas en Java se componen de sentencias, que a
su vez estn compuestas en base a expresiones. Una expresin esta formada por una combinacin de operadores
y operandos que se evalan para obtener un resultado
particular. Los operandos pueden ser variables, constantes o llamadas a mtodos. Una llamada a un mtodo
evala el valor devuelto por el mtodo y el tipo de
una llamada a un mtodo es el tipo devuelto por ese
mtodo.
Una expresin es una serie de variables, operadores y
llamadas a mtodos (construidas de acuerdo a la sintaxis del lenguaje) que se evalan a un nico valor.
Podemos escribir expresiones compuestas combinando expresiones simples. Cuando escribimos expresiones compuestas, debemos ser explcitos e indicar con parntesis que operadores se deben evaluar primero. Si elegimos no utilizar parntesis, luego la plataforma Java
evaluar la expresin compuesta en el orden dictado
por la precedencia de los operadores.
Una sentencia forma una unidad completa
es terminada con un (;). Hay tres tipos
sentencias de expresin, sentencias de
sentencias de control de flujo. Podemos

48

de ejecucin y
de sentencias:
declaracin, y
agrupar cero o

Mg. ABRAHAM GAMARRA MORENO

ms sentencias juntas en un bloque con llaves ( { y }


). Aunque no se requiere, recomendamos utilizar bloques con las sentencias de control de flujo, an cuando haya una sola sentencia en el bloque.

1.19.

SENTENCIAS DE CONTROL DE FLUJO


Las sentencias de control de flujo se usan para condicionar la ejecucin del cdigo, para hacer loops sobre
un conjunto de lneas de cdigo o para saltar de una
parte del programa a otra. A continuacin veremos como
controlar el flujo del programa con estas sentencias.

1.19.1.

SENTENCIA if

Nos permite ejecutar una parte u otra del cdigo dependiendo de la evaluacin.
La sintaxis es la siguiente:
if (expresin booleana) {
// bloque por true
sentencia v1;
sentencia v2;
...
sentencia vn;
}
else {
// bloque por false
sentencia f1;
sentencia f2;
...
sentencia fn;
}
expresin es una evaluacin lgica, es decir,
debe evaluar true o false. Por true se ejecuta el primer bloque de sentencias y por false
el segundo.
Una forma abreviada es cuando tenemos una sola sentencia, caso en el cual no hace falta
poner las llaves.
if (expresin booleana)
sentencia por true;
else
sentencia por false;
PROGRAMACION CON JAVA 2

49

Se puede obviar la sentencia else.


Ejemplo ( 7): Hacer un programa que obtenga
el valor absoluto de un nmero (Versin1).

//archivo: valabsoluto.java
import java.io.*;
class valabsoluto
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
int num,valabs;
System.out.print("Ingrese un numero : ");
sdato = flujoE.readLine(); // leer una lnea de texto
num=Integer.parseInt(sdato);//convierte cadena a int

50

Mg. ABRAHAM GAMARRA MORENO

// calcular el valor absoluto


if (num<0)
valabs=-1*num;
else
valabs=num;

System.out.println("el valor absoluto es: "+valabs);

La salida ser:

Ejemplo( 8): Hacer un programa que obtenga el


valor absoluto de un nmero (Versin 2).

PROGRAMACION CON JAVA 2

51

//archivo: valabsoluto2.java
import java.io.*;
class valabsoluto2
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
int num;
System.out.print("Ingrese un numero : ");
sdato = flujoE.readLine(); // leer una lnea de texto
num=Integer.parseInt(sdato);//convierte cadena a int
// calcular el valor absoluto
if (num<0)
num=-1*num;

System.out.println("el valor absoluto es: "+num);

La salida del programa es:

1.19.2.

ANIDAMIENTO DE SENTENCIAS if

A continuacin de la sentencia if (cuando la


condicin tiene el valor verdadero), se puede
tener otra sentencia if anidada. De igual
forma se puede anidar una sentencia if luego
del else. Inclusive se puede tener ms sentencias if dentro de estos if anidados.

52

Mg. ABRAHAM GAMARRA MORENO

if (expresin booleana)
if (expresin booleana)
sentencia por true;
else
sentencia por false;
else
if (expresin booleana)
sentencia por true;
else
sentencia por false;
Cuando no se utilizan las llaves para agrupar
expresiones las sentencias else se emparejan
con el if ms cercano.

Ejemplo ( 9): Escriba un programa que lea 3


nmeros enteros e imprima el mayor.

PROGRAMACION CON JAVA 2

53

//archivo: mayor.java
import java.io.*;
class mayor
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
int n1,n2,n3;//numeros
int mayor;// nmero mayor
// lectura de los 3 numeros
System.out.print("Ingrese 1er numero : ");
sdato = flujoE.readLine(); // leer una lnea de texto
n1=Integer.parseInt(sdato);//convierte cadena a int
System.out.print("Ingrese 2do numero : ");
sdato = flujoE.readLine(); // leer una lnea de texto
n2=Integer.parseInt(sdato);//convierte cadena a int
System.out.print("Ingrese 3er numero : ");
sdato = flujoE.readLine(); // leer una lnea de texto
n3=Integer.parseInt(sdato);//convierte cadena a int
// calcular el mayor
if (n1>n2)
if (n1>n3)
mayor=n1;
else
mayor=n3;
else
if (n2>n3)
mayor=n2;
else
mayor=n3;

System.out.println("el numero mayor es: "+mayor);

La salida es:

54

Mg. ABRAHAM GAMARRA MORENO

Ejemplo ( 10): Escriba un programa que calcule la divisin de 2 nmeros.

//archivo: division.java
import java.io.*;
class division
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
float num,den,div;//numerador, denominador y division
// lectura de los numeros
System.out.print("Ingrese numerador : ");
sdato = flujoE.readLine(); // leer una lnea de texto
num=Float.parseFloat(sdato);//convierte cadena
System.out.print("Ingrese denominador : ");
sdato = flujoE.readLine(); // leer una lnea de texto
den=Float.parseFloat(sdato);//convierte cadena

PROGRAMACION CON JAVA 2

55

// calcular la division
if (den==0)
if (num==0)
System.out.println("La divison es: Indeterminado");
else
System.out.println("La divison es: Infinito");
else
{
div=num/den;
System.out.println("La
division
:
"+div);
}
}
}

Ejemplo ( 11): Elaborar un programa donde se


ingrese el sueldo de un trabajador, su respectiva categora (A,B,C) y su ao de ingreso. Luego se calcule e imprima su nuevo sueldo si el incremento es:
a)

56

Categora "A" 15% para los que ingresaron


a trabajar antes de 1980 y 12% para el
resto.

Mg. ABRAHAM GAMARRA MORENO

b)

Categora "B" 20% para los que ingresaron


a trabajar antes de 1980 y 17% para el
resto.

c)

Categora "C" 25% para los que ingresaron


a trabajar antes de 1980 y 22% para el
resto.

//archivo: sueldo.java
import java.io.*;
PROGRAMACION CON JAVA 2

57

class sueldo
{
public static void main (String[] args)
throws IOException
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
double su;//sueldo
char cat;//categora
int ing;//ao de ingreso
// lectura de los 3 numeros
System.out.print("Ingrese sueldo : ");
sdato = flujoE.readLine(); // leer una lnea de texto
su=Float.parseFloat(sdato);//convierte cadena a float
System.out.print("Ingrese categoria (a , b o c): ");
cat = (char) flujoE.read(); // leer caracter

que

// la siguiente lnea evita errores en el flujo de entrada,


// permite saltar '\r\n'(retorno de carro y nueva lnea)
// quedarn pendientes y no fuern ledos por read().
flujoE.skip(2);
System.out.print("Ingrese ao de ingreso : ");
sdato = flujoE.readLine(); // leer una lnea de texto
ing=Integer.parseInt(sdato);//convierte cadena
//
if (ing<1980)

if (cat=='a')
su=su*1.15;
if (cat=='b')
su=su*1.20;
if (cat=='c')
su=su*1.25;

}
else //en otro caso ing>=1980
{
if (cat=='a')
su=su*1.12;
if (cat=='b')
su=su*1.17;
if (cat=='c')
su=su*1.22;
}

}
58

System.out.println("el nuevo sueldo es: "+su);

Mg. ABRAHAM GAMARRA MORENO

Nota: flujoE.skip(2), evita errores cuando se


realiza la lectura de datos a travs del flujo
de
entrada;
porque
permite
saltar
'\r\n'(el retorno de carro y nueva lnea) que
quedarn pendientes y no fuern ledos por
read().
Si usted no lo utiliza no podr leer el ao
de ingreso.

Ejemplo ( 12): La comisin sobre las ventas


totales de un empleado es como sigue:

Si ventas < 50.00 unidades monetarias


(u.m.) entonces no hay comisin.

Si esta entre 50.00 u.m. y 500.00 u.m.


incluidos, entonces la comisin es 10%
de las ventas.

Si las Ventas > 500.00, entonces la comisin es 50.00 u.m. mas 8% de las ventas superiores a 500.00.

El programa calcula la comisin cuando se ingresa las ventas.

PROGRAMACION CON JAVA 2

59

//archivo: ventas.java
import java.io.*;
public class ventas
{
public static void main(String[] args)
throws IOException
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
double ventas,comision=0;
System.out.print("Ventas totales : ");
sdato = flujoE.readLine(); // leer una lnea de texto
ventas=Double.parseDouble(sdato);//convierte cadena
60

Mg. ABRAHAM GAMARRA MORENO

if(ventas<50)
comision=0;
else if(ventas>=50&&ventas<=500)
comision=ventas*0.10;
else if(ventas>500)
comision=50+(ventas-500)*0.08;
}
}

System.out.println("Comision: "+comision);

1.19.3.

SENTENCIA switch

La sentencia switch permite ejecutar una de


varias acciones, en funcin del valor de una
expresin. Es una sentencia especial para decisiones mltiples.

Switch (expresion)
{
case expresin_constante_1:
[sentencia1;]
case expresin_constante_2:
[sentencia2;]
...
[default:]
sentencia n;
}

donde expresin es una expresin entera de


tipo
char,
byte,
short
o
int
y
expresin_constante es una constante tambin
entera y de los mismos tipos. Tanto la
expresin como las expresiones constantes son
convertidas implcitamente a int. Por ltimo,
sentencia
es
una
sentencia
simple
o
compuesta. En el caso de tratarse de una
sentencia compuesta, no hace falta incluir
las sentencias simples entre { }.
La sentencia switch evala la expresin entre
parntesis y compara su valor con las constantes de cada case. La ejecucin de las sentencias del bloque de la sentencia switch,
comienza en el case cuya constante coincida
PROGRAMACION CON JAVA 2

61

con el valor de la expresin y contina hasta


el final del bloque o hasta una sentencia que
transfiera el control fuera del bloque de
switch; por ejemplo, break. La sentencia
switch puede incluir cualquier nmero de
clusulas case.
Si no existe una constante igual al valor de
la expresin, entonces se ejecutan las sentencias que estn a continuacin de default,
si esta clusula ha sido especificada. La
clusula default puede colocarse en cualquier
parte del bloque y no necesariamente al final.
La sentencia break finaliza la ejecucin de
la sentencia switch.
Ejemplo (13): Escribir un programa que lea un
carcter e identifique si es vocal o consonante.

62

Mg. ABRAHAM GAMARRA MORENO

//archivo: vocales.java
import java.io.*;
class vocales
{
public static void main (String[] args)
throws IOException
{
char c;//caracter
// lectura
System.out.print("Ingrese letra : ");
c=(char) System.in.read();//lee caracter
//convertir a mayusculas
c=Character.toUpperCase(c);
// verificar si es letra
if (Character.isLetter(c))
switch (c)
{
case 'A':
case 'E':
case 'I':
case 'O':
case 'U':System.out.println(c+" es vocal"); break;
default : System.out.println(c+" no es vocal");
}
else
System.out.println(c+" no es letra");
}

Ejemplo (14) : Programa que lee un nmero de


1 a 12 e imprime el nombre del mes.

PROGRAMACION CON JAVA 2

63

64

Mg. ABRAHAM GAMARRA MORENO

//archivo: mes.java
import java.io.*;
class mes
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
int mes;//mes

// lectura de los numeros


System.out.print("Ingrese numero de mes : ");
sdato = flujoE.readLine(); // leer una lnea de texto
mes=Integer.parseInt(sdato);//convierte cadena
switch (mes)
{
case 1: System.out.println("Enero"); break;
case 2: System.out.println("Febrero"); break;
case 3: System.out.println("Marzo"); break;
case 4: System.out.println("Abril"); break;
case 5: System.out.println("Mayo"); break;
case 6: System.out.println("Junio"); break;
case 7: System.out.println("Julio"); break;
case 8: System.out.println("Agosto"); break;
case 9: System.out.println("Septiembre"); break;
case 10: System.out.println("Octubre"); break;
case 11: System.out.println("Noviembre"); break;
case 12: System.out.println("Diciembre"); break;
default: System.out.println("Error en el mes"); break;
}
}//fin main

Lo que hace es evaluar mes y en funcin de su


valor ejecuta las sentencias correspondientes. Cabe destacar la presencia de break, la
cual es una palabra clave que interrumpe el
flujo de ejecucin envindolo a la primera
lnea a continuacin del cierre del switch.
Podemos observar tambin la palabra clave default en ltimo lugar, la cual se ejecutar
si mes no ha coincidido con ningn valor explicitado, default no es obligatorio y por lo
tanto puede no estar.

PROGRAMACION CON JAVA 2

65

Ejemplo (15): Programa que calcula el monto a


pagar por el consumo de energa elctrica, si
durante su ejecucin se ingresa el consumo y
el tipo de tarifa. Las tarifas son:

TIPO DE
TARIFA
1
2
3
4
5

66

COSTO
(U.M./Kw-h)
2.30
8.25
6.42
5.80
9.65

Mg. ABRAHAM GAMARRA MORENO

//archivo: tarifa.java
import java.io.*;
public class tarifa
{
public static void main(String[] args)
throws IOException
{
// Definir un flujo de caracteres de entrada: flujoE
PROGRAMACION CON JAVA 2

67

InputStreamReader
isr
=
InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
//texto

new

String sdato; // variable para almacenar una lnea de


double consumo,tarifa,monto;
int tipo;
System.out.print("Consumo: ");
sdato = flujoE.readLine(); // leer una lnea de texto
consumo=Float.parseFloat(sdato);//convierte cadena
System.out.print("Tipo de tarifa (1 al 5): ");
sdato = flujoE.readLine(); // leer una lnea de texto
tipo=Integer.parseInt(sdato);//convierte cadena
switch(tipo)
{
case 1:tarifa=2.3;break;
case 2:tarifa=8.25;break;
case 3:tarifa=6.42;break;
case 4:tarifa=5.80;break;
case 5:tarifa=9.65;break;
default:tarifa=0;break;
}

if(tarifa!=0)
{
monto=consumo*tarifa;
System.out.println("\nMonto a pagar: "+monto);
}
else
System.out.println("\nTarifa incorrecta");

1.19.4.

SENTENCIA while

Sirve para ejecutar continuamente un bloque


de cdigo, mientras que una condicin permanezca en true.
La sintaxis general es:
68

Mg. ABRAHAM GAMARRA MORENO

while (expresin booleana) {


sentencia 1;
sentencia 2;
...
sentencia 3;
}
o bien:
while (expresin booleana)
sentencia;
while no ejecutar el cdigo (ni siquiera una
vez) a menos que la expresin booleana sea
true.
La ejecucin
as:

de

la

sentencia

while

sucede

1. Se evala la condicin.
2. Si el resultado de la evaluacin es false
(falso), la sentencia no se ejecuta y se pasa
el control a la siguiente sentencia en el
programa.
3. Si el resultado de la evaluacin es true
(verdadero), se ejecuta la sentencia y el
proceso descrito se repite desde el punto 1.
Uso de acumuladores en las sentencias repetitivas

Ejemplo (16): Realizar un programa


determine los divisores de un nmero.

que

Para poder encontrar los divisores de este


nmero, se utilizar una variable que se comporte como un contador. Un contador es una
variable con el siguiente formato:
Contador = Contador operador constante
Para el programa d es un contador que tiene
la siguiente forma:
PROGRAMACION CON JAVA 2

69

d = d + 1
Cada vez que se ejecute el ciclo repetitivo,
esta variable permitir incrementar a d en
una unidad.

70

Mg. ABRAHAM GAMARRA MORENO

//archivo: divisores.java
import java.io.*;
class divisores
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
int num,d; //numero y divisor
int r;//resto
System.out.print("Introduzca un numero : ");
sdato = flujoE.readLine(); // leer una lnea de texto
num=Integer.parseInt(sdato);//convierte cadena a int
System.out.println("Los divisores son: ");

//obtiene los divisores


d=1;
while (d<=num)
{ r=num%d;
if (r==0)
System.out.println(d);
d++;
}

PROGRAMACION CON JAVA 2

71

Ejemplo (17): Programa que calcula la suma de


las cifras de un nmero.
Para encontrar la suma de las cifras de un
nmero, se utilizar una variable que se comporte como un acumulador. Un acumulador es
una variable con el siguiente formato:
Acumulador = Acumulador operador variable
Para el programa s es un acumulador que tiene
la siguiente forma:
s = s + r
Cada vez que se ejecute el ciclo repetitivo,
esta variable s, permitir acumular la suma
de los valores que tenga la variable r.

72

Mg. ABRAHAM GAMARRA MORENO

//archivo: sumacifras.java
import java.io.*;
PROGRAMACION CON JAVA 2

73

class sumacifras
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
int num,r; //numero y resto
int s;//acumula suma de las cifras
System.out.print("Introduzca un numero : ");
sdato = flujoE.readLine(); // leer una lnea de texto
num=Integer.parseInt(sdato);//convierte cadena a int
//obtiene las cifras
s=0;
while (num!=0)
{ r=num%10;
s=s+r;
num=num/10;
}
System.out.println("La suma de las cifras es: "+s);

Se puede colocar un while dentro de otro while (whiles anidados)

Ejemplo (18): Escribir un programa que permita calcular el promedio de los nmeros positivos ingresados por el teclado, el ingreso
termina cuando el nmero ingresado es CERO.
(Usar while)
Ejemplo:
74

Mg. ABRAHAM GAMARRA MORENO

Ingrese un nmero:

6 <ENTER>

Ingrese un nmero:

-3 <ENTER>

Ingrese un nmero:

10 <ENTER>

Ingrese un nmero:

2 <ENTER>

Ingrese un nmero:

0 <ENTER>

El promedio de los nmeros positivos ingresados es: 6

PROGRAMACION CON JAVA 2

75

//archivo: promposi.java
// respuesta pregunta 1 examen 1 2003-1
import java.io.*;
class promposi
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
float num; //numero
float s;//suma de los nmeros
int n;//cantidad de nmeros
float p;//promedio de los nmeros
//lee numeros
n=0;
s=0;

");

System.out.print("Ingrese un numero (cero para finalizar):


sdato = flujoE.readLine(); // leer una lnea de texto
num=Float.parseFloat(sdato);//convierte cadena
while(num!=0)
{
if(num>0)
{
s=s+num;
n++;
}

System.out.print("Ingrese
un
numero
(cero
para
finalizar): ");
sdato = flujoE.readLine(); // leer una lnea de
//texto
num=Float.parseFloat(sdato);//convierte cadena
}
p=s/n;
System.out.println("El promedio es: "+p);
}//fin de main
}//fin de la clase

76

Mg. ABRAHAM GAMARRA MORENO

Ejemplo (19): Realice el diagrama de actividades y el programa en java, para un programa


que lea caracteres. El programa debe contar
cuantas vocales de cada uno existen; tambin
debe contar cuantos caracteres que no son vocales se ingresaron. La lectura de los caracteres finaliza cuando se ingresa *. Slo
debe mostrar el total de los caracteres que
son mayores que cero. El * no se debe tomar
en cuenta como carcter ingresado. (usar while)
Ejemplo:
Ingrese carcter (* para finalizar):

a <ENTER>

Ingrese carcter (* para finalizar):

e <ENTER>

Ingrese carcter (* para finalizar):

n <ENTER>

Ingrese carcter (* para finalizar):

p <ENTER>

Ingrese carcter (* para finalizar):

* <ENTER>

a existe 1 vez(ces)
e existe 1 vez(ces)
caracteres que no son vocales existe(n)

PROGRAMACION CON JAVA 2

2 vez(ces)

77

78

Mg. ABRAHAM GAMARRA MORENO

//archivo: exa1p120032.java
// respuesta pregunta 1 examen 1 2003-2
import java.io.*;
class exa1p120032
{
public static void main (String[] args)
throws IOException
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
int a=0,e=0,i=0,o=0,u=0,nv=0;//contadores
char car;
System.out.print("Ingrese caracter (* para finalizar): ");
car = (char) flujoE.read(); // leer un carcter
flujoE.skip(2);
while(car!='*')
{
switch (car)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
default :
}

a++;break;
e++;break;
i++;break;
o++;break;
u++;break;
nv++;

System.out.print("Ingrese
caracter
(*
finalizar):");
car = (char) flujoE.read(); // leer un carcter
flujoE.skip(2);
}//fin de while
if(a>0)
System.out.println("a existe "+a+" vez(ces)");
if(e>0)
System.out.println("e existe "+e+" vez(ces)");
if(i>0)
System.out.println("i existe "+i+" vez(ces)");
if(o>0)
System.out.println("o existe "+o+" vez(ces)");
if(u>0)
System.out.println("u existe "+u+" vez(ces)");
if(nv>0)
System.out.println("caracteres que no son
existen "+ nv+ " vez(ces)");
}//fin de main
}//fin de la clase

PROGRAMACION CON JAVA 2

para

vocales

79

80

Mg. ABRAHAM GAMARRA MORENO

Ejemplo (20): Realice el diagrama de actividades y el programa en java, para un programa


que lea un nmero en base 10 y lo convierta a
otra base mayor que 10. La base mayor que 10
ser ledo por el teclado. (usar while).

PROGRAMACION CON JAVA 2

81

82

Mg. ABRAHAM GAMARRA MORENO

//archivo: exa1p220032.java
// respuesta pregunta 1 examen 1 2003-2
import java.io.*;
class exa1p220032
{
public static void main (String[] args)
throws IOException
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);

10

boolean c1=false,c2=false,c3=false,c4=false,c5=false;
int cif=0, e=0, s=0;//cif=cantidad de cifras, e=exponente
//s= acumulador
int num,base;//num=nmero en base 10, base=base mayor que
int r;
String sdato;
System.out.print("Ingrese numero en base 10: ");
sdato=flujoE.readLine();
num=Integer.parseInt(sdato);
System.out.print("base mayor que 10: ");
sdato=flujoE.readLine();
base=Integer.parseInt(sdato);
while(num!=0)
{
r=num%base;
cif=cif+1;
if (r>=10)
{
switch (cif)
{
case 1: c1=true;break;
case 2: c2=true;break;
case 3: c3=true;break;
case 4: c4=true;break;
case 5: c5=true;break;
}//fin de switch
r=r-10;
}//fin de if
s=s+r*(int) Math.pow(10,e);
e=e+1;
num=num/base;
}//fin de whilw
System.out.print("EL numero en base "+base+" es:");
e=e-1;
while(s!=0)
{
r=s/(int) Math.pow(10,e);
s=s%(int) Math.pow(10,e);
e=e-1;

PROGRAMACION CON JAVA 2

83

if (cif==1 && c1==true)


r=r+10;
if (cif==2 && c2==true)
r=r+10;
if (cif==3 && c3==true)
r=r+10;
if (cif==4 && c4==true)
r=r+10;
if (cif==5 && c5==true)
r=r+10;
switch (r)
{
case 10: System.out.print("A");break;
case 11: System.out.print("B");break;
case 12: System.out.print("C");break;
case 13: System.out.print("D");break;
case 14: System.out.print("E");break;
case 15: System.out.print("F");break;
default: System.out.print(r);break;
}
cif=cif-1;

System.out.print("\n");
}//fin de main
}//fin de la clase

84

Mg. ABRAHAM GAMARRA MORENO

1.19.5.

SENTENCIA do-while

La diferencia con while es que en do-while se


asegura la ejecucin de las sentencias al menos 1 vez, ya que primero se ejecuta y luego
se evala.
La sentencia do ... while ejecuta una sentencia, simple o compuesta, una o mas veces dependiendo del valor de una expresin. Su sintaxis es la siguiente:
do {
sentencia 1;
sentencia 2;
sentencia 3;
...
sentencia n;
}
while (expresin booleana);
o bien:
do

sentencia 1;
while (expresin booleana);
Observe que la estructura do ... while finaliza con un punto y coma.
La ejecucin de una sentencia do .. while sucede de la siguiente forma:
1. Se ejecuta el bloque (sentencia simple o
compuesta) de do.
2. Se evala la expresin correspondiente a
la condicin de finalizacin del bucle.
3. Si el resultado de la evaluacin es false
(falso), se pasa el control a la siguiente
sentencia en el programa.

PROGRAMACION CON JAVA 2

85

4. Si el resultado de la evaluacin es true


(verdadero), el proceso descrito se repite
desde el punto 1.

Ejemplo (21): Escribir un programa que permita calcular la suma de la siguiente serie,
para N trminos; siendo N ingresado por teclado: (Usar slo do while)

S =1

2
2 !

3
3 !

4
4 !

5
5 !

6 !

+ ...

7 ! 8 !

N trminos

86

Mg. ABRAHAM GAMARRA MORENO

//archivo: serie.java
import java.io.*;
PROGRAMACION CON JAVA 2

87

class serie
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
float fact; //factorial
float s;//suma de los trminos
int n;//cantidad de trminos
int i;//contador
//lee numeros
i=0;
s=0;
System.out.print("Cantidad de terminos : ");
sdato = flujoE.readLine(); // leer una lnea de texto
n=Integer.parseInt(sdato);//convierte cadena
fact=1;
do
{
i++;
//calcula el factorial de i
fact=fact*i;
if (i%2==0)
//i es par
s=s-i/fact;
else
//i es impar
s=s+i/fact;
}while(n!=i);
System.out.println("La suma es: "+s);

}//fin de main
}//fin de la clase

Ejemplo (22): Programa que determina si un


nmero es perfecto. Un numero perfecto es un
entero positivo que es igual a la suma de sus
divisores, excluido si mismo.

88

Mg. ABRAHAM GAMARRA MORENO

//archivo: perfecto.java
import java.io.*;
class perfecto
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto

PROGRAMACION CON JAVA 2

89

int num,r; //numero y resto


int s;//acumula suma de los divisores
int d;//divisor
System.out.print("Introduzca un numero : ");
sdato = flujoE.readLine(); // leer una lnea de texto
num=Integer.parseInt(sdato);//convierte cadena a int
//determina si un nmero es perfecto
s=0;
d=1;
do
{ r=num%d;
if (r==0)
s=s+d;
d++;
} while (d<num);
if (s==num)
perfecto");
else
perfecto");
}

System.out.println("El
System.out.println("El

numero
numero

es
no

es

Ejemplo (23): Escribir un programa que imprima los n primeros nmeros perfectos, si n
es ingresado por el teclado.

90

Mg. ABRAHAM GAMARRA MORENO

PROGRAMACION CON JAVA 2

91

//archivo: nperfectos.java
import java.io.*;
class nperfectos
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
int
int
int
int
int

num,r; //numero y resto


s;//acumula suma de los divisores
d;//divisor
n;//variable para mostrar los "n" perfectos
c;//contador de nmeros perfectos

System.out.print("Cuantos numeros perfectos : ");


sdato = flujoE.readLine(); // leer una lnea de texto
n=Integer.parseInt(sdato);//convierte cadena a int
//determina los n perfectos
c=0;
num=1;
do
{
//determina si un nmero es perfecto
s=0;
d=1;
num++;
do
{
r=num%d;
if (r==0)
s=s+d;
d++;
} while (d<num);

92

if (s==num)
{ c++;
System.out.println(num);
}
} while(c<n);

Mg. ABRAHAM GAMARRA MORENO

1.19.6.

SENTENCIA for

La sentencia for permite ejecutar una sentencia simple o compuesta, repetidamente un nmero de veces conocido. Su sintaxis es la siguiente:
for ([v1=e1 [, v2=e2]
[progresin condicin])

];

[condicin];

{
sentencia 1;
sentencia 1;
sentencia 1;
...
sentencia 1;
}
o bien:
for ([v1=e1 [, v2=e2] ]; [condicin]; [progresin condicin])
sentencia;
Donde:

PROGRAMACION CON JAVA 2

v1, v2, , representan variables de control que sern iniciadas con los valores
de las expresiones el, e2, ;

condicin es una expresin booleana que


si se omite, se supone verdadera;

progresin condicin, es una o ms expresiones separadas por comas cuyos valores evolucionan en el sentido de que
se cumpla la condicin para finalizar la
ejecucin de la sentencia for;

sentencia es una sentencia simple o Compuesta,


93

La ejecucin de la sentencia for sucede de la


siguiente forma:
1. Se inician las variables vi, v2,
2. Se evala la condicin:
a) Si el resultado es true (verdadero), se
ejecuta el bloque de sentencias, se evala
la expresin que da lugar a la progresin
de la condicin y se vuelve al punto 2.
b) Si el resultado es false (falso), la
ejecucin de la sentencia for se da por
finalizada y se pasa el control a la siguiente sentencia del programa.
Por ejemplo, la siguiente sentencia for imprime los nmeros del 1 al 100. Literalmente
dice: desde i igual a 1, mientras i sea menor
o igual que 100, incrementado la i de uno en
uno, escribir el valor de i.
int i;
for (i = 1; i <= 100; i++)
System.out.print(i + );
El siguiente ejemplo imprime los mltiplos de
7 que hay entre 7 y 112. Se puede observar
que, en este caso, la variable se ha declarado e iniciado en la propia sentencia for (esto no se puede hacer en una sentencia while;
las variables que intervienen en la condicin
de una sentencia while deben haber sido declaradas e iniciadas antes de que se procese
la condicin por primera vez).
for (int k = 7; k <= 112; k += 7)
System.out.print(k + );
En el siguiente ejemplo se puede observar la
utilizacin de la coma como separador de las
variables de control y de las expresiones que
hacen que evolucionen los valores que intervienen en la condicin de finalizacin.

94

Mg. ABRAHAM GAMARRA MORENO

int f, c;
for (f = 3, c = 6; f + c < 40; f++, c+=2)
System.out.print(f= + f + c= + c);
Este otro ejemplo que ve a continuacin, imprime los valores desde 1 hasta 10 con incrementos de 0.5.
for (float i=1; i <= 10; i += 0.5)
System.out.print(i + );
El siguiente ejemplo imprime las letras del
abecedario en orden inverso.
char car;
for (car=z ; car >= a; car--)
System.out.print(car + );
El ejemplo siguiente indica cmo realizar un
bucle infinito. Para salir de un bucle infinito tiene que pulsar las teclas Ctrl+C.
for (;;)
x++;

Ejemplo ( 24): Escribir un programa que permita leer un nmero en base m y lo convierta a otro nmero en base n. El programa debe imprimir el nmero en base n. Los valores de m y n son menores que 10 (Usar slo
for)

PROGRAMACION CON JAVA 2

95

//archivo: basemton.java
import java.io.*;
96

Mg. ABRAHAM GAMARRA MORENO

class basemton
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
int
int
int
int
int
int

numm;//numero en base m
numn;//numero en base n
num10;//numero en base 10
m, n;//base m y n
i;//contador
r;//resto

System.out.print("Ingrese base m: ");


sdato = flujoE.readLine(); // leer una lnea de texto
m=Integer.parseInt(sdato);//convierte cadena
System.out.print("Ingrese un numero en base "+m+": ");
sdato = flujoE.readLine(); // leer una lnea de texto
numm=Integer.parseInt(sdato);//convierte cadena
System.out.print("Ingrese base n: ");
sdato = flujoE.readLine(); // leer una lnea de texto
n=Integer.parseInt(sdato);//convierte cadena
//cambiar numero de base m a base 10
num10=0;
i=0;
for(;numm!=0;)
{
r=numm%10;
num10=num10+r*(int) Math.pow(m,i);
numm=numm/10;
i++;
}
es: "+num10);

System.out.println("El

numero

en

base

10

//cambiar numero de base 10 a base n


numn=0;
i=0;
for(;num10!=0;)
{
r=num10%4;
numn=numn+r*(int) Math.pow(10,i);
num10=num10/4;
i++;
}
es: "+numn);
PROGRAMACION CON JAVA 2

System.out.println("El numero en base "+n+"


97

}//fin de main
}//fin de la clase

Ejemplo(25): Programa que imprime el factorial de un nmero.

98

Mg. ABRAHAM GAMARRA MORENO

//archivo: factorial.java
import java.io.*;
class factorial
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
int fact,n; //factorial e incremento de nmeros
int i; //contador
System.out.print("Introduzca un numero : ");
sdato = flujoE.readLine(); // leer una lnea de texto
n=Integer.parseInt(sdato);//convierte cadena
System.out.print("El factorial de "+n);
System.out.print(" es ");
//determina el factorial de un nmero
fact=1;
for(i=1;i<=n;i++)
{
System.out.print(i);
if(i!=n)
System.out.print("*");
fact=fact*i;
}
System.out.println(" = "+fact);

Ejemplo (26): Programa que imprime el factorial de 1 hasta el factorial de num.

PROGRAMACION CON JAVA 2

99

//archivo: nfactorial.java
import java.io.*;
class nfactorial
{
100

Mg. ABRAHAM GAMARRA MORENO

public static void main (String[] args)


throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
int fact,n,num;
int i; //contador
System.out.print("Introduzca un numero : ");
sdato = flujoE.readLine(); // leer una lnea de texto
num=Integer.parseInt(sdato);//convierte cadena
for(n=1;n<=num;n++)
{
System.out.print("El factorial de "+n);
System.out.print(" es ");
//determina el factorial de un nmero
fact=1;
for(i=1;i<=n;i++)
{
System.out.print(i);
if(i!=n)
System.out.print("*");
fact=fact*i;
}
System.out.println(" = "+fact);

}//fin de for externo


}

1.19.7.

SENTENCIA break

Anteriormente vimos que la sentencia break


finaliza la ejecucin de una sentencia
switch. Cuando se utiliza break en el bloque
correspondiente a una sentencia while, do, o
for, hace lo mismo: finaliza la ejecucin del
bucle.
Cuando las sentencias switch, while, do, o
for estn anidadas, la sentencia break solaPROGRAMACION CON JAVA 2

101

mente finaliza la ejecucin del bucle donde


est incluida.

1.19.8.

SENTENCIA continue

La sentencia continue obliga a ejecutar la


siguiente iteracin del bucle while, do, o
for, en el que est contenida. Su sintaxis
es:
continue;
Ejemplo (27): Escribir un programa que permita calcular el MCD (Mximo comn divisor) de
dos nmeros utilizando el algoritmo de Euclides.
Dividir n1 entre n2 hasta que el residuo sea
cero, entonces el MCD es el ultimo valor de
n2. Luego de cada divisin si el residuo es
diferente de cero asigne n1=n2 y n2=r, antes
de realizar la siguiente divisin.

MCD (60,36)=12
Nmero mayor (n1)

60

36

24

Nmero menor (n2)

36

24

12

Residuo (r)

24

12

Cociente (q)

Dado que r=0, se tiene que el MCD=12=n2.

MCD (70,12)=2
Nmero mayor (n1)

70

12

10

Nmero menor (n2)

12

10

Residuo (r)

10

Cociente (q)

Dado que r=0, se tiene que el MCD=2=n2.


102

Mg. ABRAHAM GAMARRA MORENO

//archivo: mcd.java
import java.io.*;
class mcd
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto

PROGRAMACION CON JAVA 2

103

int n1,n2; //numero mayor y menor


int r,q; //residuo y cociente
int mcd;//mximo comn divisor
System.out.print("Introduzca numero mayor : ");
sdato = flujoE.readLine(); // leer una lnea de texto
n1=Integer.parseInt(sdato);//convierte cadena
System.out.print("Introduzca numero menor : ");
sdato = flujoE.readLine(); // leer una lnea de texto
n2=Integer.parseInt(sdato);//convierte cadena
for( ; ; )
{

r=n1%n2;
if (r==0) //sale del for
{
mcd=n2;
break;// n2 es mcd
}
n1=n2;
n2=r;

System.out.println("El MCD es "+mcd);


}

1.19.9.

break ETIQUETADO

La sentencia break tiene 2 formas: sin etiqueta y etiquetado.


Hemos visto la versin sin etiquetar usada en
switch. Como pudimos ver en ese momento,
break interrumpe el flujo normal y transfiere
el control a la primera lnea despus del comando switch. La sentencia break tambin se
puede usar para salir de un for, while o dowhile, transfiriendo siempre el control a la
primera lnea posterior a cada uno de los bucles.

104

Mg. ABRAHAM GAMARRA MORENO

La versin etiquetada es similar a la anterior, con la diferencia que se usa para salir
de un bucle que tiene una etiqueta. Veamos un
ejemplo:
Ejemplo: break etiquetado - Cdigo parcial
...
busqueda:
for (; i < maximo; i++) {
for (; j < maximo; j++) {
...
...
break busqueda;
}
}
En el ejemplo, cuando se llegue al punto de
la ejecucin de break busqueda; se saldr del
for externo, donde figura la etiqueta busqueda.

PROGRAMACION CON JAVA 2

105

CAPITULO DOS
ARREGLOS (ARRAY) Y CADENAS
Un array es un medio de guardar un conjunto de objetos de la
misma clase. Se accede a cada elemento individual del array
mediante un nmero entero denominado ndice. 0 es el ndice
del primer elemento y n-1 es el ndice del ltimo elemento,
siendo n, la dimensin del array. Los arrays son objetos en
Java y como tales vamos a ver los pasos que hemos de seguir
para usarlos convenientemente

Declarar el array

Crear el array

Inicializar los elementos del array

Usar el array

2.1.

DECLARAR Y CREAR UN ARRAY


Para declarar un array se escribe
tipo_de_dato[] nombre_del_array;
o
tipo_de_dato nombre_del_array[];

PROGRAMACION CON JAVA 2

107

Para declarar un array de enteros escribimos


int[] numeros;
o int numeros[];
Para crear un array de 4 nmeros enteros escribimos
nombre=new tipo[tamao];
numeros=new int[4];
El array creado ser:
numeros[0]

Numeros[1] numeros[2] numeros[3]

La declaracin y la creacin del array se pueden hacer


en una misma lnea. Utilice el siguiente formato:
tipo[] nombre=new tipo[tamao]
por ejemplo:
int[] numeros =new int[4];

2.2.
ARRAY

INICIALIZAR Y USAR LOS ELEMENTOS DEL


Para utilizar el array de 4 enteros escribimos
numeros[0]=2;
numeros[1]=-4;
numeros[2]=15;
numeros[3]=-25;
Se pueden inicializar en un bucle for como resultado
de alguna operacin
for(int i=0; i<4; i++)
{

108

numeros[i]=i*i+4;

}
Mg. ABRAHAM GAMARRA MORENO

No necesitamos recordar el nmero de elementos del


array, este tiene un dato miembro llamado length que
nos proporciona la dimensin del array. Escribimos de
forma equivalente
for(int i=0; i<numeros.length; i++)
{

numeros[i]=i*i+4;

}
Los arrays se pueden declarar, crear e inicializar en
una misma lnea, del siguiente modo
int[] numeros={2, -4, 15, -25};
String[] nombres={"Juan", "Jos", "Miguel", "Antonio"};
Para imprimir a los elementos de array nombres se escribe
for(int i=0; i<nombres.length; i++)
{ System.out.println(nombres[i]);
}
Java verifica que el ndice no sea mayor o igual que
la dimensin del array, lo que facilita mucho el trabajo al programador.
Ejemplo (28): Programa que lee la temperatura de los
n ltimos das y calcula el promedio.

PROGRAMACION CON JAVA 2

109

//Archivo: temperatura.java
import java.io.*;
public class temperatura
{
public static void main (String[] args)
throws IOException
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
double s=0;//acumulador que suma las temperaturas
int tam;//tamao del arreglo
System.out.print("Cuantos dias?: ");
110

Mg. ABRAHAM GAMARRA MORENO

sdato = flujoE.readLine(); // leer una lnea de texto


tam=Integer.parseInt(sdato);//convierte cadena
//arreglo que almacena la temperatura
double[] t= new double[tam];
// lectura de los elementos del arreglo
for (int i=0; i < t.length; i++)
{
System.out.print("Ingrese temperatura: ");
sdato = flujoE.readLine();
t[i]=Double.parseDouble(sdato);//convierte cadena
}
System.out.println("Las temperaturas leidas son:");
for (int i=0; i < t.length; i++)
{
System.out.println(t[i]);
s=s+t[i];
}
System.out.println("El promedio es: "+ (s/t.length));
}// fin de main
}//fin de class

2.3.

ARRAYS MULTIDIMENSIONALES
Una matriz bidimensional puede tener varias filas, y
en cada fila no tiene por qu haber el mismo nmero de
elementos o columnas. Por ejemplo, podemos declarar e
inicializar la siguiente matriz bidimensional
double[][]
12},{13}};

matriz=

{{1,2,3,4},{5,6},{7,8,9,10,11,

La primer fila tiene cuatro elementos {1,2,3,4}

La segunda fila tiene dos elementos {5,6}

La
tercera
fila
{7,8,9,10,11,12}

La cuarta fila tiene un elemento {13}

tiene

seis

elementos

Para mostrar los elementos de este array bidimensional


escribimos el siguiente cdigo
PROGRAMACION CON JAVA 2

111

for (int i=0; i < matriz.length; i++)


{
for (int j=0; j < matriz[i].length; j++)
{
System.out.print(matriz[i][j]+"\t");
}
System.out.println("");
}

Como podemos apreciar, matriz.length nos proporciona


el nmero de filas (cuatro), y matriz[i].length, nos
proporciona el nmero de elementos en cada fila.
Mostramos los elementos de una fila separados por un
tabulador usando la funcin print. Una vez completada
una fila se pasa a la siguiente mediante println.
Los arrays bidimensionales nos permiten guardar los
elementos de una matriz. Queremos crear y mostrar una
matriz cuadrada unidad de dimensin 4. Recordaremos
que una matriz unidad es aquella cuyos elementos son
ceros excepto los de la diagonal principal i==j, que
son unos. Mediante un doble bucle for recorremos los
elementos de la matriz especificando su fila i y su
columna j. En el siguiente programa

Se crea una matriz cuadrada de dimensin cuatro

Se inicializa los elementos de la matriz (matriz


unidad)

Se muestra la matriz una fila debajo de la otra


separando los elementos de una fila por tabuladores.

Ejemplo(29): Creacin

112

de la matriz unidad

Mg. ABRAHAM GAMARRA MORENO

PROGRAMACION CON JAVA 2

113

//Archivo: MatrizUnidadApp.java
public class MatrizUnidadApp
{
public static void main (String[] args)
{
double[][] mUnidad= new double[4][4];
for (int i=0; i < mUnidad.length; i++)
{
for (int j=0; j < mUnidad[i].length; j++)
{
if (i == j)
{
mUnidad[i][j]=1.0;
}
else
{
mUnidad[i][j] = 0.0;
}
}
}
for (int i=0; i < mUnidad.length; i++)
{
for (int j=0; j < mUnidad[i].length; j++)
{
System.out.print(mUnidad[i][j]+"\t");
}
System.out.println("");
}

2.4.

GESTIN DE CADENAS
Una cadena es una secuencia de caracteres. Para declarar e inicializar una array de caracteres (arreglos de
caracteres o cadena), utilice el siguiente formato:
char Cad[] = { 'a','b','c'};
la instruccin anterior permitir generar el siguiente
arreglo:
Cad[0] Cad[1] Cad[2]
'a'

114

'b'

'c'
Mg. ABRAHAM GAMARRA MORENO

Ejemplo (30): Programa que imprime una cadena en forma


invertida
//Archivo: cadena.java
import java.io.*;
public class cadena
{
public static void main (String[] args)
throws IOException
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
char[] cad={'F','I','S','-','U','N','C','P'};
int i;//contador
System.out.println("La cadena original es: ");
for (i=0; i <cad.length; i++)
System.out.print(cad[i]);
System.out.println("");
System.out.println("La cadena invertida es: ");
for (i=cad.length-1; i >=0; i--)
System.out.print(cad[i]);
System.out.println("");
}// fin de main
}//fin de class

Las cadenas son una parte fundamental de la mayora de


los programas, as pues Java tiene varias caractersticas incorporadas que facilitan la manipulacin de
cadenas.
Java tiene una clase incorporada en el paquete java.lang que encapsula las estructuras de datos de una
PROGRAMACION CON JAVA 2

115

cadena. Esta clase, llamada String es la representacin como objeto de una matriz de caracteres que no se
puede cambiar.
Hay una clase que la acompaa, llamada StringBuffer,
que se utiliza para crear cadenas que pueden ser manipuladas despus de ser creadas.

2.4.1. CONSTRUCTORES
Se pueden crear instancias de String con el
operador new.
String s = new String();
El ejemplo anterior creara una instancia de
String sin caracteres en ella. Para crear un
String inicializado con caracteres hay que
pasarle una matriz de char al constructor.
Veamos un ejemplo:
char chars[] = { 'a','b','c'};
String s = new String(chars);
// s es la cadena "abc"
Si se tiene una matriz de la que solo un rango nos interesa existe un constructor que
permite especificar el ndice de comienzo y
el nmero de caracteres a utilizar.
char chars[] = {'a','b','c','d','e','f'};
String s = new String(chars, 2, 3); // s es
la cadena "cde"
Tambin existen constructores para caracteres
ASCII (caracteres de 8 bits) frente a los caracteres Unicode de Java (caracteres de 16
bits).

2.4.2. SINTAXIS DE CADENAS ESPECIAL


Java incluye algunas ayudas sintcticas con
el fin de ayudar a los programadores a realizar las operaciones ms habituales con cadenas.
116

Mg. ABRAHAM GAMARRA MORENO

Creacin de cadenas
Dado que los Strings son valores constantes,
Java incluye un atajo para un literal de cadena estndar, en el que un valor de cadena
se puede encerrar entre comillas dobles:
String s = "abad";
uno de los mtodos mas habituales que se utilizan en un String es length, que devuelve el
nmero de caracteres de una cadena:
String s = "abc";
System.out.println(s.length());//imprimira 3
Un punto interesante en Java es que se crea
una instancia de objeto para cada literal
String, por lo que se puede llamar a los mtodos directamente con una cadena entre comillas, como si fuera una referencia a objeto,
con este ejemplo se volvera a imprimir un 3:
String s = "abc";
System.out.println("abc".lenght());
Concatenacin de cadenas
El nico operador que utiliza Java es +, y en
los objetos String. El + acta como operador
de concatenacin en este caso en concreto para mejorar la legibilidad, por ser operacin
muy comn.
String s = "El tiene " + edad + " aos";
esta mucho ms claro que
String s = new StringBuffer("El tiene ")
.append (edad)
.append (" aos")
.toString();
que es lo que sucede cuando se ejecuta este
cdigo. append aade cosas al final de
PROGRAMACION CON JAVA 2

117

StringBuffer, y toString convierte a cadenas


el StringBuffer. Trataremos con detalle append y toString mas adelante en este captulo.
Aspectos de precedencia de operadores
Debe tener cuidado cuando mezcle expresiones
enteras con expresiones de concatenacin de
cadenas por que puede obtener resultados sorprendentes.
String s = "cuatro: " + 2 + 2;
Se podra esperar que el valor de s sea "cuatro: 4", pero la procedencia de operadores
provoco que se evaluase primero la subexpresin "cuatro: " + 2, y despus "cuatro: 2" +
2, donde como resultado "cuatro: 22". Si se
desea realizar primero la expresin entera,
hay que utilizar parntesis, como aqu:
String s = "cuatro: " + (2+2);
Conversin de cadenas
StringBuffer tiene una versin sobrecargada
de append para cada tipo posible. Por lo
tanto, cuando se utiliza `+' para concatenar
una variable, se llama a la versin adecuada
de append para esa variable. El mtodo append
realmente llama a un mtodo esttico de
String llamado valueOf para construir la
representacin
tipo
cadena.
Para
tipos
simples,
valueOf
crea
simplemente
una
representacin de cada int o float. Para
objetos, valueOf llama al mtodo to String
con
ese
objeto.
Cada
clase
implementa
toString, con una implementacin por defecto
que se encuentra en la clase Object. Es bueno
el sobrescribir toString y presentar una
versin propia de cadena para las clases. El
ejemplo siguiente muestra una clase que
sobrescribe toString para mostrar los valores
de sus variables de instancia.
class Point
{
int x, y;
Point(int x, int y)
{
118

Mg. ABRAHAM GAMARRA MORENO

this.x = x;
this.y = y;

}
public String toString()
{
return "Punto[" + x + "," + y + "]";
}

class toStringDemo
{
public static void main(String args[])
Point p = new Point(10, 20);
System.out.println("p = " + p);
}
}

Esta versin de la clase Point incluye una


versin con la que se sobrescribe el mtodo
toString del objeto, y que da formato a la
cadena que contiene los valores de x y de y
de cada instancia de Point. La salida de este
programa es la siguiente:
p = Punto[10, 20 ]

2.4.3. EXTRACCIN DE CARACTERES


Para extraer un nico carcter de una cadena,
se puede referir a un carcter indexado mediante el mtodo charAt:
"abc".charAt(1) // devolver 'b'
Si se necesita extraer ms de un carcter a
la vez, puede utilizar el mtodo gerChars,
que le permite especificar el ndice del primer carcter y del ltimo ms uno que se desean copiar, adems de la matriz char donde
se desean colocar dichos caracteres.
String s = "Esto no es una cancin";
char buf[] = new char[2];
s.getChars(5, 7, buf, 0);
// buf ahora tendr el valor 'no'

PROGRAMACION CON JAVA 2

119

Tambin existe una funcin til llamada toCharArray, que devuelve una matriz de char
que contiene la cadena completa.

2.4.4. COMPARACIN
Si se desean comparar dos cadenas para ver si
son iguales, puede utilizar el mtodo equals
de String. Devolver true si el nico parmetro est compuesto de los mismos caracteres
que el objeto con el que se llama a equals.
Una forma alternativa de equals llamada
equalsIgnoreCase ignora si los caracteres de
las cadenas que se comparan estn en maysculas o minsculas.
La clase String ofrece un par de mtodos tiles que son versiones especializadas de
equals. El mtodo regionMatches se utiliza
para comparar una regin especfica que se
parte de una cadena con otra regin de otra
cadena. Hay dos variantes de regionMatches,
una le permite controlar si es importante la
diferenciacin entre maysculas/minsculas;
la otra asume que si lo es.
boolean regionMatches (int toffset,
otra, int ooffset, int longitud);

String

// si importa la diferencia
boolean
regionMatches
ignorarMaysc,int toffset, String
ooffset, int longitud);

(boolean
otra, int

// no importa la diferencia
En estas dos versiones de regionMatches, el
parmetro toffset indica el desplazamiento en
caracteres en el objeto String sobre el que
estamos llamando el mtodo. La cadena con la
que estamos comparando se llama otra, y el
desplazamiento dentro de esa cadena se llama
ooffset. Se comparan longitud caracteres de
las dos cadenas comenzando a partir de los
dos desplazamientos.

120

Mg. ABRAHAM GAMARRA MORENO

Igualdad
El mtodo equals y el operador = = hacen dos
pruebas completamente diferentes para la
igualdad. Mientras que el mtodo equals compara los caracteres contenidos en una String,
el operador = = compara dos referencias de
objeto para ver si se refieren a la misma
instancia.
Ordenacin
A menudo no basta con conocer si dos cadenas
son idnticas o no. Para aplicaciones de ordenacin, necesitamos conocer cul es menor
que, igual que o mayor que la siguiente. El
mtodo de String compareTo se puede utilizar
para determinar la ordenacin. Si el resultado entero de compareTo es negativo, la cadena
es menor que el parmetro, y si es positivo,
la cadena es mayor. Si compareTo devuelve 0,
entonces las dos cadenas son iguales. Ahora
ordenaremos una matriz de cadenas utilizando
compareTo para determinar el criterio de ordenacin mediante una Ordenacin en burbuja.
//archivo: SortString
class SortString
{
static String arr[] = { "Ahora", "es", "el ",
"momento", "de", "actuar"};
public static void main(String args[])
{
System.out.println("La cadena inicial es");
for (int j = 0; j < arr.length; j++)
System.out.print(arr[j]+" ");
System.out.println("\n");
System.out.println("La cadena final es");
for (int j = 0; j < arr.length; j++)
{
for (int i = j + 1; i < arr.length; i++)
{
if (arr[i].compareTo(arr[j]) < 0)
{
String t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
System.out.print(arr[j]+" ");
PROGRAMACION CON JAVA 2

121

}
System.out.println("\n");

2.4.5. OTROS MTODOS


valueOf
Si se tiene algn tipo de datos y se desea
imprimir su valor de una forma legible, primero hay que convertirlo a String. El mtodo
valueOf est sobrecargado en todos los tipos
posibles de Java, por lo que cada tipo se
puede convertir correctamente en una String.
Cualquier objeto que se le pase a valueOf devolver el resultado de llamar al mtodo toString del objeto. De hecho, se podra llamar
directamente a toString y obtener el mismo
resultado.
StringBuffer
StringBuffer es una clase gemela de String
que proporciona gran parte de la funcionalidad de la utilizacin habitual de las cadenas. StringBuffer representa secuencias de
caracteres que se pueden ampliar y modificar.
Java utiliza ambas clases con frecuencia, pero muchos programadores slo tratan con
String y permiten que Java manipule StringBuffer por su cuenta mediante el operador sobrecargado '+'.
append
Al mtodo append de StringBuffer se le llama
a menudo a travs del operador +. Tiene ver122

Mg. ABRAHAM GAMARRA MORENO

siones sobrecargadas para todos los tipos. Se


llama a String.valueOf para cada parmetro y
el resultado se aade al StringBuffer actual.
Cada versin de append devuelve el propio
buffer.

2.4.6. LA CLASE String


La clase String representa una cadena de caracteres.
La clase String es constante
String str = "abc";
es equivalente a:
char data[] = {'a', 'b', 'c'};
String str = new String(data);
A continuacin se muestra algunos ejemplos
para la utilizacin de las cadenas:
System.out.println("abc");
String cde = "cde";
System.out.println("abc" + cde);
String c = "abc".substring(2,3);
String d = cde.substring(1, 2);
La clase Sring incluye metodos que evaluan
los caracteres en forma individual tal como
compararcin, bsqueda, extraccin de subcadenas o para crear una copia de una cadena co
todos los caracteres cambiados a maysculas o
minsculas.
A continuacin se muestran los costructores y
mtodos de la clase String.

Constructores
String()

Initializes a newly created String object so that


it represents an empty character sequence.
PROGRAMACION CON JAVA 2

123

String(byte[] bytes)

Constructs a new String by decoding the specified


array of bytes using the platform's default charset.
String(byte[] ascii, int hibyte)

Deprecated. This method does not properly convert


bytes into characters. As of JDK 1.1, the preferred way to
do this is via the String constructors that take a charset
name or that use the platform's default charset.
String(byte[] bytes, int offset, int length)
Constructs a new String by decoding the specified

subarray of bytes using the platform's default charset.


String(byte[] ascii, int hibyte, int offset, int count)

Deprecated. This method does not properly convert


bytes into characters. As of JDK 1.1, the preferred way to
do this is via the String constructors that take a charset
name or that use the platform's default charset.
String(byte[] bytes, int offset, int length, String charsetName)
Constructs a new String by decoding the specified

subarray of bytes using the specified charset.

String(byte[] bytes, String charsetName)


Constructs a new String by decoding the specified

array of bytes using the specified charset.


String(char[] value)

Allocates a new String so that it represents the


sequence of characters currently contained in the character
array argument.
String(char[] value, int offset, int count)
Allocates a new String that contains characters

from a subarray of the character array argument.


String(String original)

Initializes a newly created String object so that


it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of
the argument string.
String(StringBuffer buffer)

Allocates a new string that contains the sequence


of characters currently contained in the string buffer argument.

Mtodos
char charAt(int index)

Returns the character at the specified


124

Mg. ABRAHAM GAMARRA MORENO

index.
int compareTo(Object o)

Compares this String to another Object.


int compareTo(String anotherString)

Compares two strings lexicographically.


int compareToIgnoreCase(String str)

Compares two strings lexicographically,


ignoring case considerations.
String concat(String str)

Concatenates the specified string to


the end of this string.
boolean contentEquals(StringBuffer sb)
Returns true if and only if this String

represents the same sequence of characters as the


specified StringBuffer.
static String copyValueOf(char[] data)

Returns a String that represents the


character sequence in the array specified.
static String copyValueOf(char[] data, int offset, int count)

Returns a String that represents the


character sequence in the array specified.
boolean endsWith(String suffix)

Tests if this string ends with the specified suffix.


boolean equals(Object anObject)

Compares this string to the specified


object.
boolean equalsIgnoreCase(String anotherString)
Compares this String to another String,

ignoring case considerations.


byte[] getBytes()

Encodes this String into a sequence of


bytes using the platform's default charset, storing the result into a new byte array.
void getBytes(int srcBegin, int srcEnd, byte[] dst,
int dstBegin)

Deprecated. This method does not properly convert characters into bytes. As of
JDK 1.1, the preferred way to do this is via the
the getBytes() method, which uses the platform's
default charset.

byte[] getBytes(String charsetName)


Encodes this String into a sequence of

bytes using the named charset, storing the result


PROGRAMACION CON JAVA 2

125

into a new byte array.


void getChars(int srcBegin, int srcEnd, char[] dst,
int dstBegin)

Copies characters from this string into


the destination character array.
int hashCode()

Returns a hash code for this string.


int indexOf(int ch)

Returns the index within this string of


the first occurrence of the specified character.
int indexOf(int ch, int fromIndex)

Returns the index within this string of


the first occurrence of the specified character,
starting the search at the specified index.
int indexOf(String str)

Returns the index within this string of


the first occurrence of the specified substring.
int indexOf(String str, int fromIndex)

Returns the index within this string of


the first occurrence of the specified substring,
starting at the specified index.
String intern()

Returns a canonical representation for


the string object.
int lastIndexOf(int ch)

Returns the index within this string of


the last occurrence of the specified character.
int lastIndexOf(int ch, int fromIndex)

Returns the index within this string of


the last occurrence of the specified character,
searching backward starting at the specified index.
int lastIndexOf(String str)

Returns the index within this string of


the rightmost occurrence of the specified substring.
int lastIndexOf(String str, int fromIndex)

Returns the index within this string of


the last occurrence of the specified substring,
searching backward starting at the specified index.
int length()

Returns the length of this string.


boolean matches(String regex)
126

Mg. ABRAHAM GAMARRA MORENO

Tells whether or not this string matches the given regular expression.
boolean regionMatches(boolean ignoreCase, int toffset,
String other, int ooffset, int len)

Tests if two string regions are equal.


boolean regionMatches(int toffset, String other, int ooffset,
int len)

Tests if two string regions are equal.


String replace(char oldChar, char newChar)

Returns a new string resulting from replacing all occurrences of oldChar in this string
with newChar.
String replaceAll(String regex, String replacement)

Replaces each substring of this string


that matches the given regular expression with
the given replacement.
String replaceFirst(String regex, String replacement)

Replaces the first substring of this


string that matches the given regular expression
with the given replacement.
String[] split(String regex)

Splits this string around matches of


the given regular expression.
String[] split(String regex, int limit)

Splits this string around matches of


the given regular expression.
boolean startsWith(String prefix)

Tests if this string starts with the


specified prefix.
boolean startsWith(String prefix, int toffset)

Tests if this string starts with the


specified prefix beginning a specified index.
CharSequence subSequence(int beginIndex, int endIndex)

Returns a new character sequence that


is a subsequence of this sequence.
String substring(int beginIndex)

Returns a new string that is a substring of this string.


String substring(int beginIndex, int endIndex)

Returns a new string that is a substring of this string.


char[] toCharArray()

Converts this string to a new character


array.
PROGRAMACION CON JAVA 2

127

String toLowerCase()

Converts all of the characters in this


String to lower case using the rules of the default locale.
String toLowerCase(Locale locale)

Converts all of the characters in this


String to lower case using the rules of the given
Locale.
String toString()

This object (which is already a


string!) is itself returned.
String toUpperCase()

Converts all of the characters in this


String to upper case using the rules of the default locale.
String toUpperCase(Locale locale)

Converts all of the characters in this


String to upper case using the rules of the given
Locale.
String trim()

Returns a copy of the string, with leading and trailing whitespace omitted.
static String valueOf(boolean b)

Returns the string representation of


the boolean argument.
static String valueOf(char c)

Returns the string representation of


the char argument.
static String valueOf(char[] data)

Returns the string representation of


the char array argument.
static String valueOf(char[] data, int offset, int count)

Returns the string representation of a


specific subarray of the char array argument.
static String valueOf(double d)

Returns the string representation of


the double argument.
static String valueOf(float f)

Returns the string representation of


the float argument.
static String valueOf(int i)

Returns the string representation of


the int argument.
static String valueOf(long l)
128

Mg. ABRAHAM GAMARRA MORENO

Returns the string representation of


the long argument.
static String valueOf(Object obj)

Returns the string representation of


the Object argument.

PROGRAMACION CON JAVA 2

129

CAPITULO THREE
MTODOS CREADOS POR EL USUARIO
La mayora de los programas tienen gran cantidad de lneas de
cdigo y son grandes por lo que deberamos de construirlo a
partir de piezas ms pequeas o mdulos; adems estos sern
manejados desde un programa principal.
Los mdulos de un programa en Java se llaman mtodos y clases. Los programas que se escriben en Java tienen mtodos
creados por el usuario y mtodos preempacados del lenguaje
que estn en la biblioteca de clases de Java (algunos de estos mtodos se mostraron en la clase Integer, Float, Math,
String, etc).
Los mtodos permiten al programador modularizar sus programas
y reutilizar su cdigo. Cuando un mtodo esta creado y se
tiene acceso a l, podremos ejecutarlo desde varios puntos de
un programa con slo invocarlo.
Los mtodos en la Programacin Orientada a Objetos suelen conocerse tambin como funciones miembro. Usted debe notar que
las funciones se utilizan tambin en el Lenguaje C++. En captulos posteriores utilizaremos ls mtodos con la denominacin de funciones miembro.

PROGRAMACION CON JAVA 2

131

3.1. DEFINICIN DE UN MTODO


Un mtodo ser definido utilizando la siguiente sintaxis.
[modificador] tipo_devuelto nombreMtodo(tipo
tipo parm2, tipo parm3, . . .)
{

parm1,

declaraciones de variables locales;


//...sentencias
[return[(]expresin[)]];

nombreMtodo: es cualquier identificador vlido.


tipo_devuelto: es el tipo de datos del resultado que
el mtodo devuelve al invocador (int, float, etc ). El
tipo_devuelto void indica que el mtodo no devuelve
ningn valor.
Tipo parm1, tipo parm2, tipo parm3, . . .: es una lista separada por comas que contiene las declaraciones
de los parmetros que el mtodo recibe cuando se le
invoca. Si un mtodo no recibe valores la lista de parmetros esta vaca, es decir se coloca los parntesis
sin parmetros.
Hay dos formas de devolver el control al punto en el
que se invoc un mtodo:

La primera forma de devolver el control, es cuando se llega a la llave que cierra el final del
cuerpo de la funcin; en este caso no se utiliza
return.

La segunda forma de devolver el control, es cuando se ejecuta la sentencia return. La sentencisa


return tiene la siguiente sintaxis:
return [(expresin)];
Los corchetes indican que ese tem es opcional,
es decir se puede utilizar return de la siguiente
forma:

132

Mg. ABRAHAM GAMARRA MORENO

return (expresin);
return ;
Por supuesto que la ltima forma no devuelve ningn valor; pero el control regresa de inmediato
al punto en el que se invoc el mtodo.
Para llamar a un mtodo se escribe
retorno=nombreMtodo (arg1, arg2, arg3);

Cuando se llama al mtodo, los argumentos arg1, arg2,


arg3 se copian en los parmetros parm1, parm2, parm3 y
se ejecutan las sentencias dentro de la funcin.
Cuando se llama al mtodo, el valor devuelto mediante
la sentencia return se asigna a la variable retorno.
Cuando un mtodo no devuelve nada se dice que es de
tipo void. Para llamar a este mtodo, se escribe
nombreMtodo(arg1, arg2, arg3);

Ejemplo (31): Uso del mtodo hipotenusa para calcular


la hipotenusa de un tringulo. Notese que en el llamado
//llamado al mtodo hipotenusa
hip=hipotenusa(ca,cb);

estamos enviando valores a travs de las variables ca


y cb (valores de los catetos) y se esta recibiendo en
hip el retorno que ofrece el mtodo.

// Archivo Hipotenusa.java
import java.io.*;
class Hipotenusa
{
public static void main (String[] args)
throws IOException
{
PROGRAMACION CON JAVA 2

133

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
float ca,cb; //catetos
float hip;//almacena la hipotenusa
//lectura de datos
System.out.print("Introduzca primer cateto: ");
sdato = flujoE.readLine(); // leer una lnea de texto
ca=Float.parseFloat(sdato);//convierte cadena a float
System.out.print("Introduzca segundo cateto: ");
sdato = flujoE.readLine(); // leer una lnea de texto
cb=Float.parseFloat(sdato);//convierte cadena a float
//llamado al mtodo hipotenusa
hip=hipotenusa(ca,cb);
}

System.out.println("La hipotenusa es : "+hip);

public static float hipotenusa(float a, float b)


{ //definicin de variables locales
float h;
//sentencias internas del mtodo
h=(float) Math.sqrt(a*a+b*b);
//retorno de un valor
return h;
}

Ejemplo (32): Uso del mtodo hipotenusa para calcular


la hipotenusa de un tringulo. Notese que en el llamado
//llamado al mtodo hipotenusa
hipotenusa(ca,cb);

134

Mg. ABRAHAM GAMARRA MORENO

estamos enviando valores a travs de las variables ca


y cb (valores de los catetos) y no se recibe ningn
retorno desde el mtodo.
// Archivo Hipotenusa1.java
import java.io.*;
class Hipotenusa1
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
float ca,cb; //catetos
float hip;//almacena la hipotenusa
//lectura de datos
System.out.print("Introduzca primer cateto: ");
sdato = flujoE.readLine(); // leer una lnea de texto
ca=Float.parseFloat(sdato);//convierte cadena a float
System.out.print("Introduzca segundo cateto: ");
sdato = flujoE.readLine(); // leer una lnea de texto
cb=Float.parseFloat(sdato);//convierte cadena a float
//llamado al mtodo hipotenusa
hipotenusa(ca,cb);

}
public static void hipotenusa(float a, float b)
{ //definicin de variables locales
float h;
//sentencias internas del mtodo
h=(float) Math.sqrt(a*a+b*b);

System.out.println("La hipotenusa es : "+h);

PROGRAMACION CON JAVA 2

135

Ejemplo (33): Uso de un mtodo para simular el operador AND. Notese el uso de throws IOException en los
mtodos main y leer_vector, para evitar de este modo
utilizar try . . . catch. Observe adems como se utiliza el tipo de dato int[] en el mtodo and, para devolver un arreglo desde este mtodo.
// Archivo vectores.java
import java.io.*;
class vectores
{
public static void main (String[] args)
throws IOException
{
int [] v1= new int [4];//primer vector
int [] v2= new int [4];//segundo vector
int [] vs= new int [4];//vector que almacena el resultado
leer_vector(v1);
escribir_vector(v1);
leer_vector(v2);
escribir_vector(v2);

vs=and(v1,v2);
System.out.println("Contenido del vector AND:");
escribir_vector(vs);

public static void leer_vector(int va[])


throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
for(int i=0; i<va.length;i++)
{ //lectura de datos
System.out.print("Introduzca valor (0 o 1): ");
sdato = flujoE.readLine(); // leer una lnea de texto
va[i]=Integer.parseInt(sdato);//convierte cadena
}

}//fin de leer_vector

136

Mg. ABRAHAM GAMARRA MORENO

public static void escribir_vector(int va[])


{
System.out.println("El contenido del vector es: ");
for(int i=0; i<va.length;i++)
{
System.out.print(va[i]+"\t");
}
System.out.println("");
}//fin de escribir_vector
public static int [] and(int va[], int vb[])
{
int [] s= new int [4];//vector que almacena el resultado
// si ambas cifras son 1 el resultado es 1
// de lo contario es cero
for(int i=0; i<va.length;i++)
{
if (va[i]==1 && vb[i]==1)
s[i]=1;
else
s[i]=0;
}
return s; //retorna un arreglo
}//fin de escribir_vector
}

En el captulo siguiente se analiza el uso de mtodos


en clases.
PROGRAMACION CON JAVA 2

137

CAPITULO CUATRO
CLASES Y PROGRAMACION ORIENTADO A
OBJETOS
Cuando se escribe un programa en un lenguaje orientado a objetos, definimos una plantilla o clase que describe las caractersticas y el comportamiento de un conjunto de objetos
similares. La clase automvil describe las caractersticas
comunes de todos los automviles: sus atributos y su comportamiento (fig. 4.1). Los atributos o propiedades se refieren
a la marca o fabricante, el color, las dimensiones, si tienen
dos, tres, cuatro o ms puertas, la potencia, si utiliza como
combustible la gasolina o gasoil, etc. El comportamiento se
refiere a la posibilidad de desplazarse por una carretera,
frenar, acelerar, cambiar de marcha, girar, etc.
Luego, tenemos automviles concretos, por ejemplo el automvil propio de una determinada marca, color, potencia, etc, el
automvil del vecino de otra marca, de otro color, etc, el
automvil de un amigo, etc.
Una clase es por tanto una plantilla implementada en software
que describe un conjunto de objetos con atributos y comportamiento similares.
Una instancia u objeto de una clase es una representacin
concreta y especfica de una clase y que reside en la memoria
del ordenador.
PROGRAMACION CON JAVA 2

139

Figura 4.1 Clases y objetos

4.1.

ATRIBUTOS
Los atributos son las caractersticas individuales que
diferencian un objeto de otro y determinan su apariencia, estado u otras cualidades. Los atributos se guardan en variables denominadas de instancia, y cada objeto particular puede tener valores distintos para estas variables.
Las variables de instancia tambin denominados miembros dato, son declaradas en la clase pero sus valores
son fijados y cambiados en el objeto.
Adems de las variables de instancia hay variables de
clase, las cuales se aplican a la clase y a todas sus
instancias. Por ejemplo, el nmero de ruedas de un automvil es el mismo cuatro, para todos los automviles.

4.2.

COMPORTAMIENTO
El comportamiento de los objetos de una clase se implementa mediante funciones miembro o mtodos. Un mtodo es un conjunto de instrucciones que realizan una

140

Mg. ABRAHAM GAMARRA MORENO

determinada tarea y son similares a las funciones de


los lenguajes estructurados.
Del mismo modo que hay variables de instancia y de
clase, tambin hay mtodos de instancia y de clase. En
el primer caso, un objeto llama a un mtodo para realizar una determinada tarea, en el segundo, el mtodo
se llama desde la propia clase.

4.3.

UNA CLASE EN JAVA


Para crear una clase se utiliza la palabra reservada
class y a continuacin el nombre de la clase. La definicin de la clase se pone entre las llaves de apertura y cierre. El nombre de la clase empieza con una letra mayscula.
class NombreClase{
//miembros dato o datos miembro
//funciones miembro
}

4.3.1. LOS MIEMBROS DATO


Los valores de los atributos se guardan en
los miembros dato o variables de instancia.
Los nombres de dichas variables comienzan por
letra minscula.
Vamos
a
crear
una
clase
denominada
Rectangulo, que describa las caractersticas
comunes a estas figuras planas que son las
siguientes:

PROGRAMACION CON JAVA 2

El origen del rectngulo: el origen o


posicin de la esquina superior izquierda del rectngulo en el plano determinado por dos nmeros enteros x e y.

Las dimensiones del rectngulo: ancho y


alto, otros dos nmeros enteros.

141

class Rectangulo
{
int x;
int y;
int ancho;
int alto;
//faltan las funciones miembro
}

4.3.2. LAS FUNCIONES MIEMBRO


En el lenguaje Java las funciones miembro o
mtodos se definen y se llaman.
El nombre de las funciones miembro o mtodos
comienza por letra minscula y deben sugerir
acciones (mover, calcular, etc.). La definicin de una funcin tiene el siguiente formato:
[modificador] tipo nombreFuncion(tipo parm1,
tipo parm2, tipo parm3, . . .)
{

declaraciones de variables locales;


//...sentencias
[return[(]expresin[)]];

Entre las llaves de apertura y cierre se coloca la definicin de la funcin, tipo indica
el tipo de dato que puede ser predefinido
int, double, etc, o definido por el usuario,
una clase cualquiera.
142

Mg. ABRAHAM GAMARRA MORENO

Un modificador es una palabra clave que modifica el nivel de proteccin predeterminado


del mtodo o funcin miembro (este tema se
analizar ms adelante).
Para llamar a una funcin miembro o mtodo se
escribe
retorno=objeto.nombreFuncion (arg1, arg2, arg3);

Cuando se llama a la funcin, los argumentos


arg1, arg2, arg3 se copian en los parmetros
parm1, parm2, parm3 y se ejecutan las sentencias dentro de la funcin. La funcin finaliza cuando se llega al final de su bloque de
definicin o cuando encuentra una sentencia
return.
Cuando se llama a la funcin, el valor devuelto mediante la sentencia return se asigna
a la variable retorno.
Cuando una funcin no devuelve nada se dice
que es de tipo void. Para llamar a la funcin, se escribe
objeto.nombreFuncion (arg1, arg2, arg3);

Una funcin suele finalizar cuando llega al


final del bloque de su definicin
void funcion(....)
{
//sentencias...
}
Una funcin puede finalizar antes del llegar
al final de su definicin

PROGRAMACION CON JAVA 2

143

void funcion(....)
{
//sentencias...
if(condicion) return;
//sentencias..
}
Una funcin puede devolver un valor (un tipo
de dato primitivo o un objeto).
double funcion(....)
{
double suma=0.0;
//sentencias...
return suma;
}
Cualquier variable declarada dentro de la
funcin tiene una vida temporal, existiendo
en memoria, mientras la funcin est activa.
Se trata de variables locales a la funcin.
Por ejemplo:
void nombreFuncion(int parm){
//...
int i=5;
//...
}
La variable parm, existe desde el comienzo
hasta el final de la funcin. La variable local i, existe desde el punto de su declaracin hasta el final del bloque de la funcin.
Se ha de tener en cuenta que las funciones
miembro tienen acceso a los miembros dato,
por tanto, es importante en el diseo de una
clase decidir qu variables son miembros dato, qu variables son locales a las funciones
miembro, y qu valores les pasamos a dichas
funciones.
Hemos definido los atributos o miembros dato
de la clase Rectangulo, ahora le vamos aadir
un comportamiento: los objetos de la clase
Rectangulo o rectngulos sabrn calcular su
144

Mg. ABRAHAM GAMARRA MORENO

rea, tendrn capacidad para trasladarse a


otro punto del plano, sabrn si contienen en
su interior un punto determinado del plano.
La funcin que calcula el rea realizar la
siguiente tarea, calcular el producto del
ancho por el alto del rectngulo y devolver
el resultado. La funcin devuelve un entero
es por tanto, de tipo int. No es necesario
pasarle datos ya que tiene acceso a los miembros dato ancho y alto que guardan la anchura
y la altura de un rectngulo concreto.
class Rectangulo{
int x;
int y;
int ancho;
int alto;
int calcularArea(){
return (ancho*alto);
}
}
A la funcin que desplaza el rectngulo horizontalmente en dx, y verticalmente en dy, le
pasamos dichos desplazamientos, y a partir de
estos datos actualizar los valores que guardan sus miembros dato x e y. La funcin no
devuelve nada es de tipo void.
class Rectangulo{
int x;
int y;
int ancho;
int alto;
void desplazar(int dx, int dy){
x+=dx;
y+=dy;
}
}
La funcin que determina si un punto est o
no en el interior del rectngulo, devolver
true si el punto se encuentra en el interior
del rectngulo y devolver false si no se encuentra, es decir, ser una funcin del tipo
boolean. La funcin necesitar conocer las
PROGRAMACION CON JAVA 2

145

coordenadas de dicho punto. Para que un punto


de coordenadas x1 e y1 est dentro de un rectngulo cuyo origen es x e y, y cuyas dimensiones son ancho y alto, se deber cumplir a
la vez cuatro condiciones
x1>x y a la vez x1<x+ancho
Tambin se debe cumplir
y1>y y a la vez y1<y+alto
Como se tienen que cumplir las cuatro condiciones a la vez, se unen mediante el operador
lgico AND simbolizado por &&.
class Rectangulo
{
int x;
int y;
int ancho;
int alto;
{

}
}

boolean estaDentro(int x1, int y1)


if((x1>x)&&(x1<x+ancho)&&(y1>y)&&(y1<y+ ancho))
{
return true;
}
return false;

En el lenguaje Java, si la primera condicin


es falsa no se evalan las restantes expresiones ya que el resultado es false. Ahora
bien, si la primera es verdadera true, se pasa a evaluar la segunda, si sta el falsa el
resultado es false, y as sucesivamente.

146

Mg. ABRAHAM GAMARRA MORENO

4.3.3. LOS CONSTRUCTORES


Un objeto de una clase se crea llamando a una
funcin especial denominada constructor de la
clase. El constructor se llama de forma automtica cuando se crea un objeto, para situarlo en memoria e inicializar los miembros dato
declarados en la clase. El constructor tiene
el mismo nombre que la clase. Lo especfico
del constructor es que no tiene tipo de retorno.
class Rectangulo{
int x;
int y;
int ancho;
int alto;
Rectangulo(int x1, int y1, int w, int h){
x=x1;
y=y1;
ancho=w;
alto=h;
}
}
El constructor recibe cuatro nmeros que
guardan los parmetros x1, y1, w y h, y con
ellos inicializa los miembros dato x, y, ancho y alto.
Una clase puede tener ms de un constructor.
Por ejemplo, el siguiente constructor crea un
rectngulo cuyo origen est en el punto (0,
0).
class Rectangulo{
int x;
int y;
int ancho;
int alto;
Rectangulo(int w, int h){
x=0;
y=0;
ancho=w;
alto=h;
}
}
PROGRAMACION CON JAVA 2

147

Este constructor crea un rectngulo de dimensiones nulas situado en el punto (0, 0),
class Rectangulo{
int x;
int y;
int ancho;
int alto;
Rectangulo(){
x=0;
y=0;
ancho=0;
alto=0;
}
}
Con estas porciones de cdigo definimos la
clase, y la guardamos en un archivo que tenga
el mismo nombre que la clase Rectangulo y con
extensin .java.
public class Rectangulo
{
int x;
int y;
int ancho;
int alto;
public Rectangulo()
{
x=0;
y=0;
ancho=0;
alto=0;
}
public Rectangulo(int x1, int y1, int w, int h)
{
x=x1;
y=y1;
ancho=w;
alto=h;
}
public Rectangulo(int w, int h)
{
x=0;
y=0;
ancho=w;
alto=h;
}

148

Mg. ABRAHAM GAMARRA MORENO

int calcularArea()
{
return (ancho*alto);
}
void desplazar(int dx, int dy)
{
x+=dx;
y+=dy;
}
boolean estaDentro(int x1, int y1)
{
if((x1>x)&&(x1<x+ancho)&&(y1>y)&&(y1<y+ancho))
{
return true;
}
return false;
}
}

4.4.

LOS OBJETOS
Para crear un objeto de una clase se usa la palabra
reservada new.
Por ejemplo,
Rectangulo rect1=new Rectangulo(10, 20, 40, 80);
new reserva espacio en memoria para los miembros dato
y devuelve una referencia que se guarda en la variable
rect1 del tipo Rectangulo que denominamos ahora objeto. Dicha sentencia, crea un objeto denominado rect1
de la clase Rectangulo llamando al segundo constructor
en el listado. El rectngulo estar situado en el punto de coordenadas x=10, y=20; tendr una anchura de
ancho=40 y una altura de alto=80.
Rectangulo rect2=new Rectangulo(40, 80);
Crea un objeto denominado rect2 de la clase Rectangulo
llamando al tercer constructor, dicho rectngulo estar situado en el punto de coordenadas x=0, y=0; y tendr una anchura de ancho=40 y una altura de alto=80.
Rectangulo rect3=new Rectangulo();
Crea un objeto denominado rect3 de la clase Rectangulo
llamando al primer constructor, dicho rectngulo esta-

PROGRAMACION CON JAVA 2

149

r situado en el punto de coordenadas x=0, y=0; y tendr una anchura de ancho=0 y una altura de alto=0.

4.4.1. ACCESO A LOS MIEMBROS


Desde un objeto se puede acceder a los miembros mediante la siguiente sintaxis
objeto.miembro;
Por ejemplo, podemos acceder al miembro dato
ancho, para cambiar la anchura de un objeto
rectngulo.
rect1.ancho=100;
El rectngulo rect1 que tena inicialmente
una anchura de 40, mediante esta sentencia se
la cambiamos a 100.
Desde un objeto llamamos a las funciones
miembro para realizar una determinada tarea.
Por ejemplo, desde el rectngulo rect1 llamamos a la funcin calcularArea para calcular
el rea de dicho rectngulo.
rect1.calcularArea();
La funcin miembro area devuelve un entero,
que guardaremos en una variable entera
medidaArea, para luego usar este dato.
int medidaArea=rect1.calcularArea();
System.out.println("El rea del rectngulo es
"+medidaArea);
Para desplazar el rectngulo rect2, 10 unidades hacia la derecha y 20 hacia abajo, escribiremos
rect2.desplazar(10, 20);
Podemos verificar mediante el siguiente cdigo si el punto (20, 30) est en el interior
del rectngulo rect1.

150

Mg. ABRAHAM GAMARRA MORENO

if(rect1.estaDentro(20,30))
{
System.out.println("El punto est dentro
del rectngulo");
}else
{
System.out.println("El punto est fuera del
rectngulo");
}
rect1.dentro() devuelve true si el punto (20,
30) que se le pasa a dicha funcin miembro
est en el interior del rectngulo rect1,
ejecutndose la primera sentencia, en caso
contrario se ejecuta la segunda.
Como veremos ms adelante no siempre es posible acceder a los miembros, si establecemos
controles de acceso a los mismos.
public class RectanguloApp1
{
public static void main(String[] args)
{
Rectangulo rect1=new Rectangulo(10, 20, 40, 80);
Rectangulo rect2=new Rectangulo(40, 80);
Rectangulo rect3=new Rectangulo();
int medidaArea=rect1.calcularArea();
System.out.println("El
rea
del
rectngulo
"+medidaArea);

es

rect2.desplazar(10, 20);
if(rect1.estaDentro(20,30))
{
System.out.println("El punto est dentro del rectngulo");
}
else
{
System.out.println("El punto est fuera del rectngulo");
}
}//fin main
}

4.5.

LA VIDA DE UN OBJETO
En el lenguaje C++, los objetos que se crean con new
se han de eliminar con delete, new reserva espacio en
memoria para el objeto y delete libera dicha memoria.

PROGRAMACION CON JAVA 2

151

En el lenguaje Java no es necesario liberar la memoria


reservada, el recolector de basura (garbage collector)
se encarga de hacerlo por nosotros, liberando al programador de una de las tareas que ms quebraderos de
cabeza le producen, olvidarse de liberar la memoria
reservada.
Veamos un ejemplo
public class UnaClase
{
public static void main(String[] args)
{
Image granImagen=creaImagen();
mostrar(graImagen);
while(condicion)
{
calcular();
}
}
}
El objeto granImagen, continua en memoria hasta que se
alcanza el final de la funcin main, aunque solamente
es necesario hasta el bucle while. En C o en C++ eliminariamos dicho objeto liberando la memoria que ocupa
mediante delete. El equivalente en Java es el de asignar al objeto granImagen el valor null.
public class UnaClase
{
public static void main(String[] args)
{
Image granImagen=creaImagen();
mostrar(graImagen);
granImagen=null;
while(condicion)
{
calcular();
}
}
}
A partir de la sentencia marcada en letra negrita el
recolector de basura se encargar de liberar la memoria ocupada por dicha imagen. As pues, se asignar el
valor null a las referencias a objetos temporales que
152

Mg. ABRAHAM GAMARRA MORENO

ocupen mucha memoria tan pronto como no sean necesarios.


Creamos dos objetos de la clase rectngulo, del mismo
modo que en el apartado anterior
Rectangulo rect1=new Rectangulo(10, 20, 40, 80);
Rectangulo rect3=new Rectangulo();
Si escribimos
rect3=rect1;
En rect3 se guarda la referencia al objeto rect1. La
referencia al objeto rect3 se pierde. El recolector se
encarga de liberar el espacio en memoria ocupado por
el objeto rect3.
La destruccin de un objeto es una tarea (thread) de
baja prioridad que lleva a cabo la Mquina Virtual Java (JVM). Por tanto, nunca podemos saber cuando se va
a destruir un objeto.
Puede haber situaciones en las que es necesario realizar ciertas operaciones que no puede realizar el recolector de basura (garbage collector) cuando se destruye un objeto. Por ejemplo, se han abierto varios archivos durante la vida de un objeto, y se desea que
los archivos estn cerrados cuando dicho objeto desaparece. Se puede definir en la clase un mtodo denominado finalize que realice esta tarea. Este mtodo es
llamado por el recolector de basura inmediatamente antes de que el objeto sea destruido.
Ejemplo (34): Manejo de la clase rectngulo.
//archivo Rectangulo.java
public class Rectangulo
{
int x;
int y;
int ancho;
int alto;
public Rectangulo()
{
x=0;
y=0;
ancho=0;
alto=0;
}
PROGRAMACION CON JAVA 2

153

public Rectangulo(int x1, int y1, int w, int h)


{
x=x1;
y=y1;
ancho=w;
alto=h;
}
public Rectangulo(int w, int h)
{
x=0;
y=0;
ancho=w;
alto=h;
}
int calcularArea()
{
return (ancho*alto);
}
void desplazar(int dx, int dy)
{
x+=dx;
y+=dy;
}
boolean estaDentro(int x1, int y1)
{
if((x1>x)&&(x1<x+ancho)&&(y1>y)&&(y1<y+ancho))
{
return true;
}
return false;
}
}

__________________________________
//archivo: RectanguloApp1.java
public class RectanguloApp1
{
public static void main(String[] args)
{
Rectangulo rect1=new Rectangulo(10, 20, 40, 80);
Rectangulo rect2=new Rectangulo(40, 80);
Rectangulo rect3=new Rectangulo();
int medidaArea=rect1.calcularArea();
System.out.println("El
area
del
rectangulo
"+medidaArea);

rect2.desplazar(10, 20);
154

Mg. ABRAHAM GAMARRA MORENO

es

System.out.println("Las
nuevas
rectangulo 2 es: ");
System.out.println("x= "+ rect2.x+"

coordenadas

del

y="+rect2.y);

if(rect1.estaDentro(20,30))
{
System.out.println("El punto (20,30) esta dentro
del rectangulo 1");
}
else
{
System.out.println("El punto (20,30) esta fuera
del rectangulo 1");
}
}//fin main
}

4.6.

IDENTIFICADORES
Cmo se escriben los nombres de las variables, de las
clases, de las funciones, etc., es un asunto muy importante de cara a la comprensin y el mantenimiento
de cdigo. En la introduccin a los fundamentos del
lenguaje Java hemos tratado ya de los identificadores.
El cdigo debe de ser tanto ms fcil de leer y de entender como sea posible. Alguien que lea el cdigo,
incluso despus de cierto tiempo, debe ser capaz de
entender lo que hace a primera vista, aunque los detalles internos, es decir, cmo lo hace, precise un estudio detallado.
Vemos primero un ejemplo que muestra un cdigo poco
legible y por tanto, muy difcil de mantener
public class Cuen
{
private int ba;
public void dep(int i)
{
ba+=i;
}

PROGRAMACION CON JAVA 2

155

public void ret(int i)


{
ba-=i;
}
public int get()
{
return ba;
}
}
Las abreviaciones empleadas solamente tienen significado para el programador en el momento de escribir el
cdigo, ya que puede olvidarse de su significado con
el tiempo. Otros programadores del grupo tienen que
descifrar el significado del nombre de cada variable o
de cada funcin. El tiempo extra que se gasta en escribir con claridad el nombre de los diversos elementos que entran en el programa, se ahorra ms adelante
durante su desarrollo, depuracin, y mejora, es decir,
durante todo el ciclo de vida del programa.
public class CuentaBancaria
{
private int balance;
public void depositar(int cantidad)
{
balance+=cantidad;
}
public void retirar(int cantidad)
{
balance-=cantidad;
}
public int obtenerBalance()
{
return balance;
}
}

4.7.
MODIFICADORES DE ACCESO A LOS MIEMBROS
DE UNA CLASE
Una faceta importante de los lenguajes de Programacin
Orientada a Objetos se denomina encapsulacin. El acceso a los miembros de una clase est controlado. Para
usar una clase, solamente necesitamos saber que funciones miembro se pueden llamar y a qu datos podemos
acceder, no necesitamos saber como est hecha la cla156

Mg. ABRAHAM GAMARRA MORENO

se, como son sus detalles internos. Una vez que la


clase est depurada y probada, la clase es como una
caja negra. Los objetos de dicha clase guardan unos
datos, y estn caracterizados por una determinada conducta. Este ocultamiento de la informacin niega a las
entidades exteriores el acceso a los miembros privados
(private) de un objeto. De este modo, las entidades
exteriores acceden a los datos de una manera controlada a travs de algunas funciones miembro. Para acceder
a un miembro pblico (public), sea dato o funcin basta escribir:
objeto_de_la_clase.miembro_pblico_no_esttico
clase.miembro_pblico_esttico

La segunda representacin se ampliar cuando veamos


miembros dato esttico y mtodos esttico.

4.7.1. MIEMBROS PBLICOS


Los miembros pblicos son aquellos que tienen
delante la palabra public, y se puede acceder
a ellos sin ninguna restriccin.

4.7.2. MIEMBROS PRIVADOS


Los miembros privados son aquellos que tienen
delante la palabra private, y se puede acceder a ellos solamente dentro del mbito de la
clase.

4.7.3. POR DEFECTO (A NIVEL DE PAQUETE)


Cuando no se pone ningn modificador de acceso delante de los miembros, se dice que son
accesibles dentro del mismo paquete (package). Esto es lo que hemos utilizado en algunos de los ejemplos estudiados antes.
package es la primera sentencia que se pone
en un archivo .java. El nombre del paquete es
el mismo que el nombre del subdirectorio que
contiene los archivos .java. Cada archivo
.java contiene habitualmente una clase. Si
tiene ms de una solamente una de ellas es
pblica. El nombre de dicha clase coincide
PROGRAMACION CON JAVA 2

157

con el nombre del archivo. El uso de paquetes


se estudiar ms adelante.
Como se habr dado cuenta hay una correspondencia entre archivos y clases, entre paquetes y subdirectorios. El Entorno Integrado de Desarrollo (IDE) en el
que creamos los programas facilita esta tarea sin que
el usuario se aperciba de ello.

Ejemplo (35): Uso de los modificadores de acceso package


//archivo: Linea.java
import java.io.*;
class Linea
{
//coordenada 1er punto, modificador de acceso:package
int x1,y1;
//coordenada 2do punto, modificador de acceso:package
int x2,y2;
void leer() //modificador de acceso:package
{
try
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
//lectura
System.out.println("Introduzca 1er punto: ");
System.out.print("x1: ");
sdato = flujoE.readLine(); // leer una lnea de texto
x1=Integer.parseInt(sdato);//convierte cadena
System.out.print("y1: ");
sdato = flujoE.readLine(); // leer una lnea de texto
y1=Integer.parseInt(sdato);//convierte cadena

}
158

System.out.println("Introduzca 2do punto: ");


System.out.print("x2: ");
sdato = flujoE.readLine(); // leer una lnea de texto
x2=Integer.parseInt(sdato);//convierte cadena
System.out.print("y2: ");
sdato = flujoE.readLine(); // leer una lnea de texto
y2=Integer.parseInt(sdato);//convierte cadena
}
catch (IOException ignorada)
{}
Mg. ABRAHAM GAMARRA MORENO

void escribir() //modificador de acceso:package


{
System.out.println("Puntos de la recta
");
System.out.println("x1="+x1+" y1="+y1);
System.out.println("x2="+x2+" y2="+y2);
}
}

// Archivo LineaAppl.java
import java.io.*;
class LineaAppl
{
public static void main (String[] args)
{
//Creacin de un objeto recta: r1
Linea r1=new Linea();
// uso del objeto r1
//como el modificador de acceso es package
//y la clase Linea esta en el mismo directorio
//entonces main() puede utilizar los mtodos
//leer() y escribir()

r1.leer();
r1.escribir();

PROGRAMACION CON JAVA 2

159

Ejemplo (36): Uso del modificador de acceso privado


(private). El siguiente programa es similar al anterior salvo que los mtodos de la clase Linea son private.
//archivo: Linea1.java
import java.io.*;
class Linea1
{
//coordenada 1er punto, modificador de acceso:package
int x1,y1;
//coordenada 2do punto, modificador de acceso:package
int x2,y2;
private void leer() //modificador de acceso:privado
{
try
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
//lectura
System.out.println("Introduzca 1er punto: ");
System.out.print("x1: ");
sdato = flujoE.readLine(); // leer una lnea de texto
x1=Integer.parseInt(sdato);//convierte cadena
System.out.print("y1: ");
sdato = flujoE.readLine(); // leer una lnea de texto
y1=Integer.parseInt(sdato);//convierte cadena

System.out.println("Introduzca 2do punto: ");


System.out.print("x2: ");
sdato = flujoE.readLine(); // leer una lnea de texto
x2=Integer.parseInt(sdato);//convierte cadena
System.out.print("y2: ");
sdato = flujoE.readLine(); // leer una lnea de texto
y2=Integer.parseInt(sdato);//convierte cadena
}
catch (IOException ignorada)
{}

private void escribir() //modificador de acceso:privado


{
System.out.println("Puntos de la recta
");
System.out.println("x1="+x1+" y1="+y1);
System.out.println("x2="+x2+" y2="+y2);
}
}
160

Mg. ABRAHAM GAMARRA MORENO

// Archivo Linea1Appl.java
import java.io.*;
class Linea1Appl
{
public static void main (String[] args)
{
//Creacin de un objeto recta: r1
Linea1 r1=new Linea1();
// uso del objeto r1
//como el modificador de acceso de los metodos
//de la clase Linea es privado
//entonces main() no puede utilizar los mtodos
//leer() y escribir()

r1.leer();
r1.escribir();

NOTA: Este programa no ejecuta porque el compilador


protesta mostrando el siguiente mensaje:
\Linea1Appl.java:18: leer() has private access in Linea1
r1.leer();
^
\Linea1Appl.java:19: escribir() has private access in Linea1
r1.escribir();
^
2 errors

Ejemplo (37): Uso del modificador private y public.


Notese como la funcin main(), puede acceder a los mtodos pblicos de la clase Linea2.
//archivo: Linea2.java
import java.io.*;
class Linea2
{
//coordenada 1er punto, modificador de acceso:privado
private int x1,y1;
//coordenada 2do punto, modificador de acceso:privado
private int x2,y2;
//los datos miembro solo seran accedidos por su mtodos
//por ser privados
public void leer() //modificador de acceso:pblico
{
try
PROGRAMACION CON JAVA 2

161

{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
//lectura
System.out.println("Introduzca 1er punto: ");
System.out.print("x1: ");
sdato = flujoE.readLine(); // leer una lnea de texto
x1=Integer.parseInt(sdato);//convierte cadena
System.out.print("y1: ");
sdato = flujoE.readLine(); // leer una lnea de texto
y1=Integer.parseInt(sdato);//convierte cadena

System.out.println("Introduzca 2do punto: ");


System.out.print("x2: ");
sdato = flujoE.readLine(); // leer una lnea de texto
x2=Integer.parseInt(sdato);//convierte cadena
System.out.print("y2: ");
sdato = flujoE.readLine(); // leer una lnea de texto
y2=Integer.parseInt(sdato);//convierte cadena
}
catch (IOException ignorada)
{}

public void escribir() //modificador de acceso:pblico


{
System.out.println("Puntos de la recta
");
System.out.println("x1="+x1+" y1="+y1);
System.out.println("x2="+x2+" y2="+y2);
}
}

// Archivo Linea2Appl.java
import java.io.*;
class Linea2Appl
{
public static void main (String[] args)
{
//Creacin de un objeto recta: r1
Linea2 r1=new Linea2();
// uso del objeto r1
//como el modificador de acceso de los mtodos
//de la clase Linea es public
//entonces main() puede utilizar los mtodos
//leer() y escribir()
162

Mg. ABRAHAM GAMARRA MORENO

r1.leer();
r1.escribir();

Ejemplo (38) Uso del modificador public. Notese como


la funcin main(), puede acceder a los datos y mtodos
pblicos.
//archivo: Linea3.java
import java.io.*;
class Linea3
{
//coordenada 1er punto, modificador de acceso:pblico
public int x1,y1;
//coordenada 2do punto, modificador de acceso:pblico
public int x2,y2;
//los datos miembro solo seran accedidos por su mtodos
//por ser privados
public void leer() //modificador de acceso:pblico
{
try
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
//lectura
System.out.println("Introduzca 1er punto: ");
System.out.print("x1: ");
sdato = flujoE.readLine(); // leer una lnea de texto
x1=Integer.parseInt(sdato);//convierte cadena
System.out.print("y1: ");
PROGRAMACION CON JAVA 2

163

sdato = flujoE.readLine(); // leer una lnea de texto


y1=Integer.parseInt(sdato);//convierte cadena

System.out.println("Introduzca 2do punto: ");


System.out.print("x2: ");
sdato = flujoE.readLine(); // leer una lnea de texto
x2=Integer.parseInt(sdato);//convierte cadena
System.out.print("y2: ");
sdato = flujoE.readLine(); // leer una lnea de texto
y2=Integer.parseInt(sdato);//convierte cadena
}
catch (IOException ignorada)
{}

public void escribir() //modificador de acceso:pblico


{
System.out.println("Puntos de la recta
");
System.out.println("x1="+x1+" y1="+y1);
System.out.println("x2="+x2+" y2="+y2);
}
}

// Archivo Linea3Appl.java
import java.io.*;
class Linea3Appl
{
public static void main (String[] args)
{
//Creacin de un objeto recta: r1
Linea3 r1=new Linea3();
// uso del objeto r1
//como el modificador de acceso de los datos
//de la clase Linea es public
//entonces main() puede accesar a los datos
//sin necesidad de utilizar sus mtodos
System.out.println("Valores inciales de la recta:");
r1.x1=10;r1.y1=11;
r1.x2=100;r1.y2=101;

}
164

System.out.println("x1="+r1.x1+" y1="+r1.y1);
System.out.println("x2="+r1.x2+" y2="+r1.y2);
//como el modificador de acceso de los mtodos
//de la clase Linea es public
//entonces main() puede accesar a
//leer() y escribir(), para modificar sus datos
//miembro
System.out.println("Valores para modificar la recta:");
r1.leer();
r1.escribir();

Mg. ABRAHAM GAMARRA MORENO

4.8.

EJEMPLOS DEL USO DE CLASES


Ejemplo (39): Realice un programa que maneje la clase
tiempo. Esta clase debe tener las siguientes caractersticas:

La clase tiene los datos miembro hora, min , seg;


los cuales guardan las horas, minutos y segundos
respectivamente.

Los mtodos (funciones miembro) a implementar son:

void leer_tiempo() : que asigna valores a


seg. (2 PTOS)

hora, min ,

void escribir_tiempo() : Permite visualizar el valor


de hora, min , seg (2 PTOS)
tiempo tiempo_transcurrido(tiempo nuevotiempo) : retorna un objeto de la clase tiempo, que contiene el
tiempo transcurrido con respecto al parmetro recibido
(4 PTOS).

La clase que contiene al mtodo principal main(),


debe manipular estos mtodos. (2 PTOS)

//archivo tiempo.java
import java.io.*;
class tiempo
PROGRAMACION CON JAVA 2

165

{ //hora minutos y segundos


private int hora,min,seg;
public void leer_tiempo() throws IOException
{ // Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
System.out.print("hora (0-23): ");
sdato = flujoE.readLine(); // leer una lnea de texto
hora=Integer.parseInt(sdato);//convierte cadena
System.out.print("minutos (0-59): ");
sdato = flujoE.readLine(); // leer una lnea de texto
min=Integer.parseInt(sdato);//convierte cadena

System.out.print("segundos (0-59): ");


sdato = flujoE.readLine(); // leer una lnea de texto
seg=Integer.parseInt(sdato);//convierte cadena

public void escribir_tiempo()


{ System.out.println(hora+":"+min+":"+seg);
}
public tiempo tiempo_transcurrido(tiempo nt)
//se recibe el tiempo nuevo
{ int tseg=0;//guarda los segundos del tiempo anterior
int ntseg=0;//guarda los segundos del tiempo nuevo
int transeg;//guarda los segundos del tiempo transcurrido
tiempo dif=new tiempo();
//convertir los tiempos a seg
//con el tiempo anterior
tseg=tseg+hora*3600;tseg=tseg+min*60;tseg=tseg+seg;
//con el tiempo nuevo nt
ntseg=ntseg+nt.hora*3600;ntseg=ntseg+nt.min*60;
ntseg=ntseg+nt.seg;
//hallar los segundos transcurridos
transeg=ntseg-tseg;
//convertir a horas, minutos y segundos
dif.hora=transeg/3600; transeg=transeg%3600;
dif.min=transeg/60;transeg=transeg%60;
dif.seg=transeg;
return dif;
}
166

Mg. ABRAHAM GAMARRA MORENO

//archivo: exa2p120032App.java
import java.io.*;
class exa2p120032App
{
public static void main (String[] args)
throws IOException
{ tiempo t1=new tiempo();tiempo t2=new tiempo();
tiempo trans=new tiempo();
System.out.println("Ingrese tiempo :");
t1.leer_tiempo(); t1.escribir_tiempo();
System.out.println("Ingrese nuevo tiempo :");
t2.leer_tiempo(); t2.escribir_tiempo();

System.out.println("Tiempo transcurrido :");


trans=t1.tiempo_transcurrido(t2);
trans.escribir_tiempo();

Ejemplo (40): Uso de la clase complejo.


// Archivo: Complejo.java
import java.lang.Math;
class Complejo
{
private float real;
private float imaginario;
Complejo()
{ real=0;
imaginario=0;
}
public void asignar(float r, float i)
{
real=r;
imaginario=i;
}
PROGRAMACION CON JAVA 2

167

public void escribir()


{
System.out.println("El
"+imaginario+" i");
}

complejo

es:

"+real+"

public float absoluto(Complejo c)


{ float va;
va=c.real*c.real+c.imaginario*c.imaginario;
va=(float) Math.sqrt(va);
return va;
}

_________________________________________
// Archivo ComplejoAppl.java
import java.io.*;
class ComplejoAppl
{
public static void main (String[] args)
throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
float re,im; //real, imaginario
float valabs;//valor absoluto
//Creacin de un objeto complejo: c1
Complejo c1=new Complejo();
//lectura de datos
System.out.print("Introduzca parte real: ");
sdato = flujoE.readLine(); // leer una lnea de texto
re=Float.parseFloat(sdato);//convierte cadena a float
System.out.print("Introduzca parte imaginaria: ");
sdato = flujoE.readLine(); // leer una lnea de texto
im=Float.parseFloat(sdato);//convierte cadena a float
// uso del objeto c1
c1.asignar(re,im);
c1.escribir();
valabs=c1.absoluto(c1);
System.out.println("El valor absoluto es : "+valabs);

}
168

}
Mg. ABRAHAM GAMARRA MORENO

Ejemplo (41): Clase quebrado


//archivo: quebrado.java
import java.io.*;
class quebrado
{
private int n;//numerador
private int d;//denominador
public void leer()
{
try
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto

//lectura
System.out.print("Introduzca numerador: ");
sdato = flujoE.readLine(); // leer una lnea de texto
n=Integer.parseInt(sdato);//convierte cadena
System.out.print("Introduzca denominador: ");
sdato = flujoE.readLine(); // leer una lnea de texto
d=Integer.parseInt(sdato);//convierte cadena
}
catch (IOException ignorada)
{}

public void escribir()


{
System.out.print("El quebrado es: ");
if (d!=1)
System.out.println(n+"/"+d);
else
System.out.println(n);
}
public quebrado sumar(quebrado r)
PROGRAMACION CON JAVA 2

169

{ quebrado s=new quebrado();


s.n=n*r.d+d*r.n;
s.d=d*r.d;
return(s);
}

public quebrado simplificar(quebrado r)


{ int i;
i=2;
while(i<=r.n && i<=r.d)
{
while(r.n%i==0 && r.d%i==0)
{ r.n=r.n/i;
r.d=r.d/i;
}
i++;
}
return(r);
}

//archivo: quebradoAppl.java
public class quebradoAppl
{
public static void main(String[] args)
{
quebrado q1=new quebrado();
quebrado q2=new quebrado();
quebrado q=new quebrado();
q1.leer();
q1.escribir();
q2.leer();
q2.escribir();
System.out.println("La suma es: ");
q=q1.sumar(q2);
q=q.simplificar(q);
q.escribir();
}

170

}//fin main

Mg. ABRAHAM GAMARRA MORENO

Ejemplo (42): Clase cuenta (Versin 1). Muestra el uso


de las funciones miembro con parmetros, por lo que se
debe pasar valores a estas funciones.
// Archivo: Cuenta.java
import java.lang.Math;
class Cuenta
{
private float saldo;
public void asignar(float s)
{ saldo=s;
}
public void escribir()
{ System.out.println("El saldo es: "+saldo);
}
public void deposito(float d)
{ saldo=saldo+d;
}

public void retiro(float r)


{ // no se verifica si el saldo es mayor que el retiro
saldo=saldo-r;
}

// Archivo CuentaAppl.java
import java.io.*;
class CuentaAppl
{
public static void main (String[] args)
PROGRAMACION CON JAVA 2

171

throws IOException
{

// Definir un flujo de caracteres de entrada: flujoE


InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
float sal,dep,ret; //saldo inicial, depsito y retiro
//Creacin de un objeto Cuenta: c
Cuenta c=new Cuenta();
//lectura de datos
System.out.print("Introduzca saldo inicial: ");
sdato = flujoE.readLine(); // leer una lnea de texto
sal=Float.parseFloat(sdato);//convierte cadena a float
c.asignar(sal);
c.escribir();
System.out.print("Introduzca deposito: ");
sdato = flujoE.readLine(); // leer una lnea de texto
dep=Float.parseFloat(sdato);//convierte cadena a float
c.deposito(dep);
c.escribir();
System.out.print("Introduzca retiro: ");
sdato = flujoE.readLine(); // leer una lnea de texto
ret=Float.parseFloat(sdato);//convierte cadena a float

c.retiro(ret);
c.escribir();

Ejemplo (43): Clase cuenta (Versin 2). Muestra el uso


de las funciones miembro sin parmetros, por lo que se
debe leer los valores desde la misma funcin. Observe
el uso de throws IOException en las funciones.
172

Mg. ABRAHAM GAMARRA MORENO

// Archivo: Cuenta1.java
import java.io.*;
class Cuenta1
{
private float saldo;
public void asignar() throws IOException
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);

String sdato; // variable para almacenar una lnea de texto


//lectura de datos
System.out.print("Introduzca saldo inicial: ");
sdato = flujoE.readLine(); // leer una lnea de texto
saldo=Float.parseFloat(sdato);//convierte cadena a float

public void escribir()


{
System.out.println("El saldo es: "+saldo);
}
public void deposito() throws IOException
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
float dep;

System.out.print("Introduzca deposito: ");


sdato = flujoE.readLine(); // leer una lnea de texto
dep=Float.parseFloat(sdato);//convierte cadena a float
saldo=saldo+dep;

public void retiro() throws IOException


{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
float ret;
System.out.print("Introduzca retiro: ");
sdato = flujoE.readLine(); // leer una lnea de texto
ret=Float.parseFloat(sdato);//convierte cadena a float

// no se verifica si el saldo es mayor que el retiro


saldo=saldo-ret;

PROGRAMACION CON JAVA 2

173

// Archivo Cuenta1Appl.java
import java.io.*;
class Cuenta1Appl
{
public static void main (String[] args)
throws IOException
{
//Creacin de un objeto Cuenta1
Cuenta1 c=new Cuenta1();
c.asignar();
c.escribir();
c.deposito();
c.escribir();

c.retiro();
c.escribir();

Ejemplo (44): Clase cuenta (Versin 3). Muestra el uso


de las funciones miembro sin parmetros, por lo que se
debe leer los valores desde la misma funcin. Observe
el uso de try. . .catch en lugar de throws IOException
en las funciones.
// Archivo: Cuenta2.java
import java.io.*;
class Cuenta2
{
private float saldo;
public void asignar()
{ try
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
174

Mg. ABRAHAM GAMARRA MORENO

String sdato; // variable para almacenar una lnea de


//texto
//lectura de datos
System.out.print("Introduzca saldo inicial: ");
sdato = flujoE.readLine(); // leer una lnea de texto
saldo=Float.parseFloat(sdato);//convierte cadena a float
}
catch (IOException ignorada)
{}
}
public void escribir()
{
System.out.println("El saldo es: "+saldo);
}
public void deposito()
{ try
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de
//texto
float dep;
System.out.print("Introduzca deposito: ");
sdato = flujoE.readLine(); // leer una lnea de texto
dep=Float.parseFloat(sdato);//convierte cadena a float
saldo=saldo+dep;

}
catch (IOException ignorada)
{}

public void retiro()


{ try
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de
//texto
float ret;
System.out.print("Introduzca retiro: ");
sdato = flujoE.readLine(); // leer una lnea de texto
ret=Float.parseFloat(sdato);//convierte cadena a float

// no se verifica si el saldo es mayor que el retiro


saldo=saldo-ret;
}
catch (IOException ignorada)
{}

PROGRAMACION CON JAVA 2

175

// Archivo Cuenta2Appl.java
import java.io.*;
class Cuenta2Appl
{
public static void main (String[] args)
{

//Creacin de un objeto Cuenta2: c


Cuenta2 c=new Cuenta2();
c.asignar();
c.escribir();
c.deposito();
c.escribir();

c.retiro();
c.escribir();

Ejemplo (45): Clase Conjunto (Versin 1). Muestra el


uso de la funcion miembro union con un parmetro. Observe el uso de try. . .catch en lugar de throws IOException en la funcin leer().
//archivo: Conjunto.java
import java.io.*;
import java.lang.String.*;
class Conjunto
{
private char [] e;//elemento del conjunto
public void leer()
{//la lectura no verifica que existan elementos repetidos
try
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
176

Mg. ABRAHAM GAMARRA MORENO

String sdato; // variable para almacenar una lnea de texto


//lectura
System.out.print("Elementos del conjunto como cadena: ");
sdato = flujoE.readLine(); // leer una lnea de texto

//crear un arreglo de caracteres


e=sdato.toCharArray();
}
catch (IOException ignorada)
{}

public void escribir()


{
System.out.print("Los elementos del Conjunto son : {");
for(int i=0;i<e.length;i++)
if (i!=e.length)
System.out.print(e[i]+",");
else
System.out.print(e[i]);
System.out.println("}");

public Conjunto union(Conjunto c1)


{
int i,j; //contadores
//tam guarda el tamao de los dos conjuntos
int tam=e.length+c1.e.length;
//conjunto union
Conjunto u=new Conjunto();
//el conjunto union supone que no va a existir
//elementos que puedan repetirse en ambos conjuntos
//inicializa elementos del conjunto union
u.e=new char [tam];
//aade elementos del primer conjunto
for(i=0;i<e.length;i++)
u.e[i]=e[i];
//aade elementos del segundo conjunto
j=i;
for(i=0;i<c1.e.length;i++)
{u.e[j]=c1.e[i];
j++;
}
}

return u;

PROGRAMACION CON JAVA 2

177

//archivo: ConjuntoAppl.java
public class ConjuntoAppl
{
public static void main(String[] args)
{
Conjunto c=new Conjunto();
Conjunto c1=new Conjunto();
Conjunto c2=new Conjunto();
c1.leer();
c1.escribir();
c2.leer();
c2.escribir();

}//fin main

System.out.println("Conjunto union");
c=c1.union(c2);
c.escribir();

Ejemplo (46): Clase Conjunto (Versin 2). Muestra el


uso de la funcion miembro union con dos parmetros.
Observe el uso de try. . .catch en lugar de throws
IOException en la funcin leer().
//archivo: Conjunto1.java
import java.io.*;
import java.lang.String.*;
class Conjunto1
{
private char [] e;//elemento del conjunto
public void leer()
{//la lectura no verifica que existan elementos repetidos
try
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
178

Mg. ABRAHAM GAMARRA MORENO

String sdato; // variable para almacenar una lnea de texto


//lectura
System.out.print("Elementos del conjunto como cadena: ");
sdato = flujoE.readLine(); // leer una lnea de texto

//crear un arreglo de caracteres


e=sdato.toCharArray();
}
catch (IOException ignorada)
{}

public void escribir()


{
System.out.print("Los elementos del Conjunto son : {");
for(int i=0;i<e.length;i++)
if (i!=e.length)
System.out.print(e[i]+",");
else
System.out.print(e[i]);
}

System.out.println("}");

public Conjunto1 union(Conjunto1 c1, Conjunto1 c2)


{
int i,j; //contadores
//tam guarda el tamao de los dos conjuntos
int tam=c1.e.length+c2.e.length;
//conjunto union
Conjunto1 u=new Conjunto1();
//el conjunto union supone que no va a existir
//elementos que puedan repetirse en ambos conjuntos
//inicializa elementos del conjunto union
u.e=new char [tam];
//aade elementos del primer conjunto
for(i=0;i<c1.e.length;i++)
u.e[i]=c1.e[i];
//aade elementos del segundo conjunto
j=i;
for(i=0;i<c2.e.length;i++)
{u.e[j]=c2.e[i];
j++;
}
}

return u;

PROGRAMACION CON JAVA 2

179

//archivo: Conjunto1Appl.java
public class Conjunto1Appl
{
public static void main(String[] args)
{
Conjunto1 c=new Conjunto1();
Conjunto1 c1=new Conjunto1();
Conjunto1 c2=new Conjunto1();
c1.leer();
c1.escribir();
c2.leer();
c2.escribir();

180

System.out.println("Conjunto union");
c=c.union(c1,c2);
c.escribir();
}//fin main

Mg. ABRAHAM GAMARRA MORENO

Ejemplo (47): Realice un programa que maneje la clase


enterazo. Esta clase permite almacenar los dgitos de
un nmero en base diez, en cada posicin de un arreglo:

La clase tiene los siguientes datos miembros: valor[ ]: arreglo que almacena los dgitos del nmero.

Los mtodos (funciones miembro) a implementar son:


void asignar(): Define el valor almacenar del dato
miembro. (No usar charToArray()) (2 PTOS)
void mostrar(): Muestra
miembro. (2 PTOS)

el

contenido

del

dato

enterazo multiplicar(enterazo numero2): Recibe un


objeto de la clase enterazo y lo multiplica con el
enterazo de la clase actual. Esta funcin devuelve
un objeto enterazo que contiene la multiplicacin
de esos dos nmeros. (4 PTOS)

La clase que contiene al mtodo principal main(),


debe manipular estos mtodos. (2 PTOS)

//archivo enterazo.java
import java.io.*;
class enterazo
{ //arreglo que almacena los dgitos de un nmero
//consideremos tres cifras
private int[] valor;
public void asignar() throws IOException
{ // Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
valor= new int[3];
System.out.println("Ingrese cifra por cifra del numero: ");
for (int i=0;i<valor.length;i++)
{
sdato = flujoE.readLine(); // leer una lnea de texto
valor[i]=Integer.parseInt(sdato);//convierte cadena
}
PROGRAMACION CON JAVA 2

181

}
public void mostrar()
{
for (int i=0;i<valor.length;i++)
System.out.print(valor[i]);
System.out.println("");
}
public enterazo multiplicar(enterazo ent2)
{ int tam=valor.length+ent2.valor.length;
int[]n1=new int[tam];
int[]n2=new int[tam];
int[]n3=new int[tam];
enterazo mult=new enterazo();
mult.valor= new int[tam];
int in;//contador para 1er, 2do y 3er termino de la suma
int j;//cifra derecha del 1er enterazo
int i;//cifra derecha del 1er enterazo
int aux,acarreo=0;
// Recorre las cifras del segundo nmero y
// lo almacena en 1er trmino suma n1[]
in=tam-1;//derecha del 1er trmino de la suma
j=ent2.valor.length-1;// cifra derecha 2do enterazo
for(i=valor.length-1;i>=0;i--)
{ aux=valor[i]*ent2.valor[j]+acarreo;
n1[in]=aux%10;
acarreo=aux/10;
in--;
}
n1[in]=acarreo;
acarreo=0;
// Recorre las cifras del segundo nmero y
// lo almacena en 2do trmino suma n2[]
in=tam-2;//derecha del 2do trmino de la suma
j=ent2.valor.length-2;// cifra 2do enterazo
for(i=valor.length-1;i>=0;i--)
{ aux=valor[i]*ent2.valor[j]+acarreo;
n2[in]=aux%10;
acarreo=aux/10;
in--;
}
n2[in]=acarreo;
acarreo=0;
// Recorre las cifras del segundo nmero y
// lo almacena en 3er trmino suma n3[]
in=tam-3;//derecha del 3er trmino de la suma
j=ent2.valor.length-3;// cifra derecha 2do enterazo
182

Mg. ABRAHAM GAMARRA MORENO

for(i=valor.length-1;i>=0;i--)
{ aux=valor[i]*ent2.valor[j]+acarreo;
n3[in]=aux%10;
acarreo=aux/10;
in--;
}
n3[in]=acarreo;
acarreo=0;
//suma de los tres trminos
for(i=n1.length-1;i>=0;i--)
{ aux=n1[i]+n2[i]+n3[i]+acarreo;
mult.valor[i]=aux%10;
acarreo=aux/10;
}

return mult;

//archivo: exa2p220032App.java
import java.io.*;
class exa2p220032App
{
public static void main (String[] args)
throws IOException
{ enterazo e1=new enterazo();enterazo e2=new enterazo();
enterazo em=new enterazo();
e1.asignar();
System.out.println("primer numero: ");e1.mostrar();
e2.asignar();
System.out.println("segundo numero: ");e2.mostrar();

em=e1.multiplicar(e2);
System.out.println("multiplicacion: ");em.mostrar();

PROGRAMACION CON JAVA 2

183

4.9.

SOBRECARGA DE UN

MTODO

Es posible y a menudo deseable crear ms de un mtodo


con el mismo nombre, pero con listas de parmetros
distintas. A esto se le llama sobrecarga de mtodo. Se
sobrecarga un mtodo siempre que se crea un mtodo en
una clase que ya tiene un mtodo con el mismo nombre.
Aqu presentamos una versin de la clase quebrado
(ejemplo mostrado antes) que utiliza sobrecarga de mtodo para sumar 2 y 3 quebrados. A diferencia del
ejemplo con la clase quebrado anterior este no utiliza
un solo parmetro en la suma sino 2 y tres parmetros.
Sugerimos analizar las diferencias.
Ejemplo(48): Sobrecarga del mtodo sumar(...), de la
clase quebrado1.
//archivo: quebrado1.java
import java.io.*;
class quebrado1
{
private int n;//numerador
private int d;//denominador
public void leer()
{
try
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto

//lectura
System.out.print("Introduzca numerador: ");
sdato = flujoE.readLine(); // leer una lnea de texto
n=Integer.parseInt(sdato);//convierte cadena
System.out.print("Introduzca denominador: ");
sdato = flujoE.readLine(); // leer una lnea de texto
d=Integer.parseInt(sdato);//convierte cadena
}
catch (IOException ignorada)
{}

public void escribir()


{
System.out.print("El quebrado es: ");
if (d!=1)
System.out.println(n+"/"+d);
else
184

Mg. ABRAHAM GAMARRA MORENO

System.out.println(n);

public quebrado1 sumar(quebrado1 r1, quebrado1 r2)


{ quebrado1 r=new quebrado1();
r.n=r1.n*r2.d+r1.d*r2.n;
r.d=r1.d*r2.d;
return(r);
}
public quebrado1 sumar(quebrado1 r1,quebrado1 r2,quebrado1 r3)
{ quebrado1 r=new quebrado1();
r.n=r1.n*r2.d*r3.d+r2.n*r1.d*r3.d+r3.n*r1.d*r2.d;
r.d=r1.d*r2.d*r3.d;
return(r);
}
public quebrado1 simplificar(quebrado1 r)
{ int i;
i=2;
while(i<=r.n && i<=r.d)
{
while(r.n%i==0 && r.d%i==0)
{ r.n=r.n/i;
r.d=r.d/i;
}
i++;
}
return(r);
}
}

PROGRAMACION CON JAVA 2

185

//archivo: quebrado1Appl.java
public class quebrado1Appl
{
public static void main(String[] args)
{
quebrado1 q1=new quebrado1();
quebrado1 q2=new quebrado1();
quebrado1 q3=new quebrado1();
quebrado1 q=new quebrado1();
q1.leer();
q1.escribir();
q2.leer();
q2.escribir();
q3.leer();
q3.escribir();
System.out.println("La suma de los dos primeros es: ");
q=q.sumar(q1,q2);
q=q.simplificar(q);
q.escribir();
System.out.println("La suma de los tres primeros es: ");
q=q.sumar(q1,q2,q3);
q=q.simplificar(q);
q.escribir();

186

}//fin main

Mg. ABRAHAM GAMARRA MORENO

4.10.

REFERENCIA this
Cada objeto mantiene su propia copia de los atributos
pero no de los mtodos de su clase, de los cuales slo
existe una copia para todos los objetos de esa clase.
Esto es, cada objeto almacena sus propios datos, pero
para acceder y operar con ellos, todos comparten los
mismos mtodos definidos en su clase. Por lo tanto,
para que un mtodo conozca la identidad del objeto
particular para el que ha sido invocado, Java proporciona una referencia al objeto denominada this.
Ejemplo: Clase Circulo (Parcialmente definida)
public class Circulo {
// Atributos
private double x, y;
private double r;

// coordenadas del centro


// el radio

//Mtodos que devuelven la circunferencia y el rea


double circunferencia()
{
return 2*3.14159*r;
}
double area()
{
return 3.14159*r*r;
}
}

Recordemos que la sintaxis para acceder a los atributos de un objeto es la siguiente:


//Inicializamos nuestro crculo para tener centro en (2, 2) y
// radio 1
c.x = 2.0;
c.y = 2.0;
c.r = 1.0;

Adems recordamos que para acceder a los mtodos de un


objeto usamos la misma sintaxis que para acceder a los
atributos de un objeto:

PROGRAMACION CON JAVA 2

187

double a;

a = c.area();

Miremos nuevamente esta ltima lnea:


a = c.area();
Esto es porque lo importante aqu es el objeto, no la
llamada a funcin. Notemos tambin que no estamos pasando ningn argumento a c.area(). El objeto con el
que estamos operando, c, est implcito en la sintaxis.
En realidad hay un argumento, llamado this, el cual
est implcito y hace referencia al objeto que estamos
manipulando.
Por ejemplo, podramos haber escrito el mtodo area():
public double area() {
return 3.14159 * this.r * this.r;
}

En un mtodo simple, no es necesario explicitarlo. En


casos ms complicados, sin embargo, podemos ver que
esto aclara el cdigo, inclusive cuando no es estrictamente necesario.
Hay casos donde el uso del this es necesario. Uno es
cuando el argumento de un mtodo tiene el mismo nombre
que uno de los atributos de la clase.
Miremos cmo se crea nuestro objeto crculo:
Circulo c = new Circulo();
La forma en que trabaja es la siguiente: la palabra
clave new crea una nueva instancia de la clase. Es ah
cuando se llama al constructor, pasndole al constructor el nuevo objeto implcitamente (this, como vimos
anteriormente), y pasndole tambin los argumentos especificados explcitamente entre parntesis, si es que
los hubiera.

188

Mg. ABRAHAM GAMARRA MORENO

4.10.1.
TOR

UTILIZACION DE this EN UN CONSTRUC-

Hagamos un constructor para nuestra clase


crculo. En el ejemplo siguiente, se muestra
un constructor que nos deja especificar los
valores iniciales para el centro y el radio
de nuestro nuevo objeto Circulo. Aprovechemos
el ejemplo para ver el uso de la palabra clave this.
Ejemplo : Un constructor para la clase Circulo
public class Circulo {
// Atributos
private double x, y, r; //El centro y el radio de
//nuestro circulo
// Constructor
public Circulo (double x, double y, double r) {
this.x = x;
this.y = y;
this.r = r;
}
// Mtodos
public double circunferencia() {
return 2*3.14159*r;
}

public double area() {


return 3.14159*r*r;
}

Por lo tanto, para poder crear un objeto de


centro (x, y) en el punto (3.33, 4.75) y de
radio 2.25 y usando nuestro nuevo constructor
tenemos el siguiente cdigo:
Circulo c = new Circulo (3.33, 4.75, 2.25);

4.10.2.

this Y MLTIPLE CONSTRUCTORES

Veamos el ejemplo siguiente, en el cual figura el cdigo de 3 constructores y algunos


utilizan this.
Ejemplo : Mltiple constructores para la clase Circulo
PROGRAMACION CON JAVA 2

189

public class Circulo


{
// Atributos
private double x, y, r;
// Nuestro constructor anterior
public Circulo (double x, double y, double r) {
this.x = x;
this.y = y;
this.r = r;
}
// Ms constructores !!!
public Circulo (double r) {
x = 0.0;
y = 0.0;
this.r = r;
}
public
x =
y =
r =
}

Circulo (Circulo c) {
c.x;
c.y;
c.r;

public
x =
y =
r =
}

Circulo () {
0.0;
0.0;
1.0;

//Mtodos
public double circunferencia() {
return 2*3.14159*r;
}

190

public double area() {


return 3.14159*r*r;
}

Mg. ABRAHAM GAMARRA MORENO

Ejemplo(49): Programa completo de la clase circulo.


//archivo Circulo.java
class Circulo
{
// Atributos
private double x, y, r;
// Nuestro constructor anterior
public Circulo (double x, double y, double r)
{
this.x = x;
this.y = y;
this.r = r;
}
// Ms constructores !!!
public Circulo (double r)
{
x = 0.0;
y = 0.0;
this.r = r;
}
public
{
x =
y =
r =
}

Circulo (Circulo c)

public
{
x =
y =
r =
}

Circulo ()

c.x;
c.y;
c.r;

0.0;
0.0;
1.0;

//Mtodos
public double circunferencia()
{
return 2*3.14159*r;
}

public double area()


{
return 3.14159*r*r;
}

PROGRAMACION CON JAVA 2

191

// Archivo CirculoApp.java
import java.io.*;
class CirculoApp
{
public static void main (String[] args)
{
Circulo c1=new Circulo();
System.out.print("Circunferencia del circulo 1: ");
System.out.println(c1.circunferencia());
System.out.print("Area del circulo 1: ");
System.out.println(c1.area());
Circulo c2=new Circulo(2,5,100);
System.out.print("Circunferencia del circulo 2: ");
System.out.println(c2.circunferencia());
System.out.print("Area del circulo 2: ");
System.out.println(c2.area());

Circulo c3=new Circulo(10);


System.out.print("Circunferencia del circulo 3: ");
System.out.println(c3.circunferencia());
System.out.print("Area del circulo 3: ");
System.out.println(c3.area());

4.10.3.

OTRA VEZ this

Hay un uso especializado para la palabra clave this que toma mayor importancia cuando una
clase tiene mltiple constructores, y es que
un constructor puede ser usado desde otro
constructor de la misma clase. Vamos a rescribir el cdigo anterior usando esta tcnica:

public class Circulo1


192

Mg. ABRAHAM GAMARRA MORENO

// Atributos
private double x, y, r;
// Nuestro constructor anterior (1)
public Circulo1 (double x, double y, double r)
{
this.x = x;
this.y = y;
this.r = r;
}
// Ms constructores !!!
public Circulo1 (double r)
{
this (0.0, 0.0, r); //Estamos llamando a (1)
}
public Circulo1 (Circulo1 c)
{
this (c.x, c.y, c.r); //Estamos llamando a (1)
}
public Circulo1 ()
{
this (0.0, 0.0, 1.0); //Estamos llamando a (1)
}
//Mtodos
public double circunferencia()
{
return 2*3.14159*r;
}

public double area()


{
return 3.14159*r*r;
}

La llamada a this() tiene como restriccin


que puede hacerse slo en la 1ra lnea del
constructor, el cual puede tener ms lneas a
continuacin.

PROGRAMACION CON JAVA 2

193

Ejemplo (50): Programa completo de la clase


Circulo1.
//Archivo Circulo1.java
class Circulo1
{
// Atributos
private double x, y, r;
// Nuestro constructor anterior (1)
public Circulo1 (double x, double y, double r)
{
this.x = x;
this.y = y;
this.r = r;
}
// Ms constructores !!!
public Circulo1 (double r)
{
this (0.0, 0.0, r); //Estamos llamando a (1)
}
public Circulo1 (Circulo1 c)
{
this (c.x, c.y, c.r); //Estamos llamando a (1)
}
public Circulo1 ()
{
this (0.0, 0.0, 1.0); //Estamos llamando a (1)
}
//Mtodos
public double circunferencia()
{
return 2*3.14159*r;
}

194

public double area()


{
return 3.14159*r*r;
}

Mg. ABRAHAM GAMARRA MORENO

// Archivo Circulo1App.java
import java.io.*;
class Circulo1App
{
public static void main (String[] args)
{
Circulo c1=new Circulo();
System.out.print("Circunferencia del circulo 1: ");
System.out.println(c1.circunferencia());
System.out.print("Area del circulo 1: ");
System.out.println(c1.area());
Circulo c2=new Circulo(2,5,100);
System.out.print("Circunferencia del circulo 2: ");
System.out.println(c2.circunferencia());
System.out.print("Area del circulo 2: ");
System.out.println(c2.area());

Circulo c3=new Circulo(10);


System.out.print("Circunferencia del circulo 3: ");
System.out.println(c3.circunferencia());
System.out.print("Area del circulo 3: ");
System.out.println(c3.area());

PROGRAMACION CON JAVA 2

195

4.11. ARREGLO DE OBJETOS


Supongamos que se tiene la clase persona definida de
la siguiente forma:
class Persona
{
private String nombre;
private float sueldo;
public void leer()
{ . . .
}
public void escribir()
{ . . .
}

public float obtener_sueldo()


{ . . .
}

y se desea utilizar no solamente un objeto persona sino un conjunto de objetos persona; para lograr este
objetivo, debemos definir un arreglo de objetos de la
siguiente forma:
//declara y crea el arreglo de objetos
Persona[] p=new Persona[5];

La instruccin anterior permite crear un arreglo de


objetos tal como se muestra en la figura:

Persona[0]

Persona[1]

Persona[2]

Persona[3]

Persona[4]

Debemos aclarar que cada posicin del arreglo tiene


los atributos miembro nombre, sueldo y todos comparten
los mtodos de la clase.
El acceso a los miembros del objeto se realiza de la
siguiente manera:
196

Mg. ABRAHAM GAMARRA MORENO

p[i]=new Persona();

p[i].leer();

p[i].escribir();

Ejemplo(51): Uso de la clase persona con arreglos.


//Archivo: Personaa.java
import java.io.*;
class Personaa
{
private String nombre;
private float sueldo;
public void leer()
{
try
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
//lectura
System.out.print("nombre: ");
nombre= flujoE.readLine(); // leer una lnea de texto
System.out.print("sueldo: ");
sdato = flujoE.readLine(); // leer una lnea de texto
sueldo=Float.parseFloat(sdato);//convierte cadena

}
catch (IOException ignorada)
{}

public void escribir()


{
System.out.println("Nombre
System.out.println("Sueldo
}

: "+nombre);
: "+sueldo);

public float obtener_sueldo()


{
return sueldo;
}
}
PROGRAMACION CON JAVA 2

197

//archivo: PersonaaApp.java
import java.io.*;
class PersonaApp
{
public static void main (String[] args)
throws IOException
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
String sdato; // variable para almacenar una lnea de texto
int n;
//lectura de tamao del arreglo
System.out.print("# de personas: ");
sdato = flujoE.readLine(); // leer una lnea de texto
n=Integer.parseInt(sdato);//convierte cadena
//declara y crea el arreglo de objetos
Persona[] p=new Persona[n];
//otras variables
int i;//contador
float prom;//promedio de los sueldos
float sueldos=0;//acumulador de los sueldos
//inicializacin de objetos
for (i=0;i<p.length;i++)
p[i]=new Persona();
//lectura de datos
System.out.println("Ingrese datos de las personas: ");
for (i=0;i<p.length;i++)
p[i].leer();
//Impresin de datos
System.out.println("Datos de las personas: ");
for (i=0;i<p.length;i++)
{
System.out.println("Persona No. "+i);
p[i].escribir();
sueldos+=p[i].obtener_sueldo();
}

198

//Imprime el promedio de los sueldos


prom=sueldos/p.length;
System.out.println("El promedio es: "+prom);
}

Mg. ABRAHAM GAMARRA MORENO

4.12. VARIABLES DE CLASE (VARIABLE ESTTICA)


En nuestra definicin de la clase Circulo hemos declarado 3 variables de instancias (x, y, r). Variable de
instancia significa que cada clase (cada crculo) tiene su propia copia de esas 3 variables. Pero hay veces
que necesitamos una variable de la cual haya una sola
copia, algo as como una variable global.
El problema es que Java no soporta variables globales
(A modo de comentario, esto no se considera un problema sino una ventaja). Cada variable en Java debe declararse dentro de una clase. As que Java utiliza la
palabra clave static para indicar que una variable
particular es una variable de clase en lugar de una
variable de instancia. Las variables de clase existen
independientemente del nmero de instancias creadas de
la clase, existen y pueden usarse inclusive si la clase nunca se inicializ.
Este tipo de variable, declarada con la palabra clave
static se llama a menudo variable esttica. Pero es
preferible, y de ahora en adelante lo vamos a hacer
as, llamarlas variables de clase, porque de esta manera es fcilmente distinguible de su opuesta, variables de instancia.
PROGRAMACION CON JAVA 2

199

Ejemplo: Ejemplo de uso variable esttica


public class Circulo2
{
static int numCirculos = 0;
//variable de clase: contador de crculos creados
public double x, y, r;
//variable de instancia: centro y radio del circulo
// Constructores
public Circulo2 (double x, double y, double r)
{
this.x = x;
this.y = y;
this.r = r;
numCirculos++;
}
public Circulo2 (double r)
{
this (0.0, 0.0, r);
}
public Circulo2 (Circulo2 c)
{
this (c.x, c.y, c.r);
}
public Circulo2 ()
{
this (0.0, 0.0, 1.0);
}
//Mtodos
public double circunferencia()
{
return 2*3.14159*r;
}

public double area()


{
return 3.14159*r*r;
}

4.12.1. ACCEDIENDO A LAS VARIABLES DE CLASE


Ahora que sabemos el nmero de objetos Circulo creados, cmo podemos acceder a esa informacin? Porque las variables de clase estn asociadas con la clase antes que con una
instancia, accedemos a ellas a travs de la
clase. Por lo tanto, debemos escribir:
200

Mg. ABRAHAM GAMARRA MORENO

System.out.println
("Nmero
Circulo2.numCirculos);

de

crculos

creados:

"

Podemos notar que en uno de los constructores


usamos la variable escribiendo numCirculos,
en lugar de Circulo.numCirculos. Podemos
hacer esto dentro de la definicin de la misma clase.
Ejemplo(52): Programa completo de la clase Circulo2
//Archivo Circulo2.java
public class Circulo2
{
static int numCirculos = 0;
//variable de clase: contador de crculos creados
public double x, y, r;
//variable de instancia: centro y radio del circulo
// Constructores
public Circulo2 (double x, double y, double r)
{
this.x = x;
this.y = y;
this.r = r;
numCirculos++;
}
public Circulo2 (double r)
{
this (0.0, 0.0, r);
}
public Circulo2 (Circulo2 c)
{
this (c.x, c.y, c.r);
}
public Circulo2 ()
{
this (0.0, 0.0, 1.0);
}
//Mtodos
public double circunferencia()
{
return 2*3.14159*r;
}

public double area()


{
return 3.14159*r*r;
}

PROGRAMACION CON JAVA 2

201

// Archivo Circulo2App.java
import java.io.*;
class Circulo2App
{
public static void main (String[] args)
throws IOException
{
Circulo2 c1=new Circulo2();
System.out.print("Circunferencia del circulo 1: ");
System.out.println(c1.circunferencia());
System.out.print("Area del circulo 1: ");
System.out.println(c1.area());
Circulo2 c2=new Circulo2(2,5,100);
System.out.print("Circunferencia del circulo 2: ");
System.out.println(c2.circunferencia());
System.out.print("Area del circulo 2: ");
System.out.println(c2.area());
Circulo2 c3=new Circulo2(10);
System.out.print("Circunferencia del circulo 3: ");
System.out.println(c3.circunferencia());
System.out.print("Area del circulo 3: ");
System.out.println(c3.area());
System.out.print("El numero de circulos creados es: ");
System.out.println( Circulo2.numCirculos);
}

4.13. Y LAS VARIABLES GLOBALES ???


Java
no
soporta
variables
globales,
aunque
Circulo.numCirculos se comporta como si lo fuera. La
diferencia con el lenguaje C es que aqu no hay
posibilidad de conflictos de nombres. Si usamos otra
clase con una variable de clase llamada numCirculos,
no hay colisin porque ambas deben ser referenciadas
por sus nombres de clases.
202

Mg. ABRAHAM GAMARRA MORENO

4.14. CONSTANTES: OTRO EJEMPLO DE VARIABLES DE


CLASE
Intentemos un ejemplo un poco ms complicado. Cuando
calculamos el rea y la circunferencia usamos el valor
de . Dado que usamos ese valor con frecuencia, no
queremos tipear 3.14159 cada vez que lo usamos, por lo
que podemos ponerlo en una variable.
public class Circulo
{
public static final double PI = 3.14159265358979323846;
public double x, y, r;
// etc...
}

Adems del uso de static, el cual ya lo hemos visto,


en el ejemplo usamos la palabra clave final, la cual
significa que la variable no puede cambiar su valor.
Esto previene de hacer una estupidez, como la siguiente:
Circulo.PI = 4;
El compilador Java es hbil respecto de las variables
declaradas static y final, ya que sabe que tienen valores constantes. Por lo que cuando escribimos cdigo
como el siguiente:
double circunferencia = 2 * Circulo.PI * radio;
el compilador precalcula el valor 2 * Circulo.PI, en
lugar de dejarlo para el intrprete.

4.15.

EJEMPLOS DE VARIABLES DE CLASE


Ejemplo(53): Realice un programa que calcule el total
de la compra de 3 libros. Debe tener en cuenta lo siguiente:

Utilizar la clase libro que tiene los datos miembro titulo, autor y precio. Adems la clase libro tiene los mtodos: void leer_datos ( ), y
void escribir_total_compra ( ).
El mtodo void
leer_datos ( ) permite leer los datos miembros de
los libros y la vez calcula el total de la compra. El mtodo
void escribir_total_compra ( )

PROGRAMACION CON JAVA 2

203

permite escribir el total de la compra para los


tres libros. (5 PTOS)

Debe utilizar variables de clase (variables estticas), las que usted considere conveniente, para
almacenar la cantidad de libros comprados, as
como para calcular el total de la compra.(5
PTOS).

//archivo: Libro.java
import java.io.*;
class Libro
{
//variables de clase
static int cantidad;
static float total=0;
//datos miembro
private String titulo;
private float precio;
//funciones miembro
public void leer_datos()
{
try
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader
isr
=
new
InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
texto

String sdato; // variable para almacenar una lnea de


//lectura
System.out.print("Introduzca titulo: ");

204

Mg. ABRAHAM GAMARRA MORENO

titulo = flujoE.readLine(); // leer una lnea de texto


System.out.print("Introduzca precio: ");
sdato = flujoE.readLine(); // leer una lnea de texto
precio=Float.parseFloat(sdato);//convierte cadena
System.out.print("Cantidad de libros a comprar: ");
sdato = flujoE.readLine(); // leer una lnea de texto
cantidad=Integer.parseInt(sdato);//convierte cadena
}
catch (IOException ignorada)
{}
total=total+precio*cantidad;
}//fin leer
public void escribir_total_compra()
{
System.out.println("El total de la compra es: "+total);
}//fin escribir_total_compra
}

// Archivo LibroAppl.java
class LibroAppl
{
public static void main (String[] args)
{
//Creacin de los objetos libro: li1,li2,li3
Libro li1=new Libro();
Libro li2=new Libro();
Libro li3=new Libro();
System.out.println("Ingrese datos del primer libro");
li1.leer_datos();
System.out.println("Ingrese datos del segundo libro");
li2.leer_datos();
System.out.println("Ingrese datos del tercer libro");
li3.leer_datos();
//escribe el total
//puede utilizar cualquiera de los objetos
li1.escribir_total_compra();

PROGRAMACION CON JAVA 2

205

4.16. MTODOS DE CLASE (MTODOS ESTTICOS)


El uso de Math.sqrt(4), permite encontrar la raiz cuadrada de 4; lo que est pasando aqu es que Math es el
nombre de una clase, sqrt() es el nombre de un mtodo
de clase (mtodo esttico) definido en Math, a diferencia con los mtodos de instancia, tales como area()
y circunferencia() en la clase Circulo, que son los
que hemos visto ahora.
Caractersticas:

Los mtodos de clase se declaran con la palabra


clave static.

A los mtodos de clase los podemos ver tambin


como mtodos estticos.

Los mtodos de clase se invocan a travs de la


clase en lugar de una instancia (objeto).

Los mtodos de clase son lo ms parecido a mtodos globales. Como a ellos se hacen referencia a
travs de la clase, no hay peligro de conflicto
de nombres.

4.16.1. SIN THIS


Los mtodos de clases difieren de los mtodos
de instancias en un punto importante: no pasan la referencia implcita this. De esta manera, los mtodos sin this no estn asociados
con ninguna instancia de la clase y no pueden
hacer referencia a ninguna variable de instancia o invocar mtodos de instancia.

4.16.2. UN MTODO DE CLASE PARA Circulo


El siguiente ejemplo, muestra dos definiciones de un mtodo para nuestra clase Circulo.
Una es un mtodo de instancia y la otra es un
mtodo de clase.
Ejemplo: Un mtodo de clase y un mtodo de
instancia

206

Mg. ABRAHAM GAMARRA MORENO

public class Circulo3


{
public double x, y, r;
//....
//MTODO DE INSTANCIA. DEVUELVE EL MAYOR DE LOS DOS CRCULOS
public Circulo3 elMayor (Circulo3 c)
{
if (c.r > r)
return c;
else
return this;
}
//MTODO DE CLASE. DEVUELVE EL MAYOR DE LOS DOS CRCULOS
public static Circulo3 elMayor (Circulo3 a, Circulo3 b)
{
if (a.r > b.r)
return a;
else
return b;
}
}

//....

Podemos invocar el mtodo de instancia de la


siguiente manera:
Circulo3 a = new Circulo3 (2.0);
Circulo3 b = new Circulo3 (3.0);
Circulo3 c = a.elMayor(b);

y el mtodo de clase as:


Circulo3 a = new Circulo3 (2.0);
Circulo3 b = new Circulo3 (3.0);
Circulo3 d = Circulo3.elMayor(a,b);

Ejemplo(54): Programa completo de la clase Circulo3


//archivo: Circulo3.java
public class Circulo3
{
//variable de instancia: centro y radio del circulo
private double x, y, r;
// Constructores
Circulo3 (double x, double y, double r)
{ this.x = x;
this.y = y; this.r = r;
}
PROGRAMACION CON JAVA 2

207

Circulo3 (double r)
{
this (0.0, 0.0, r);
}
public void escribir()
{
System.out.println("x= "+x+" y= "+y+" r= "+r);
}
//Mtodos:
//MTODO DE INSTANCIA. DEVUELVE EL MAYOR DE LOS DOS CRCULOS
public Circulo3 elMayor (Circulo3 c)
{
if (c.r > r)
return c;
else
return this;
}
//MTODO DE CLASE. DEVUELVE EL MAYOR DE LOS DOS CRCULOS
public static Circulo3 elMayor (Circulo3 a, Circulo3 b)
{
if (a.r > b.r)
return a;
else
return b;
}
}

// Archivo Circulo3App.java
import java.io.*;
class Circulo3App
{
public static void main (String[] args)
throws IOException
{
Circulo3 a=new Circulo3(50);
System.out.println("primer circulo:");
a.escribir();
Circulo3 b=new Circulo3(100);
System.out.println("segundo circulo:");
b.escribir();
System.out.println("Utilizando el metodo
tiene:");
Circulo3 c = a.elMayor(b);
System.out.println("Circulo mayor:");
c.escribir();
208

de

instancia

Mg. ABRAHAM GAMARRA MORENO

se

System.out.println("Utilizando el metodo de clase se tiene:");


Circulo3 d = Circulo3.elMayor(a,b);
System.out.println("Circulo mayor:");
c.escribir();
}
}

Ejemplo(55): Programa que utiliza mtodos estaticos


para calcular la matriz inversa.
Solucin:
La inversa de una matriz dada es otra matriz tal que
multiplicada a la derecha o a la izquierda por la matriz dada, da la matriz unidad. Veamos como se obtiene
la matriz inversa de una matriz 4 x 4, y luego generalizaremos para una matriz cuadrada de dimensin n.

El producto de las dos matrices da lugar a los siguientes sistemas de cuatro ecuaciones con cuatro incgnitas. Los trminos independientes bij son todos
ceros
excepto
los
de
la
diagonal
principal
b00=b11=b22=b33=1.
Primera columna:
PROGRAMACION CON JAVA 2

209

Segunda columna:

Tercera columna

Cuarta columna

Para el clculo de la matriz inversa, deberemos transformar la matriz a, los trminos independientes b (cada una de las columnas de la matriz unidad), y calcular las n2 incgnitas x.
La matriz de los trminos independientes b es la matriz unidad, cuyos elementos son todos cero, excepto
los de la diagonal principal que son unos.
for(int i=0; i<n; i++){
b[i][i]=1.0;
}
210

Mg. ABRAHAM GAMARRA MORENO

El cdigo de la transformacin de los elementos de la matriz es el mismo que nos sirvi para calcular el
determinante de una matriz cuadrada. Le aadimos el cdigo de la transformacin de los trminos
independientes ( a la derecha en las frmulas que siguen) para cada uno de los cuatro sistemas de ecuaciones
s=0, 1, 2, 3

k=0

k=1

k=2
for(int k=0; k<n-1; k++){
for(int i=k+1; i<n; i++){
//trminos independientes
for(int s=0; s<n; s++){
b[i][s]-=a[i][k]*b[k][s]/a[k][k];
}
//elementos de la matriz
for(int j=k+1; j<n; j++){
a[i][j]-=a[i][k]*a[k][j]/a[k][k];
}
}
}

Una vez realizadas las transformaciones, se calcula


las n2 incgnitas x en orden inverso y las guardamos
en la matriz c . Primero, la ltima incgnita y luego
todas las n-1 restantes. De nuevo, el ndice s representa la columna de la matriz b de los trminos independientes, y de la matriz c de las incgnitas.

PROGRAMACION CON JAVA 2

211

for(int s=0; s<n; s++){


c[n-1][s]=b[n-1][s]/a[n-1][n-1];
for(int i=n-2; i>=0; i--){
c[i][s]=b[i][s]/a[i][i];
for(int k=n-1; k>i; k--){
c[i][s]-=a[i][k]*c[k][s]/a[i][i];
}
}
}

Si queremos mantener la matriz original d, hacemos una


copia a de dicha matriz en el cuerpo de la funcin inversa y realizamos las operaciones con la matriz copia
dejando la original sin modificar.
double [][] a=d;

El cdigo completo de esta funcin esttica inversa


que halla la matriz inversa de una matriz cuadrada es
el siguiente.
Archivo Matriz.java
class Matriz
{
public static double [][] inversa(double d[][])
{
int n=d.length;
//dimensin de la matriz
double [][] a=d;
//La matriz a es una copia de d
double [][] b=new double [n][n];
//matriz
de
los
trminos independientes
double [][] c=new double [n][n];
//matriz
de
las
incgnitas
//matriz unidad
for(int i=0; i<n; i++)
{
b[i][i]=1.0;
}
//transformacin de la matriz y de los trminos independientes
for(int k=0; k<n-1; k++)
{
for(int i=k+1; i<n; i++)
{
//trminos independientes
for(int s=0; s<n; s++)
{
b[i][s]-=a[i][k]*b[k][s]/a[k][k];
}
212

Mg. ABRAHAM GAMARRA MORENO

//elementos de la matriz
for(int j=k+1; j<n; j++)
{
a[i][j]-=a[i][k]*a[k][j]/a[k][k];
}
}
}
//clculo de las incgnitas, elementos de la matriz inversa
for(int s=0; s<n; s++)
{
c[n-1][s]=b[n-1][s]/a[n-1][n-1];
for(int i=n-2; i>=0; i--)
{
c[i][s]=b[i][s]/a[i][i];
for(int k=n-1; k>i; k--)
{
c[i][s]-=a[i][k]*c[k][s]/a[i][i];
}
}
}
return c;
}
public static void mostrar(double m[][])
{
System.out.println("\n\n");
for (int i=0; i < m.length; i++)
{
for (int j=0; j <m[i].length; j++)
{
System.out.print(m[i][j]+"\t");
}
System.out.println("");
}
System.out.println("\n\n");
}
}

Archivo MatrizAppl.java
class MatrizAppl
{
public static void main (String[] args)
{
double [][] m={{2,1,-3},
{-1,3,2},
{3,1,-3}
};
double [][] m1= new double [3][3];
PROGRAMACION CON JAVA 2

213

System.out.println("Matriz original");
Matriz.mostrar(m);
System.out.println("Matriz inversa");
m1=Matriz.inversa(m);
Matriz.mostrar(m1);
}
}

4.17. DESTRUCCIN DE LOS OBJETOS


Ahora que ya hemos visto como crear y usar objetos, la
pregunta obvia es: cmo destruirlos?. La respuesta
es: no hay que destruirlos. En Java no existe un mtodo destructor como en C++, ac Java se encarga de la
destruccin de los objetos por nosotros, y nos permite
concentrarnos en otras cosas ms importantes, como el
algoritmo en el que estemos trabajando.

4.17.1. EL RECOLECTOR DE BASURA (GARBAGE COLLECTOR)


La tcnica que usa Java para deshacerse de
los objetos una vez que ellos no se necesitan
ms es llamada garbage collection. El intrprete Java conoce qu objetos tiene almacenado. Tambin puede resolver cules variables
214

Mg. ABRAHAM GAMARRA MORENO

refieren a cules objetos y cules objetos


refieren a otros objetos. De esta manera,
puede resolver cuando un objeto almacenado ya
no es referenciado por ningn objeto ni por
ninguna variable. Cuando encuentra un objeto
en esta situacin, el garbage collector sabe
que puede destruirlo, y lo hace. El garbage
collector tambin puede detectar y destruir
ciclos de objetos que refieren a cada uno,
pero que no son referenciados por ningn otro
objeto.
El garbage collector corre en un hilo
(thread) de baja prioridad, y hace la mayora
de su trabajo cuando no se est ejecutando
nada. Generalmente corre cuando el procesador
se encuentra inactivo, por ejemplo esperando
una entrada por teclado del usuario o un
evento con el mouse. Pero hay un momento en
que puede llegar a correr con alta prioridad,
y haciendo caer un poco al sistema en grandes
aplicaciones, y es cuando el intrprete se
empieza a quedar sin memoria. Cabe aclarar
que esto no ocurre seguido, ya que como el
garbage collector se est ejecutando en un
thread de baja prioridad ya viene recuperando
memoria.
Todo este esquema si bien puede parecer algo
pesado y poco econmico, podemos asegurar que
no lo es. Un buen garbage collector puede ser
sorprendentemente eficiente.

4.18. LA REFERENCIA null


En nuestras referencias a objetos, podemos tener el
valor null. Este valor indica que no estamos apuntando
a ningn objeto. El valor null puede ser devuelto por
mtodos que devuelvan referencias a objetos, para indicar que no existe el objeto requerido. Podemos preguntar si una referencia a un objeto es igual o distinta a null, por ejemplo:
Circulo c = new Circulo();
if ( c != null )
System.out.println("El Circulo 'c' existe !");
Circulo b=null;
PROGRAMACION CON JAVA 2

// b referencia a null
215

if ( b == null )
System.out.println("El Circulo 'b' NO existe !");

El valor null puede asignarse a cualquier variable de


referencia a objetos o arrays. Si una variable hace
referencia a un objeto y luego le asignamos el valor
null, lo que estamos haciendo es eliminar la referencia al objeto (esta variable ahora referencia a null),
pero no el objeto en s, por lo menos no directamente,
de esto se encargar el garbage collector (recolector
de basura). Si intentamos acceder a un miembro (atributo o mtodo) con esa variable, el sistema de runtime
lanzar una NullPointerException, ya que nuestra variable referencia a null. Por ejemplo
Circulo d = new Circulo(5);

// Creamos un nuevo objeto Circulo

System.out.println(d.area()); // mostramos su area


d=null;
// eliminamos la referencia al objeto Circulo
d.circunferencia(); // Se lanza una NullPointerException
// debido a que 'd' ya NO referencia
// al objeto Circulo

216

Mg. ABRAHAM GAMARRA MORENO

4.19. HERENCIA
La herencia es una propiedad esencial de la Programacin Orientada a Objetos que consiste en la creacin
de nuevas clases a partir de otras ya existentes. Este
trmino ha sido prestado de la Biologa donde afirmamos que un nio tiene la cara de su padre, que ha
heredado ciertas facetas fsicas o del comportamiento
de sus progenitores.

La herencia es la caracterstica fundamental que distingue un lenguaje orientado a objetos, como el C++ o
Java, de otro convencional como C, BASIC, etc. Java
permite heredar a las clases caractersticas y conductas de una o varias clases denominadas base. Las clases que heredan de clases base se denominan derivadas,
estas a su vez pueden ser clases bases para otras clases derivadas. Se establece as una clasificacin jerrquica, similar a la existente en Biologa con los
animales y las plantas.
PROGRAMACION CON JAVA 2

217

La herencia permite crear una clase (clase derivada) a


partir de otras ya existentes, y sta tendr todos los
atributos y los mtodos de su 'superclase' (clase base), y adems se le podrn aadir otros atributos y
mtodos propios.
Se llama 'Superclase' (clase base) a la clase de la
que desciende una clase.
Los objetos se definen en trminos de clases. Se puede
saber mucho acerca de un objeto conociendo su clase.
Por ejemplo, aunque el nombre Tucker pueda no ser significativo, si se dice que Tucker fue un automvil inmediatamente sabremos varias de sus caractersticas,
como ser que consta de cuatro ruedas, tiene un volante, tiene transmisin, etc.
Los sistemas orientados a objetos permiten que las
clases se definan en trminos de otras clases. Por
ejemplo, camionetas, autos de carrera y autos de calle, son diferentes clases de automviles. En la terminologa orientada a objetos, las camionetas, los autos de carrera y los autos de calle son subclases de
la clase automviles. De la misma manera la clase automviles es la superclase de las clases camionetas,
autos de carrera y autos de calle.

Automviles

Camionetas

218

Autos de
carrera

Autos de calle

Mg. ABRAHAM GAMARRA MORENO

Cada subclase hereda el estado (en la forma de declaracin de atributos) de la superclase. Las camionetas,
los autos de carrera y los autos de calle comparten
algunos de esos estados: tipo de ruedas, color del
chasis, velocidad mxima, velocidad actual, cantidad
de marchas, etc.
Cada subclase tambin hereda los mtodos de su superclase. Las camionetas, los autos de carrera y los autos de calle comparten algunos de los comportamientos:
cambiarDeMarcha, acelerar, frenar, etc..
Sin embargo, las subclases (clase derivada) no estn
limitadas a los estados y comportamientos heredados de
la superclase (clase base). Las subclases pueden agregar atributos y mtodos a los heredados de la superclase. Por ejemplo, las Camionetas pueden tener cpulas, los AutosDeCarreras pueden tener una marcha ms y
los AutosDeCalle pueden ser cups.
Las subclases tambin pueden redefinir mtodos heredados y proveer implementaciones especializadas para
esos mtodos. Por ejemplo, si AutosDeCarrera posee una
marcha ms se puede redefinir el mtodo cambiarDeMarcha para que el corredor pueda utilizar ese cambio extra.
No se est limitado a una sola capa de herencia. El
rbol de herencia, o jerarqua de clases, puede ser
tan profundo como sea necesario. Los mtodos y los
atributos se heredan bajando los niveles. En general,
las clases que aparecen ms abajo en la jerarqua de
clases, poseen un comportamiento ms especializado.
La herencia ofrece una ventaja importante, permite la
reutilizacin del cdigo. Una vez que una clase ha sido depurada y probada, el cdigo fuente de dicha clase
no necesita modificarse. Su funcionalidad se puede
cambiar derivando una nueva clase que herede la funcionalidad de la clase base y le aada otros comportamientos. Reutilizando el cdigo existente, el programador ahorra tiempo y dinero, ya que solamente tiene
que verificar la nueva conducta que proporciona la
clase derivada.
La programacin en los entornos grficos, en particular Windows, con el lenguaje C++, es un ejemplo ilustrativo. Los compiladores como los de Borland y Microsoft proporcionan libreras cuyas clases describen el
PROGRAMACION CON JAVA 2

219

aspecto y la conducta de las ventanas, controles, mens, etc. Una de estas clases denominada TWindow describe el aspecto y la conducta de una ventana, tiene
una funcin miembro denominada Paint, que no dibuja
nada en el rea de trabajo de la misma. Definiendo una
clase derivada de TWindow, podemos redefinir en ella
la funcin Paint para que dibuje una figura. Aprovechamos de este modo la ingente cantidad y complejidad
del cdigo necesario para crear una ventana en un entorno grfico. Solamente, tendremos que aadir en la
clase derivada el cdigo necesario para dibujar un
rectngulo, una elipse, etc.
En el lenguaje Java, todas las clases derivan implcitamente de la clase base Object, por lo que heredan
las funciones miembro definidas en dicha clase. Las
clases derivadas pueden redefinir algunas de estas
funciones miembro como toString y definir otras nuevas.
Para crear un applet, solamente tenemos que definir
una clase derivada de la clase base Applet, redefinir
ciertas funciones como init o paint, o definir otras
como las respuestas a las acciones sobre los controles.

Los programadores crean clases base:

Cuando se dan cuenta que diversos tipos tienen


algo en comn, por ejemplo en el juego del ajedrez peones, alfiles, rey, reina, caballos y torres, son piezas del juego. Creamos, por tanto,
una clase base y derivamos cada pieza individual
a partir de dicha clase base.

Cuando se precisa ampliar la funcionalidad de un


programa sin tener que modificar el cdigo existente.

4.19.1. LA CLASE BASE


Vamos a poner un ejemplo del segundo tipo,
que simule la utilizacin de liberas de clases para crear un interfaz grfico de usuario
como Windows 3.1 o Windows 95.

220

Mg. ABRAHAM GAMARRA MORENO

Supongamos que tenemos una clase que describe


la conducta de una ventana muy simple, aquella que no dispone de ttulo en la parte superior, por tanto no puede desplazarse, pero
si cambiar de tamao actuando con el ratn en
los bordes derecho e inferior.
La clase Ventana tendr los siguientes miembros dato: la posicin x e y de la ventana,
de su esquina superior izquierda y las dimensiones de la ventana: ancho y alto.
class Ventana
{
protected int x;
protected int y;
protected int ancho;
protected int alto;
public Ventana(int x, int y, int ancho, int alto) {
this.x=x;
this.y=y;
this.ancho=ancho;
this.alto=alto;
}
//...
}

Las funciones miembros, adems del constructor sern las siguientes: la funcin mostrar
que simula una ventana en un entorno grfico,
aqu solamente nos muestra la posicin y las
dimensiones de la ventana.
{

public void mostrar()

System.out.println("posicin
: x="+x+", y="+y);
System.out.println("dimensiones
:
w="+ancho+",
h="+alto);
}

La funcin cambiarDimensiones que simula el


cambio en la anchura y altura de la ventana.
public void cambiarDimensiones(int dw, int dh){
ancho+=dw;
alto+=dh;
}

El cdigo completo de la clase base Ventana,


es el siguiente
PROGRAMACION CON JAVA 2

221

class Ventana
{
protected int x;
protected int y;
protected int ancho;
protected int alto;
public Ventana(int x, int y, int ancho, int alto) {
this.x=x;
this.y=y;
this.ancho=ancho;
this.alto=alto;
}
public void mostrar(){
System.out.println("posicin
: x="+x+", y="+y);
System.out.println("dimensiones
:
w="+ancho+",
h="+alto);
}
public void cambiarDimensiones(int dw, int dh){
ancho+=dw;
alto+=dh;
}
}

4.19.2. OBJETOS DE LA CLASE BASE


Como vemos en el cdigo, el constructor de la
clase base inicializa los cuatro miembros dato. Llamamos al constructor creando un objeto
de la clase Ventana
Ventana ventana=new Ventana(0, 0, 20, 30);
Desde el objeto ventana podemos llamar a las
funciones miembro pblicas
ventana.mostrar();
ventana.cambiarDimensiones(10, 10);
ventana.mostrar();

222

Mg. ABRAHAM GAMARRA MORENO

4.19.3. LA CLASE DERIVADA

Incrementamos la funcionalidad de la clase


Ventana definiendo una clase derivada denominada VentanaTitulo. Los objetos de dicha clase tendrn todas las caractersticas de los
objetos de la clase base, pero adems tendrn
un ttulo, y se podran desplazar (se simula
el desplazamiento de una ventana con el ratn).
La clase derivada heredar los miembros dato
de la clase base y las funciones miembro, y
tendr un miembro dato ms, el ttulo de la
ventana.
class VentanaTitulo extends Ventana
{
protected String titulo;
public VentanaTitulo(int x, int y, int w, int h, String
nombre) {
super(x, y, w, h);
titulo=nombre;
}

extends es la palabra reservada que indica


que la clase VentanaTitulo deriva, o es una
subclase (clase derivada), de la clase Ventana.
La primera sentencia del constructor de la
clase derivada es una llamada al constructor
de la clase base mediante la palabra reservada super. La llamada
super(x, y, w, h);
inicializa los cuatro miembros dato de la
clase base Ventana: x, y, ancho, alto. A continuacin, se inicializa los miembros dato de
la clase derivada, y se realizan las tareas
PROGRAMACION CON JAVA 2

223

de inicializacin que sean necesarias. Si no


se llama explcitamente al constructor de la
clase base Java lo realiza por nosotros, llamando al constructor por defecto si existe.
La funcin miembro denominada desplazar cambia la posicin de la ventana, aadindoles
el desplazamiento.
public void desplazar(int dx, int dy)
{
x+=dx;
y+=dy;
}

Redefine la funcin miembro mostrar para mostrar una ventana con un ttulo.
public void mostrar()
{
super.mostrar();
System.out.println("titulo
}

: "+titulo);

En la clase derivada se define una funcin


que tiene el mismo nombre y los mismos parmetros que la de la clase base. Se dice que
redefinimos la funcin mostrar en la clase
derivada. La funcin miembro mostrar de la
clase derivada VentanaTitulo hace una llamada
a la funcin mostrar de la clase base Ventana, mediante
super.mostrar();
De este modo aprovechamos el cdigo ya escrito, y le aadimos el cdigo que describe la
nueva funcionalidad de la ventana por ejemplo, que muestre el ttulo.
Si nos olvidamos de poner la palabra reservada super llamando a la funcin mostrar, tendramos una funcin recursiva. La funcin
mostrar llamara a mostrar indefinidamente.
public void mostrar()
{ //ojo!, funcin recursiva
System.out.println("titulo
mostrar();
}
224

: "+titulo);

Mg. ABRAHAM GAMARRA MORENO

La
definicin
de
la
clase
VentanaTitulo, ser la siguiente.

derivada

class VentanaTitulo extends Ventana


{
protected String titulo;
public VentanaTitulo(int x, int y, int w, int h, String
nombre) {
super(x, y, w, h);
titulo=nombre;
}
public void mostrar(){
super.mostrar();
System.out.println("titulo
: "+titulo);
}
public void desplazar(int dx, int dy){
x+=dx;
y+=dy;
}
}

4.19.4. OBJETOS DE LA CLASE DERIVADA


Creamos un objeto ventana de la clase derivada VentanaTitulo
VentanaTitulo ventana=new VentanaTitulo(0, 0,
20, 30, "Principal");
Mostramos la ventana con su ttulo, llamando
a la funcin mostrar, redefinida en la clase
derivada
ventana.mostrar();
Desde el objeto ventana de la clase derivada
llamamos a las funciones miembro definidas en
dicha clase
ventana.desplazar(4, 3);
Desde el objeto ventana de la clase derivada
podemos llamar a las funciones miembro definidas en la clase base.
ventana.cambiarDimensiones(10, -5);
Para mostrar la nueva ventana desplazada y
cambiada de tamao escribimos
ventana.mostrar();
PROGRAMACION CON JAVA 2

225

Ejemplo ( 56): Programa completo de la clase


base Ventana y su clase derivada.
//Archivo: Ventana.java
class Ventana
{
protected
protected
protected
protected

int
int
int
int

x;
y;
ancho;
alto;

public Ventana(int x, int y, int ancho, int alto)


{
this.x=x;
this.y=y;
this.ancho=ancho;
this.alto=alto;
}
public void mostrar()
{
System.out.println("posicion
: x="+x+", y="+y);
System.out.println("dimensiones
:
w="+ancho+",
h="+alto);
}

public void cambiarDimensiones(int dw, int dh)


{
ancho+=dw;
alto+=dh;
}

//Archivo: VentanaTitulo.java
class VentanaTitulo extends Ventana
{
protected String titulo;
public VentanaTitulo(int x, int y, int w, int h, String
nombre)
{
super(x, y, w, h);
titulo=nombre;
}
public void mostrar()
{
System.out.println("titulo
: "+titulo);
super.mostrar();
}
public void desplazar(int dx, int dy)
{
x+=dx;
y+=dy;
226

Mg. ABRAHAM GAMARRA MORENO

//Archivo: VentanaApp.java

class VentanaApp
{
public static void main(String[] args)
{
VentanaTitulo ventana=new VentanaTitulo(0, 0, 20, 30,
"Principal");
ventana.mostrar();
ventana.cambiarDimensiones(10, -5);
ventana.desplazar(4, 3);
System.out.println("************************");
ventana.mostrar();
}
}

4.20. MODIFICADORES DE ACCESO Y HERENCIA


Como
hemos
visto
anteriormente,
existen
los
modificadores de acceso public, private y as como el
control de acceso por defecto a nivel de paquete,
cuando no se especifica nada. En la herencia, surge un
nuevo control de acceso denominado protected.
Hemos puesto protected delante de los miembros dato x
e y de la clase base Ventana
class Ventana
{
protected int x;
protected int y;
//...
}

PROGRAMACION CON JAVA 2

227

En la clase derivada la funcin miembro desplazar accede a dichos miembros dato


class VentanaTitulo extends Ventana
{ //...
public void desplazar(int dx, int dy){
x+=dx;
y+=dy;
}
}

Si cambiamos el modificador de acceso de los miembros


x e y de la clase base Ventana de protected a private,
veremos que el compilador se queja diciendo que los
miembro x e y no son accesibles.
Los miembros ancho y alto se pueden poner con acceso
private sin embargo, es mejor dejarlos como protected
ya que podran ser utilizados por alguna funcin miembro de otra clase derivada de VentanaTitulo. Dentro de
una jerarqua pondremos un miembro con acceso private,
si estamos seguros de que dicho miembro solamente va a
ser usado por dicha clase.
Como vemos hay cuatro modificadores de acceso a los
miembros dato y a los mtodos (funciones): private,
protected, public y default (por defecto, o en ausencia de cualquier modificador). La herencia complica
an ms
el
problema
de acceso, ya que las clases
dentro del mismo paquete tienen diferentes accesos que
las clases de distinto paquete
Los siguientes cuadros tratan de aclarar este problema
Clases dentro del mismo paquete
Modificador de
Heredado Accesible
acceso
Por defecto (sin
Si
Si
modificador)
Private
No
No
Protected
Si
Si
Public
Si
Si

228

Mg. ABRAHAM GAMARRA MORENO

Clases en distintos paquetes


Modificador de
Heredado Accesible
acceso
Por defecto (sin
No
No
modificador)
Private
No
No
Protected
Si
No
Public
Si
Si
Desde el punto de vista prctico, cabe resear que no
se heredan los miembros privados, ni aquellos miembros
(dato o funcin) cuyo nombre sea el mismo en la clase
base y en la clase derivada.

4.21. LA JERARQUA DE CLASES QUE DESCRIBEN LAS


FIGURAS PLANAS
Consideremos las figuras planas cerradas como el rectngulo, y el crculo. Tales figuras comparten caractersticas comunes como es la posicin de la figura,
de su centro, y el rea de la figura, aunque el procedimiento para calcular dicha rea sea completamente
distinto. Podemos por tanto, disear una jerarqua de
clases, tal que la clase base denominada Figura, tenga
las caractersticas comunes y cada clase derivada las
especficas. La relacin jerrquica se muestra en la
figura

La clase Figura es la que contiene las caractersticas


comunes a dichas figuras concretas por tanto, no tiene
forma ni tiene rea. Esto lo expresamos declarando Figura como una clase abstracta, declarando la funcin
miembro area abstract.
PROGRAMACION CON JAVA 2

229

Las clases abstractas


clases base para otras
jetos pertenecientes a
go, se pueden declarar

solamente se pueden usar como


clases. No se pueden crear obuna clase abstracta. Sin embarvariables de dichas clases.

En el juego del ajedrez podemos definir una clase base


denominada Pieza, con las caractersticas comunes a
todas las piezas, como es su posicin en el tablero, y
derivar de ella las caractersticas especficas de cada pieza particular. As pues, la clase Pieza ser una
clase abstracta con una funcin abstract denominada
mover, y cada tipo de pieza definir dicha funcin de
acuerdo a las reglas de su movimiento sobre el tablero.

4.21.1. LA CLASE Figura


La definicin de la clase abstracta Figura,
contiene la posicin x e y de la figura particular, de su centro, y la funcin area, que
se va a definir en las clases derivadas para
calcular el rea de cada figura en particular.
abstract class Figura
{
protected int x;
protected int y;
public Figura(int x, int y)
{
this.x=x;
this.y=y;
}
public abstract double area();
}

4.21.2. LA CLASE Rectangulo


Las clases derivadas heredan los miembros dato x e y de la clase base, y definen la funcin area, declarada abstract en la clase base Figura, ya que cada figura particular tiene una frmula distinta para calcular su
rea. Por ejemplo, la clase derivada Rectangulo, tiene como datos, aparte de su posicin
(x, y) en el plano, sus dimensiones, es decir, su anchura ancho y altura alto.
class Rectangulo extends Figura
{
protected double ancho, alto;
public Rectangulo(int x, int y, double ancho, double alto)
230

Mg. ABRAHAM GAMARRA MORENO

super(x,y);
this.ancho=ancho;
this.alto=alto;

}
public double area()
{
return ancho*alto;
}

La primera sentencia en el constructor de la


clase derivada es una llamada al constructor
de la clase base, para ello se emplea la palabra reservada super. El constructor de la
clase derivada llama al constructor de la
clase base y le pasa las coordenadas del punto x e y. Despus inicializa sus miembros dato ancho y alto.
En la definicin de la funcin area, se calcula el rea del rectngulo como producto de
la anchura por la altura, y se devuelve el
resultado

4.21.3. LA CLASE Circulo


A contiuacin se muestra la clase Circulo
class Circulo extends Figura
{
protected double radio;
public Circulo(int x, int y, double radio)
{
super(x,y);
this.radio=radio;
}
public double area()
{
return Math.PI*radio*radio;
}
}

Como vemos, la primera sentencia en el constructor de la clase derivada es una llamada


al constructor de la clase base empleando la
palabra reservada super. Posteriormente, se
inicializa el miembro dato radio, de la clase
derivada Circulo.
En la definicin de la funcin area, se calcula el rea del crculo mediante la conocida
frmula r2, o bien *r*r. La constante
PROGRAMACION CON JAVA 2

231

Math.PI es una aproximacin decimal del nmero irracional .

4.22. USO DE LA JERARQUA DE CLASES


Creamos un objeto c de la clase Circulo situado en el
punto (0, 0) y de 5.5 unidades de radio. Calculamos y
mostramos el valor de su rea.
Circulo c=new Circulo(0, 0, 5.5);
System.out.println("Area del crculo "+c.area());
Creamos un objeto r de la clase Rectangulo situado en
el punto (0, 0) y de dimensiones 5.5 de anchura y 2
unidades de largo. Calculamos y mostramos el valor de
su rea.
Rectangulo r=new Rectangulo(0, 0, 5.5, 2.0);
System.out.println("Area del rectngulo "+r.area());
Veamos ahora, una forma alternativa, guardamos el valor devuelto por new al crear objetos de las clases
derivadas en una variable f del tipo Figura (clase base).
Figura f=new Circulo(0, 0, 5.5);
System.out.println("Area del crculo "+f.area());
f=new Rectangulo(0, 0, 5.5, 2.0);
System.out.println("Area del rectngulo "+f.area());

4.23. ENLACE DINMICO


En el lenguaje C, los identificadores de la funcin
estn asociados siempre a direcciones fsicas antes de
la ejecucin del programa, esto se conoce como enlace
temprano o esttico. Ahora bien, el lenguaje C++ y Java permiten decidir a que funcin llamar en tiempo de
ejecucin, esto se conoce como enlace tardo o dinmico. Las 4 lneas de cdigo anterior muestran el uso
del enlace dinmico.

232

Mg. ABRAHAM GAMARRA MORENO

Ejemplo(57): Programa completo del uso de la clase Figura.


//Archivo: Figura.java
abstract class Figura
{
protected int x;
protected int y;
public Figura(int x, int y)
{
this.x=x;
this.y=y;
}
public abstract double area();
}

class Circulo extends Figura


{
protected double radio;
public Circulo(int x, int y, double radio)
{
super(x,y);
this.radio=radio;
}

public double area()


{
return Math.PI*radio*radio;
}

class Rectangulo extends Figura


{
protected double ancho, alto;
public Rectangulo(int x, int y, double ancho, double alto)
{
super(x,y);
this.ancho=ancho;
this.alto=alto;
}
public double area()
{
return ancho*alto;
}
}

//Archivo: FiguraApp.java
class FiguraApp
{
public static void main(String[] args)
PROGRAMACION CON JAVA 2

233

//enlace temprano
Circulo c=new Circulo(0, 0, 5.5);
System.out.println("Utilizacion de enlace temprano");
System.out.println("Area del circulo "+c.area());
Rectangulo r=new Rectangulo(0, 0, 5.5, 2.0);
System.out.println("Area del rectangulo "+r.area());
//enlace tardo
System.out.println("Utilizacion de enlace tardio (dinamico)");
Figura f=new Circulo(0, 0, 5.5);
System.out.println("Area del circulo "+f.area());
f=new Rectangulo(0, 0, 5.5, 2.0);
System.out.println("Area del rectangulo "+f.area());
}
}

234

Mg. ABRAHAM GAMARRA MORENO

CAPITULO CINCO
GESTION DE EXCEPCIONES
5.1. LAS EXCEPCIONES ESTNDAR
Los programadores de cualquier lenguaje se esfuerzan
por escribir programas libres de errores, sin embargo,
es muy difcil que los programas reales se vean libres
de ellos. En Java las situaciones que pueden provocar
un fallo en el programa se denominan excepciones.
Java lanza una excepcin en respuesta a una situacin
poco usual. El programador tambin puede lanzar sus
propias excepciones. Las excepciones en Java son objetos de clases derivadas de la clase base Exception.
Existen tambin los errores internos que son objetos
de la clase Error. Ambas clases Error y Exception son
clases derivadas de la clase base Throwable, tal comose muestra en la figura 5.1.
Existe toda una jerarqua de clases derivada de la
clase base Exception. Estas clases derivadas se ubican
en dos grupos principales:
Las excepciones en tiempo de ejecucin ocurren cuando
el programador no ha tenido cuidado al escribir su cdigo. Por ejemplo, cuando se sobrepasa la dimensin de
un array se lanza una excepcin ArrayIndexOutOfBounds.
Cuando se hace uso de una referencia a un objeto que
no ha sido creado se lanza la excepcin NullPointerExPROGRAMACION CON JAVA 2

235

ception. Estas excepciones le indican al programador


que tipos de fallos tiene el programa y que debe arreglarlo antes de proseguir.

Figura 5.1

El segundo grupo de excepciones, es el ms interesante, ya que indican que ha sucedido algo inesperado o
fuera de control.

5.1.1. LAS EXCEPCIONES


En la clase String, se tiene una funcin que
convierte un string en un nmero. Esta funcin es muy usuada cuando creamos applets.
Introducimos el nmero en un control de edicin, se obtiene el texto y se guarda en un
string. Luego, se convierte el string en nmero entero mediante la funcin esttica Integer.parseInt, y finalmente, usamos dicho
nmero.
String str="

12 ";

int numero=Integer.parseInt(str);
Si se introducen caracteres no numricos, o
no se quitan los espacios en blanco al principio y al final del string, mediante la funcin trim, se lanza una excepcin NumberFormatException.
236

Mg. ABRAHAM GAMARRA MORENO

El mensaje que aparece en la ventana nos indica el tipo de excepcin NumberFormatException, la funcin que la ha lanzado Integer.parseInt, que se llama dentro de main.
Objeto no inicializado
Habitualmente, cuando llamamos desde un objeto no inicializado, a una funcin miembro.
public static void main(String[] args)
{
String str;
str.length();
//...
}
El compilador se queja con el siguiente mensaje "variable str might not have been initilized". En otras ocasiones, se lanza una excepcin del tipo NulPointerException. Fijarse
que en la porcin de cdigo que sigue, grafico es una variable de instancia que es inicializada por defecto a null.
class MiCanvas....
{
Grafico grafico;
public void paint(...)
{
grafico.dibuja();
//...
}
//...
}

Como vemos en la porcin de cdigo, si al


llamarse a la funcin paint, el objeto grafico no ha sido inicializado con el valor devuelto por new al crear un objeto de la clase
Grafico o de alguna de sus clases derivadas,
se lanza la excepcin NullPointerException.
Entrada/salida
En otras situaciones el mensaje de error aparece en el momento en el que se compila el
PROGRAMACION CON JAVA 2

237

programa. As, cuando intentamos leer un carcter del teclado, llamamos a la la funcin
System.in.read();
Cuando compilamos el programa, nos aparece un
mensaje de error que no nos deja proseguir.
unreported
exception:
java.io.IOException;
must be caught or declared to be thrown

5.1.2. CAPTURA DE LAS EXCEPCIONES


Empecemos por solucionar el error que se produce en el programa durante la compilacin.
Tal como indica el mensaje que genera el compilador, se ha de poner la sentencia System.in.read(); en un bloque try...catch, del
siguiente modo.
try
{
System.in.read();
}
catch (IOException ex)
{ }

Para solucionar el error que se produce en el


programa durante su ejecucin, se debe poner
la llamada a Integer.parseInt en el siguiente
bloque try...catch.
String str=" 12 ";
int numero;
try
{
numero=Integer.parseInt(str);
}
catch(NumberFormatException ex)
{
System.out.println("No es un nmero");
}

En el caso de que el string str contenga caracteres no numricos como es ste el caso,
el nmero 12 est acompaado de espacios en
blanco, se produce una excepcin del tipo
NumberFormatException que es capturada y se
imprime el mensaje "No es un nmero".
238

Mg. ABRAHAM GAMARRA MORENO

En vez de un mensaje propio se puede imprimir


el objeto ex de la clase NumberFormatException
try
{

//...
}
catch(NumberFormatException ex)
{
System.out.println(ex);
}

La clase base Throwable de todas las clases


que describen las excepciones, redefine la
funcin toString, que devuelve el nombre de
la clase que describe la excepcin acompaado
del mensaje asociado, que en este caso es el
propio string str.
java.lang.NumberFormatException:

12

Podemos extraer dicho mensaje mediante la


funcin miembro getMessage, del siguiente modo
Try
{
//...
}
catch(NumberFormatException ex)
{
System.out.println(ex.getMessage());
}

5.1.3. MANEJANDO VARIAS EXCEPCIONES


Vamos a crear un programa que divida dos nmeros. Supongamos que se introducen dos nmeros, se obtiene el texto de cada uno y se
guardan en dos strings. En esta situacin se
pueden producir dos excepciones NumberFormatException, si se introducen caracteres no
numricos y ArithmeticException si se divide
entre cero.

PROGRAMACION CON JAVA 2

239

Ejemplo (58): Uso de varias excepciones.


//Archivo: ExcepcionApp.java
class ExcepcionApp
{
public static void main(String[] args)
{
String str1="12";
String str2="0";
String respuesta;
int numerador, denominador, cociente;
try
{
numerador=Integer.parseInt(str1);
denominador=Integer.parseInt(str2);
cociente=numerador/denominador;
respuesta=String.valueOf(cociente);
}
catch(NumberFormatException ex)
{
respuesta="Se han introducido caracteres no numericos";
}
catch(ArithmeticException ex)
{
respuesta="Division entre cero";
}
System.out.println(respuesta);
}
}

Como vemos las sentencias susceptibles de


lanzar una excepcin se sitan en un bloque
try...catch. Si el denominador es cero, se
produce una excepcin de la clase ArithmeticException en la expresin que halla el cociente, que es inmediatamente capturada en el
bloque catch que maneja dicha excepcin, ejecutndose las sentencias que hay en dicho
bloque. En este caso se guarda en el string
respuesta el texto "Divisin entre cero".
Hay veces en las que se desea estar seguro de
que un bloque de cdigo se ejecute se produzcan o no excepciones. Se puede hacer esto
aadiendo un bloque finally despus del ltimo catch. Esto es importante cuando accedemos
240

Mg. ABRAHAM GAMARRA MORENO

a archivos, para asegurar que se cerrar


siempre un archivo se produzca o no un error
en el proceso de lectura/escritura.

try
{
//Este cdigo
}catch(Exception
{
//Este cdigo
}finally
{
//Este cdigo
cin
}

puede generar una excepcin


ex)
se ejecuta cuando se produce una excepcin
se ejecuta cuando se produzca o no una excep-

5.2. LAS EXCEPCIONES PROPIAS


El lenguaje Java proporciona las clases que manejan
casi cualquier tipo de excepcin. Sin embargo, podemos
imaginar situaciones en la que producen excepciones
que no estn dentro del lenguaje Java. Siguiendo el
ejemplo de la pgina anterior estudiaremos una situacin en la que el usuario introduce un valor fuera de
un determinado intervalo, el programa lanza un excepcin, que vamos a llamar ExcepcionIntervalo.

5.2.1. LA CLASE QUE DESCRIBE LA EXCEPCIN


Para crear y lanzar una excepcin propia tenemos que definir la clase ExcepcionIntervalo
derivada de la clase base Exception.

public class ExcepcionIntervalo extends Exception


{
public ExcepcionIntervalo(String msg)
{
super(msg);
}
}

La definicin de la clase es muy simple. Se


le pasa un string msg, que contiene un mensaje, en el nico parmetro que tiene el constructor de la clase derivada y ste se lo pasa a la clase base mediante super.
PROGRAMACION CON JAVA 2

241

5.2.2. EL MTODO QUE PUEDE LANZAR UNA EXCEPCIN


La funcin miembro que lanza una excepcin
tiene la declaracin habitual que cualquier
otro mtodo pero se le aade a continuacin
la palabra reservada throws seguido de la excepcin o excepciones que puede lanzar.
static void rango(int num, int den)throws ExcepcionIntervalo
{
if((num>100)||(den<-5))
{
throw new ExcepcionIntervalo("Nmeros fuera del intervalo");
}
}

Cuando el numerador es mayor que 100 y el denominador es menor que 5 se lanza throw una
excepcin, un objeto de la clase ExcepcionIntervalo. Dicho objeto se crea llamando al
constructor de dicha clase y pasndole un
string que contiene el mensaje "Nmeros fuera
del intervalo".

5.2.3. CAPTURA DE LAS EXCEPCIONES


Al programa estudiado en la pgina anterior,
aadimos la llamada a la funcin rango que
verifica si los nmeros estn dentro del intervalo dado, y el bloque catch que captura
la excepcin que puede lanzar dicha funcin
si los nmeros no estn en el intervalo especificado.
Ejemplo (59): Uso de excepciones.
public class ExcepcionApp3
{
public static void main(String[] args)
{
String str1="120";
String str2="3";
String respuesta;
int numerador, denominador, cociente;
242

Mg. ABRAHAM GAMARRA MORENO

try
{

cos";

numerador=Integer.parseInt(str1);
denominador=Integer.parseInt(str2);
rango(numerador, denominador);
cociente=numerador/denominador;
respuesta=String.valueOf(cociente);

}
catch(NumberFormatException ex)
{
respuesta="Se han introducido

caracteres

no

numri-

}
catch(ArithmeticException ex)
{
respuesta="Divisin entre cero";
}
catch(ExcepcionIntervalo ex)
{
respuesta=ex.getMessage();
}
System.out.println(respuesta);

}
valo

static void rango(int num, int den)throws ExcepcionInter{

valo");
}

if((num>100)||(den<-5))
{
throw new ExcepcionIntervalo("Numeros fuera del inter}

Como vemos el numerador que vale 120 tiene un


valor fuera del intervalo especificado en la
funcin rango, por lo que se lanza una excepcin cuando se llega a la llamada a dicha
funcin en el bloque try. Dicha excepcin es
capturada por el bloque catch correspondiente
a dicha excepcin, y se ejecutan las sentencias de dicho bloque. En concreto, se obtiene
mediante getMessage el texto del mensaje que
PROGRAMACION CON JAVA 2

243

guarda el objeto ex de la clase ExcepcionIntervalo.


El ciclo de vida de una excepcin se puede
resumir del siguiente modo:

Se coloca la llamada a la funcin susceptible de producir una excepcin en un


bloque try...catch

En dicha funcin se crea mediante new un


objeto de la clase Exception o derivada
de sta

Se lanza mediante throw el objeto recin


creado

Se captura en el correspondiente bloque


catch

En este bloque se notifica al usuario


esta eventualidad imprimiendo el mensaje
asociado a dicha excepcin, o realizando
una tarea especfica.

5.2.4. UNA FUNCIN QUE QUE PUEDE LANZAR VARIAS EXCEPCIONES


Hay otra alternativa para el ejercicio anterior, que es la de definir una funcin denominada calcular, que devuelva el cociente entre el numerador y el denominador, cuando se
le pasa los strings obtenidos de los respectivos controles de edicin. La funcin calcular, convierte los strings en nmeros enteros, verifica el rango, calcula y devuelve el
cociente entre el numerador y el denominador,

244

Mg. ABRAHAM GAMARRA MORENO

Ejemplo (60): Uso de excepciones.


//Archivo: ExcepcionApp4.java
public class ExcepcionApp4
{
public static void main(String[] args)
{
String str1="220";
String str2="2";
String respuesta;
int numerador, denominador, cociente;
try
{
cociente=calcular(str1, str2);
respuesta=String.valueOf(cociente);
}
catch(NumberFormatException ex)
{
respuesta="Se han introducido caracteres no numricos";
}
catch(ArithmeticException ex)
{
respuesta="Divisin entre cero";
}
catch(ExcepcionIntervalo ex)
{
respuesta=ex.getMessage();
}
System.out.println(respuesta);
}
static
int
calcular(String
str1,
String
str2)throws
ExcepcionIntervalo, NumberFormatException, ArithmeticException
{
int num=Integer.parseInt(str1);
int den=Integer.parseInt(str2);
if((num>100)||(den<-5))
{
throw new ExcepcionIntervalo("Nmeros fuera del intervalo");
}
return (num/den);
}
}

Vemos que la funcin calcular puede lanzar,


throws, tres tipos de excepciones. En el
PROGRAMACION CON JAVA 2

245

cuerpo de la funcin se crea, new, y se lanza, throw, explcitamente un objeto de la


clase ExcepcionIntervalo, definida por el
usuario, e implcitamente se crea y se lanza
objetos de las clases NumberFormatException y
ArithmeticException definidas en el lenguaje
Java.
La sentencia que llama a la funcin calcular
dentro del bloque try puede producir alguna
de las tres excepciones que es capturada por
el correspondiente bloque catch.
Podemos simplificar algo el codigo ahorrndonos la variable temporal cociente, escribiendo en vez de las dos sentencias
cociente=calcular(str1, str2);
respuesta=String.valueOf(cociente);

Una nica sentencia


respuesta=String.valueOf(calcular(str1, str2));

246

Mg. ABRAHAM GAMARRA MORENO

CAPITULO SEIS
PAQUETES
6.1. PAQUETES
Un paquete es un conjunto de clases, lgicamente relacionadas entre s, agrupadas bajo un nombre (por ejemplo, el paquete java.io agrupa las clases que permiten
a un programa realizar la entrada y salida de informacin); incluso, un paquete puede contener a otros paquetes.
Prcticamente son bibliotecas a las que el usuario
puede acceder y que ofrecen varias funciones (mtodos). Los usuarios pueden tambin crear paquetes informticos, por ejemplo, haciendo que contengan todas
las clases que ha definido para poner en marcha algunas funciones que luego usar en varios programas.
Los paquetes son los mdulos de Java. Recipientes que
contienen clases y que se utilizan tanto para mantener
el espacio de nombres dividido en compartimentos ms
manejables como un mecanismo de restriccin de visibilidad. Se pueden poner clases dentro de los paquetes
restringiendo la accesibilidad a stas en funcin de
la localizacin de los otros miembros del paquete. Cada archivo .java tiene las mismas cuatro partes internas y hasta ahora slo hemos utilizado una de ellas en
nuestros ejemplos. Esta es la forma general de un archivo fuente de Java, una nica sentencia de paquete
PROGRAMACION CON JAVA 2

247

(opcional) las sentencias de importacin deseadas (opcional) una nica declaracin de clase pblica las
clases privadas de paquete deseadas (opcional).

6.1.1. LA SENTENCIA PACKAGE (PAQUETE)


Lo primero que se permite en un archivo Java
es una sentencia package, que le dice al compilador en qu paquete se deberan definir
las clases incluidas. Si se omite la sentencia package, las clases terminan en el paquete por defecto, que no tiene nombre. El compilador Java utiliza directorios de sistema
de archivos para almacenar paquetes.
Si se declara que una clase est dentro de un
paquete llamado MiPaquete, entonces el archivo fuente de esa clase se debe almacenar en
un directorio llamado MiPaquete.
Recuerde que se diferencia entre maysculas y
minsculas y que el nombre del directorio debe coincidir con el nombre exactamente. Esta
es la forma general de la sentencia package.
package paq1[ .paq2 [ .paq3 ]];
Observe que se puede crear una jerarqua de
paquetes dentro de paquetes separando los niveles por puntos. Esta jerarqua se debe reflejar en el sistema de archivos de desarrollo de Java. Un paquete declarado como
package java.awt.imagen;
se debe almacenar en java/awt/imagen, en java\awt\imagen o en java:awt:imagen en los
sistemas de archivo UNIX, Windows o Macintosh, respectivamente.

6.1.2. COMPILACIN DE CLASES EN PAQUETES


Cuando se intenta poner una clase en un paquete, el primer problema es que la estructura de directorios debe coincidir con la jerarqua de paquetes exactamente. No se puede
renombrar un paquete sin renombrar el directorio en el cual estn almacenadas las cla248

Mg. ABRAHAM GAMARRA MORENO

ses. El otro problema que presenta la compilacin es ms sutil.


Cuando desee llamar a una clase que se
encuentre en un paquete deber prestar
atencin a su ubicacin en la jerarqua de
paquetes. Por ejemplo, si se crea una clase
llamada PaquetePrueba en un paquete llamado
prueba. Para ello se crea el directorio
llamado
prueba
y
se
pone
en
l
PaquetePrueba.java y se compila. Si intenta
ejecutarlo, el intrprete no lo encontrar.
Esto se debe a que esta clase se encuentra
ahora en un paquete llamado prueba y no nos
podemos referir a ella simplemente con
PaquetePrueba, sin embargo si es posible
referirse a cualquier paquete enumerando su
jerarqua de paquetes, separando los paquetes
por puntos. Por lo tanto, si intenta ejecutar
ahora
Java
con
prueba.PaquetePrueba,
el
intrprete tampoco lo encontrar.
El motivo de este nuevo fracaso se encuentra
en la variable CLASSPATH. Probablemente contenga algo parecido a ".;C:\java\classes" que
le dice al intrprete que busque en el directorio de trabajo actual y en el directorio de
instalacin del Equipo de herramientas de desarrollo de Java estndar. El problema es que
no hay un directorio prueba en el directorio
de trabajo actual porque usted ya est en el
directorio prueba. Tiene dos opciones en este
momento: cambiar de directorio un nivel arriba y ejecutar "java prueba.PaquetePrueba"3, o
aadir el extremo de su jerarqua de clases
de desarrollo a la variable de entorno CLASSPATH. Despus podr utilizar "java prueba.PaquetePrueba" desde cualquier directorio
y Java encontrar el archivo .class adecuado.
Si trabaja con su cdigo fuente en un directorio llamado C:\mijava, d a CLASSPATH el
valor ".;C:\mijava;C:\java\classes".
Para realizar modificaciones de CLASSPATH en
el JCreator, que nos permita definir la ubicacin de nuestros paquetes, debemos hacerlo
utilizando Configure, Options, JDK Profiles,
3

La ejecucin de la clase Paquete.Prueba se realiza desde la lnea de comandos del DOS.


PROGRAMACION CON JAVA 2
249

Edit, Add; tal como se muestra en la figura


5.1.

Figura 6.1.

6.1.3. LA SENTENCIA IMPORT


Lo siguiente que se pone despus de una sentencia package y antes de las definiciones de
clase en un archivo fuente en Java puede ser
una lista de sentencias import. Todas las
clases interesantes estn almacenadas en algn paquete con nombre. Para no tener que introducir el largo nombre de trayecto de paquete para cada clase, Java incluye la sentencia import para que se puedan ver ciertas
250

Mg. ABRAHAM GAMARRA MORENO

clases o paquetes enteros. La forma general


de la sentencia import:
import paquete1.[ paquete2 ].( nombre_clase | * );

paquete1 es el nombre de un paquete de alto


nivel, paquete2 es el nombre de un paquete
opcional contenido en el paquete exterior separado por un punto (.). No hay ningn lmite
prctico a la profundidad de la jerarqua de
paquetes.
Finalmente, nombre_clase explcito o un asterisco (*) que indica que el compilador Java
debera buscar este paquete completo.
import java.util.Date;
import java.io.*;

6.1.4. PROTECCIN DE ACCESOS


Java proporciona unos cuantos mecanismos para
permitir un control de acceso entre clases en
circunstancias diferentes.
Las tablas siguientes muestran el nivel de
acceso que est permitido a cada uno de los
especificadores:

PROGRAMACION CON JAVA 2

Nivel de Clase
acceso

Subclase
paquete
(clase
derivada)

todos

private

No

No

No

protected

No

public

package

No

No

251

Un miembro declarado en una clase como:


Puede ser
sin modificaaccedido Private dor (default: protected public
desde
package)
Su misma
clase

Cualquier
Clase o
subclase del
mismo paquete

no

Cualquier
subclase de
otro paquete.

no

no

Cualquier
clase de otro
paquete.

no

no

no

Una gua de uso indicara tener en cuenta lo


siguiente:
Usar private para mtodos y variables que
solamente se utilicen dentro de la clase y
que
deberan
estar
ocultas para todo el
resto.
Usar public para mtodos, constantes y
otras variables importantes que deban ser visibles para todo el mundo.
Usar protected si se quiere que las clases
del mismo paquete puedan tener acceso a estas
variables o mtodos.
Usar la sentencia package para poder agrupar las clases en paquetes.
No usar nada, dejar la visibilidad por defecto (default, package) para mtodos y variables que deban estar ocultas fuera del paquete, pero que deban estar disponibles al
acceso desde dentro del mismo paquete. Utilizar protected en su lugar si se quiere que
esos componentes sean visibles fuera del paquete.

252

Mg. ABRAHAM GAMARRA MORENO

6.1.5. LOS PAQUETES ESTNDAR


Paquete

Descripcin
Contiene las clases necesarias para crear
java.applet applets que se ejecutan en la ventana del
navegador
Contiene clases para crear una aplicacin
java.awt
GUI independiente de la plataforma
Entrada/Salida. Clases que definen disjava.io
tintos flujos de datos
Contiene clases esenciales, se importa
java.lang impcitamente sin necesidad de una sentencia import.
Se usa en combinacin con las clases del
java.net
paquete java.io para leer y escribir datos en la red.
Contiene otras clases tiles que ayudan
java.util
al programador

6.2. EJEMPLOS DE USO DE PAQUETES


Ejemplo (61): El presente ejemplo permite asignar la
clase Leer al paquete LeerDatos. La clase Leer permite
obtener tipos de datos primitivos desde el teclado.
Para la implementacin debemos considerrar que el archivo Leer.java debe estar en la carpeta LeerDatos (el
mismo nombre del paquete), dentro del directorio actual.
//Archivo Leer.java
// Debe estar en la carpeta LeerDatos dentro del
// directorio activo
package LeerDatos;
import java.io.*;
public class Leer
{
public static String dato()
{
String sdato = "";
try
{
// Definir un flujo de caracteres de entrada: flujoE
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
// Leer. La entrada finaliza al pulsar la tecla Entrar
PROGRAMACION CON JAVA 2

253

sdato = flujoE.readLine();
}
catch(IOException e)
{
System.err.println("Error: " + e.getMessage());
}
return sdato; // devolver el dato tecleado

public static short datoShort()


{
try
{
return Short.parseShort(dato());
}
catch(NumberFormatException e)
{
return Short.MIN_VALUE; // valor ms pequeo
}
}
public static int datoInt()
{
try
{
return Integer.parseInt(dato());
}
catch(NumberFormatException e)
{
return Integer.MIN_VALUE; // valor ms pequeo
}
}
public static long datoLong()
{
try
{
return Long.parseLong(dato());
}
catch(NumberFormatException e)
{
return Long.MIN_VALUE; // valor ms pequeo
}
}
public static float datoFloat()
{
try
{
Float f = new Float(dato());
return f.floatValue();
}
catch(NumberFormatException e)
{
return Float.NaN; // No es un Nmero; valor float.
}
}
254

Mg. ABRAHAM GAMARRA MORENO

public static double datoDouble()


{
try
{
Double d = new Double(dato());
return d.doubleValue();
}
catch(NumberFormatException e)
{
return Double.NaN; // No es un Nmero; valor double.
}
}

El archivo LecturaDatos.java debe estar un


nivel arriba, en el rbol de carpetas con
respecto a la carpeta LeerDatos.

Aqu se encuentra
LecturaDatos.java

Aqu se encuentra
Leer.java

//Archivo: LecturaDatos.java
// Utiliza la clase Leer que debe de estar almacenada
// en la carpeta LeerDatos (pauete LeerDatos)
import LeerDatos.*;
class LecturaDatos
{
public static void main(String[] args)
{
short dato_short = 0;
int dato_int = 0;
long dato_long = 0;
float dato_float = 0;
double dato_double = 0;
System.out.print("Dato short: ");
dato_short = Leer.datoShort();
System.out.print("Dato int: ");
dato_int = Leer.datoInt();
System.out.print("Dato long: ");
dato_long = Leer.datoLong();
System.out.print("Dato float: ");
dato_float = Leer.datoFloat();
System.out.print("Dato double: ");
dato_double = Leer.datoDouble();
PROGRAMACION CON JAVA 2

255

256

System.out.println(dato_short);
System.out.println(dato_int);
System.out.println(dato_long);
System.out.println(dato_float);
System.out.println(dato_double);

Mg. ABRAHAM GAMARRA MORENO

CAPITULO SIETE
INTERFACES
7.1. QU ES UN INTERFACE?
Una interface Java es un dispositivo que permite interactuar a objetos no relacionados entre s. Las interfaces Java en realidad definen un conjunto de mensajes que se puede aplicar a muchas clases de objetos,
a los que cada una de ellas debe responder de forma
adecuada.
Un interface es una coleccin de declaraciones de mtodos (sin definirlos) y tambin puede incluir constantes.
Runnable es un ejemplo de interface en el cual se declara, pero no se implemementa, una funcin miembro
run.
[public] interface Runnable
{
public abstract void run();
}

El modificador de acceso public indica que la Interfaz


puede ser utilizada por cualquier clase de cualquier
paquete.
PROGRAMACION CON JAVA 2

257

Las clases que implementen (implements) el interface


Runnable han de definir obligatoriamente la funcin
run.
class Animacion implements Runnable
{
//..
public void run()
{
//define la funcin run
}
}

El papel del interface es el de describir algunas de


las caractersticas de una clase. Por ejemplo, el
hecho de que una persona sea un futbolista no define
su personalidad completa, pero hace que tenga ciertas
caractersticas que las distinguen de otras.
Clases que no estn relacionadas pueden implementar el
interface Runnable, por ejemplo, una clase que describa una animacin, y tambin puede implementar el interface Runnable una clase que realice un clculo intensivo.

7.2. DIFERENCIAS ENTRE


CLASE ABSTRACTA

UN

INTERFACE

UNA

Un interface es simplemente una lista de mtodos no


implementados, adems puede incluir la declaracin de
constantes. Una clase abstracta puede incluir mtodos
implementados y no implementados o abstractos, miembros dato, constantes y otros no constantes.
Ahora bien, la diferencia es mucho ms profunda. Imaginemos que Runnable fuese una clase abstracta. Un applet descrito por la clase MiApplet que moviese una
figura por su rea de trabajo, derivara a la vez de
la clase base Applet (que describe la funcionalidad
mnima de un applet que se ejecuta en un navegador) y
de la clase Runnable. Pero el lenguaje Java no tiene
herencia mltiple.
En el lenguaje Java la clase MiApplet deriva de la
clase base Applet e implementa el interface Runnable.

258

Mg. ABRAHAM GAMARRA MORENO

class MiApplet extends Applet implements Runnable


{
//...
//define la funcin run del interface
public void run()
{
//...
}
//redefine paint de la clase base Applet
public void paint(Graphics g)
{
//...
}
//define otras funciones miembro
}

Una clase solamente puede derivar extends de una clase


base, pero puede implementar varios interfaces. Los
nombres de los interfaces se colocan separados por una
coma despus de la palabra reservada implements.
El lenguaje Java no fuerza por tanto, una relacin jerrquica, simplemente permite que clases no relacionadas puedan tener algunas caractersticas de su comportamiento similares.

7.3. LOS INTERFACES Y EL POLIMORFISMO


En el lenguaje C++, es posible la herencia mltiple,
pero este tipo de herencia presenta dificultades. Por
ejemplo, cuando dos clases B y C derivan de una clase
base A, y a su vez una clase D deriva de B y C. Este
problema es conocido con el nombre de diamante.

En el lenguaje Java solamente existe la


herencia simple, pero las clases pueden implementar interfaces. Vamos a ver en este
PROGRAMACION CON JAVA 2

259

apartado que la importancia de los interfaces


no estriba en resolver los problemas inherentes a la herencia mltiple sin forzar relaciones jerrquicas, sino es el de incrementar
el polimorfismo del lenguaje ms all del que
proporciona la herencia simple.

7.3.1. HERENCIA SIMPLE


Creamos una clase abstracta denominada Animal
de la cual deriva las clases Gato y Perro.
Ambas clases redefinen la funcin habla declarada abstracta en la clase base Animal.
Ejemplo (62): Clase abstracta y Herencia simple.
//Archivo Animal.java
package polimorfismo;
public abstract class Animal
{
public abstract void habla();
}
class Perro extends Animal
{
public void habla()
{
System.out.println("Guau!");
}
}
class Gato extends Animal
{
public void habla()
{
System.out.println("Miau!");
}
}

El polimorfismo nos permite pasar la referencia a un objeto de la clase Gato a una funcin hazleHablar que conoce al objeto por su
clase base Animal
//Archivo: PoliApp.java
package polimorfismo;
public class PoliApp
{
260

Mg. ABRAHAM GAMARRA MORENO

public static void main(String[] args)


{
Gato gato=new Gato();
hazleHablar(gato);

static void hazleHablar(Animal sujeto)


{
sujeto.habla();
}

El compilador no sabe exactamente que objeto


se le pasar a la funcin hazleHablar en el
momento de la ejecucin del programa. Si se
pasa un objeto de la clase Gato se imprimir
Miau!, si se pasa un objeto de la clase Perro se imprimir Guau!. El compilador solamente sabe que se le pasar un objeto de alguna clase derivada de Animal. Por tanto, el
compilador no sabe que funcin habla ser
llamada en el momento de la ejecucin del
programa.
El polimorfismo nos ayuda a hacer el programa
ms flexible, por que en el futuro podemos
aadir nuevas clases derivadas de Animal, sin
que cambie para nada el mtodo hazleHablar.
Como ejercicio, se sugiere al lector aadir
la clase Pajaro a la jerarqua, y pasar un
objeto de dicha clase a la funcin hazleHablar para que se imprima pio, pio, pio ..!.

7.3.2. INTERFACES
Vamos a crear un interface denominado Parlanchin que contenga la declaracin de una funcin denominada habla.
public interface Parlanchin
{
public abstract void habla();
}

PROGRAMACION CON JAVA 2

261

Hacemos que la jerraqua de clases que deriva


de Animal implemente el interface Parlanchin
public abstract class Animal1 implements Parlanchin
{
public abstract void habla();
}
class Perro extends Animal1
{
public void habla()
{
System.out.println("Guau!");
}
}
class Gato extends Animal1
{
public void habla()
{
System.out.println("Miau!");
}
}

Ahora veamos otra jerarqua de clases completamente distinta, la que deriva de la clase
base Reloj. Una de las clases de dicha jerarqua Cucu implementa el interface Parlanchin
y por tanto, debe de definir obligatoriamente
la funcin habla declarada en dicho interface.
public abstract class Reloj
{
}
class Cucu extends Reloj implements Parlanchin
{
public void habla()
{
System.out.println("Cucu, cucu, ..!");
}
}

Definamos la funcin hazleHablar de modo que


conozca al objeto que se le pasa no por una
clase base, sino por el interface Parlanchin.
A dicha funcin le podemos pasar cualquier
objeto que implemente el interface Parlanchin, este o no en la misma jerarqua de clases.
public class PoliApp
{
262

Mg. ABRAHAM GAMARRA MORENO

public static void main(String[] args)


{
Gato gato=new Gato();
hazleHablar(gato);
Cucu cucu=new Cucu();
hazleHablar(cucu);
}

static void hazleHablar(Parlanchin sujeto)


{
sujeto.habla();
}

Al ejecutar el programa, veremos que se imprime en la consola Miau!, por que a la funcin hazleHablar se le pasa un objeto de la
clase Gato, y despus Cucu, cucu, ..! por
que a la funcin hazleHablar se le pasa un
objeto de la clase Cucu.
Si solamente hubiese herencia simple, Cucu
tendra que derivar de la clase Animal (lo
que no es lgico) o bien no se podra pasar a
la funcin hazleHablar. Con interfaces, cualquier clase en cualquier familia puede implementar el interface Parlanchin, y se podr
pasar un objeto de dicha clase a la funcin
hazleHablar. Esta es la razn por la cual los
interfaces proporcionan ms polimorfismo que
el que se puede obtener de una simple jerarqua de clases.

Ejemplo (63): Programa completo de la interface Parlanchin


//Archivo: Parlanchin.java
public interface Parlanchin
{
public abstract void habla();
}

//Archivo Animal1.java
public abstract class Animal1 implements Parlanchin
{
public abstract void habla();
}
PROGRAMACION CON JAVA 2

263

class Perro extends Animal1


{
public void habla()
{
System.out.println("Guau!");
}
}
class Gato extends Animal1
{
public void habla()
{
System.out.println("Miau!");
}
}

//archivo: Reloj.java
public abstract class Reloj
{
}
class Cucu extends Reloj implements Parlanchin
{
public void habla()
{
System.out.println("Cucu, cucu, ..!");
}
}

//Archivo: PoliApp1.java
public class PoliApp1
{
public static void main(String[] args)
{
Gato gato=new Gato();
System.out.println("Uso de hazlehablar() con el el objeto
gato:\n");
hazleHablar(gato);
Cucu cucu=new Cucu();
System.out.println("Uso de hazlehablar() con el el objeto
cucu:\n");
hazleHablar(cucu);
}

}
264

static void hazleHablar(Parlanchin sujeto)


{
sujeto.habla();
}
Mg. ABRAHAM GAMARRA MORENO

PROGRAMACION CON JAVA 2

265

CAPITULO OCHO
ENTRADA/SALIDA PARA EL MANEJO DE
ARCHIVOS
8.1. ARCHIVOS Y DIRECTORIOS
8.1.1. LA CLASE FILE
Antes de proceder al estudio de las clases
que describen la entrada/salida vamos a estudiar la clase File, que nos proporciona informacin acerca de los archivos, de sus
atributos, de los directorios, etc. Tambin
explicaremos como se crea un filtro mediante
el interface FilenameFilter para obtener la
lista de los archivos que tengan por ejemplo,
la extensin .java.
La clase File tiene tres constructores

File(String path)

File(String path, String name)

File(File dir, String name)

El parmetro path indica el camino hacia el


directorio donde se encuentra el archivo, y
name indica el nombre del archivo. Los mtoPROGRAMACION CON JAVA 2

267

dos ms importantes que describe esta clase


son los siguientes:

String getName()

String getPath()

String getAbsolutePath()

boolean exists()

boolean canWrite()

boolean canRead

boolean isFile()

boolean isDirectory()

boolean isAbsolute()

long lastModified()

long length()

boolean mkdir()

boolean mkdirs()

boolean renameTo(File dest);

boolean delete()

String[] list()

String[] list(FilenameFilter filter)

Mediante un ejemplo explicaremos algunos de


los mtodos de la clase File.
Creamos un objeto fichero de la clase File,
pasndole el nombre del archivo, en este caso, el nombre del archivo cdigo fuente ArchivoApp1.java.
File fichero=new File("ArchivoApp1.java");

268

Mg. ABRAHAM GAMARRA MORENO

Si este archivo existe, es decir, si la funcin exists devuelve true, entonces se obtiene informacin acerca del archivo:

getName devuelve el nombre del archivo

getPath devuelve el camino relativo

getAbsolutePath devuelve el camino absoluto.

canRead nos indice si el archivo se puede leer.

canWrite nos indica


puede escribir

length nos devuelve el tamao del archivo, si dividimos la cantidad devuelta


entre 1024 obtenemos el tamao del archivo en KB.

if(fichero.exists())
{
System.out.println("Nombre
"+fichero.getName());
System.out.println("Camino
"+fichero.getPath());
System.out.println("Camino
"+fichero.getAbsolutePath());
System.out.println("Se
"+fichero.canRead());
System.out.println("Se
"+fichero.canWrite());
System.out.println("Tamao
}

si

el

archivo

del

se

archivo

absoluto
puede

escribir

puede

leer

"+fichero.length());

La salida del programa es la siguiente:


Nombre del arachivo
Camino
Camino absoluto
Se puede escribir
Se puede leer
Tamao

PROGRAMACION CON JAVA 2

ArchivoApp1.java
ArchivoApp1.java
c:\JBuilder2\myNumerico\archivo1\ArchivoApp1.java
true
true
1366

269

Para obtener la lista de los archivos del directorio actual se crea un nuevo objeto de la
clase File
fichero=new File(".");
Para obtener la lista de los archivos que
contiene este directorio se llama a la funcin miembro list, la cual nos devuelve un
array de strings.
String[] listaArchivos=fichero.list();
for(int i=0; i<listaArchivos.length; i++)
{
System.out.println(listaArchivos[i]);
}

La salida es la siguiente
archivo1.jpr
archivo1.html
ArchivoApp1.java
ArchivoApp1.~jav
Filtro.java
Filtro.~jav

8.1.2. CREACIN DE UN FILTRO


Un filtro es un objeto de una clase que implemente el interface FilenameFilter, y tiene
que redefinir la nica funcin del interface
denominada accept. Esta funcin devuelve un
dato de tipo boolean. En este caso, la hemos
definido de forma que si el nombre del archivo termina con una determinada extensin devuelve true en caso contrario devuelve false.
La funcin endsWith de la clase String realiza esta tarea tal como se ve en la porcin de
cdigo que viene a continuacin. La extensin
se le pasa al constructor de la clase Filtro
para inicializar el miembro dato extension.
import java.io.*;
public class Filtro implements FilenameFilter
{
String extension;
Filtro(String extension)
{
this.extension=extension;
}
270

Mg. ABRAHAM GAMARRA MORENO

public boolean accept(File dir, String name)


{
return name.endsWith(extension);
}

Para obtener la lista de archivos con extensin .java en el directorio actual, creamos
un objeto de la clase Filtro y se lo pasamos
a la funcin list miembro de la clase File.
listaArchivos=fichero.list(new Filtro(".java"));
for(int i=0; i<listaArchivos.length; i++)
{
System.out.println(listaArchivos[i]);
}

La salida es ahora la siguiente


ArchivoApp1.java
Filtro.java

Ejemplo (64): Programa completo para el uso de la clase File y Filtro.


//Archivo: Filtro.java
import java.io.*;
public class Filtro implements FilenameFilter
{
String extension;
Filtro(String extension)
{
this.extension=extension;
}

public boolean accept(File dir, String name)


{
return name.endsWith(extension);
}

//Archivo: ArchivoApp1.java
import java.io.*;
public class ArchivoApp1
PROGRAMACION CON JAVA 2

271

public static void main(String[] args)


{
File fichero=new File("ArchivoApp1.java");
if(fichero.exists())
{
System.out.println("Nombre
del
archivo
"+fichero.getName());
System.out.println("Camino
"+fichero.getPath());
System.out.println("Camino
absoluto
"+fichero.getAbsolutePath());
System.out.println("Se
puede
escribir
"+fichero.canRead());
System.out.println("Se
puede
leer
"+fichero.canWrite());
System.out.println("Tamao
"+fichero.length());
//para calcular el tamao del archivo en KB se divide entre
1024
System.out.println(" ******* lista de los archivos de
este directorio *******");
fichero=new File(".");
String[] listaArchivos=fichero.list();
for(int i=0; i<listaArchivos.length; i++)
{
System.out.println(listaArchivos[i]);
}
System.out.println(" ******* lista de los archivos con
filtro *******");
listaArchivos=fichero.list(new Filtro(".txt"));
for(int i=0; i<listaArchivos.length; i++)
{
System.out.println(listaArchivos[i]);
}

272

Mg. ABRAHAM GAMARRA MORENO

8.2. FLUJOS DE DATOS


Todos los datos fluyen a travs del ordenador desde
una entrada hacia una salida. Este flujo de datos se
denomina tambin stream. Hay un flujo de entrada (fig.
input stream) que manda los datos desde el exterior
(normalmente el teclado) del ordenador, y un flujo de
salida (output stream) que dirige los datos hacia los
dispositivos de salida (la pantalla o un archivo).

PROGRAMACION CON JAVA 2

273

El proceso para leer o escribir datos consta de tres


pasos

Abrir el flujo de datos

Mientras exista ms informacin (leer o escribir)


los datos

Cerrar el flujo de datos

8.2.1. LAS JERARQUAS DE CLASES


En el lenguaje Java los flujos de datos se
describen mediante clases que forman jerarquas segn sea el tipo de dato char Unicode
de 16 bits o byte de 8 bits. A su vez, las
clases se agrupan en jerarquas segn sea su
funcin de lectura o de escritura.
La caracterstica de internacionalizacin del
lenguaje Java es la razn por la que existe
una jerarqua separada de clases para la lectura y escritura de caracteres.
Todas estas clases se encuentran en el
paquete java.io, por lo que al principio del
cdigo fuente tendremos que escribir la sentencia
import java.io.*;

274

Mg. ABRAHAM GAMARRA MORENO

char Unicode, 16 bits

byte, 8 bits.

PROGRAMACION CON JAVA 2

275

Reader y Writer son las clases bases de la


jerarqua para los flujos de caracteres. Para
leer o escribir datos binarios tales como
imgenes o sonidos, se emplea otra jerarqua
de clases cuyas clases base son InputStream y
OutputStream.

8.2.2. LECTURA
Las clases Reader e InputStream son similares
aunque se refieren a distintos tipos de
datos,
lo
mismo
ocurre
con
Writer
y
OutputSream.
Por ejemplo, Reader proporciona tres mtodos
para leer un carcter char o un array de caracteres
int read()
int read(char buf[])
int read(char buf[], int offset, int len)
InputStream proporciona mtodos similares para leer un byte o un array de bytes.
int read()
int read(byte buf[])
int read(byte buf[], int offset, int len)
La primera versin lee un byte como entero
del flujo de entrada, devuelve 1 si no hay
ms datos que leer. La segunda versin, lee
un array de bytes devolviendo el nmero de
bytes ledos. La tercera versin, lee tambin, un array de bytes, pero nos permite especificar, la posicin de comienzo del array
en la que se empiezan a guardar los bytes, y
el mximo nmero de bytes que se van a leer.
Dichas clases definen otras funciones miembro
que no estudiaremos de momento.

276

Mg. ABRAHAM GAMARRA MORENO

8.2.3. ESCRITURA
La clase Writer proporciona tres mtodos para
escribir un carcter char o un array de caracteres
int write(int c)
int write(char buf[])
int write(char buf[], int offset, int len)
La clase OutputStream proporciona mtodos similares
int write(int c)
int write(byte buf[])
int write(byte buf[], int offset, int len)

8.3. ENTRADA/SALIDA ESTNDAR


8.3.1. LOS OBJETOS SYSTEM.IN Y SYSTEM.OUT
La entrada/salida estndar (normalmente el
teclado y la pantalla, respectivamente) se
definen mediante dos objetos que puede usar
el programador sin tener que crear flujos especficos.
La clase System tiene un miembro dato denominado in que es una instancia de la clase InputStream que representa al teclado o flujo
de entrada estndar. Sin embargo, el miembro
out de la clase System es un objeto de la
clase PrintStream, que imprime texto en la
pantalla (la salida estndar).
Para leer un carcter solamente tenemos que
llamar a la funcin read desde System.in.
try
{

System.in.read();
}catch (IOException ex) {

PROGRAMACION CON JAVA 2

277

Obligatoriamente, el proceso de lectura ha de


estar en un bloque try..catch.
Esta porcin de cdigo se puede emplear para
detener la ejecucin de una aplicacin hasta
que se pulse la tecla RETORNO.
Para leer un conjunto de caracteres hasta que
se pulse la tecla RETORNO escribimos
StringBuffer str=new StringBuffer();
char c;
try
{
while ((c=(char)System.in.read())!='\n')
{
str.append(c);
}
}catch(IOException ex){}

La clase StringBuffer es una clase que nos


permite crear strings. Contiene mtodos para
aadir nuevos caracteres a un buffer y convertir el resultado final en un string. Las
principales funciones miembro son insert y
append. Usamos una versin de esta ltima
funcin para aadir un carcter al final de
un objeto de la clase StringBuffer.
Para convertir un objeto str de la clase
StringBuffer a String se usa la funcin miembro toString. Esta llamada se hace de forma
implcita cuando dicho objeto se le pasa a
System.out.println.
System.out.println(str);
Finalmente, se ha de hacer notar, que la
funcin read miembro de InputStream devuelve
un int que es promocionado a char.

8.3.2. LA CLASE READER


Existe la posibilidad de conectar el objeto
System.in con un objeto de la clase InputStreamReader para leer los caracteres tecleados por el usuario.
Esta conexin se realiza mediante la sentencia
278

Mg. ABRAHAM GAMARRA MORENO

Reader entrada=new InputStreamReader(System.in);

Para leer una sucesin de caracteres se emplea un cdigo similar (Vea el archivo TecladoApp2.java)
StringBuffer str=new StringBuffer();
char c;
try
{
Reader entrada=new InputStreamReader(System.in);
while ((c=(char)entrada.read())!='\n')
{
str.append(c);
}
}catch(IOException ex){}

Para imprimir los carcteres ledos se escribe


como en la seccin anterior
System.out.println(str);
Ejemplo (65): Programa completo para el uso de read.
//Archivo TecladoApp2.java
import java.io.*;
public class TecladoApp2
{
public static void main(String[] args)
{
StringBuffer str=new StringBuffer();
char c;
System.out.println("Ingrese cadena: ");
try
{
Reader entrada=new InputStreamReader(System.in);
//
while ((c=(char)System.in.read())!='\n'){
while ((c=(char)entrada.read())!='\n')
{
str.append(c);
}
}
catch(IOException ex)
{}
System.out.println(str);
try
{
//espera la pulsacin de una tecla y luego RETORNO
System.in.read();
}catch (Exception e) { }
}
}
PROGRAMACION CON JAVA 2

279

Podemos usar la segunda versin de la funcin


read para leer el conjunto de caracteres tecleados por el usuario. (Vea el archivo TecladoApp1.java)
char[] buffer=new char[255];
try
{
Reader entrada=new InputStreamReader(System.in);
int numBytes=entrada.read(buffer);
System.out.println("Nmero de bytes ledos "+numBytes);
}catch(IOException ex){
}

En esta segunda porcin de cdigo, se lee


conjunto de caracteres hasta que se pulsa
tecla RETORNO, los caracteres se guardan
el array buffer. La funcin read devuelve
nmero de caracteres ledos.

un
la
en
el

Para imprimir los caracteres ledos se crea


un objeto str de la clase String a partir de
un array de caracteres buffer, empleando uno
de los contructores de dicha clase. A
continuacin, se imprime el string str.
String str=new String(buffer);
System.out.println(str);
Ejemplo (66): Programa completo para el uso de read
(versin 2).
//archivo: TecladoApp1.java
import java.io.*;
public class TecladoApp1
{
public static void main(String[] args)
{
char[] buffer=new char[255];
280

Mg. ABRAHAM GAMARRA MORENO

System.out.println("Introduce una linea de texto y pulsa


RETORNO ");
try
{
Reader entrada=new InputStreamReader(System.in);
int numBytes=entrada.read(buffer);
System.out.println("Numero de bytes leidos "+numBytes);
}catch(IOException ex)
{
System.out.println("Error entrada/salida");
}
System.out.println("La linea de texto que has escrito es
");
String str=new String(buffer);
System.out.println(str);
try
{
//espera la pulsacin de una tecla y luego RETORNO
System.in.read();
}catch (Exception e)
{ }
}
}

8.4. ENTRADA/SALIDA A UN ARCHIVO EN DISCO


8.4.1. LECTURA DE UN ARCHIVO
El proceso de lectura de un archivo de texto
es similar a la lectura desde el dispositivo
estndar. Creamos un objeto entrada de la
clase FileReader en vez de InputStreamReader.
El final del archivo viene dado cuando la
funcin read devuelve -1. El resto del cdigo
es similar.
FileReader entrada=null;
StringBuffer str=new StringBuffer();
PROGRAMACION CON JAVA 2

281

try
{
entrada=new FileReader("mensaje.txt");
int c;
while((c=entrada.read())!=-1)
{
str.append((char)c);
}
}catch (IOException ex) {}

Para mostrar el archivo de texto en la pantalla del monitor, se imprime el contenido del
objeto str de la clase StringBuffer.
System.out.println(str);
Una vez concludo el proceso de lectura, es
conveniente cerrar el flujo de datos, esto se
realiza en una clasula finally que siempre
se llama independientemente de que se produzcan o no errores en el proceso de lectura/escritura.
finally
{
if(entrada!=null)
{
try
{
entrada.close();
}catch(IOException ex){}
}
}

El cdigo completo de este ejemplo es el siguiente:


Ejemplo (67): Programa completo para la lectura de un archivo de texto.
// Archivo: ArchivoApp2.java
import java.io.*;
public class ArchivoApp2
{
public static void main(String[] args)
{
FileReader entrada=null;
StringBuffer str=new StringBuffer();

282

Mg. ABRAHAM GAMARRA MORENO

try
{
entrada=new FileReader("mensaje.txt");
int c;
while((c=entrada.read())!=-1)
{
str.append((char)c);
}
System.out.println(str);
System.out.println("-------------------------------

-------");
}catch (IOException ex)
{
System.out.println(ex);
}
finally
{
//cerrar los flujos de datos
if(entrada!=null)
{
try
{
entrada.close();
}catch(IOException ex){}
}
System.out.println("el bloque
ejecuta");
}
}
}

finally

siempre

se

8.4.2. LECTURA/ESCRITURA
Los pasos para leer y escribir en disco son
los siguientes:

Se crean dos objetos de las clases FileReader y FileWriter, llamando a los respectivos constructores a los que se les
pasa los nombres de los archivos o bien,
objetos de la clase File, respectivamente

entrada=new FileReader("mensaje.txt");
salida=new FileWriter("copia.txt");

PROGRAMACION CON JAVA 2

Se lee mediante read los caracteres del


flujo de entrada, hasta llegar al final
(la funcin read devuelve entonces -1),
y se escribe dichos caracteres en el
flujo de salida mediante write.
283

while((c=entrada.read())!=-1)
{
salida.write(c);
}

Finalmente, se cierran ambos flujos llamando a sus respectivas funciones close


en bloques try..catch

entrada.close();
salida.close();

El cdigo completo de este ejemplo que crea


un archivo copia del original, es el siguiente:
Ejemplo (68): Programa completo para realizar
la copia de un archivo de texto a otro.
// Archivo: ArchivoApp3.java
import java.io.*;
public class ArchivoApp3
{
public static void main(String[] args)
{
FileReader entrada=null;
FileWriter salida=null;
//FileInputStream entrada=null;
//FileOutputStream salida=null;
try
{

entrada=new FileReader("mensaje.txt");
salida=new FileWriter("copia.txt");
//entrada=new FileInputStream("mensaje.txt");
//salida=new FileOutputStream("copia.txt");
int c;
while((c=entrada.read())!=-1)
{
salida.write(c);
}

}
catch (IOException ex)
{
System.out.println(ex);
}
finally
{
//cerrar los flujos de datos
if(entrada!=null)
{
try
{
entrada.close();
284

Mg. ABRAHAM GAMARRA MORENO

ejecuta");
}
}
}

}catch(IOException ex){}
}
if(salida!=null)
{
try
{
salida.close();
}catch(IOException ex){}
}
System.out.println("el bloque

finally

siempre

se

Cuando se trate de leer y escribir datos binarios se sustituye FileReader por FileInputStream y FileWriter por FileOutputStream.
De hecho, si se realiza esta sustitucin en
el cdigo fuente de este ejemplo, los resultados no cambian.

8.5. LEER Y ESCRIBIR DATOS PRIMITIVOS


8.5.1. LOS FLUJOS DE DATOS DATAINPUTSTREAM Y
DATAOUTPUTSTREAM
La clase DataInputStream es til para leer
datos del tipo primitivo de una forma portable. Esta clase tiene un slo constructor que
toma un objeto de la clase InputStream o sus
derivadas como parmetro.
Se crea un objeto de la clase DataInputStream
vinculndolo a un objeto FileInputStream para
leer desde un archivo en disco denominado pedido.txt.
FileInputStream fileIn=new FileInputStream("pedido.txt");
DataInputStream entrada=new DataInputStream(fileIn));

o en una sola lnea


DataInputStream
entrada=new
FileInputStream("pedido.txt"));

DataInputStream(new

La clase DataInputStream define diversos mtodos readXXX que son variaciones del mtodo
PROGRAMACION CON JAVA 2

285

read de la clase base para leer datos de tipo


primitivo
boolean readBoolean();
byte readByte();
int readUnsignedByte();
short readShort();
int readUnsignedShort();
char readChar();
int readInt();
String readLine();
long readLong();
float readFloat();
double readDouble();

La clase DataOutputStream es til para escribir datos del tipo primitivo de una forma
portable. Esta clase tiene un slo constructor que toma un objeto de la clase OutputStream o sus derivadas como parmetro.
Se crea un objeto de la clase DataOutputStream vinculndolo a un un objeto FileOutputStream para escribir en un archivo en disco denominado pedido.txt..
FileOutputStream fileOut=new FileOutputStream("pedido.txt");
DataOutputStream salida=new DataOutputStream(fileOut));

o en una sola lnea


DataOutputStream
salida=new
FileOutputStream("pedido.txt"));

DataOutputStream(new

La clase DataOutputStream define diversos mtodos writeXXX que son variaciones del mtodo
286

Mg. ABRAHAM GAMARRA MORENO

write de la clase base para escribir datos de


tipo primitivo
void writeBoolean(boolean v);
void writeByte(int v);
void writeBytes(String s);
void writeShort(int v);
void writeChars(String s);
void writeChar(int v);
void writeInt(int v);
void writeLong(long v);
void writeFloat(float v);
void writeDouble(double v);

8.5.2. EJEMPLO: UN PEDIDO


En este ejemplo, se escriben datos a un archivo y se leen del mismo, que corresponden a
un pedido

La descripcin del item, un objeto de la


clase String

El nmero de unidades, un dato del tipo


primitivo int

El precio de cada item, un dato de tipo


double.

Observamos en la tabla y en el cdigo el nombre de las funciones que leen y escriben los
distintos tipos de datos.
Escritura
writeChar
writeInt

Lectura
readChar
readInt

Un carcter
Un entero
Un nmero dewriteDouble readDouble
cimal
Un string
writeChars readLine
PROGRAMACION CON JAVA 2

287

Veamos el cdigo que escribe los datos a un


archivo pedido.txt en disco

Se parte de los datos que se guardan en


los arrays denominados descripciones,
unidades y precios

Se crea un objeto de la clase DataOutputStream vinculndolo a un un objeto


FileOutputStream para escribir en un archivo en disco denominado pedido.txt.

Se escribe en el flujo de salida los


distintos datos llamando a las distintas
versiones de la funcin writeXXX segn
el tipo de dato (segunda columna de la
tabla).

Se cierra el flujo de salida, llamando a


su funcin miembro close.

double[] precios={1350, 400, 890, 6200, 8730};


int[] unidades={5, 7, 12, 8, 30};
String[] descripciones={"paquetes de papel", "lpices", "bolgrafos", "carteras", "mesas"};
DataOutputStream salida=new DataOutputStream(new
Stream("pedido.txt"));
for (int i=0; i<precios.length; i ++)
{
salida.writeChars(descripciones[i]);
salida.writeChar('\n');
salida.writeInt(unidades[i]);
salida.writeChar('\t');
salida.writeDouble(precios[i]);
}
salida.close();

FileOutput-

Para leer bien los datos, el string ha de separarse del siguiente dato con un carcter
nueva lnea '\n'. Esto no es necesario si el
string se escribe en el ltimo lugar, despus
de los nmeros. Por otra parte, el carcter
tabulador como separador no es estrictamente
necesario.
Veamos el cdigo que lee los datos a un archivo pedido.txt en disco

288

Mg. ABRAHAM GAMARRA MORENO

Se crea un objeto de la clase DataInputStream vinculndolo a un un objeto


FileInputStream para leer en un archivo
en disco denominado pedido.txt.

Se lee el flujo de entrada los distintos


datos en el mismo orden en el que han
sido escritos, llamando a las distintas
versiones de la funcin readXXX segn el
tipo de dato (tercera columna de la tabla).

Se guardan los datos ledos en memoria


en las variables denominadas descripcion, unidad y precio y se usan para
distintos propsitos

Se cierra el flujo de entrada, llamando


a su funcin miembro close.

double precio;
int unidad;
String descripcion;
double total=0.0;
DataInputStream
entrada=new
DataInputStream(new
FileInputStream("pedido.txt"));
try
{
while ((descripcion=entrada.readLine())!=null)
{
unidad=entrada.readInt();
entrada.readChar();
//lee el carcter tabulador
precio=entrada.readDouble();
System.out.println("has
pedido
"+unidad+"
"+descripcion+" a "+precio+" soles.");
total=total+unidad*precio;
}
}catch (EOFException e) {}
System.out.println("por un TOTAL de: "+total+" soles.");
entrada.close();

Como vemos en esta porcin de cdigo, segn


se van leyendo los datos del archivo, se imprimen y se calcula el precio total del pedido.
System.out.println("has pedido
"+precio+" soles.");
total=total+unidad*precio;
PROGRAMACION CON JAVA 2

"+unidad+"

"+descripcion+"

289

8.5.3. EL FINAL DEL ARCHIVO


El final del archivo se detecta cuando la
funcin
readLine
devuelve
null.
Alternativamente, cuando se alcanza el final
del archivo se produce una excepcin del tipo
EOFException.
Podemos
comprobarlo
del
siguiente modo, si escribimos la siguiente
porcin de cdigo

try
{

while(true)
{
descripcion=entrada.readLine();
unidad=entrada.readInt();
entrada.readChar();
//lee el carcter tabulador
precio=entrada.readDouble();
System.out.println("has
pedido
"+unidad+"
"+descripcion+" a "+precio+" soles.");
total=total+unidad*precio;
}
}catch (EOFException e)
{
System.out.println("Excepcin cuando se alcanza el final
del archivo");
}

Cuando se alcanza el final del archivo se


produce una excepcin del tipo EOFException
que interrumpe la ejecucin del bucle indefinido al ser capturada por el correspondiente
bloque catch, el cual imprime en la pantalla
el mensaje "Excepcin cuando se alcanza el
final del archivo".
Si escribimos la siguiente porcin de cdigo
try
{

while ((descripcion=entrada.readLine())!=null)
{
unidad=entrada.readInt();
entrada.readChar();//lee el carcter tabulador
precio=entrada.readDouble();
System.out.println("has
pedido
"+unidad+"
"+descripcion+" a "+precio+" soles.");
total=total+unidad*precio;
}
System.out.println("Final del archivo");
}catch (EOFException e)
290

Mg. ABRAHAM GAMARRA MORENO

System.out.println("Excepcin
del archivo");
}

cuando

se

alcanza

el

final

Se imprime "Final de archivo" ya que cuando


readLine toma el valor null (no hay ms que
leer) se sale del bucle while, y por tanto,
no se lanza ninguna excepcin.
Ejemplo (69): Programa completo para leer y
escribir datos primitivos.
//Archivo: ArchivoApp7.java
import java.io.*;
public class ArchivoApp7
{
public static void main(String[] args) throws IOException
{
// escribe los datos
DataOutputStream salida=new DataOutputStream(new FileOutputStream("pedido.txt"));
double[] precios={1350, 400, 890, 6200, 8730};
int[] unidades={5, 7, 12, 8, 30};
String[] descripciones={"paquetes de papel", "lapices",
"boligrafos", "carteras", "mesas"};
for (int i=0; i<precios.length; i ++)
{
salida.writeChars(descripciones[i]);
salida.writeChar('\n');
salida.writeInt(unidades[i]);
salida.writeChar('\t');
salida.writeDouble(precios[i]);
}
salida.close();
//leer los datos del archivo
DataInputStream entrada=new DataInputStream(new FileInputStream("pedido.txt"));
double precio;
int unidad;
String descripcion;
double total=0.0;
try
{
//while(true)
while ((descripcion=entrada.readLine())!=null)
{
//descripcion=entrada.readLine();
unidad=entrada.readInt();
entrada.readChar();//lee el carcter tabulador
precio=entrada.readDouble();
PROGRAMACION CON JAVA 2

291

System.out.println("has
pedido
"+unidad+"
"+descripcion+" a "+precio+" Soles.");
total=total+unidad*precio;
}
System.out.println("Final del archivo");
}
catch (EOFException e)
{
System.out.println("Excepcin cuando se alcanza el final del archivo");
}
System.out.println("por un TOTAL de: "+total+" soles.");
entrada.close();
}
}

8.6. LEER Y ESCRIBIR OBJETOS


Java ha aadido una interesante faceta al lenguaje denominada serializacin de objetos que permite convertir cualquier objeto cuya clase implemente el interface Serializable en una secuencia de bytes que pueden
ser posteriormente ledos para restaurar el objeto
original. Esta caracterstica se mantiene incluso a
travs de la red, por lo que podemos crear un objeto
en un ordenador que corra bajo Windows 95/98, serializarlo y enviarlo a travs de la red a una estacin de
trabajo que corra bajo UNIX donde ser correctamente
reconstruido. No tenemos que procuparnos, en absoluto,
de las diferentes representaciones de datos en los
distintos ordenadores.
La serializacin es una caracterstica aadida al lenguaje Java para dar soporte a

292

La invocacin remota de objetos (RMI)

La persistencia
Mg. ABRAHAM GAMARRA MORENO

La invocacin remota de objetos permite a los objetos


que viven en otros ordenadores comportarse como si vivieran en nuestra propia mquina. La serializacin es
necesaria para transportar los argumentos y los valores de retorno.
La persistencia, es una caracterstica importante de
los JavaBeans. El estado de un componente es configurado durante el diseo. La serializacin nos permite
guardar el estado de un componente en disco, abandonar
el Entorno Integrado de Desarrollo (IDE) y restaurar
el estado de dicho componente cuando se vuelve a correr el IDE.

8.6.1. EL INTERFACE SERIALIZABLE


Un objeto se puede serializar si implementa
el interface Serializable. Este interface no
declara ninguna funcin miembro, se trata de
un interface vaco.
import java.io.*;
public interface Serializable
{
}

Para hacer una clase serializable simplemente


ha de implementar el interface Serializable,
por ejemplo, si se tiene la clase Lista, se
aade la implementacin del interface
public class
{
private
private
//otros
}

Lista implements java.io.Serializable


int[] x;
int n;
miembros...

No tenemos que escribir ningn otro mtodo.


El mtodo defaultWriteObject de la clase ObjectOutputStream realiza la serializacin de
los objetos de una clase. Este mtodo escribe
en el flujo de salida todo lo necesario para
reconstruir dichos objetos:

PROGRAMACION CON JAVA 2

La clase del objeto

La firma de la clase (class signature)

293

Los valores de los miembros que no tengan los modificadores static o transient, incluyendo los miembros que se
refieren a otros objetos.

El mtodo defaultReadObject de la clase ObjectInputStream realiza la deserializacin de


los objetos de una clase. Este mtodo lee el
flujo de entrada y reconstruye los objetos de
dicha clase.

8.6.2. LECTURA/ESCRITURA
Dos flujos de datos ObjectInputStream y ObjectOutputStream estn especializados en la
lectura y escritura de objetos. El comportamiento de estos dos flujos es similar a sus
correspondientes que procesan flujos de datos
primitivos DataInputStream y DataOutputStream.
Escribir
objetos
al
flujo
de
salida
ObjectOutputStream es muy simple y requiere
los siguientes pasos:

Creamos un objeto de la clase Lista

Lista lista1= new Lista(new int[]{12, 15, 11, 4, 32});

Creamos un flujo de salida a disco, pasndole el nombre del archivo en disco o


un objeto de la clase File.

FileOutputStream fileOut=new FileOutputStream("media.obj");

El flujo de salida ObjectOutputStream es


el que procesa los datos y se ha de vincular a un objeto fileOut de la clase
FileOutputStream .

ObjectOutputStream salida=new ObjectOutputStream(fileOut);


o en una sla lnea
ObjectOutputStream
salida=new
FileOutputStream("media.obj"));
294

ObjectOutputStream(new
Mg. ABRAHAM GAMARRA MORENO

El mtodo writeObject escribe los objetos al flujo de salida y los guarda en


un archivo en disco. Por ejemplo, un
string y un objeto de la clase Lista.

salida.writeObject("guardar este string y un objeto\n");


salida.writeObject(lista1);

Finalmente, se cierran los flujos

salida.close();
Lista lista1= new Lista(new int[]{12, 15, 11, 4, 32});
ObjectOutputStream
salida=new
ObjectOutputStream(new
FileOutputStream("media.obj"));
salida.writeObject("guardar este string y un objeto\n");
salida.writeObject(lista1);
salida.close();

El proceso de lectura es paralelo al proceso


de escritura, por lo que leer objetos del
flujo de entrada ObjectInputStream es muy
simple y requiere los siguientes pasos:

Creamos un flujo de entrada a disco, pasndole el nombre del archivo en disco o


un objeto de la clase File.

FileInputStream fileIn=new FileInputStream("media.obj");

El flujo de entrada ObjectInputStream es


el que procesa los datos y se ha de vincular a un objeto fileIn de la clase FileInputStream.

ObjectInputStream entrada=new ObjectInputStream(fileIn);


o en una sla lnea

ObjectInputStream
entrada=new
FileInputStream("media.obj"));

PROGRAMACION CON JAVA 2

ObjectInputStream(new

295

El mtodo readObject lee los objetos del


flujo de entrada, en el mismo orden en
el que ha sido escritos. Primero un
string y luego, un objeto de la clase
Lista.

String str=(String)entrada.readObject();
Lista obj1=(Lista)entrada.readObject();

Se realizan tareas con dichos objetos,


por ejemplo, desde el objeto obj1 de la
clase Lista se llama a la funcin miembro valorMedio, para hallar el valor medio del array de datos, o se muestran en
la pantalla

System.out.println("Valor medio "+obj1.valorMedio());


System.out.println("-----------------------------");
System.out.println(str+obj1);

Finalmente, se cierra los flujos

entrada.close();
ObjectInputStream
entrada=new
ObjectInputStream(new
FileInputStream("media.obj"));
String str=(String)entrada.readObject();
Lista obj1=(Lista)entrada.readObject();
System.out.println("Valor medio "+obj1.valorMedio());
System.out.println("-----------------------------");
System.out.println(str+obj1);
System.out.println("-----------------------------");
entrada.close();

Ejemplo(70): Programa completo de la lectura/escritura


del objeto de la clase lista
//Archivo: Lista.java
public class Lista implements java.io.Serializable
{
private int[] x;
//array de datos
private int n;
//dimensin
public Lista(int[] x)
{
this.x=x;
n=x.length;
ordenar();
}
296

Mg. ABRAHAM GAMARRA MORENO

public double valorMedio()


{
int suma=0;
for(int i=0; i<n; i++)
{
suma+=x[i];
}
return (double)suma/n;
}
public int valorMayor()
{
return x[n-1];
}
public int valorMenor()
{
return x[0];
}
private void ordenar()
{
int aux;
for(int i=0; i<n-1; i++)
{
for(int j=i+1; j<n; j++)
{
if(x[i]>x[j])
{
aux=x[j];
x[j]=x[i];
x[i]=aux;
}
}
}
}

public String toString()


{
String texto="";
for(int i=0; i<n; i++)
{
texto+="\t"+x[i];
}
return texto;
}

// Archivo: ArchivoApp4.java
import java.io.*;
import java.util.*;
public class ArchivoApp4
{
public static void main(String[] args)
{
PROGRAMACION CON JAVA 2

297

Lista lista1= new Lista(new int[]{12, 15, 11, 4, 32});


try
{
ObjectOutputStream
salida=new
ObjectOutputStream(new FileOutputStream("media.obj"));
salida.writeObject("guardar
este
string
y
un
objeto\n");
salida.writeObject(lista1);
salida.close();
ObjectInputStream entrada=new ObjectInputStream(new
FileInputStream("media.obj"));
String str=(String)entrada.readObject();
Lista obj1=(Lista)entrada.readObject();
System.out.println("Valor
medio
"+obj1.valorMedio());
System.out.println("----------------------------");
System.out.println(str+obj1);
System.out.println("----------------------------");
entrada.close();
//se puede fundir en una catch Exception
}catch (IOException ex)
{
System.out.println(ex);
}catch (ClassNotFoundException ex)
{
System.out.println(ex);
}
}

8.6.3. EL MODIFICADOR TRANSIENT


Cuando un miembro dato de una clase contiene
informacin sensible, hay disponibles varias
tcnicas para protegerla. Incluso cuando dicha informacin es privada (el miembro dato
tiene el modificador private) una vez que se
ha enviado al flujo de salida alguien puede
298

Mg. ABRAHAM GAMARRA MORENO

leerla en el archivo en disco o interceptarla


en la red.
El modo ms simple de proteger la informacin
sensible, como una contrasea (password) es
la de poner el modificador transient delante
del miembro dato que la guarda.
La clase Cliente tiene dos miembros dato, el
nombre del cliente y la contrasea o password.
Redefine la funcin toString miembro de la
clase base Object. Esta funcin devolver el
nombre del cliente y la contrasea. En el caso de que el miembro password guarde el valor
null se imprimir el texto (no disponible).
En el cuadro que sigue se muestra el cdigo
que define la clase Cliente.
public class Cliente implements java.io.Serializable
{
private String nombre;
private transient String passWord;
public Cliente(String nombre, String pw)
{
this.nombre=nombre;
passWord=pw;
}
public String toString()
{
String texto=(passWord==null) ? "(no disponible)" : passWord;
texto+=nombre;
return texto;
}
}

En el cuadro siguiente se muestra los pasos


para guardar un objeto de la clase Cliente en
el archivo cliente.obj. Posterioremente, se
lee el archivo para reconstruir el objeto
obj1 de dicha clase.

PROGRAMACION CON JAVA 2

Se crea el objeto cliente de la clase


Cliente pasndole el nombre del cliente
"Angel" y la contrasea "xyz".

Se crea un flujo de salida (objeto


salida de la clase ObjectOutputStream) y
se asocia con un objeto de la clase
299

FileOutputStream
para
guardar
la
informacin en el archivo cliente.obj.

Se escribe el objeto cliente en el flujo


de salida mediante writeObject.

Se cierra el flujo de salida llamando a


close.

Cliente cliente=new Cliente("Angel", "xyz");


ObjectOutputStream
salida=new
ObjectOutputStream(new
FileOutputStream("cliente.obj"));
salida.writeObject("Datos del cliente\n");
salida.writeObject(cliente);
salida.close();

Para reconstruir el objeto obj1 de la clase


Cliente se procede del siguiente modo:

Se crea un flujo de entrada (objeto entrada de la clase ObjectInputStream) y


se asocia con un objeto de la clase FileInputStream para leer la informacin
que gurada el archivo cliente.obj.

Se lee el objeto cliente en el flujo de


salida mediante readObject.

Se imprime en la pantalla dicho objeto


llamando implcitamente a su funcin
miembro toString.

Se cierra el flujo de entrada llamando a


close.

ObjectInputStream
entrada=new
ObjectInputStream(new
FileInputStream("cliente.obj"));
String str=(String)entrada.readObject();
Cliente obj1=(Cliente)entrada.readObject();
System.out.println("------------------------------");
System.out.println(str+obj1);
System.out.println("------------------------------");
entrada.close();

Ejemplo(71): Programa completo del uso del


modificador transient.

300

Mg. ABRAHAM GAMARRA MORENO

// Archivo: Cliente.java
public class Cliente implements java.io.Serializable
{
private String nombre;
private transient String passWord;
public Cliente(String nombre, String pw)
{
this.nombre=nombre;
passWord=pw;
}
public String toString()
{
String texto=(passWord==null) ? "(no disponible)" : passWord;
texto+=nombre;
return texto;
}
}

// Archivo: ArchivoApp6.java
import java.io.*;
public class ArchivoApp6
{
public static void main(String[] args)
{
Cliente cliente=new Cliente("Angel", "xyz");
try
{

ObjectOutputStream
salida=new
ObjectOutputStream(new FileOutputStream("cliente.obj"));
salida.writeObject("Datos del cliente\n");
salida.writeObject(cliente);
salida.close();
ObjectInputStream entrada=new ObjectInputStream(new
FileInputStream("cliente.obj"));
String str=(String)entrada.readObject();
Cliente obj1=(Cliente)entrada.readObject();
System.out.println("-----------------------------");
System.out.println(str+obj1);
System.out.println("-----------------------------");
entrada.close();
//se puede fundir en una catch Exception
}
catch (IOException ex)
{
System.out.println(ex);
}
catch (ClassNotFoundException ex)
PROGRAMACION CON JAVA 2

301

System.out.println(ex);

La salida del programa es

Lo que nos indica que la informacin sensible


guardada en el miembro dato password que tiene por modificador transient no ha sido guardada en el archivo. En la reconstruccin del
objeto obj1 con la informacin guardada en el
archivo el miembro dato password toma el valor null.

8.6.4. OBJETOS COMPUESTOS


Volvemos de nuevo al estudio de la clase Rectangulo que contiene un subobjeto de la clase
Punto.
A dichas clases se les ha aadido la redefinicin de la funcin toString miembro de la
clase base Object (esta redefinicin no es
necesaria aunque es ilustrativa para explicar
el comportamiento de un objeto compuesto).
Como podemos apreciar, ambas clases implementan el interface Serializable.
En el cuadro que sigue se muestra parte del
cdigo que define la clase Punto.
public class Punto implements java.io.Serializable
{
private int x;
private int y;
//otros miembros...
public String toString()
{
return new String("("+x+", "+y+")");
}
}
302

Mg. ABRAHAM GAMARRA MORENO

La definicin de la clase Rectangulo se muestra en el siguiente cuadro


public class Rectangulo implements java.io.Serializable
{
private int ancho ;
private int alto ;
private Punto origen;
//otras funciones miembro...
public String toString()
{
String texto=origen+" w:"+ancho+" h:"+alto;
return texto;
}
}

Como podemos observar, en la definicin de


toString de la clase Rectangulo se hace una
llamada implcita a la funcin toString miembro de la clase Punto. La composicin como se
ha estudiado permite reutilizar el cdigo
existente.
Para guardar en un archivo un objeto de la
clase Rectangulo hay que seguir los mismos
pasos que para guardar un objeto de la clase
Lista o de la clase Cliente.
Rectangulo rect=new Rectangulo(new Punto(10,10), 30, 60);
ObjectOutputStream
salida=new
ObjectOutputStream(new
FileOutputStream("figura.obj"));
salida.writeObject("guardar un objeto compuesto\n");
salida.writeObject(rect);
salida.close();

Para reconstruir un objeto de la clase Rectangulo a partir de los datos guardados en el


archivo hay que seguir los mismos pasos que
en los dos ejemplos previos.
ObjectInputStream
entrada=new
ObjectInputStream(new
FileInputStream("figura.obj"));
String str=(String)entrada.readObject();
Rectangulo obj1=(Rectangulo)entrada.readObject();
System.out.println("------------------------------");
System.out.println(str+obj1);
System.out.println("------------------------------");
entrada.close();

PROGRAMACION CON JAVA 2

303

En el caso de que nos olvidemos de implementar el interface Serializable en la clase


Punto que describe el subobjeto de la clase
Rectangulo, se lanza una excepcin, imprimindose en la consola.
java.io.NotSerializableException: archivo5.Punto.

Ejemplo(72): Programa completo de escribir/leer objetos compuestos.


//Archivo: Punto.java
public class Punto implements java.io.Serializable
{
private int x;
private int y;
public Punto(int x, int y)
{
this.x = x;
this.y = y;
}
public Punto()
{
x=0;
y=0;
}
public void desplazar(int dx, int dy)
{
x+=dx;
y+=dy;
}

public String toString()


{
return new String("("+x+", "+y+")");
}

//Archivo: Rectangulo.java
public class Rectangulo implements java.io.Serializable
{
private int ancho ;
private int alto ;
private Punto origen;
public Rectangulo()
{

}
304

origen = new Punto(0, 0);


ancho=0;
alto=0;
Mg. ABRAHAM GAMARRA MORENO

public Rectangulo(Punto p)
{
this(p, 0, 0);
}
public Rectangulo(int w, int h)
{
this(new Punto(0, 0), w, h);
}
public Rectangulo(Punto p, int w, int h)
{
origen = p;
ancho = w;
alto = h;
}
public void desplazar(int dx, int dy)
{
origen.desplazar(dx, dy);
}
public int calcularArea()
{
return ancho * alto;
}

public String toString()


{
String texto=origen+" w:"+ancho+" h:"+alto;
return texto;
}

// Archivo: ArchivoApp5.java
import java.io.*;
public class ArchivoApp5
{
public static void main(String[] args)
{
Rectangulo rect=new Rectangulo(new
60);

Punto(10,10),

30,

try
{

ObjectOutputStream
salida=new
ObjectOutputStream(new FileOutputStream("figura.obj"));
salida.writeObject("guardar
un
objeto
compuesto\n");
salida.writeObject(rect);
salida.close();
ObjectInputStream entrada=new ObjectInputStream(new
FileInputStream("figura.obj"));
String str=(String)entrada.readObject();
PROGRAMACION CON JAVA 2

305

");
");

Rectangulo obj1=(Rectangulo)entrada.readObject();
System.out.println("-----------------------------System.out.println(str+obj1);
System.out.println("-----------------------------entrada.close();
//se puede fundir en una catch Exception
}
catch (IOException ex)
{
System.out.println(ex);
}
catch (ClassNotFoundException ex)
{
System.out.println(ex);
}

8.6.5. LA HERENCIA
En el apartado anterior hemos examinado la
composicin, ahora examinemos la herencia. En
el captulo de la herencia examinamos una jerarqua formada por una clase base denominada
Figura y dos clases derivadas denominadas
Circulo y Rectangulo.
Como podemos observar en el cuadro adjunto se
han hecho dos modificaciones. La clase base
Figura implementa el interface Serializable y
en la clase Circulo en vez de usar el nmero
PI proporcionado por la clase Math, definimos
una constante esttica PI con una aproximacin de 4 decimales. De este modo probamos el
comportamiento de un miembro esttico en el
proceso de serializacin.
Para serializar objetos de una jerarqua solamente la clase base tiene que implementar
el interface Serializable
306

Mg. ABRAHAM GAMARRA MORENO

public abstract class Figura implements java.io.Serializable


{
protected int x;
protected int y;
public Figura(int x, int y)
{
this.x=x;
this.y=y;
}
public abstract double area();
}
class Circulo extends Figura
{
protected double radio;
private static final double PI=3.1416;
public Circulo(int x, int y, double radio)
{
super(x,y);
this.radio=radio;
}
public double area()
{
return PI*radio*radio;
}
}
class Rectangulo extends Figura
{
protected double ancho, alto;
public Rectangulo(int x, int y, double ancho, double alto)
{
super(x,y);
this.ancho=ancho;
this.alto=alto;
}
public double area()
{
return ancho*alto;
}
}

Vamos a serializar dos objetos uno de la clase Rectangulo y otro de la clase Circulo, y a
continuacin reconstruiremos dichos objetos.
Una vez de que dispongamos de los objetos
llamaremos a las funciones area para calcular
el rea de cada una de las figuras.
Para guardar en el archivo figura.obj un objeto fig1 de la clase Rectangulo y otro objeto fig2 de la clase Circulo, se siguen los
mismos pasos que hemos estudiado en apartados
anteriores
PROGRAMACION CON JAVA 2

307

Figura fig1=new Rectangulo(10,15, 30, 60);


Figura fig2=new Circulo(12,19, 60);
ObjectOutputStream
salida=new
ObjectOutputStream(new
FileOutputStream("figura.obj"));
salida.writeObject("guardar
un
objeto
de
una
clase
derivada\n");
salida.writeObject(fig1);
salida.writeObject(fig2);
salida.close();

Fijarse que fig1 y fig2 son dos referencias


de la clase base Figura en la que se guardan
objetos de las clases derivadas Rectangulo y
Circulo, respectivamente
Para leer los datos guardados en el archivo
figura.obj y reconstruir dos objetos obj1 y
obj2 de las clases Rectangulo y Circulo respectivamente, se procede de forma similar a
la estudiada en los apartados previos.
ObjectInputStream
entrada=new
ObjectInputStream(new
FileInputStream("figura.obj"));
String str=(String)entrada.readObject();
Figura obj1=(Figura)entrada.readObject();
Figura obj2=(Figura)entrada.readObject();
System.out.println("------------------------------");
System.out.println(obj1.getClass().getName()+"
origen
("+obj1.x+", "+obj1.y+")"+" area="+obj1.area());
System.out.println(obj2.getClass().getName()+"
origen
("+obj2.x+", "+obj2.y+")"+" area="+obj2.area());
System.out.println("------------------------------");
entrada.close();

Fijarse que obj1 y obj2 son referencias a la


clase base Figura. Sin embargo, cuando obj1
llama a la funcin area nos devuelve (correctamente) el rea del rectngulo y cuando,
obj2 llama a la funcin area devuelve el rea
del crculo.
Fijarse tambin que aunque PI es un miembro
esttico de la clase Circulo, se reconstruye
el objeto obj2 con el valor del miembro esttico con el que se calcula el rea del crculo.

308

Mg. ABRAHAM GAMARRA MORENO

Ejemplo (73): Programa completo de escribir/leer objetos con herencia.


// Archivo: Figura.java
public abstract class Figura implements java.io.Serializable
{
protected int x;
protected int y;

public Figura(int x, int y)


{
this.x=x;
this.y=y;
}
public abstract double area();

class Circulo extends Figura


{
protected double radio;
private static final double PI=3.1416;
public Circulo(int x, int y, double radio)
{
super(x,y);
this.radio=radio;
}

public double area()


{
return PI*radio*radio;
}

class Rectangulo extends Figura


{
protected double ancho, alto;
public Rectangulo(int x, int y, double ancho, double alto)
{
super(x,y);
this.ancho=ancho;
this.alto=alto;
}

public double area()


{
return ancho*alto;
}

PROGRAMACION CON JAVA 2

309

// Archivo: ArchivoApp8.java
import java.io.*;
public class ArchivoApp8
{
public static void main(String[] args)
{
Figura fig1=new Rectangulo(10,15, 30, 60);
Figura fig2=new Circulo(12,19, 60);
try
{

ObjectOutputStream
salida=new
ObjectOutputStream(new FileOutputStream("figura.obj"));
salida.writeObject("guardar un objeto de una clase
derivada\n");
salida.writeObject(fig1);
salida.writeObject(fig2);
salida.close();
ObjectInputStream entrada=new ObjectInputStream(new
FileInputStream("figura.obj"));
String str=(String)entrada.readObject();
Figura obj1=(Figura)entrada.readObject();
Figura obj2=(Figura)entrada.readObject();
System.out.println("-----------------------------");
System.out.println(obj1.getClass().getName()+"
origen ("+obj1.x+", "+obj1.y+")"+" area="+obj1.area());
System.out.println(obj2.getClass().getName()+"
origen ("+obj2.x+", "+obj2.y+")"+" area="+obj2.area());
System.out.println("-----------------------------");
entrada.close();
//se puede fundir en una catch Exception
}
catch (IOException ex)
{
System.out.println(ex);
}
catch (ClassNotFoundException ex)
{
System.out.println(ex);
}
}
}

310

Mg. ABRAHAM GAMARRA MORENO

8.6.6. SERIALIZACIN PERSONALIZADA


El proceso de serializacin proporcionado por
el lenguaje Java es suficiente para la mayor
parte de las clases, ahora bien, se puede
personalizar para aquellos casos especficos.
Para
personalizar
la
serializacin,
es
necesario definir dos funciones miembros
writeObject
y
readObject.
El
primero,
controla que informacin es enviada al flujo
de salida. La segunda, lee la informacin
escrita por writeObject .
La definicin de writeObject ha de ser la siguiente
private
void
writeObject
(ObjectOutputStream
IOException
{
s.defaultWriteObject();
//...cdigo para escribir datos
}

s)

throws

La funcin readObject ha de leer todo lo que


se ha escrito con writeObject en el mismo orden en el que se ha escrito. Adems, puede
realizar otras tareas necesarias para actualizar el estado del objeto.
private
void
readObject
(ObjectInputStream
s)
IOException
{
s.defaultReadObject();
//...cdigo para leer datos
//...
//actualizacin del estado del objeto, si es necesario
}

throws

Para un control explcito del proceso de serializacin la clase ha de implementar el interface Externalizable. La clase es responsaPROGRAMACION CON JAVA 2

311

ble de escribir y de leer su contenido, y ha


de estar coordinada con sus clases base para
hacer esto.
La definicin del interface Externalizable es
la siguiente
package java.io;
1
public interface Externalizable extends Serializable
{
public
void
writeExternal(ObjectOutput
out)
IOException;
public
void
readExternal(ObjectOutput
in)
IOException, java.lang.ClassNotFoundException;;
}

312

throws
throws

Mg. ABRAHAM GAMARRA MORENO

CAPITULO NUEVE
APPLETS
En este captulo vamos a tratar de ver todo lo que necesitamos para saber escribir un applet Java. Dado que los applets
pueden usar una gran cantidad de clases del API de Java, veremos muchas caractersticas que no hemos explicado en forma
completa, las cuales iremos aprendiendo junto a los applets.

9.1. DEFINICIN DE APPLET


El lenguaje Java se puede usar para crear dos tipos de
programas: los applets y las aplicaciones. Un applet
es un elemento ms de una pgina web, como una imagen
o una porcin de texto. Cuando el navegador carga la
pgina web, el applet insertado en dicha pgina se
carga y se ejecuta.
Mientras que un applet puede transmitirse por la red
Internet una aplicacin reside en el disco duro local.
Una aplicacin Java es como cualquier otra que est
instalada en el ordenador. La otra diferencia es que
un applet no est autorizado a acceder a archivos o
directorios del ordenador cliente si no es un applet
completamente fiable.
La definicin ms extendida de applet, es que un applet es "una pequea aplicacin accesible en un servidor de Internet, que se transporta por la red, se instala automticamente y se ejecuta in situ como parte
PROGRAMACION CON JAVA 2

313

de un documento web". Claro que as la definicin establece el entorno (Internet, Web, etc.). En realidad,
un applet es una aplicacin pretendidamente corta (nada impide que ocupe ms de un gigabyte, a no ser el
pensamiento de que se va a transportar por la red) basada en un formato grfico sin representacin independiente: es decir, se trata de un elemento a incluir en
otras aplicaciones; es un componente en su sentido estricto.

9.2. EL APPLET MNIMO


Lo primero que apreciamos a continuacin es que la
nueva clase Applet1 deriva de la clase base Applet
public class Applet1 extends Applet
{
//...
}

Y en segundo lugar, que tiene un mtodo denominado


init, que se llama cuando se carga el applet en el navegador.
public class Applet1 extends Applet
{
public void init()
{
//...
}
}

9.3. EL PRIMER APPLET


Para crear un applet tenemos que definir una clase denominada Applet1 derivada de Applet. La primera sentencia import nos proporciona informacin acerca de
las clases del paquete applet. Dicho paquete contiene
las clases necesarias para crear applets que se ejecutan en la ventana del navegador, entre las cuales est
la clase base Applet.
import java.applet.*;
public class Applet1 extends Applet
{
}

314

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

El siguiente paso es dar funcionalidad a la clase, definir nuestras propias funciones miembro o redefinir
funciones de la clase base Applet.
Definimos la funcin init para establecer el color de
fondo del applet mediante setBackground. La funcin
init se llama cuando se carga el applet.
public class Applet1 extends Applet
{
public void init()
{
setBackgroung(Color.cyan);
}
//...
}

A continuacin, vamos a mostrar un mensaje, para ello


definimos el mtodo paint. El mtodo paint nos suministra el contexto grfico g, un objeto de la clase
Graphics con el cual podemos dibujar en el rea de
trabajo del componente llamando desde dicho objeto g a
las funciones definidas en la clase Graphics.
Para mostrar un mensaje, llamamos
la funcin miembro drawString, el
el string que deseamos mostrar, y
dican las coordendas de la lnea
rcter.

desde el objeto g a
primer argumento es
los dos nmeros inbase del primer ca-

import java.applet.*;
public class Applet1 extends Applet
{
public void init()
{
setBackgroung(Color.cyan);
}
public void paint(Graphics g)
{
g.drawString("Primer applet", 10, 10);
}
}

Un applet, no es como una aplicacin que tiene un mtodo main. El applet est insertado en una pgina web
que se muestra en la ventana del navegador. El navegador toma el control del applet llamando a algunos de
sus mtodos, uno de estos es el mtodo paint que se
PROGRAMACION CON JAVA 2

315

llama cada vez que se necesita mostrar el applet en la


ventana del navegador.
Cuando el applet se carga, el navegador llama a su
todo init. En este mtodo el programador realiza
reas de inicializacin, por ejemplo, establecer
propiedades de los controles, disponerlos en el
plet, cargar imgenes, etc.

mtalas
ap-

El mtodo init se llama una sla vez. Despus, el navegador llama al mtodo paint.
A continuacin, se llama al mtodo start. Este mtodo
se llama cada vez que se accede a la pgina que contiene el applet. Esto quiere decir, que cuando dejamos
la pgina web que contiene el applet y regresamos de
nuevo pulsando en el botn "hacia atrs" el mtodo
start vuelve a llamarse de nuevo, pero no se llama el
mtodo init.
Cuando dejamos la pgina web que contiene el applet,
por ejemplo, pulsando en un enlace, se llama al mtodo
stop.
Finalmente, cuando salimos del navegador se llama al
mtodo destroy.
Mtodos fundamentales
public class Simple extends Applet
{
. . .
public void init() { . . . }
public void start() { . . . }
public void stop() { . . . }
public void destroy() { . . . }
. . .
}

9.4. INSERTANDO UN APPLET EN UNA PGINA WEB


Las etiquetas HTML como <H1>, <TABLE>, <IMG>, etc. sealan el tamao y la disposicin del texto y las figuras en la ventana del navegador. Cuando Sun Microsystems desarroll el lenguaje Java, se aadi la etiqueta que permite insertar applets en las pginas web.
Como otras etiquetas tiene un comienzo <APPLET> y un
final sealado por </APPLET>
316

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

En el Entorno Integrado de Desarrollo (IDE) de JCreator creamos un applet. Con JCreator generamos la clase
que describe el applet con algunos mtodos y lo guardamos en un archivo cuyo nombre es el mismo que el de
la clase y con extensin .java. Generamos tambin, un
archivo HTML de la pgina que contiene el applet tal
como se ve a continuacin:
<!--Archivo: applet1.htm -->
<HTML>
<HEAD>
<TITLE> Applet en Java </TITLE>
</HEAD>
<BODY>
Esta es la salida del primer applet Java:
<APPLET CODE="Applet1.class" WIDTH=300 HEIGHT=150> </APPLET>
</BODY>
</HTML>

Cuado se compila el applet se producen archivos cuya


extensin es .class. Uno de estos archivos es el que
resulta de la compilacin de la clase que describe el
applet, en nuestro caso Applet1.class.
Si queremos insertar un applet en una pgina web, utilice <APPLET> ... </APPLET> en su pgina.
Dentro de la etiqueta applet el parmetro ms importante es CODE que seala el nombre del archivo cuya
extensin es .class, y cuyo nombre coincide con el de
la clase que describe el applet.
Los valores de los parmetros WIDTH y HEIGHT determinan las dimensiones del applet. En este caso el applet
tiene una anchura de 300 y una altura de 150.
El nombre del applet, parmetro NAME, es importante
cuando se pretende comunicar los applets insertados en
una pgina web.
Luego de haber compilado el Applet1.java, ubique el
archivo applet1.htm y realice doble clic para ejecutar
la pgina que contiene al applet. Usted ver la siguiente salida:

PROGRAMACION CON JAVA 2

317

Ejemplo(74): Programa completo del uso de un applet.


//Archivo: Applet1.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class Applet1 extends Applet
{
public void init()
{
setBackground(Color.cyan);
}

public void paint(Graphics g)


{
g.drawString("Primer applet", 10, 25);
}

<!--Archivo: applet1.htm -->


<!--Archivo: applet1.htm -->
<HTML>
<HEAD>
<TITLE> Applet en Java </TITLE>
318

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

</HEAD>
<BODY>
Esta es la salida del primer applet Java: <br>
<APPLET CODE="Applet1.class" WIDTH=300 HEIGHT=150>
</APPLET>
</BODY>
</HTML>

9.5. FUNCIONES GRFICAS


Hemos introducido la nocin de contexto grfico en las
pginas anteriores, cuando se ha creado el primer applet, que muestra un mensaje. En este captulo se estudiarn algunas funciones grficas definidas en la
clase Graphics, y tres clases que sirven de apoyo para
dibujar en el contexto grfico: la clase Color que
describe los colores, la clase Font que nos permite
crear fuentes de texto y la clase FontMetrics que nos
proporciona sus caractersticas.
A continuacin se tienen los constructores y mtodos
de la clase graphics (tomado del JDK HELP):
java.lang.Object
|
+--java.awt.Graphics

Resumn del Constructor


protected Graphics()

Constructs a new Graphics object.

Resumn de los Mtodos


abstract clearRect(int x, int y, int width, int height)
void
Clears the specified rectangle by fill-

ing it with the background color of the current


drawing surface.
abstract clipRect(int x, int y, int width, int height)
void
Intersects the current clip with the

specified rectangle.

abstract copyArea(int x, int y, int width, int height, int dx,


void int dy)

Copies an area of the component by a


distance specified by dx and dy.

PROGRAMACION CON JAVA 2

319

abstract create()
Graphics

Creates a new Graphics object that is a


copy of this Graphics object.

Graphics create(int x, int y, int width, int height)


Creates a new Graphics object based on
this Graphics object, but with a new translation

and clip area.

abstract dispose()
void

Disposes of this graphics context and


releases any system resources that it is using.

void draw3DRect(int x, int y, int width, int height, boolean raised)

Draws a 3-D highlighted outline of the


specified rectangle.
abstract drawArc(int x, int y, int width, int height, int startAngle,
void int arcAngle)

Draws the outline of a circular or elliptical arc covering the specified rectangle.
void drawBytes(byte[] data, int offset, int length, int x, int y)

Draws the text given by the specified


byte array, using this graphics context's current
font and color.
void drawChars(char[] data, int offset, int length, int x, int y)

Draws the text given by the specified


character array, using this graphics context's current font and color.
abstract drawImage(Image img, int x, int y, Color bgcolor,
boolean ImageObserver observer)

Draws as much of the specified image as


is currently available.
abstract drawImage(Image img, int x, int y, ImageObserver observer)
boolean
Draws as much of the specified image as

is currently available.

abstract drawImage(Image img, int x, int y, int width, int height,


boolean Color bgcolor, ImageObserver observer)

Draws as much of the specified image as


has already been scaled to fit inside the specified rectangle.
abstract drawImage(Image img, int x, int y, int width, int height,
boolean ImageObserver observer)

Draws as much of the specified image as


has already been scaled to fit inside the specified rectangle.

320

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

abstract drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
boolean int sx1, int sy1, int sx2, int sy2, Color bgcolor,
ImageObserver observer)

Draws as much of the specified area of


the specified image as is currently available,
scaling it on the fly to fit inside the specified
area of the destination drawable surface.
abstract drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
boolean int sx1, int sy1, int sx2, int sy2, ImageObserver observer)

Draws as much of the specified area of


the specified image as is currently available,
scaling it on the fly to fit inside the specified
area of the destination drawable surface.
abstract drawLine(int x1, int y1, int x2, int y2)
void
Draws a line, using the current color,
between the points (x1, y1) and (x2, y2) in this

graphics context's coordinate system.


abstract drawOval(int x, int y, int width, int height)
void
Draws the outline of an oval.
abstract drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
void
Draws a closed polygon defined by arrays

of x and y coordinates.

void drawPolygon(Polygon p)

Draws the outline of a polygon defined


by the specified Polygon object.
abstract drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
void
Draws a sequence of connected lines de-

fined by arrays of x and y coordinates.

void drawRect(int x, int y, int width, int height)

Draws the outline of the specified rectangle.


abstract drawRoundRect(int x, int y, int width, int height,
void int arcWidth, int arcHeight)

Draws an outlined round-cornered rectangle using this graphics context's current color.
abstract drawString(AttributedCharacterIterator iterator, int x,
void int y)

Draws the text given by the specified


iterator, using this graphics context's current
color.
abstract drawString(String str, int x, int y)
void
Draws the text given by the specified

string, using this graphics context's current font


and color.
PROGRAMACION CON JAVA 2

321

void fill3DRect(int x, int y, int width, int height, boolean raised)

Paints a 3-D highlighted rectangle filled with the current color.


abstract fillArc(int x, int y, int width, int height, int startAngle,
void int arcAngle)

Fills a circular or elliptical arc covering the specified rectangle.


abstract fillOval(int x, int y, int width, int height)
void
Fills an oval bounded by the specified

rectangle with the current color.

abstract fillPolygon(int[] xPoints, int[] yPoints, int nPoints)


void
Fills a closed polygon defined by arrays

of x and y coordinates.

void fillPolygon(Polygon p)

Fills the polygon defined by the specified Polygon object with the graphics context's
current color.
abstract fillRect(int x, int y, int width, int height)
void
Fills the specified rectangle.
abstract fillRoundRect(int x, int y, int width, int height,
void int arcWidth, int arcHeight)

Fills the specified rounded corner rectangle with the current color.
void finalize()

Disposes of this graphics context once


it is no longer referenced.
abstract getClip()
Shape

Gets the current clipping area.

abstract getClipBounds()
Rectangle
Returns the bounding rectangle of the

current clipping area.

Rectangle getClipBounds(Rectangle r)

Returns the bounding rectangle of the


current clipping area.
Rectangle getClipRect()

Deprecated. As of JDK version 1.1, replaced by getClipBounds().

abstract getColor()
Color

Gets this graphics context's current co-

lor.
abstract getFont()
Font
322

Gets the current font.


A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

FontMetrics getFontMetrics()

font.

Gets the font metrics of the current

abstract getFontMetrics(Font f)
FontMetrics
Gets the font metrics for the specified

font.
boolean hitClip(int x, int y, int width, int height)

Returns true if the specified rectangular area might intersect the current clipping
area.
abstract setClip(int x, int y, int width, int height)
void
Sets the current clip to the rectangle

specified by the given coordinates.

abstract setClip(Shape clip)


void
Sets the current clipping area to an ar-

bitrary clip shape.

abstract setColor(Color c)
void
Sets this graphics context's current co-

lor to the specified color.

abstract setFont(Font font)


void
Sets this graphics context's font to the

specified font.
abstract setPaintMode()
void
Sets the paint mode of this graphics

context to overwrite the destination with this


graphics context's current color.
abstract setXORMode(Color c1)
void
Sets the paint mode of this graphics

context to alternate between this graphics context's current color and the new specified color.

String toString()

Returns a String object representing this


Graphics object's value.
abstract translate(int x, int y)
void
Translates the origin of the graphics

context to the point (x, y) in the current coordinate system.

PROGRAMACION CON JAVA 2

323

9.5.1. EL CONTEXTO GRFICO


La funcin paint y update nos suministran el
contexto grfico del applet o del componente,
en otros casos, hemos de obtener el contexto
grfico del componente mediante la funcin
getGraphics. Una vez obtenido el contexto
grfico podemos llamar desde este objeto a
las funciones grficas definidas en la clase
Graphics.
public void paint(Graphics g)
{
//usar el contexto grfico g
}
public void update(Graphics g)
{
//usar el contexto grfico g
}
void funcion()
{
Graphics g=getGraphics();
//usar el contexto grfico g
g.dispose();
}

Como vemos en esta porcin de cdigo existe


una sutil diferencia entre suministrar y obtener el contexto grfico g. Solamente es necesario liberar los recursos asociados al
contexto g, mediante la llamada a la funcin
dispose, cuando se obtiene el contexto grfico mediante getGraphics.
La clase Graphics es abstracta por lo que no
se pueden crear mediante new objetos de esta
clase, pero se pueden guardar en una referencia g de la clase Graphics los contextos grficos concretos de los distintos componentes.
Un contexto grfico es como la hoja en blanco
situada en un trazador (plotter). Para dibujar en dicha hoja se toma una pluma, se dibuja, se toma otra pluma de distinto color o
grosor, se dibuja otra porcin del grfico, y
as sucesivamente. Cuando no se selecciona
explcitamente, se dibuja con una pluma que
se establece por defecto.
324

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

Las libreras grficas como la de Windows,


disponen de plumas de distinto grosor para
dibujar lneas con distintos estilos, brochas
para rellenar el interior de una figura cerrada con un color slido, con una determinada trama o figura, y fuentes de texto, para
dibujar texto con distintas fuentes y estilos. La librera grfica que viene con la
versin 1.1 de Java es muy limitada. No hay
objetos pinceles, ni brochas. Las lneas tienen un nico grosor y estilo, solamente se
pueden cambiar de color, las figuras cerradas
solamente se pueden rellenar con un color slido, y las fuentes de texto disponibles son
muy pocas.
La clase Graphics describe el contexto grfico y proporciona un conjunto de funciones para dibujar las siguientes figuras

Lneas

Crculos y elipses

Rectngulos y polgones

Imgenes

Texto
El sistema de coordenadas
que se usa en Java es similar a Windows. El rea
de trabajo del applet est
compuesta por una matriz
bidimensional de puntos o
pixels.
Decimos
que
un
punto
tiene coordenadas
(x, y) cuando est en la
columna x medida desde la
izquierda, y est en la
fila y, medida desde arriba.

La esquina superior izquierda es el origen (0, 0).


La esquina inferior derecha viene determinada por las dimensiones del comPROGRAMACION CON JAVA 2

325

ponente. La funcin getSize nos devuelve un objeto de la clase Dimension cuyos miembros width y height nos suministran la anchura y altura del componente.
int ancho=getSize().width;
int alto=getSize().heigth;

No vamos a examinar completamente la clase Graphics,


pero si vamos a mostrar mediante un applet el uso de
algunas funciones de esta clase.
La funcin paint nos va a proporcionar el objeto g de
la clase Graphics que denominamos contexto grfico del
componente (applet). Desde dicho objeto llamaremos a
las funciones miembro de la clase Graphics.

9.5.2. ESTABLECER UN COLOR


El color negro es el color por defecto del
contexto grfico. Para establecer otro color,
como veremos en la pgina siguiente, se utiliza la funcin setColor, y se le pasa un color predefinido o definido por el usuario.
g.setColor(Color.cyan);

9.5.3. DIBUJAR UNA LNEA


Para dibujar una lnea recta se llama a la
funcin drawLine, le pasamos el punto inicial
y el punto final. Para dibujar una lnea diagonal desde el origen (0, 0) o esquina superior izquierda, hasta la esquina inferior derecha, obtenemos las dimensiones del applet
mediante la funcin getSize, que devuelve un
objeto de la clase Dimension. El miembro
width nos sproporciona la anchura y el miembro height la altura.
g.drawLine(0, 0, getSize().width-1, getSize().height-1);

9.5.4. DIBUJAR UN RECTNGULO


Un rectngulo viene definido por un origen
(esquina superior izquierda), su anchura y
326

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

altura. La siguiente sentencia dibuja un rectngulo cuyo origen es el punto 50, 150, que
tiene una anchura de 50, y una altura de 60.
La funcin drawRect dibuja el contorno del
color seleccionado, y fillRect dibuja el rectngulo pintando su interior del color seleccionado, en este caso de color rojo.
g.setColor(Color.red);
g.fillRect(50, 150, 50, 60);

9.5.5. DIBUJAR UN ARCO


Los elipses (oval), arcos (arc), se dibujan
en el interior del rectngulo circundante.
Una elipse de dibuja mediante drawOval o
fillOval, con los mismos parmetros que el
rectngulo. Un arco requiere dos parmetros
ms el ngulo inicial y el ngulo final. Las
sentencias que vienen a continuacin, dibujan
un arco en el interior del rectngulo cuyo
origen es el punto 10, 10, cuya anchura es
150, y cuya altura es 100. El ngulo inicial
es 0 y el ngulo final es 270, expresado en
grados.
g.setColor(Color.cyan);
g.fillArc(10, 10, 150, 100, 0, 270);
g.setColor(Color.black);
g.drawArc(10, 10, 150, 100, 0, 270);

9.5.6. DIBUJAR UN POLGONO


Para dibujar un polgono, se requieren un
array de puntos. Un polgono y una polilnea
son parecidos, el primero es una figura cerrada mientas que una polilnea es un conjunto de segmentos. Para formar un polgono a
partir de una pililnea se une el punto inicial y el punto final. El polgono precisa de
un array de abscisas x, un array de ordenadas
y, y la dimensin del array.
int[] x={100, 150, 170, 190, 200};
int[] y={120, 280, 200, 250, 60};
g.setColor(Color.blue);
g.drawPolygon(x, y, x.length);

PROGRAMACION CON JAVA 2

327

Alternativamente, se puede usar un objeto de


la clase Polygon, al cual se le aaden puntos
mediante la funcin miembro addPoint.
Polygon poligono=new Polygon();
poligono.addPoint(100, 120);
poligono.addPoint(150, 280);
poligono.addPoint(170, 200);
poligono.addPoint(190, 250);
poligono.addPoint(200, 60);

Para dibujar el polgono con su interior pintado del color seleccionado se llama a la
funcin fillPolygon y se le pasa el objeto
poligono de la clase Polygon.
g.setColor(Color.yellow);
g.fillPolygon(poligono);

Veremos en el applet un polgono cuyo contorno est dibujado en azul y su interior en


amarillo.

9.5.7. DIBUJAR UNA IMAGEN


Para dibujar una imagen se requieren dos pasos:

Cargar la imagen y crear un objeto de la


clase Image

Dibujar dicho objeto en el contexto grfico

Para crear una imagen u objeto disco de la


clase Image a partir del archivo disco.gif se
usa la funcin getImage. Le hemos de indicar
la ubicacin de dicho archivo relativa a la
pgina web que contiene el applet o al cdigo
compilado. En nuestro caso, hemos situado la
imagen en el mismo subdirectorio que la pgina web que contiene al applet. El lugar ms
adecuado para cargar la imagen es en la funcin init, ya que como se ha mencionado se
llama una sola vez.
public void init()
{
disco=getImage(getDocumentBase(), "disco.gif");
}
328

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

Para dibujar la imagen en el contexto grfico


g, se llama a la funcin drawImage. Hay varias versiones de esta funcin, la ms simple
es aquella a la que se le proporciona el objeto disco de la clase Image, las coordenadas
de su esquina superior izquierda (250, 50), y
el observador, el propio applet o this.
g.drawImage(disco, 250, 50, this);

Si deseamos obtener las dimensiones del objeto disco de la clase Image, llamamos a dos
funciones de esta clase getWidth y getHeight
int ancho=disco.getWidth(this);
int alto=disco.getHeight(this);

Ejemplo(75): Programa completo del uso de las funciones grficas


// Archivo: FuncionesApplet.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class FuncionesApplet extends Applet
{
Image disco;
public void init()
{
try
{
jbInit();
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void jbInit() throws Exception
{
setBackground(Color.white);
this.setSize(400,300);
disco=getImage(getDocumentBase(), "disco.gif");
}
public void paint(Graphics g)
{
g.drawLine(0, 0, getSize().width-1, getSize().height-1);
g.setColor(Color.red);
g.fillRect(50, 150, 50, 60);
PROGRAMACION CON JAVA 2

329

g.setColor(Color.cyan);
g.fillArc(10, 10, 150, 100, 0, 270);
g.setColor(Color.black);
g.drawArc(10, 10, 150, 100, 0, 270);
Polygon poligono=new Polygon();
poligono.addPoint(100, 120);
poligono.addPoint(150, 280);
poligono.addPoint(170, 200);
poligono.addPoint(190, 250);
poligono.addPoint(200, 60);
g.setColor(Color.yellow);
g.fillPolygon(poligono);
int[] x={100, 150, 170, 190, 200};
int[] y={120, 280, 200, 250, 60};
g.setColor(Color.blue);
g.drawPolygon(x, y, x.length);

g.drawImage(disco, 250, 50, this);

<!--Archivo: applet2.htm -->


<HTML>
<HEAD>
<TITLE> Applet en Java </TITLE>
</HEAD>
<BODY>
<APPLET CODE="FuncionesApplet.class" WIDTH=700 HEIGHT=750>
</APPLET>
</BODY>
</HTML>

330

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

9.6. LAS CLASES Color, Font Y Fontmetrics


9.6.1. LA CLASE Color
Los colores primarios son el rojo, el verde y
el azul. Java utiliza un modelo de color denominado RGB, que significa que cualquier color se puede describir dando las cantidades
de rojo (Red), verde (Green), y azul (Blue).
Estas
cantidades
son
nmeros
enteros
comprendidos entre 0 y 255, o bien, nmeros
reales comprendidos entre 0.0 y 1.0. La
siguiente tabla nos proporciona los colores
ms comunes y sus valores RGB.
Nombre

Red (rojo)

white
lightGray
gray
drakGray
black
red
pink
orange
yellow
green
magenta
cyan
blue

255
192
128
64
0
255
255
255
255
0
255
0
0

Green
(verde)
255
192
128
64
0
0
175
200
255
255
0
255
0

Blue
(azul)
255
192
128
64
0
0
175
0
0
0
255
255
255

Para crear un objeto de la clase Color, se


pasan tres nmeros a su constructor que indican la cantidad de rojo, verde y azul.
Color colorRosa=new Color(255, 175, 175);

Mediante la funcin setColor, cambiamos color


con el que dibujamos una lnea, un texto o
rellenamos una figura cerrada en el contexto
grfico g.
g.setColor(colorRosa);
PROGRAMACION CON JAVA 2

331

No es necesario tener a mano la tabla de las


componentes RGB de cada color. La clase Color
nos proporciona un conjunto de colores predefinidos en forma de miembros estticos de dicha clase. Podemos escribir alternativamente
g.setColor(Color.pink);

Los colores predefinidos son los siguientes


Color.white
Color.black Color.yellow
Color.lightGray Color.red
Color.green
Color.gray
Color.pink Color.magenta
Color.darkGray Color.orange Color.cyan
Color.blue
Ejemplo(76): Programa que imprime un rectangulo
// Archivo: PaintRect.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class PaintRect extends Applet
{
public void init()
{
setBackground(Color.yellow);
}

public void paint(Graphics g)


{
g.setColor(Color.red);
g.drawRect(10,20,300,200);
}

<!--Archivo: applet3a.htm -->


<HTML>
<HEAD>
<TITLE> Applet en Java </TITLE>
</HEAD>
<BODY>
<APPLET CODE="PaintRect.class" WIDTH=700 HEIGHT=750>
</APPLET>
</BODY>
</HTML>
332

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

El color de fondo del componente se establece


con setBackground y se obtiene con getBackground. En el siguiente applet observamos cmo se utiliza esta segunda funcin para crear
una diana. En la funcin init establecemos el
color de fondo en blanco mediante setBackground. En la funcin miembro paint obtenemos
el color de fondo mediante getBackground. Los
crculos se pintan de mayor a menor radio. Se
pinta un crculo de color rojo y se borra
parte de su interior con el color de fondo,
de este modo se crea un anillo, luego otro y
as sucesivamente, hasta completar cuatro
anillos de color rojo con la apariencia de
una diana.
En el programa, tambin podemos apreciar que
la funcin paint suministra el contexto grfico g del componente (applet) en el cual podemos dibujar. El objeto g llama a setColor
para establecer el color, y a fillOval para
dibujar un crculo pintado de dicho color.
Las funcin getSize nos devuelve el tamao
del componente (applet), de modo que los dimetros de la elipse mayor son respectivamete
la anchura y altura del applet.
Ejemplo(77): Programa completo del uso de Color
// Archivo: PaintApplet.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class PaintApplet extends Applet
{
public void init()
{
setBackground(Color.white);
}
public void paint(Graphics g)
{
int x, y, ancho, alto;
int appletAlto = getSize().height;
int appletAncho = getSize().width;
for (int i=8; i>=0; i--)
{
if ((i % 2)==0) g.setColor(Color.red);
else g.setColor(getBackground());
PROGRAMACION CON JAVA 2

333

}
}

alto = appletAlto*i/8;
ancho = appletAncho*i/8;
x=appletAncho/2-i*appletAncho/16;
y=appletAlto/2-i*appletAlto/16;
g.fillOval(x, y, ancho, alto);

<!--Archivo: applet3.htm -->


<HTML>
<HEAD>
<TITLE> Applet en Java </TITLE>
</HEAD>
<BODY>
<APPLET CODE="PaintApplet.class" WIDTH=700 HEIGHT=750>
</APPLET>
</BODY>
</HTML>

334

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

9.6.2. LA CLASE Font


Para crear una fuente de texto u objeto de la
clase Font llamamos a su constructor, y le
pasamos el nombre de la fuente de texto, el
estilo y el tamao. Por ejemplo,
Font fuente=new Font("TimesRoman", Font.BOLD, 12);

Esta sentencia, crea una fuente de texto Times Roman, en letra negrita, de 12 puntos.
Los estilos vienen datos por constantes
(miembros estticos de la clase Font),
Font.BOLD
establece
el
estilo
negrita,
Font.ITALIC, el estilo cursiva, y Font.PLAIN,
el estilo normal. Se pueden combinar las
constantes Font.BOLD+Font.ITALIC para establecer el estilo negrita y cursiva a la vez.
La funcin setFont de la clase Graphics establece la fuente de texto en el contexto grfico g.
g.setFont(fuente);

La funcin getFont obtiene la fuente de texto


actual de dicho contexto grfico. La funcin
drawString dibuja el string guardado en el
objeto texto de la clase String, y lo sita
en la posicin cuyas coordenadas vienen dadas
por los dos nmeros enteros que le siguen.
En la siguiente porcin de cdigo, establecemos una fuente de texto, dibujamos el texto,
y reestablecemos la fuente de texto por defecto, una operacin habitual que se realiza
al programar un applet.
Font oldFont=getFont();
Font fuente=new Font("Monospaced", Font.BOLD, 36);
g.setFont(fuente);
g.drawString(texto, 100, 50);
g.setFont(oldFont);
g.drawString(otroTexto, 100, 70);

Para obtener el nombre de las fuentes de texto disponibles se escribe el siguiente cdigo
PROGRAMACION CON JAVA 2

335

String[] nombreFuentes=getToolkit().getFontList();
for(int i=0; i<nombreFuentes.length; i++){
System.out.println(nombreFuentes[i]);
}

9.6.3. LA CLASE FontMetrics


La clase FontMetrics nos permite conocer las
caractersticas de una fuente de texto.
Desde el contexto grfico g, llamamos a la
funcin getFontMetrics para obtener un objeto
fm de la clase FontMetrics que nos describe
las caractersticas de una fuente determinada
o de la fuente actualmente seleccionada. En
el primer caso escribimos
Font fuente=new Font("Dialog", Font.BOLD, 36);
FontMetrics fm=g.getFontMetrics(fuente);

En el segundo caso, escribimos


Font fuente=new Font("Courier", Font.BOLD, 36);
g.setFont(fuente);
FontMetrics fm=g.getFontMetrics();

En el applet mostramos las caractersticas de


una fuente de texto: Ascent es la distancia
entre lnea horizontal de color azul (baseline) y la lnea horizontal de color rojo. Descent es la distancia entre la lnea horizontal de color azul (baseline) y la lnea horizontal de color verde. Leading sera la distancia entre las lnea de color verde (descent) y la lnea roja (ascent) de la siguiente lnea de texto.

336

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

Para obtener la altura


de una fuente de texto,
llamamos a la funcin
getHeight miembro de
FontMetrics. La altura
de una fuente de texto,
es la distancia entre
dos lneas base (baseline) consecutivas, y
es la suma de el ascent, descent y leading.

Tres funciones que comienzan por


get devuelven los valores de estos
tres atributos de una fuente de texto: getAscent, getDescent, y getLeading.

Para escribir dos lneas de texto, una debajo


de otra escribimos
FontMetrics fm=g.getFontMetrics();
String texto="La cigea vendr";
g.drawString(texto, 10, 50);
int hFont=fm.getHeight();
texto=new String("ser en primavera");
g.drawString(texto, 10, 50+hFont);

La primera lnea de texto, se sita en el


punto (10, 50), la ordenada 50, seala la posicin vertical de la lnea base de la fuente
de texto, vase la figura. La segunda lnea
de texto tiene una lnea base cuya posicin
vertical se obtiene sumando a 50 la altura
hFont de la fuente de texto.
Otro valor interesante, es la anchura de un
texto, que se obtiene mediante la funcin
miembro stringWidth, y se le pasa el texto.
Por ejemplo, para centrar horizontalmente un
texto en el applet escribimos.
String texto="La cigea vendr";
int ancho=fm.stringWidth(texto);
g.drawString(texto, (anchoApplet-ancho)/2, 50);
PROGRAMACION CON JAVA 2

337

La funcin getSize().width obtiene la anchura


del componente (applet), y la variable ancho,
guarda la anchura del string texto.
Un poco ms difcil es centrar un texto verticalmente, en una determinada posicin. Teniendo en cuanta, que las coordendas que se
le pasan a la funcin drawString se refieren
a la lnea base del primer carcter, tal como
se ve en la figura. La frmula de centrado
vertical en un punto de ordenada y sera: la
ordenada y de la lnea base menos descent ms
la mitad de la altura de los caracteres
hFont. Se ha de tener en cuenta que la ordenada y aumenta de arriba hacia abajo.
g.drawLine(0, y, anchoApplet, y);
g.setColor(Color.red);
texto="Centrado: a, p, , , ";
g.drawString(texto, 10, y+hFont/2-descent);

Como los caracteres pueden estar o no acentuados, escritos en maysculas o minsculas,


etc, la frmula para mostrar un texto centrado verticamente no es nica, se sugiere probar estas dos dadas por otros autores
g.drawString(texto, 10, y+ascent/4);
g.drawString(texto, 10, y-hFont/2+ascent);

El cdigo completo de este ejemplo es, el siguiente:


Ejemplo(78): Ejemplo del uso de Font y FontMetrics
// Archivo: FontApplet2.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class FontApplet2 extends Applet
{
public FontApplet2()
{
}
//Initialize the applet
338

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

public void init()


{
try
{
jbInit();
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void jbInit() throws Exception
{
int
ancho
=
Integer.parseInt(this.getParameter("WIDTH"));
int
alto
=
Integer.parseInt(this.getParameter("HEIGHT"));
this.setSize(new Dimension(ancho, alto));
setBackground(Color.white);
}
public void paint(Graphics g)
{
int anchoApplet=getSize().width;
Font oldFont=getFont();
Font fuente=new Font("Monospaced", Font.BOLD, 36);
g.setFont(fuente);
FontMetrics fm=g.getFontMetrics();
String texto="La cigea vendr";
int ancho=fm.stringWidth(texto);
int y=50;
g.drawString(texto, (anchoApplet-ancho)/2, y);
texto=new String("ser en primavera");
ancho=fm.stringWidth(texto);
//caractersticas de las fuentes de texto
int hFont=fm.getHeight();
int ascent=fm.getAscent();
int descent=fm.getDescent();
int leading=fm.getLeading();
g.drawString(texto, (anchoApplet-ancho)/2, y+hFont);
//dibuja lnea base
g.setColor(Color.blue);
g.drawLine(0, y, getSize().width, y);
g.drawLine(0, y+hFont, anchoApplet, y+hFont);
//dibuja ascent
g.setColor(Color.red);
g.drawLine(0, y-ascent, anchoApplet, y-ascent);
g.drawLine(getSize().width/2,
y+hFont-ascent,
anchoApplet, y+hFont-ascent);
//dibuja descent
g.setColor(Color.green);
g.drawLine(0, y+descent, anchoApplet/2, y+descent);
g.drawLine(0,
y+hFont+descent,
anchoApplet,
y+hFont+descent);
//texto centrado verticalmente en la posicin
y+=2*hFont;
g.setColor(Color.black);
PROGRAMACION CON JAVA 2

339

g.drawLine(0, y, anchoApplet, y);


g.setColor(Color.red);
texto="Centrado: a, p, , 5, ";
g.drawString(texto, 10, y+hFont/2-descent);
//Escribe tres lneas de texto en la fuente de texto
por defecto.
g.setFont(oldFont);
fm=g.getFontMetrics();
hFont=fm.getHeight();
y+=3*hFont;
g.setColor(Color.black);
texto="leading ="+leading;
g.drawString(texto, 10, y);
texto="ascent ="+ascent;
y+=hFont;
g.drawString(texto, 10, y);
texto="descent ="+descent;
y+=hFont;
g.drawString(texto, 10, y);
texto="altura=ascent+descent+leading=
"+(ascent+descent+leading);
y+=hFont;
g.drawString(texto, 10, y);
}
}

<!--Archivo: applet4.htm -->


<HTML>
<HEAD>
<TITLE> Applet en Java </TITLE>
</HEAD>
<BODY>
<APPLET CODE="FontApplet2.class" WIDTH=700 HEIGHT=750>
</APPLET>
</BODY>
</HTML>

340

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

Ejemplo(79): Programa que grafica una parabola.


// Archivo: GraficaParabola.java
import
import
import
import

java.awt.*;
java.awt.event.*;
java.applet.*;
java.lang.Math;

public class GraficaParabola extends Applet


{
public void init()
{
setBackground(Color.yellow);
}
public void paint(Graphics g)
{
double x,y;
//(x, y) :
coordenadas cartesianas
int x0,y0; //(x0, y0): origen de las coordenadas cartesianas
// en la pantalla
int xp,yp;
//(xp, yp) :
coordenadas de pantalla
x0 = 200;
y0 = 200;
//dibuja ejes
g.drawLine(0,y0,400,y0);
g.drawLine(x0,0,x0,400);
//dibuja parabola
for(x=-300;x<=300;x++)
PROGRAMACION CON JAVA 2

341

y=x*x;
//convertir a coordenadas de pantalla
xp=(int)(x0+x);
yp=(int)(y0-y);
//dibujar punto
g.drawOval(xp,yp,2,2);

<!--Archivo: applet4a.htm -->

<HTML>
<HEAD>
<TITLE> Applet en Java </TITLE>
</HEAD>
<BODY>
<APPLET CODE="GraficaParabola.class" WIDTH=500 HEIGHT=750>
</APPLET>
</BODY>
</HTML>

342

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

Ejemplo(80): Programa que grafica la funcin


seno.
// Archivo: GraficaSeno.java
import
import
import
import

java.awt.*;
java.awt.event.*;
java.applet.*;
java.lang.Math;

public class GraficaSeno extends Applet


{
public void init()
{
setBackground(Color.yellow);
}
public void paint(Graphics g)
{
double x,y;
//(x, y) :
coordenadas cartesianas
int x0,y0; //(x0, y0): origen de las coordenadas cartesianas
// en la pantalla
double xp,yp;
//(xp, yp) :
coordenadas de pantalla
double angrad;
x0 = 400;
y0 = 200;
//dibuja ejes
g.drawLine(0,y0,800,y0);
g.drawLine(x0,0,x0,400);

//dibuja parabola
for(x=-400;x<=400;x++)
{
angrad=Math.toRadians(x);
y=100*Math.sin(angrad);
//convertir a coordenadas de pantalla
xp=x0+x;
yp=y0-y;
//dibujar punto
g.drawOval((int) xp,(int) yp,2,2);
}

<!--Archivo: applet4b.htm -->


<HTML>
<HEAD>
<TITLE> Applet en Java </TITLE>
</HEAD>
<BODY>
<APPLET CODE="GraficaSeno.class" WIDTH=1000 HEIGHT=400>
</APPLET>
</BODY>
</HTML>
PROGRAMACION CON JAVA 2

343

9.7.
INTERFAZ GRAFICA CON EL USUARIO (GUI)
Y COMPONENTES BASICOS
Toda interfaz grfica con el usuario (GUI, graphical
user interface) presenta una interfaz de imagenes con
un programa. Esta interfaz permite al usuario reducir
el tiempo de ingreso de los datos, as como el manejo
de un programa.
Las GUI se construyen a partir de componentes de GUI
(llamados widgets). Un componente de GUI es un objeto
visual con el que el usuario puede interactuar a travs del teclado o el mouse.
Las clases para crear los componentes de GUI estan en
el paquete java.awt(Another Windowing Toolkit, otro
juego de herramientas para manejar ventanas). Para
utilizar este paquete debemos importarlo de la siguiente manera:
import java.awt.*;
344

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

9.7.1. COMPONENTES
Hay dos tipos de componentes:

los controles

los paneles

Los controles derivan


y los paneles derivan
Los paneles (un applet
zado) pueden contener
neles y controles). La
muestra en la figura

de la clase Component,
de la clase Container.
es un panel especialiotros componentes (pajerarqua de clases se

La librera AWT no es muy rica en componentes, tal como se ve en la figura. Sin embargo, hemos de tener cuidado en usar solamente
componentes AWT para los applets que vayamos
a publicar en Internet. Los navegadores no
ejecutan applets que utilicen componentes no
estndar.
PROGRAMACION CON JAVA 2

345

Por debajo de los controles AWT estn los


controles nativos, esto presenta algunas dificultades, por ejemplo, los controles son
siempre rectangulares y opacos. La versin
Java 2.0 sustituye la libera AWT por la denominada Swing en la que se elimina la dependencia de los controles nativos, el nmero y
el tipo de componentes puede satisfacer con
creces las aspiraciones de cualquier programador exigente. Adems, podemos crear nuestros propios controles, comprarlos o encargarlos a medida, y situarlos en la paleta de
componentes.

9.7.2. ROTULOS (Label)


Un rtulo es una area donde se exhibe una sola lnea de texto estatico (slo de lectura).
El texto no puede ser modificado por el usuario cuando se esta ejecutando el programa.
Los rotulos se crean con la clase Label que
deriva de la clase Component.
java.lang.Object
|
+--java.awt.Component
|
+--java.awt.Label

Los atributos, constructores y mtodos de


Label se muestran a continuacin(Tomado del
JDK HELP):

Resumn de atributos
static int CENTER

tered.

Indicates that the label should be cen-

static int LEFT

Indicates that the label should be left


justified.
static int RIGHT

Indicates that the label should be right


justified.

346

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

Resumn de Constructores
Label()

Constructs an empty label.


Label(String text)

Constructs a new label with the specified string


of text, left justified.
Label(String text, int alignment)

Constructs a new label that presents the specified


string of text with the specified alignment.

Resumn de Mtodos
void addNotify()

Creates the peer for this label.


AccessibleContext getAccessibleContext()

Gets the AccessibleContext associated with this Label.


int getAlignment()

label.

Gets the current alignment of this

String getText()

Gets the text of this label.


protected

String paramString()

Returns a string representing the


state of this Label.
void setAlignment(int alignment)

Sets the alignment for this label


to the specified alignment.
void setText(String text)

Sets the text for this label to the


specified text.

Mtodos que heredados de la clase java.awt.Component


action, add, addComponentListener, addFocusListener,
addHierarchyBoundsListener, addHierarchyListener, addInputMethodListener,
addKeyListener, addMouseListener, addMouseMotionListener,
addMouseWheelListener, addPropertyChangeListener,
addPropertyChangeListener, applyComponentOrientation,
areFocusTraversalKeysSet, bounds, checkImage, checkImage, coalesceEvents,
contains, contains, createImage, createImage, createVolatileImage,
createVolatileImage, deliverEvent, disable, disableEvents, dispatchEvent,
doLayout, enable, enable, enableEvents, enableInputMethods,
firePropertyChange, firePropertyChange, firePropertyChange,
getAlignmentX, getAlignmentY, getBackground, getBounds, getBounds,
PROGRAMACION CON JAVA 2

347

getColorModel, getComponentAt, getComponentAt, getComponentListeners,


getComponentOrientation, getCursor, getDropTarget,
getFocusCycleRootAncestor, getFocusListeners, getFocusTraversalKeys,
getFocusTraversalKeysEnabled, getFont, getFontMetrics, getForeground,
getGraphics, getGraphicsConfiguration, getHeight,
getHierarchyBoundsListeners, getHierarchyListeners, getIgnoreRepaint,
getInputContext, getInputMethodListeners, getInputMethodRequests,
getKeyListeners, getListeners, getLocale, getLocation, getLocation,
getLocationOnScreen, getMaximumSize, getMinimumSize, getMouseListeners,
getMouseMotionListeners, getMouseWheelListeners, getName, getParent,
getPeer, getPreferredSize, getPropertyChangeListeners,
getPropertyChangeListeners, getSize, getSize, getToolkit, getTreeLock,
getWidth, getX, getY, gotFocus, handleEvent, hasFocus, hide, imageUpdate,
inside, invalidate, isBackgroundSet, isCursorSet, isDisplayable,
isDoubleBuffered, isEnabled, isFocusable, isFocusCycleRoot, isFocusOwner,
isFocusTraversable, isFontSet, isForegroundSet, isLightweight, isOpaque,
isShowing, isValid, isVisible, keyDown, keyUp, layout, list, list, list,
list, list, locate, location, lostFocus, minimumSize, mouseDown,
mouseDrag, mouseEnter, mouseExit, mouseMove, mouseUp, move, nextFocus,
paint, paintAll, postEvent, preferredSize, prepareImage, prepareImage,
print, printAll, processComponentEvent, processEvent, processFocusEvent,
processHierarchyBoundsEvent, processHierarchyEvent,
processInputMethodEvent, processKeyEvent, processMouseEvent,
processMouseMotionEvent, processMouseWheelEvent, remove,
removeComponentListener, removeFocusListener,
removeHierarchyBoundsListener, removeHierarchyListener,
removeInputMethodListener, removeKeyListener, removeMouseListener,
removeMouseMotionListener, removeMouseWheelListener, removeNotify,
removePropertyChangeListener, removePropertyChangeListener, repaint,
repaint, repaint, repaint, requestFocus, requestFocus,
requestFocusInWindow, requestFocusInWindow, reshape, resize, resize,
setBackground, setBounds, setBounds, setComponentOrientation, setCursor,
setDropTarget, setEnabled, setFocusable, setFocusTraversalKeys,
setFocusTraversalKeysEnabled, setFont, setForeground, setIgnoreRepaint,
setLocale, setLocation, setLocation, setName, setSize, setSize,
setVisible, show, show, size, toString, transferFocus,
transferFocusBackward, transferFocusUpCycle, update, validate

Los atributos, constructores y mtodos de


Component se muestran a continuacin(Tomado
del JDK HELP):
java.lang.Object
|
+--java.awt.Component

Resumn de atributos
static float BOTTOM_ALIGNMENT

Ease-of-use constant for getAlignmentY.


static float CENTER_ALIGNMENT

Ease-of-use constant for getAlignmentY and


getAlignmentX.
348

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

static float LEFT_ALIGNMENT

Ease-of-use constant for getAlignmentX.


static float RIGHT_ALIGNMENT

Ease-of-use constant for getAlignmentX.


static float TOP_ALIGNMENT

Ease-of-use constant for getAlignmentY().

Resumn de Constructores
protected Component()

Constructs a new component.

Resumen de Mtodos
boolean action(Event evt, Object what)

Deprecated. As of JDK version 1.1, should


register this component as ActionListener on component which fires action events.

void add(PopupMenu popup)

ponent.

Adds the specified popup menu to the com-

void addComponentListener(ComponentListener l)

Adds the specified component listener to


receive component events from this component.
void addFocusListener(FocusListener l)

Adds the specified focus listener to receive focus events from this component when this
component gains input focus.
void addHierarchyBoundsListener(HierarchyBoundsListener l)

Adds the specified hierarchy bounds listener to receive hierarchy bounds events from this
component when the hierarchy to which this container
belongs changes.
void addHierarchyListener(HierarchyListener l)

Adds the specified hierarchy listener to


receive hierarchy changed events from this component
when the hierarchy to which this container belongs
changes.
void addInputMethodListener(InputMethodListener l)

Adds the specified input method listener


to receive input method events from this component.

PROGRAMACION CON JAVA 2

349

void addKeyListener(KeyListener l)

Adds the specified key listener to receive


key events from this component.
void addMouseListener(MouseListener l)

Adds the specified mouse listener to receive mouse events from this component.
void addMouseMotionListener(MouseMotionListener l)

Adds the specified mouse motion listener


to receive mouse motion events from this component.
void addMouseWheelListener(MouseWheelListener l)

Adds the specified mouse wheel listener to


receive mouse wheel events from this component.
void addNotify()

Makes this Component displayable by connecting it to a native screen resource.


void addPropertyChangeListener(PropertyChangeListener listener)

Adds a PropertyChangeListener to the listener list.


void addPropertyChangeListener(String propertyName,
PropertyChangeListener listener)

Adds a PropertyChangeListener to the listener list for a specific property.


void applyComponentOrientation(ComponentOrientation orientation)
Sets the ComponentOrientation property of

this component and all components contained within


it.

boolean areFocusTraversalKeysSet(int id)

Returns whether the Set of focus traversal


keys for the given focus traversal operation has
been explicitly defined for this Component.
Rectangle bounds()

Deprecated. As of JDK version 1.1, replaced by getBounds().

int checkImage(Image image, ImageObserver observer)

Returns the status of the construction of


a screen representation of the specified image.
int checkImage(Image image, int width, int height,
ImageObserver observer)

Returns the status of the construction of


a screen representation of the specified image.
protected coalesceEvents(AWTEvent existingEvent, AWTEvent newEvent)
AWTEvent
Potentially coalesce an event being posted

with an existing event.


350

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

boolean contains(int x, int y)

Checks whether this component "contains"


the specified point, where x and y are defined to be
relative to the coordinate system of this component.
boolean contains(Point p)

Checks whether this component "contains"


the specified point, where the point's x and y coordinates are defined to be relative to the coordinate
system of this component.
Image createImage(ImageProducer producer)

producer.

Creates an image from the specified image

Image createImage(int width, int height)

Creates an off-screen drawable image to be


used for double buffering.
VolatileI createVolatileImage(int width, int height)
mage
Creates a volatile off-screen drawable im-

age to be used for double buffering.

VolatileI createVolatileImage(int width, int height,


mage ImageCapabilities caps)

Creates a volatile off-screen drawable image, with the given capabilities.


void deliverEvent(Event e)

Deprecated. As of JDK version 1.1, replaced by dispatchEvent(AWTEvent e).

void disable()

Deprecated. As of JDK version 1.1, replaced by setEnabled(boolean).

protected disableEvents(long eventsToDisable)


void
Disables the events defined by the speci-

fied event mask parameter from being delivered to


this component.
void dispatchEvent(AWTEvent e)

Dispatches an event to this component or


one of its sub components.
void doLayout()

Prompts the layout manager to lay out this


component.
void enable()

Deprecated. As of JDK version 1.1, replaced by setEnabled(boolean).

void enable(boolean b)

Deprecated. As of JDK version 1.1, replaced by setEnabled(boolean).

PROGRAMACION CON JAVA 2

351

protected enableEvents(long eventsToEnable)


void
Enables the events defined by the speci-

fied event mask parameter to be delivered to this


component.
void enableInputMethods(boolean enable)

Enables or disables input method support


for this component.
protected firePropertyChange(String propertyName, boolean oldValue, boovoid lean newValue)

Support for reporting bound property changes for boolean properties.


protected firePropertyChange(String propertyName, int oldValue,
void int newValue)

Support for reporting bound property changes for integer properties.


protected firePropertyChange(String propertyName, Object oldValue,
void Object newValue)

Support for reporting bound property changes for Object properties.


Accessibl getAccessibleContext()
eContext
Gets the AccessibleContext associated with
this Component.
float getAlignmentX()

Returns the alignment along the x axis.


float getAlignmentY()

Returns the alignment along the y axis.


Color getBackground()

Gets the background color of this component.


Rectangle getBounds()

Gets the bounds of this component in the


form of a Rectangle object.
Rectangle getBounds(Rectangle rv)

Stores the bounds of this component into


"return value" rv and return rv.
ColorMode getColorModel()
l
Gets the instance of ColorModel used to dis-

play the component on the output device.

Component getComponentAt(int x, int y)

Determines if this component or one of its


immediate subcomponents contains the (x, y) location, and if so, returns the containing component.
Component getComponentAt(Point p)

Returns the component or subcomponent that


contains the specified point.
352

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

Component getComponentListeners()
Listener[]
Returns an array of all the component lis-

teners registered on this component.


Component getComponentOrientation()
OrientaRetrieves the language-sensitive orientation tion that is to be used to order the elements or

text within this component.


Cursor getCursor()

Gets the cursor set in the component.


DropTarge getDropTarget()
t
Gets the DropTarget associated with this
Component.
Container getFocusCycleRootAncestor()

Returns the Container which is the focus


cycle root of this Component's focus traversal cycle.
FocusList getFocusListeners()
ener[]
Returns an array of all the focus listen-

ers registered on this component.


Set getFocusTraversalKeys(int id)

Returns the Set of focus traversal keys


for a given traversal operation for this Component.
boolean getFocusTraversalKeysEnabled()

Returns whether focus traversal keys are


enabled for this Component.
Font getFont()

Gets the font of this component.


FontMetri getFontMetrics(Font font)
cs
Gets the font metrics for the specified

font.
Color getForeground()

Gets the foreground color of this component.


Graphics getGraphics()

Creates a graphics context for this component.


GraphicsC getGraphicsConfiguration()
onfiguraGets the GraphicsConfiguration associated with
tion this Component.
int getHeight()

nent.

PROGRAMACION CON JAVA 2

Returns the current height of this compo-

353

Hierarchy getHierarchyBoundsListeners()
BoundsLisReturns an array of all the hierarchy
tener[] bounds listeners registered on this component.
Hierarchy getHierarchyListeners()
Listener[]
Returns an array of all the hierarchy lis-

teners registered on this component.


boolean getIgnoreRepaint()
InputCont getInputContext()
ext
Gets the input context used by this compo-

nent for handling the communication with input methods when text is entered in this component.

InputMeth getInputMethodListeners()
odListeReturns an array of all the input method
ner[] listeners registered on this component.
InputMeth getInputMethodRequests()
odRequests
Gets the input method request handler

which supports requests from input methods for this


component.
KeyListen getKeyListeners()
er[]
Returns an array of all the key listeners

registered on this component.


EventList getListeners(Class listenerType)
ener[]
Returns an array of all the objects currently registered as FooListeners upon this Component.
Locale getLocale()

Gets the locale of this component.


Point getLocation()

Gets the location of this component in the


form of a point specifying the component's top-left
corner.
Point getLocation(Point rv)

Stores the x,y origin of this component


into "return value" rv and return rv.
Point getLocationOnScreen()

Gets the location of this component in the


form of a point specifying the component's top-left
corner in the screen's coordinate space.
Dimension getMaximumSize()

Gets the maximum size of this component.


Dimension getMinimumSize()

Gets the mininimum size of this component.


MouseList getMouseListeners()
354

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

ener[]

Returns an array of all the mouse listeners registered on this component.

MouseMoti getMouseMotionListeners()
onListeReturns an array of all the mouse motion
ner[] listeners registered on this component.
MouseWhee getMouseWheelListeners()
lListeReturns an array of all the mouse wheel
ner[] listeners registered on this component.
String getName()

Gets the name of the component.


Container getParent()

Gets the parent of this component.


ja- getPeer()
va.awt.pee
Deprecated. As of JDK version 1.1, pror.Componen grams should not directly manipulate peers; replaced
tPeer
by boolean isDisplayable().
Dimension getPreferredSize()

Gets the preferred size of this component.


PropertyC getPropertyChangeListeners()
hangeLisReturns an array of all the property chantener[] ge listeners registered on this component.
PropertyC getPropertyChangeListeners(String propertyName)
hangeLisReturns an array of all the listeners
tener[] which have been associated with the named property.
Dimension getSize()

Returns the size of this component in the


form of a Dimension object.
Dimension getSize(Dimension rv)

Stores the width/height of this component


into "return value" rv and return rv.
Toolkit getToolkit()

Gets the toolkit of this component.


Object getTreeLock()

Gets this component's locking object (the


object that owns the thread sychronization monitor)
for AWT component-tree and layout operations.
int getWidth()

nent.

Returns the current width of this compo-

int getX()

Returns the current x coordinate of the


components origin.

PROGRAMACION CON JAVA 2

355

int getY()

Returns the current y coordinate of the


components origin.
boolean gotFocus(Event evt, Object what)

Deprecated. As of JDK version 1.1, replaced by processFocusEvent(FocusEvent).

boolean handleEvent(Event evt)

Deprecated. As of JDK version 1.1 replaced


by processEvent(AWTEvent).

boolean hasFocus()

Returns true if this Component is the focus


owner.
void hide()

Deprecated. As of JDK version 1.1, replaced by setVisible(boolean).

boolean imageUpdate(Image img, int infoflags, int x, int y, int w,


int h)

changed.

Repaints the component when the image has

boolean inside(int x, int y)

Deprecated. As of JDK version 1.1, replaced by contains(int, int).

void invalidate()

Invalidates this component.


boolean isBackgroundSet()

Returns whether the background color has


been explicitly set for this Component.
boolean isCursorSet()

Returns whether the cursor has been explicitly set for this Component.
boolean isDisplayable()

playable.

Determines whether this component is dis-

boolean isDoubleBuffered()

Returns true if this component is painted


to an offscreen image ("buffer") that's copied to
the screen later.
boolean isEnabled()

Determines whether this component is enabled.


boolean isFocusable()

Returns whether this Component can be focused.


356

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

boolean isFocusCycleRoot(Container container)

Returns whether the specified Container is


the focus cycle root of this Component's focus traversal cycle.
boolean isFocusOwner()

Returns true if this Component is the focus


owner.
boolean isFocusTraversable()

Deprecated. As of 1.4, replaced by isFocus-

able().
boolean isFontSet()

Returns whether the font has been explicitly set for this Component.
boolean isForegroundSet()

Returns whether the foreground color has


been explicitly set for this Component.
boolean isLightweight()

A lightweight component doesn't have a native toolkit peer.


boolean isOpaque()

Returns true if this component is completely opaque, returns false by default.


boolean isShowing()

Determines whether this component is showing on screen.


boolean isValid()

lid.

Determines whether this component is va-

boolean isVisible()

Determines whether this component should


be visible when its parent is visible.
boolean keyDown(Event evt, int key)

Deprecated. As of JDK version 1.1, replaced by processKeyEvent(KeyEvent).

boolean keyUp(Event evt, int key)

Deprecated. As of JDK version 1.1, replaced by processKeyEvent(KeyEvent).

void layout()

Deprecated. As of JDK version 1.1, replaced by doLayout().

void list()

Prints a listing of this component to the


standard system output stream System.out.
PROGRAMACION CON JAVA 2

357

void list(PrintStream out)

Prints a listing of this component to the


specified output stream.
void list(PrintStream out, int indent)

Prints out a list, starting at the specified indentation, to the specified print stream.
void list(PrintWriter out)

Prints a listing to the specified print


writer.
void list(PrintWriter out, int indent)

Prints out a list, starting at the specified indentation, to the specified print writer.
Component locate(int x, int y)

Deprecated. As of JDK version 1.1, replaced by getComponentAt(int, int).

Point location()

Deprecated. As of JDK version 1.1, replaced by getLocation().

boolean lostFocus(Event evt, Object what)

Deprecated. As of JDK version 1.1, replaced by processFocusEvent(FocusEvent).

Dimension minimumSize()

Deprecated. As of JDK version 1.1, replaced by getMinimumSize().

boolean mouseDown(Event evt, int x, int y)

Deprecated. As of JDK version 1.1, replaced by processMouseEvent(MouseEvent).

boolean mouseDrag(Event evt, int x, int y)

Deprecated. As of JDK version 1.1, replaced by processMouseMotionEvent(MouseEvent).

boolean mouseEnter(Event evt, int x, int y)

Deprecated. As of JDK version 1.1, replaced by processMouseEvent(MouseEvent).

boolean mouseExit(Event evt, int x, int y)

Deprecated. As of JDK version 1.1, replaced by processMouseEvent(MouseEvent).

boolean mouseMove(Event evt, int x, int y)

Deprecated. As of JDK version 1.1, replaced by processMouseMotionEvent(MouseEvent).

boolean mouseUp(Event evt, int x, int y)

Deprecated. As of JDK version 1.1, replaced by processMouseEvent(MouseEvent).

358

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

void move(int x, int y)

Deprecated. As of JDK version 1.1, replaced by setLocation(int, int).

void nextFocus()

Deprecated. As of JDK version 1.1, replaced by transferFocus().

void paint(Graphics g)

Paints this component.


void paintAll(Graphics g)

Paints this component and all of its subcomponents.


protected paramString()
String
Returns a string representing the state of

this component.
boolean postEvent(Event e)

Deprecated. As of JDK version 1.1, replaced by dispatchEvent(AWTEvent).

Dimension preferredSize()

Deprecated. As of JDK version 1.1, replaced by getPreferredSize().

boolean prepareImage(Image image, ImageObserver observer)

Prepares an image for rendering on this


component.
boolean prepareImage(Image image, int width, int height,
ImageObserver observer)

Prepares an image for rendering on this


component at the specified width and height.
void print(Graphics g)

Prints this component.


void printAll(Graphics g)

Prints this component and all of its subcomponents.


protected processComponentEvent(ComponentEvent e)
void
Processes component events occurring on

this component by dispatching them to any registered


ComponentListener objects.
protected processEvent(AWTEvent e)
void
Processes events occurring on this compo-

nent.

protected processFocusEvent(FocusEvent e)
void
Processes focus events occurring on this
component by dispatching them to any registered FocusListener objects.
PROGRAMACION CON JAVA 2

359

protected processHierarchyBoundsEvent(HierarchyEvent e)
void
Processes hierarchy bounds events occur-

ring on this component by dispatching them to any


registered HierarchyBoundsListener objects.
protected processHierarchyEvent(HierarchyEvent e)
void
Processes hierarchy events occurring on

this component by dispatching them to any registered


HierarchyListener objects.
protected processInputMethodEvent(InputMethodEvent e)
void
Processes input method events occurring on

this component by dispatching them to any registered


InputMethodListener objects.

protected processKeyEvent(KeyEvent e)
void
Processes key events occurring on this

component by dispatching them to any registered KeyListener objects.


protected processMouseEvent(MouseEvent e)
void
Processes mouse events occurring on this
component by dispatching them to any registered MouseListener objects.
protected processMouseMotionEvent(MouseEvent e)
void
Processes mouse motion events occurring on

this component by dispatching them to any registered


MouseMotionListener objects.
protected processMouseWheelEvent(MouseWheelEvent e)
void
Processes mouse wheel events occurring on

this component by dispatching them to any registered


MouseWheelListener objects.

void remove(MenuComponent popup)

Removes the specified popup menu from the


component.
void removeComponentListener(ComponentListener l)

Removes the specified component listener


so that it no longer receives component events from
this component.
void removeFocusListener(FocusListener l)

Removes the specified focus listener so


that it no longer receives focus events from this
component.
void removeHierarchyBoundsListener(HierarchyBoundsListener l)

Removes the specified hierarchy bounds


listener so that it no longer receives hierarchy
bounds events from this component.

360

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

void removeHierarchyListener(HierarchyListener l)

Removes the specified hierarchy listener


so that it no longer receives hierarchy changed
events from this component.
void removeInputMethodListener(InputMethodListener l)

Removes the specified input method listener so that it no longer receives input method
events from this component.
void removeKeyListener(KeyListener l)

Removes the specified key listener so that


it no longer receives key events from this component.
void removeMouseListener(MouseListener l)

Removes the specified mouse listener so


that it no longer receives mouse events from this
component.
void removeMouseMotionListener(MouseMotionListener l)

Removes the specified mouse motion listener so that it no longer receives mouse motion
events from this component.
void removeMouseWheelListener(MouseWheelListener l)

Removes the specified mouse wheel listener


so that it no longer receives mouse wheel events
from this component.
void removeNotify()

Makes this Component undisplayable by destroying it native screen resource.


void removePropertyChangeListener(PropertyChangeListener listener)

Removes a PropertyChangeListener from the


listener list.
void removePropertyChangeListener(String propertyName,
PropertyChangeListener listener)

Removes a PropertyChangeListener from the


listener list for a specific property.
void repaint()

Repaints this component.


void repaint(int x, int y, int width, int height)

Repaints the specified rectangle of this


component.
void repaint(long tm)

Repaints the component.


void repaint(long tm, int x, int y, int width, int height)

Repaints the specified rectangle of this


component within tm milliseconds.
PROGRAMACION CON JAVA 2

361

void requestFocus()

Requests that this Component get the input


focus, and that this Component's top-level ancestor
become the focused Window.
protected requestFocus(boolean temporary)
boolean
Requests that this Component get the input

focus, and that this Component's top-level ancestor


become the focused Window.
boolean requestFocusInWindow()

Requests that this Component get the input


focus, if this Component's top-level ancestor is already the focused Window.
protected requestFocusInWindow(boolean temporary)
boolean
Requests that this Component get the input

focus, if this Component's top-level ancestor is already the focused Window.


void reshape(int x, int y, int width, int height)

Deprecated. As of JDK version 1.1, replaced by setBounds(int, int, int, int).

void resize(Dimension d)

Deprecated. As of JDK version 1.1, replaced by setSize(Dimension).

void resize(int width, int height)

Deprecated. As of JDK version 1.1, replaced by setSize(int, int).

void setBackground(Color c)

nent.

Sets the background color of this compo-

void setBounds(int x, int y, int width, int height)

Moves and resizes this component.


void setBounds(Rectangle r)

Moves and resizes this component to conform to the new bounding rectangle r.
void setComponentOrientation(ComponentOrientation o)

Sets the language-sensitive orientation


that is to be used to order the elements or text
within this component.
void setCursor(Cursor cursor)

Sets the cursor image to the specified


cursor.
void setDropTarget(DropTarget dt)
Associate a DropTarget with this component.

362

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

void setEnabled(boolean b)

Enables or disables this component, depending on the value of the parameter b.


void setFocusable(boolean focusable)

Sets the focusable state of this Component


to the specified value.
void setFocusTraversalKeys(int id, Set keystrokes)

Sets the focus traversal keys for a given


traversal operation for this Component.
void setFocusTraversalKeysEnabled(boolean focusTraversalKeysEnabled)

Sets whether focus traversal keys are enabled for this Component.
void setFont(Font f)

Sets the font of this component.


void setForeground(Color c)

Sets the foreground color of this component.


void setIgnoreRepaint(boolean ignoreRepaint)

Sets whether or not paint messages received from the operating system should be ignored.
void setLocale(Locale l)

Sets the locale of this component.


void setLocation(int x, int y)

Moves this component to a new location.


void setLocation(Point p)

Moves this component to a new location.


void setName(String name)

Sets the name of the component to the specified string.


void setSize(Dimension d)

Resizes this component so that it has


width d.width and height d.height.
void setSize(int width, int height)

Resizes this component so that it has


width width and height height.
void setVisible(boolean b)

Shows or hides this component depending on


the value of parameter b.
void show()

Deprecated. As of JDK version 1.1, replaced by setVisible(boolean).

PROGRAMACION CON JAVA 2

363

void show(boolean b)

Deprecated. As of JDK version 1.1, replaced by setVisible(boolean).

Dimension size()

Deprecated. As of JDK version 1.1, replaced by getSize().

String toString()

Returns a string representation of this


component and its values.
void transferFocus()

Transfers the focus to the next component,


as though this Component were the focus owner.
void transferFocusBackward()

Transfers the focus to the previous component, as though this Component were the focus owner.
void transferFocusUpCycle()

Transfers the focus up one focus traversal


cycle.
void update(Graphics g)

Updates this component.


void validate()

Ensures that this component has a valid


layout.
Ejemplo (81): Programa completo para el uso
de Label.
// Archivo: UsoLabel.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class UsoLabel extends Applet
{
public void init()
{
setBackground(Color.yellow);
//declaracin e inicializacin de un objeto Font
Font f1=new Font("Courier",Font.BOLD,24);
//declaracin e inicializacin de un objeto Label
Label textolabel1=new Label("PROGRAMACION EN JAVA 2");
//define el font para el Label
//usa el mtodo setFont de la clase Component
textolabel1.setFont(f1);
add(textolabel1);
364

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

//declaracin e inicializacin de un objeto Font


Font f2=new Font("Script",Font.BOLD,34);
//declaracin e inicializacin de un objeto Label
Label textolabel2=new Label();
//define el font para el Label
//usa el mtodo setFont de la clase Component
textolabel2.setFont(f2);

//define el contenito del rtulo


textolabel2.setText("APLICACIONES");
add(textolabel2);

public void paint(Graphics g)


{
}

<!--Archivo: applet5.htm -->


<HTML>
<HEAD>
<TITLE> Applet en Java </TITLE>
</HEAD>
<BODY>
<APPLET CODE="UsoLabel.class" WIDTH=700 HEIGHT=750>
</APPLET>
</BODY>
</HTML>

Por suepeusto que el cdigo anterior no posiciona los textos en dos lneas.
Si usted desea realizar que los textos se posicionen en dos lneas debe utilizar el administrador de diseos GridLayout (Diseo de
Retcula)

9.7.3. ADMINISTRADOR DE DISEOS GRIDLAYOUT


El administrador de diseos GridLayout divide
el contenedor en una retcula que permite colocar los componentes en filas y columnas.
PROGRAMACION CON JAVA 2

365

Los componentes se se agregan comenzando en


la celda superior y de izquierda a derecha,
luego continua en la siguiente fila de la
misma forma.
Los constructores y mtodos de GridLayout se
detallan a continuacin:
java.lang.Object
|
+--java.awt.GridLayout

Resumn de Constructores
GridLayout()

Creates a grid layout with a default of one column


per component, in a single row.
GridLayout(int rows, int cols)

Creates a grid layout with the specified number of


rows and columns.
GridLayout(int rows, int cols, int hgap, int vgap)

Creates a grid layout with the specified number of


rows and columns.

Resumn de Mtodos
void addLayoutComponent(String name, Component comp)

Adds the specified component with the


specified name to the layout.
int getColumns()

Gets the number of columns in this layout.


int getHgap()

Gets the horizontal gap between components.


int getRows()

Gets the number of rows in this layout.


int getVgap()

Gets the vertical gap between components.


void layoutContainer(Container parent)

Lays out the specified container using


this layout.
Dimension minimumLayoutSize(Container parent)

Determines the minimum size of the container argument using this grid layout.
366

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

Dimension preferredLayoutSize(Container parent)

Determines the preferred size of the container argument using this grid layout.
void removeLayoutComponent(Component comp)

layout.

Removes the specified component from the

void setColumns(int cols)

Sets the number of columns in this layout


to the specified value.
void setHgap(int hgap)

Sets the horizontal gap between components to the specified value.


void setRows(int rows)

Sets the number of rows in this layout to


the specified value.
void setVgap(int vgap)

Sets the vertical gap between components


to the specified value.
String toString()

Returns the string representation of this


grid layout's values.
Ejemplo (82): Programa completo para el uso
de GridLayout y Label.
// Archivo: UsoGridLayout.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class UsoGridLayout extends Applet
{
public void init()
{
setBackground(Color.yellow);
//declaracin e inicializacin de un objeto Font
Font f1=new Font("Courier",Font.BOLD,24);
//declaracin e inicializacin de un objeto Label
Label textolabel1=new Label("PROGRAMACION EN JAVA 2");
//define el font para el Label
//usa el mtodo setFont de la clase Component
textolabel1.setFont(f1);
//declaracin e inicializacin de un objeto Font
Font f2=new Font("Script",Font.BOLD,34);
//declaracin e inicializacin de un objeto Label
PROGRAMACION CON JAVA 2

367

Label textolabel2=new Label();


//define el font para el Label
//usa el mtodo setFont de la clase Component
textolabel2.setFont(f2);
//define el contenito del rtulo
textolabel2.setText("APLICACIONES");
//uso de GridLayout
setLayout( new GridLayout(2,1));

add(textolabel1);
add(textolabel2);

<!--Archivo: applet6.htm -->


<HTML>
<HEAD>
<TITLE> Applet en Java </TITLE>
</HEAD>
<BODY>
<APPLET CODE="UsoGridLayout.class" WIDTH=500 HEIGHT=100>
</APPLET>
</BODY>
</HTML>

368

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

9.7.4. BOTONES PARA PULSAR (BUTTON)


Un botn es un componente en que el usuario
puede relizar un clic para disparar una accin especfica. Los botones para pulsar se
crean con la clase Button (botn) que se
hereda de Component.
Los atributos, constructores y
Button se listan a continuacin:

mtodos

de

java.lang.Object
|
+--java.awt.Component
|
+--java.awt.Button

Resumn de atributos
Fields inherited from class java.awt.Component
BOTTOM_ALIGNMENT, CENTER_ALIGNMENT, LEFT_ALIGNMENT, RIGHT_ALIGNMENT,
TOP_ALIGNMENT

Fields inherited from interface java.awt.image.ImageObserver


ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, WIDTH

Resumn de Constructores
Button()

Constructs a Button with no label.


Button(String label)

Constructs a Button with the specified label.

Resumn de Mtodos
void addActionListener(ActionListener l)

Adds the specified action listener


to receive action events from this button.
void addNotify()

Creates the peer of the button.


AccessibleContext getAccessibleContext()

Gets the AccessibleContext associated


PROGRAMACION CON JAVA 2

369

with this Button.


String getActionCommand()

Returns the command name of the action event fired by this button.
ActionListener[] getActionListeners()

Returns an array of all the action


listeners registered on this button.
String getLabel()

Gets the label of this button.


EventListener[] getListeners(Class listenerType)

Returns an array of all the objects


currently registered as FooListeners upon this
Button.
protected

String paramString()

Returns a string representing the


state of this Button.
protected

void processActionEvent(ActionEvent e)

Processes action events occurring


on this button by dispatching them to any registered ActionListener objects.
protected

void processEvent(AWTEvent e)

Processes events on this button.


void removeActionListener(ActionListener l)

Removes the specified action listener so that it no longer receives action


events from this button.
void setActionCommand(String command)

Sets the command name for the action event fired by this button.
void setLabel(String label)

Sets the button's label to be the


specified string.

Methods inherited from class java.awt.Component


action, add, addComponentListener, addFocusListener,
addHierarchyBoundsListener, addHierarchyListener, addInputMethodListener,
addKeyListener, addMouseListener, addMouseMotionListener,
addMouseWheelListener, addPropertyChangeListener,
addPropertyChangeListener, applyComponentOrientation,
areFocusTraversalKeysSet, bounds, checkImage, checkImage, coalesceEvents,
contains, contains, createImage, createImage, createVolatileImage,
createVolatileImage, deliverEvent, disable, disableEvents, dispatchEvent,
doLayout, enable, enable, enableEvents, enableInputMethods,
firePropertyChange, firePropertyChange, firePropertyChange,
getAlignmentX, getAlignmentY, getBackground, getBounds, getBounds,
370

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

getColorModel, getComponentAt, getComponentAt, getComponentListeners,


getComponentOrientation, getCursor, getDropTarget,
getFocusCycleRootAncestor, getFocusListeners, getFocusTraversalKeys,
getFocusTraversalKeysEnabled, getFont, getFontMetrics, getForeground,
getGraphics, getGraphicsConfiguration, getHeight,
getHierarchyBoundsListeners, getHierarchyListeners, getIgnoreRepaint,
getInputContext, getInputMethodListeners, getInputMethodRequests,
getKeyListeners, getLocale, getLocation, getLocation,
getLocationOnScreen, getMaximumSize, getMinimumSize, getMouseListeners,
getMouseMotionListeners, getMouseWheelListeners, getName, getParent,
getPeer, getPreferredSize, getPropertyChangeListeners,
getPropertyChangeListeners, getSize, getSize, getToolkit, getTreeLock,
getWidth, getX, getY, gotFocus, handleEvent, hasFocus, hide, imageUpdate,
inside, invalidate, isBackgroundSet, isCursorSet, isDisplayable,
isDoubleBuffered, isEnabled, isFocusable, isFocusCycleRoot, isFocusOwner,
isFocusTraversable, isFontSet, isForegroundSet, isLightweight, isOpaque,
isShowing, isValid, isVisible, keyDown, keyUp, layout, list, list, list,
list, list, locate, location, lostFocus, minimumSize, mouseDown,
mouseDrag, mouseEnter, mouseExit, mouseMove, mouseUp, move, nextFocus,
paint, paintAll, postEvent, preferredSize, prepareImage, prepareImage,
print, printAll, processComponentEvent, processFocusEvent,
processHierarchyBoundsEvent, processHierarchyEvent,
processInputMethodEvent, processKeyEvent, processMouseEvent,
processMouseMotionEvent, processMouseWheelEvent, remove,
removeComponentListener, removeFocusListener,
removeHierarchyBoundsListener, removeHierarchyListener,
removeInputMethodListener, removeKeyListener, removeMouseListener,
removeMouseMotionListener, removeMouseWheelListener, removeNotify,
removePropertyChangeListener, removePropertyChangeListener, repaint,
repaint, repaint, repaint, requestFocus, requestFocus,
requestFocusInWindow, requestFocusInWindow, reshape, resize, resize,
setBackground, setBounds, setBounds, setComponentOrientation, setCursor,
setDropTarget, setEnabled, setFocusable, setFocusTraversalKeys,
setFocusTraversalKeysEnabled, setFont, setForeground, setIgnoreRepaint,
setLocale, setLocation, setLocation, setName, setSize, setSize,
setVisible, show, show, size, toString, transferFocus,
transferFocusBackward, transferFocusUpCycle, update, validate

Ejemplo (83): Programa completo para el uso


de Button.
// Archivo: UsoButton.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class UsoButton extends Applet
{
private Button boton1,boton2;
private int opcion;
public void init()
{
setBackground(Color.yellow);
PROGRAMACION CON JAVA 2

371

//declaracin e inicializacin de objetos Button


boton1=new Button("Funcin seno");
boton2=new Button("Funcin parbola");
//agegar botones
add(boton1);
add(boton2);

public void paint(Graphics g)


{
//llamar a la grafica de las funciones
switch(opcion)
{ case 1: fseno(g); break;
case 2: fparabola(g);break;
}
}
public boolean action(Event e, Object o)
{
//verificar si un boton dispar el evento
if(e.target instanceof Button)
{
//comprobar si se puls boton1 o boton2
if(e.target==boton1)
{opcion=1;repaint();} //opcion=1 y repintar
else if(e.target==boton2)
{opcion=2;repaint();}//opcion=2 y repintar
return true;
}
return true;
}
//dibuja la funcin seno
void fseno(Graphics g)
{
double x,y;
//(x, y) :
coordenadas cartesianas
int x0,y0; //(x0, y0): origen de las coordenadas cartesianas
// en la pantalla
double xp,yp;
//(xp, yp) :
coordenadas de pantalla
double angrad;
x0 = 400;
y0 = 200;
//dibuja ejes
g.drawLine(0,y0,800,y0);
g.drawLine(x0,0,x0,400);
//dibuja parabola
for(x=-400;x<=400;x++)
{
angrad=Math.toRadians(x);
y=100*Math.sin(angrad);
//convertir a coordenadas de pantalla
xp=x0+x;
372

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

yp=y0-y;
//dibujar punto
g.drawOval((int) xp,(int) yp,2,2);

//dibuja la funcin parabola


void fparabola(Graphics g)
{
double x,y;
//(x, y) :
coordenadas cartesianas
int x0,y0; //(x0, y0): origen de las coordenadas cartesianas
// en la pantalla
int xp,yp;
//(xp, yp) :
coordenadas de pantalla
x0 = 200;
y0 = 200;
//dibuja ejes
g.drawLine(0,y0,400,y0);
g.drawLine(x0,0,x0,400);
//dibuja parabola
for(x=-300;x<=300;x++)
{
y=x*x;
//convertir a coordenadas de pantalla
xp=(int)(x0+x);
yp=(int)(y0-y);
//dibujar punto
g.drawOval(xp,yp,2,2);
}
}
}
<!--Archivo: applet7.htm -->
<HTML>
<HEAD>
<TITLE> Applet en Java </TITLE>
</HEAD>
<BODY>
<APPLET CODE="UsoButton.class" WIDTH=1000 HEIGHT=400>
</APPLET>
</BODY>
</HTML>

La salida del programa cuando se pulsa funcin seno y funcin parbola se muestra en
las siguientes figuras.

PROGRAMACION CON JAVA 2

373

374

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

9.8. LOS GESTORES FLOWLAYOUT, BORDERLAYOUT Y


GRIDLAYOUT
En la superficie del applet se disponen los componentes, como paneles y controles. Ahora bien, las herramientas de diseo no disponen de opciones para situar
los componentes en lugares precisos, alinearlos, etc,
como ocurre en Windows, ya que en Java existen los denominados gestores de diseo que no sitan los componentes en posiciones absolutas, sino que la disposicin se determina mediante un algoritmo. El ms simple
de los gestores de diseo es FlowLayout y el ms complicado es GridBagLayout.
Para el programador acostumbrado a disear ventanas y
dilogos en el entorno Windows le parecer extraa esta forma de proceder y pensar que con este sistema
ser difcil elaborar un interfaz grfico de usuario.
Como veremos, se puede crear un diseo complejo mediante el gestor GridBagLayout y tambin, mediante la
aproximacin de paneles anidados.
No obstante, el programador debe percibir la diferencia entre applets y aplicaciones. Los applets estn
insertados en una pgina web y se ejecutan en la ventana del navegador. El applet comparte espacio con
texto, imgenes y otros elementos multimedia. El usuario tiene la libertad de moverse por la pgina, y por
otras pginas a travs de los enlaces. La percepcin
que tiene el usuario del applet es completamente distinta de la percepcin que tiene de una aplicacin que
llama completamente su atencin.
El programador debe tener en cuenta estas diferencias
de percepcin, y debe esforzarse en crear un diseo de
modo que el usuario encuentre evidente el manejo del
applet a primera vista.

9.8.1. EL GESTOR FlowLayout


FlowLayout es un gestor que pone los controles en una lnea, como puede verse en la figura

PROGRAMACION CON JAVA 2

375

Si se cambia el tamao del applet y los controles no caben en una lnea, pasan a la lnea siguiente, como puede verse en la figura.

El cdigo fuente
Los controles son objetos de la clase Button,
y el gestor de diseo es un objeto de la clase FlowLayout. Una vez inicializados los
miembros dato, en la funcin miembro init se
establecen sus propiedades y se aaden al applet mediante la funcin add, una vez establecido el gestor de diseo mediante setLayout. Los pasos son los siguientes:

Crear los botones (objetos de la clase


Button) y el gestor de diseo (objeto de
la clase FlowLayout)

Button btn1 = new Button();


FlowLayout flowLayout1 = new FlowLayout();

376

Establecer sus propiedades en init


A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

btn1.setFont(new Font("Dialog", 1, 16));


btn1.setLabel("1");
flowLayout1.setHgap(20);

Establecer el gestor de diseo del applet (o de un panel) mediante setLayout

this.setLayout(flowLayout1);

Aadir los controles al applet (o a un


panel) mediante add

this.add(btn1, null);

Lo que se ha dicho para un applet vale para


cualquier panel, ya que un applet no es otra
cosa que un panel especializado.
public class FlowApplet extends Applet
{
Button btn1 = new Button();
Button btn2 = new Button();
Button btn3 = new Button();
Button btn4 = new Button();
FlowLayout flowLayout1 = new FlowLayout();
{

public void init()

setBackground(Color.white);
btn1.setFont(new Font("Dialog",
btn1.setLabel("1");
btn2.setFont(new Font("Dialog",
btn2.setLabel("2");
btn3.setFont(new Font("Dialog",
btn3.setLabel("3");
btn4.setFont(new Font("Dialog",
btn4.setLabel("4");
flowLayout1.setHgap(20);
this.setLayout(flowLayout1);
this.add(btn1, null);
this.add(btn2, null);
this.add(btn3, null);
this.add(btn4, null);

1, 16));
1, 16));
1, 16));
1, 16));

9.8.2. EL GESTOR BorderLayout


Los pasos para establecer el gestor BorderLayout son distintos a los empleados para el
gestor FlowLayout.
PROGRAMACION CON JAVA 2

377

Crear los botones (objetos de la clase


Button) y el gestor de diseo (objeto de
la clase BorderLayout)

Button btnOeste = new Button();


BorderLayout borderLayout1 = new BorderLayout();

Establecer sus propiedades en init

btnOeste.setFont(new Font("Dialog", 1, 16));


btn1.setLabel("Oeste");

Aadir los controles al applet (o a un


panel) mediante add, indicando en el segundo argumento la posicin que ocupar
cada control en el panel mediante miembros estticos de la clase BorderLayout.

this.add(btnOeste, BorderLayout.WEST);
En este ejemplo, se han creado cinco botones
cuyos ttulos son Oeste, Norte, Sur, Este y
Centro. Cuando se aplica el gestor BorderLayout al applet los cinco botones se disponen
como se muestra en la figura.

Public class BorderApplet extends Applet


{
Button btnOeste = new Button();
Button btnEste = new Button();
Button btnNorte = new Button();
Button btnSur = new Button();
Button btnCentro = new Button();
378

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

BorderLayout borderLayout1 = new BorderLayout();


public void init()
{
setBackground(Color.white);
this.setSize(new Dimension(336, 253));
this.setLayout(borderLayout1);
btnOeste.setFont(new Font("Dialog", 1, 16));
btnOeste.setLabel("Oeste");
btnEste.setFont(new Font("Dialog", 1, 16));
btnEste.setLabel("Este");
btnNorte.setFont(new Font("Dialog", 1, 16));
btnNorte.setLabel("Norte");
btnSur.setFont(new Font("Dialog", 1, 16));
btnSur.setLabel("Sur");
btnCentro.setFont(new Font("Dialog", 1, 16));
btnCentro.setLabel("Centro");
borderLayout1.setVgap(20);
borderLayout1.setHgap(20);
this.add(btnOeste, BorderLayout.WEST);
this.add(btnEste, BorderLayout.EAST);
this.add(btnNorte, BorderLayout.NORTH);
this.add(btnSur, BorderLayout.SOUTH);
this.add(btnCentro, BorderLayout.CENTER);
}
}

9.8.3. EL GESTOR GridLayout


Los
pasos
para
establecer
el
gestor
GridLayout son idnticos a los que hemos
seguido
para
establecer
lel
gestor
FlowLayout. Este gestor dispone los controles
en forma de un matriz tal como puede verse en
la figura. Tenemos ocho botones dispuestos en
dos filas y en cuatro columnas.

PROGRAMACION CON JAVA 2

379

Para disponer los controles de esta manera,


hemos de seleccionar el objeto gridLayout1 en
el panel de estructura y cambiar las popiedades columns y rows. Opcionalmente podemos establecer un espaciado vertical y horizontal
entre los controles, introduciendo valores
las propiedades hgap y vgap.

public class GridApplet extends Applet


{
Button btn00 = new Button();
Button btn01 = new Button();
Button btn02 = new Button();
Button btn03 = new Button();
Button btn10 = new Button();
Button btn11 = new Button();
Button btn12 = new Button();
Button btn13 = new Button();
GridLayout gridLayout1 = new GridLayout();
{
380

public void init()


setBackground(Color.white);
btn00.setFont(new Font("Dialog", 1, 16));
A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

btn00.setLabel("00");
btn01.setFont(new Font("Dialog",
btn01.setLabel("01");
btn02.setFont(new Font("Dialog",
btn02.setLabel("02");
btn03.setFont(new Font("Dialog",
btn03.setLabel("03");
btn10.setFont(new Font("Dialog",
btn10.setLabel("10");
btn11.setFont(new Font("Dialog",
btn11.setLabel("11");
btn12.setFont(new Font("Dialog",
btn12.setLabel("12");
btn13.setFont(new Font("Dialog",
btn13.setLabel("13");
gridLayout1.setRows(2);
gridLayout1.setHgap(10);
gridLayout1.setColumns(3);
gridLayout1.setVgap(10);
this.setLayout(gridLayout1);
this.add(btn00, null);
this.add(btn01, null);
this.add(btn02, null);
this.add(btn03, null);
this.add(btn10, null);
this.add(btn11, null);
this.add(btn12, null);
this.add(btn13, null);

1, 16));
1, 16));
1, 16));
1, 16));
1, 16));
1, 16));
1, 16));

9.9. EL GESTOR DE DISEO GRIDBAGLAYOUT


El gestor de diseo GridBagLayout es muy complicado,
ya que est gobernado por un conjunto de propiedades
que estn interelacionados entre s. Los componentes
se disponen en una matriz tal como vimos al estudiar
el gestor GridLayout. En la figura vemos la disposicin de los controles y a la derecha los valores de
los propiedades de dicho gestor para el primer control
(en color gris oscuro)

9.9.1. EJEMPLO: DISEO DE UNA FICHA


Vamos a estudiar los pasos necesarios para
crear una ficha como la que muestra la figura
empleando el gestor de diseo GridBagLayout

PROGRAMACION CON JAVA 2

381

Aadimos un panel en la parte inferior del


applet y varios controles en la parte superior. Sobre el panel situamos dos botones.

9.9.2. EL PANEL
Poner un panel en la parte inferior y cambiar
su propiedad name
Panel panelBotones = new Panel();

Seleccionar en el panel panelBotones


cambiar su propiedad layout a XYLayout

Poner dos botones sobre el panel. Cambiar sus


propiedades name y label
Button btnPago=new Button();
382

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

Button btnCancelar=new Button();


btnPago.setLabel("Comprar");
btnCancelar.setLabel("Cancelar");

Seleccionar de nuevo en el panel panelBotones


y cambiar su propiedad layout a FlowLayout.
Los botones se sitan en el centro del panel.
Opcionalmente, establecer un espaciado horizontal entre los botones.

9.9.3. EL APPLET
Situar los siguientes controles sobre el applet cambiando su propiedad name.
Label
Label
Label
Label
Label
Label
Label

titulo=new Label();
nombre=new Label();
direccion=new Label();
pago=new Label();
telefono=new Label();
ciudad=new Label();
provincia=new Label();

TextField
TextField
TextField
TextField

textNombre=new TextField();
textDireccion=new TextField();
textCiudad=new TextField();
textProvincia=new TextField();

Choice chPago=new Choice();

Cambiar las propiedades de los controles a


los valores que se indican en el cdigo de la
funcin miembro init.
titulo.setText("Compre algo ahora");
titulo.setFont(new
Font("Times-Roman",
Font.ITALIC, 16));
nombre.setText("Nombre:");
direccion.setText("Direccin:");
pago.setText("Mtodo de pago:");
telefono.setText("Telfono:");
ciudad.setText("Ciudad:");
provincia.setText("Provincia:");

Font.BOLD

textNombre.setColumns(25);
textDireccion.setColumns(25);
textCiudad.setColumns(15);
textProvincia.setColumns(2);
btnPago.setLabel("Comprar");
btnCancelar.setLabel("Cancelar");
PROGRAMACION CON JAVA 2

383

Aadir elementos al control seleccin (Choice) denominado chPago.


chPago.add("Visa");
chPago.add("MasterCard");
chPago.add("Caja Ahorros");

9.9.4. EL GESTOR DE DISEO GRIDBAGLAYOUT


Crear
dos
objetos
uno
de
la
clase
GridBagLayout
y
otro
de
la
clase
GridBagConstraints.
El
segundo
objeto
establece los constraints. El objeto gbc
tiene los valores por defecto que hemos
mencionado en el primer apartado. Si se
cambia un valor de una propiedad (gridwidth,
anchor, fill, etc) el cambio permanece hasta
que se vuelve a establecer otro valor.
GridBagLayout gbl=new GridBagLayout();
GridBagConstraints gbc=new GridBagConstraints();

Establecer el gestor de diseo GridBagLayout


mediante setLayout.
setLayout(gbl);

9.9.5. AADIR LOS COMPONENTES AL APPLET


Se aade un componente al applet (o a un panel) en el que se ha establecido el gestor de
diseo GridBagLayout, y se han definido los
constraints del siguiente modo.
add(componente, constraints);

La primera fila est formada por un nico


(REMAINDER) componente el titulo, centrado en
la parte superior (NORTH)
gbc.anchor=GridBagConstraints.NORTH;
gbc.gridwidth=GridBagConstraints.REMAINDER;
add(titulo, gbc);
384

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

La segunda fila, est formada por dos controles, nombre y a continuacin textNombre. El
primero est anclado (anchor) al este (WEST),
antes estaba en NORTH, gridwidth toma el valor 1 (por defecto) antes estaba en REMAINDER. Como textNombre es el ltimo control de
la fila gridwidth vuelve a tomar el valor REMAINDER. Los controles ocupan todo el espacio
horizontal disponible, la propiedad fill toma
el valor HORIZONTAL
gbc.fill=GridBagConstraints.HORIZONTAL;
gbc.anchor=GridBagConstraints.WEST;
gbc.gridwidth=1;
add(nombre, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(textNombre, gbc);
La tercera fila, est formada por dos controles: direccion y textDireccion. Las propiedades anchor y fill ya tienen fijados sus valores a WEST y HORIZONTAL, por lo que no hay
que volver a establecerlo. Como textDireccion
es el ltimo control de la fila su propiedad
gridwidth toma el valor REMAINDER.
gbc.gridwidth = 1;
add(direccion, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(textDireccion, gbc);
La cuarta fila, est formada por cuatro controles: ciudad, textCiudad, provincia y textProvincia. Cuando se coloca el ltimo control
textProvincia, su propiedad gridwidth toma el
valor REMAINDER.
gbc.gridwidth = 1;
add(ciudad, gbc);
add(textCiudad, gbc);
add(provincia, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(textProvincia, gbc);

PROGRAMACION CON JAVA 2

La quinat fila, est formada por dos controles: pago y chPago. El cdigo es semejante,
salvo la propiedad fill que toma el valor NONE antes estaba en HORIZONTAL. Esto hace que
el control chPago no ocupe toda el rea disponible, extendindose horizontalmente hasta
385

alinearse con los otros controles por la parte derecha.


gbc.gridwidth = 1;
add(pago, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill=GridBagConstraints.NONE;
add(chPago, gbc);
Finalmente, aadimos el panel panelBotones
centrado. Cambiamos la propiedad anchor de
WEST a SOUTH.
gbc.anchor=GridBagConstraints.SOUTH;
add(panelBotones, gbc);
Terminamos el diseo de la ficha separando
convenientemente las filas de controles con
objetos de la clase Insets, tal como se muestra en el cdigo.
public class GridBagApplet1 extends Applet
{
Panel panelBotones = new Panel();
Label
Label
Label
Label
Label
Label
Label

titulo=new Label();
nombre=new Label();
direccion=new Label();
pago=new Label();
telefono=new Label();
ciudad=new Label();
provincia=new Label();

TextField
TextField
TextField
TextField

textNombre=new TextField();
textDireccion=new TextField();
textCiudad=new TextField();
textProvincia=new TextField();

Choice chPago=new Choice();


Button btnPago=new Button();
Button btnCancelar=new Button();
GridBagLayout gbl=new GridBagLayout();
GridBagConstraints gbc=new GridBagConstraints();
FlowLayout flowLayout1=new FlowLayout();
{

public void init()

setBackground(Color.lightGray);
//propiedades de los controles
titulo.setText("Compre algo ahora");
386

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

titulo.setFont(new
Font("Times-Roman",
Font.ITALIC, 16));
nombre.setText("Nombre:");
direccion.setText("Direccin:");
pago.setText("Mtodo de pago:");
telefono.setText("Telfono:");
ciudad.setText("Ciudad:");
provincia.setText("Provincia:");

Font.BOLD

textNombre.setColumns(25);
textDireccion.setColumns(25);
textCiudad.setColumns(15);
textProvincia.setColumns(2);
btnPago.setLabel("Comprar");
btnCancelar.setLabel("Cancelar");
chPago.add("Visa");
chPago.add("MasterCard");
chPago.add("Caja Ahorros");
//gestor gridBaglayout
setLayout(gbl);
//primera fila - ttulo
gbc.anchor=GridBagConstraints.NORTH;
gbc.insets=new Insets(0,0,10,0);
gbc.gridwidth=GridBagConstraints.REMAINDER;
add(titulo, gbc);
//segunda fila - nombre
gbc.fill=GridBagConstraints.HORIZONTAL;
gbc.anchor=GridBagConstraints.WEST;
gbc.gridwidth=1;
gbc.insets=new Insets(0,0,0,0);
add(nombre, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(textNombre, gbc);
//tercera fila - direccin
gbc.gridwidth = 1;
add(direccion, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(textDireccion, gbc);
//cuarta fila - ciudad
- provincia
gbc.gridwidth = 1;
add(ciudad, gbc);
add(textCiudad, gbc);
add(provincia, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(textProvincia, gbc);
//quinta fila - pago
gbc.gridwidth = 1;
add(pago, gbc);
gbc.insets=new Insets(5,0,5,0);
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill=GridBagConstraints.NONE;
add(chPago, gbc);
//panel de los botones
panelBotones.setLayout(flowLayout1);
PROGRAMACION CON JAVA 2

387

panelBotones.add(btnPago);
panelBotones.add(btnCancelar);

388

gbc.anchor=GridBagConstraints.SOUTH;
gbc.insets=new Insets(15,0,0,0);
add(panelBotones, gbc);

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

CAPITULO DIEZ
HILO Y SINCRONIZACIN
La programacin multihilo es un paradigma conceptual de la
programacin por el cual se dividen los programs en dos o ms
procesos que se pueden ejecutar en paralelo. En un momento
dado pueden haber datos de entrada de usuario a los que responder, animaciones y visualizaciones de interfaz de usuario,
tambin clculos grandes que podran tardar varios segundos
en terminar, y nuestros programas tendrn que tratar con estos temas sin provocar retrasos desagradables al usuario.
Lo interesante de todos estos procesos en paralelo es que la
mayor parte de ellos realmente no necesitan los recursos completos de la computadora durante su vida operativa. El problema en los entornos de hilo nico tradicionales es que se
tiene que esperar a que se terminen cada una de estas tareas
antes de proseguir con la siguiente. Aunque la CPU est libre
la mayor parte del tiempo, tiene que colocar las tareas en la
cola ordenadamente.

10.1. EL MODELO DE HILO DE JAVA


Los sistemas multihilo aprovechan la circunstancia de
que la mayora de los hilos computacionales invierten
la mayor parte del tiempo esperando a que un recurso
quede disponible, o bien esperando a que se cumpla alguna condicin de temporizacin. Si fusemos capaces
de describir todas las tareas como hilos de control
independientes, conmutando de manera automtica entre
PROGRAMACION CON JAVA 2

389

una tarea que est lista para pasar a un modo de espera, y otra que s tenga algo que hacer, conseguiramos
realizar una cantidad mayor de trabajo en le mismo intervalo de tiempo.
Java se diseo partiendo de cero, en un mundo en el
que el entorno multihilo, a nivel de sistema operativo, era una realidad. El intrprete de Java hace uso
intensivo de hilos para multitud de propsitos, y todas las bibliotecas de clases se disearon teniendo en
mente el modelo multihilo. Una vez que un hilo comienza su tarea, puede suspenderse, lo que equivale a detener temporalmente su actividad. El hilo suspendido
puede reanudarse, lo que supone que contina su tarea
all donde la dej. En cualquier momento, un hilo puede deteriores, finalizando su ejecucin de manera inmediata. Una vez detenido, el proceso no puede reiniciarse.

10.1.1. PRIORIDADES DE HILO


El intrprete de Java utiliza prioridades para determinar cmo debe comportarse cada hilo
con respecto a los dems. Las prioridades de
hilo son valores entre 1 y 10 que indican la
prioridad relativa de un hilo con respecto a
los dems.

10.1.2. SINCRONIZACIN

390

Ya que los hilos permiten y potencian el comportamiento asncrono de los programas, debe
existir alguna manera de forzar el sincronismo all donde sea necesario. Por ejemplo, si
desease que dos hilos se comunicasen para
compartir una estructura de datos compleja
(como una lista enlazada), necesitar alguna
manera de garantizar que cada uno se aparte
del camino del otro. Java incorpora una versin rebuscada de un modelo clsico para la
sincronizacin, el monitor. La mayor parte de
los sistemas multihilo implementan los monitores a modo de objetos, pero Java proporciona una solucin ms elegante: no existe la
clase monitor, cada objeto lleva asociado su
propio monitor implcito, en el que puede entrar sin ms que hacer una llamada a los mtodos synchronized del objeto. Una vez que el
hilo est dentro del mtodo synchronized,
A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

ningn otro hilo puede efectuar una llamada a


otro mtodo synchronized sobre el mismo objeto.

10.1.3. INTERCAMBIO DE MENSAJES


Una vez que el programa se ha dividido en sus
partes lgicas, a modo de hilo, es preciso
definir exactamente como se comunicarn entre
si dichos hilos. Java utiliza los mtodos
wait y notify para el intercambio de informacin entre hilos.

10.2. THREAD
En Java los hilos se representa mediante una clase. La
clase Thread encapsula todo el control necesario sobre
los hilos. Hay que tomar la precaucin de distinguir
claramente un objeto Thread de un hilo en ejecucin.
Un objeto Thread se define como el panel de control o
proxy de un hilo en ejecucin. En el objeto Thread hay
mtodos que controlan si el hilo se est ejecutando,
est durmiendo, en suspenso o detenido. La clase
Thread es la nica manera de controlar el comportamiento de los hilos. En la siguiente instruccin se
muestra como acceder al hilo en ejecucin actual:
Thread t = Thread.currentThread();
* el hilo actual se almacena en la variable t *

10.3. RUNNABLE
Si queremos tener ms de un hilo necesitamos crear
otra instancia de Thread. Cuando construimos una nueva
instancia de Thread, necesitamos decirle que cdigo
ejecutar en el nuevo hilo de control. Se puede comenzar un hilo sobre cualquier objeto que implemente la
interfaz Runnable.
Runnable es una interfaz simple que abstrae la nocin
de que se desea que algn cdigo se "ejecute" asncronamente. Para implementar Runnable, a una clase le
basta con implementar un solo mtodo llamado run. Este
es un ejemplo que crea un nuevo hilo.

PROGRAMACION CON JAVA 2

391

class ThreadDemo implements Runnable


{
ThreadDemo() {
Thread ct = Thread.currentThread();
Thread t = new Thread(this, "demo
Thread");
System.out.println("hilo actual: " +
ct);
System.out.println("Hilo creado: " + t);
t.start();
try {
Thread.sleep(3000);
} catch (interrupteExecption e) {
System.out.println("Interrumpido");
}
System.out.println(!saliendo
del
hilo
main");
}
public void run() {
try {
for >(int y = 5; y > 0; y--) {
System.out.println(" " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("hijo interrumpido");
}
System.out.println("saliendo
del
hilo
hijo");
}
public static void main (String args []) {
new ThreadDemo();
}
}

El hilo main crea un nuevo objeto Thread, con new


Thread (this, "Demo Thread"), pasando this como primer
argumento para indicar que queremos que el nuevo hilo
llame al mtodo run sobre este (this) objeto. A continuacin llamamos a start, lo que inicia el hilo de la
ejecucin a partir del mtodo run. Despus, el hilo
main se duerme durante 3000 milisegundos antes de imprimir un mensaje y despus termina. Demo Thread todava est contando desde cinco cuando sucede esto. Se
contina ejecutando hasta que termina con el bucle de
run. Esta es la salida despus de cinco segundos:
C:\>
Hilo
Hilo
5
4
392

java
ThreadDemo
actual:
Thread[main,
5,
main]
creado:
Thread[demo
Thread,
5,
main]

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

3
saliendo
del
2
1
saliendo del hilo hijo

hilo

main

10.4. PRIORIDADES DE LOS HILOS


El planificador de hilos hace uso de las prioridades
de los mismos para decidir cundo debe dejar a cada
hilo que se ejecute, de manera que los hilos con mayor
prioridad deben ejecutarse ms a menudo que lo de menor prioridad. Cuando est ejecutndose un hilo de baja prioridad, y otro de mayor prioridad se despierta
de su sueo, o de la espera por un operacin de E/S,
debe dejarse que se ejecute de manera inmediata, desalojando al hilo de menor prioridad. Cuando los hilos
son de igual prioridad deben desalojarse los unos a
los otros, cada cierto tiempo, utilizando el algoritmo
circular round-robin para gestionar el acceso al la
CPU.
En JDK 1.0 la planificacin de hilos es un problema
que no est completamente resuelto. Por lo que si pretendemos tener un comportamiento predecible sobre las
aplicaciones deberemos utilizar hilos que, voluntariamente, cedan el control de la CPU.

10.5. SINCRONIZACIN
Cuando dos o ms hilos necesitan acceder de manera simultnea a un recurso de datos compartido necesitan
asegurarse de que slo uno de ellos accede al mismo
cada vez. Java proporciona un soporte nico, el monitor, es un objeto que se utiliza como cerrojo exclusivo. Solo uno de los hilos puede ser el propietario de
un monitor en un instante dado. Los restantes hilos
que estuviesen intentando acceder al monitor bloqueado
quedan en suspenso hasta que el hilo propietario salga
del monitor.
Todos los objetos de Java disponen de un monitor propio implcitamente asociado a ellos. La manera de acceder a un objeto monitor es llamando a un mtodo marcado con la palabra clave synchronized. Durante todo
el tiempo en que un hilo permanezca en un mtodo sincronizado, los dems hilos que intenten llamar a un
mtodo sincronizado sobre la misma instancia tendrn
PROGRAMACION CON JAVA 2

393

que esperar. Para salir del monitor y permitir el control del objeto al siguiente hilo en espera, el propietario del monitor slo tiene que volver del mtodo

10.5.1. LA SENTENCIA SYNCHRONIZED


Si se utiliza una clase que no fue diseada
para accesos multihilo y, por ello, dispone
de mtodos no sincronizados que manipulan el
estado interno, puede envolver la llamada al
mtodo en un bloque sincronizado. El formato
general de la sentencia sincronizada es el
siguiente:
synchronized(objeto) sentencia;
En el ejemplo, objeto es cualquier referencia
al objeto, y sentencia suele ser un bloque
que incluye una llamada al mtodo de objeto,
que solo tendr lugar una vez que el hilo
haya entrado con xito en el monitor de objeto. Ahora veremos las formas de sincronizacin con un ejemplo:
class Callme {

void call (String msg) { * tambin poda


haber puesto synchronized antes de void *
System.out.print("[" + msg);
try Thread.sleep(1000); catch (Exception
e);
System.out.println("]");
}
}
class caller implements Runnable {
String msg;
Callme target;
public caller(Callme t, String s) {
target = t;
msg = s;
new Thread(this).start();
}
public void run() {
synchronized(target) {
target.call(msg);
}
}
}
class Synch {
public static void main(String args[]) {
Callme target = new Callme();
new caller(target, "Hola");
new caller(target, "Mundo");
new caller(target, "Sincronizado");
394

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

Este programa imprime por pantalla el literal "Hola


Mundo Sincronizado", cada palabra en una lnea y entre
comillas, se crea una instancia de Callme y tres instancias de caller que cada una de ellas referencia al
mismo Callme con lo que necesitamos de una sincronizacin para el acceso a Callme, pues sino se mezclaran
las tres llamada al haber una sentencia sleep que retrasa la ejecucin de Callme dando lugar a que antes
de que acabe un proceso deje libre el acceso a dicho
objeto.

10.6. COMUNICACIN ENTRE HILOS


Veamos, por ejemplo, el problema clsico de las colas,
donde uno de los hilos produce datos y otro los consume. Para que el problema sea ms interesante supongamos que el productor tiene que esperar a que el consumidor haya terminado, para empezar a producir ms datos. En un sistema basado en sondeo el consumidor estara desperdiciando ciclos de CPU mientras espera a
que el productor produzca. Una vez que el productor ha
terminado, se queda sondeando hasta ver que el consumidor ha finalizado, y as sucesivamente.
Evidentemente, hay una forma mejor de hacerlo. Java
proporciona un mecanismo elegante de comunicacin entre procesos, a travs de los mtodos wait, notify y
notifyAll. Estos mtodos se implementan como mtodos
de final en Object, de manera que todas las clases
disponen de ellos. Cualquiera de los tres mtodos slo
puede ser llamado desde dentro de un mtodo synchronized.

wait: le indica al hilo en curso que abandone el


monitor y se vaya a dormir hasta que otro hilo entre en el mismo monitor y llame a notify.

notify: despierta al primer hilo que realiz una


llamada a wait sobre el mismo objeto.

notifyAll_: despierta todos los hilos que realizaron una llamada a wait sobre el mismo objeto. El
hilo con mayor prioridad de los despertados es el
primero en ejecutarse.

PROGRAMACION CON JAVA 2

395

El ejemplo del productor y el consumidor es en Java


como sigue:
class Q {

int n;
boolean valueSet = false;
synchronized int get() {
if (!valueSet)
try
wait();
catch(InterruptedException e);
System.out.println("Obtenido: " + n);
valueSet = false;
notify();
return n;
}
synchronized void put(int n) {
if (valueSet)
try
wait();
catch(InterruptedException e);
this.n = n;
valueSet = true;
System.out.println("Colocado: " + n);
notify();
}
}
class Producer implements Runnable {
Q q;
Producer (Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int y = 0;
while(true) {
q.put(i++);
}
}
}
class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get();
}
}
class PC {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
}
}
396

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

10.6.1. BLOQUEOS
Los bloqueos son condiciones anmalas inusuales, pero muy difciles de depurar, donde dos
hilos presentan una dependencia circular sobre un par de objetos sincronizados. Por
ejemplo, si un hilo entra en el monitor sobre
el objeto X y otro hilo entra en le monitor
sobre el objeto Y, y si X intenta llamar a
cualquier mtodo sincronizado sobre Y, tal y
como cabe esperar quedar detenido. Sin embargo, si Y, por su parte, intenta llamar a
cualquier mtodo sincronizado con X, entonces
quedar esperando indefinidamente, ya que para conseguir el cerrojo de X tendra antes
que liberar su propio cerrojo en Y, con el
fin de que el primer hilo pudiera completarse.

10.7. RESUMEN DE LA INTERFAZ DE PROGRAMACIN


(API) DE HILOS
Se incluye a continuacin una referencia rpida a todos los mtodos de la clase Thread que se han comentado en este captulo.

10.7.1. MTODOS DE CLASE


Estos son los mtodos estticos
llamarse de manera directa en
Thread.

PROGRAMACION CON JAVA 2

que
la

deben
clase

currentThread: el mtodo esttico devuelve el objeto Thread que representa


al hilo que se ejecuta actualmente.

yield: este mtodo hace que el intrprete cambie de contexto entre el hilo actual y el siguiente hilo ejecutable disponible. Es una manera de asegurar que
los hilos de menor prioridad no sufran
inanicin.

Sleep(int n): el mtodo sleep provoca


que el intrprete ponga al hilo en curso
a dormir durante n milisegundos. Una vez
transcurridos los n milisegundos, dicho
hilo volver a estar disponible para su
397

ejecucin. Los relojes asociados a la


mayor parte de los intrpretes Java nos
sern capaces de obtener precisiones mayores de 10 milisegundos.

10.7.2. MTODOS DE INSTANCIA

398

start: indica al intrprete de Java que


cree un contexto de hilo del sistema y
comience a ejecutarlo. A continuacin,
el mtodo run objeto de este hilo ser
llamado en el nuevo contexto del hilo.
Debe tomarse la precaucin de no llamar
al mtodo start ms de una vez sobre un
objeto hilo dado.

run: constituye el cuerpo de un hilo en


ejecucin. Este es el nico mtodo de la
interfaz Runnable. Es llamado por el mtodo start despus de que el hilo apropiado del sistema se haya inicializado.
Siempre que el mtodo run devuelva el
control, el hilo actual se detendr.

stop: provoca que el hilo se detenga de


manera inmediata. A menudo constituye
una manera brusca de detener un hilo,
especialmente si este mtodo se ejecuta
sobre el hilo en curso. En tal caso, la
lnea inmediatamente posterior a la llamada al mtodo stop no llega a ejecutarse jams, pues el contexto del hilo muere antes de que stop devuelva el control.

suspend: es distinto de stop. suspend


toma el hilo y provoca que se detenga su
ejecucin sin destruir el hilo de sistema subyacente, ni el estado del hilo anteriormente en ejecucin. Si la ejecucin de un hilo se suspende, puede llamarse a resume sobre el mismo hilo para
lograr que vuelva a ejecutarse de nuevo.

resume: se utiliza para revivir un hilo


suspendido.

A. GAMARRA M. D. GAMARRA M. J. GAMARRA M.

PROGRAMACION CON JAVA 2

setPriority(int p): asigna al hilo la


prioridad indicada por el valor entero
pasado como parmetro.

getPriority: devuelve la prioridad del


hilo en curso, que es un valor entre 1 y
10.

setName(String nombre): identifica al


hilo con un nombre mnemnico. De esta
manera se facilita la depuracin de programas multihilo.

getName: devuelve el valor actual, de


tipo cadena, asignado como nombre al
hilo mediante setName.

399

BIBLIOGRAFIA

1. Allen Weiss, Mark (2000). Estructuras de Datos en Java,


compatible con Java 2. Editorial Addison Wesley. Espaa.
2. Ceballos Sierra, Javier (2000). JAVA 2 Curso de Programacin. Editorial Alfaomega-Rama. Mxico.
3. December, John (1996). Introduccin a Java. Editorial
Prentice Hall. Mxico.
4. Decker, Rick y Hirshfield, Stuart (2001). Introduccin a
la Programacin en Java. Segunda edicin. Mxico.
5. Deitel, H. M. y Deitel, P. J.(1998).Cmo programar en Java. Editorial Prentice Hall. Mxico.
6. Froufe Quintas, Agustn (2000). JAVA 2 Manual de usuario
y tutorial. Editorial Alfaomega-Rama. Mxico.
7. J. Koosis, Donald y S. Koosis, David (1996). Java Programming For Dummies. Editorial IDG Books. USA.
8. S. Wang, Paul (2000). Java con programacin orientada a
objetos y aplicaciones en la World Wide Web. Editorial
Thomson. Mxico.

PROGRAMACION CON JAVA 2

401

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