Download - Lenguaje de programacion i
Excelencia Académica
5
PROGRAMACIÓN GENERAL
UNIDAD TEMÁTICA Nº 1 Representación de datos en el computador Estructura de un computador Hardware Software y lenguajes de programación Autoaprendizaje 8 horas
UNIDAD TEMÁTICA Nº 2 Fundamentos de la Programación Orientada a Objetos El lenguaje de Programación Java Modelamiento de Problemas Actividad 2.1 Componentes de una solución Actividad 2.2 Modelaje Características de los datos Especificación Actividad 2.3 Refinamiento a pasos Pasos para el refinamiento a pasos Actividad 2.4 Autoaprendizaje 8 horas
UNIDAD TEMÁTICA Nº 3 Estructura de un programa orientado a objetos Gramática en Java Comentarios Identificadores Palabras reservadas Importación de clases Declaración de clases y métodos El IDE de Java Tipos de datos en Java Declaración de datos Instrucciones en Java Operadores aritméticos Instrucciones de salida de datos en Java Instrucciones de entrada de datos en Java Traducción del modelaje y especificación a un programa Java Autoaprendizaje 8 horas
UNIDAD TEMÁTICA Nº 4 Taller de programación 1 La clase math Funciones matemáticas La clase carácter
Excelencia Académica
6
Declaraciones Comprobaciones boleanas Traslación de caracteres Métodos de la clase carácter La clase float La clase double La clase integer La clase long La clase bolean La clase String Autoaprendizaje 8 horas
UNIDAD TEMÁTICA Nº 5 Estructuras de Control Estructura condicional if y switch La sentencia switch Actividad 5.1 Ciclos repetitivos Bucle while Bucle do-while Bucle for Sentencias de salto: break, continue y return Sentencia break Sentencia continue Sentencia return Actividad 5.2 Autoaprendizaje 8 horas
UNIDAD TEMÁTICA Nº 6 Métodos, características y propiedades Clases y métodos abstractos Modificadores de visibilidad Otros modificadores Conceptos básicos de arreglos Declaración de arreglos Creación de objetos de arreglos Arreglos multidimensionales Autoaprendizaje 8 horas
UNIDAD TEMÁTICA Nº 7 Paquetes Autoaprendizaje 8 horas
UNIDAD TEMÁTICA Nº 8 Gráficos Autoaprendizaje 8 horas
Excelencia Académica
7
TABLA DE CONTENIDO UNIDAD TEMÁTICA I Representación de datos en el computador 9 Estructura de un computador 11 Hardware 11 Software y lenguajes de programación 13 UNIDAD TEMÁTICA II Fundamentos de la Programación Orientada a Objetos 17 El lenguaje de Programación Java 19 Modelamiento de Problemas 20 Componentes de una solución 21 Modelaje 22 Características de los datos 22 Especificación 22 Refinamiento a pasos 23 Pasos para el refinamiento a pasos 24 UNIDAD TEMÁTICA III Estructura de un programa orientado a objetos 29 Gramática en Java 29 Comentarios 29 Identificadores 30 Palabras reservadas 31 Importación de clases 31 Declaración de clases y métodos 32 El IDE de Java 32 Tipos de datos en Java 35 Declaración de datos 37 Instrucciones en Java 37 Operadores aritméticos 38 Instrucciones de salida e datos en Java 40 Instrucciones de entrada de datos en Java 41 Traducción del modelaje y especificación a un programa Java 41 UNIDAD TEMÁTICA IV Taller de programación I 47 La clase math 49 Funciones matemáticas 50 La clase carácter 53 Declaraciones 53 Comprobaciones boleanas 53 Traslación de caracteres 53 Métodos de la clase carácter 53 La clase float 54 La clase double 54
Excelencia Académica
8
La clase integer 55 La clase long 56 La clase bolean 57 La clase String 58 UNIDAD TEMÁTICA V Estructuras de Control 65 Estructura condicional if y switch 65 La sentencia switch 66 Ciclos repetitivos 69 Bucle while 70 Bucle do-while 70 Bucle for 71 Sentencias de salto: break, continue y return 71 Sentencia break 71 Sentencia continue 72 Sentencia return 73 UNIDAD TEMÁTICA VI Métodos, características y propiedades 77 Clases y métodos abstractos 78 Modificadores de visibilidad 80 Otros modificadores 81 Conceptos básicos de arreglos 82 Declaración de arreglos 82 Creación de objetos de arreglos 83 Arreglos multidimensionales 85 UNIDAD TEMÁTICA VII Conceptos básicos de la programación orientada a objetos 89 Atributos 89 Comportamiento 89 El proyecto 90 La clase 90 Los constructores 93 La vida de un objeto 97 Composición 100 Los paquetes 104 Classpath 105 Los paquetes estándar 107 Interfaces 107 UNIDAD TEMÁTICA VIII Fundamentos para el dibujo con Java 115 Las funciones Saint, repaint y update 115 Visualización de las imágenes 118 Dibujos 123 Apéndices 129
Excelencia Académica
9
REPRESENTACIÓN DE DATOS DE UN
COMPUTADOR Los computadores manejan los datos usando solamente los dígitos binarios 0 y 1 a los que
se les denomina bit. Con este sistema los números se calculan usando potencias de 2 en el
sistema de numeración binario.
Los números binarios se pueden representar fácilmente en otras potencias cuya base es
múltiplo de 2, como la base 8 u octal y la base 16 o hexadecimal.
Una forma fácil de pasar de binario a octal es agrupar los bits de 3 en 3 y representar su
número octal:
Binario Octal
000 0
001 1
010 2
011 3
100 4
101 5
110 6
111 7
De forma similar, se pueden representar los datos en base hexadecimal (base 16), basta
con agrupar los bits en grupos de 4 y representar sus números equivalentes en
hexadecimal:
Binario Hexadecimal Decimal Binario Hexadecimal Decimal
0000 0 0 1000 8 8
0001 1 1 1001 9 9
0010 2 2 1010 A 10
0011 3 3 1011 B 11
0100 4 4 1100 C 12
0101 5 5 1101 D 13
0110 6 6 1110 E 14
0111 7 7 1111 F 15
Excelencia Académica
10
Los Números con Signo
De acuerdo al sistema de numeración que se use se reserva por lo general el bit de más a
la izquierda para el signo. Para evitar las ambigüedades del cero cuando se usan la
representación con signo casi universalmente se ha adoptado el sistema de representación
en complemento a 2. La conversión es un poco más difícil de entender inicialmente, pero la
representación en complemento a 2 con números de 8 bits seria:
Binario Decimal
0011 3
0010 2
0001 1
0000 0
1101 -1
1110 -2
1111 -3
En cualquier caso, con 8 bits se pueden representar números sin signo desde 0 hasta 255
mientras que los números con signo serán desde -128 hasta 127.
Los números se representan según algoritmos o métodos de conversión que dependen del
tipo de dato que se quiere representar como enteros sin signo, enteros con signo, números
reales o de punto flotante, números reales de doble precisión, etc.
En cambio el otro tipo de datos que se maneja son los caracteres que van a formar los
textos, estos caracteres se representan mediante un código numérico equivalente, es decir
a cada símbolo de texto o carácter se se asigna un número equivalente llamado código,
siendo el más común el código ASCII que sirve para representar hasta 256 caracteres
diferentes con valores equivalentes desde 0 a 255.
Como la cantidad de caracteres necesarios para realizar comunicaciones es mayor a 256
símbolos, como el caso del español que maneja la ñ y las tildes, o en otros lenguajes que
manejan símbolos especiales, se ha tenido que ampliar la cantidad de símbolos codificados
por lo que actualmente se maneja el UNICODE que dispone de una mayor cantidad de
códigos ya que maneja 16 bits que equivale a 65,536 códigos diferentes.
Así, la letra A se representa con el código 65, el espacio en blanco tiene el código 32, la
letra a se representa con el código 97, el carácter de tabulación tiene el código 9, etc.
Se denomina byte al grupo de 8 bits y es la unidad básica de almacenamiento de datos que
se usa. Esta unidad tiene algunos múltiplos conocidos que son los siguietes:
Kilobyte o Kbyte o Kb equivale a 210 bytes o 1,024 bytes aprox. 103 bytes
Megabyte o Mbyte o Mb equivale a 220 bytes o 1’048,576 bytes aprox. 106 bytes
Gigabyte o Gbyte o Gb equivale a 230 bytes o 1,073’741,824 bytes aprox. 103 bytes
Excelencia Académica
11
Estructura de un Computador Todos los computadores para su funcionamiento requieren dos componentes
fundamentales que son el Hardware y el Software.
Hardware Son todos los componentes físicos que forman parte de la computadora, es todo lo que se
puede ver y tocar.
Todos los computadores personales tienen una estructura similar que esta formada por
cuatro componentes básicos que son : La CPU (Unidad Central de Procesamiento), La
Memoria, Unidades de entrada/salida y los dispositivos de almacenamiento.
La Unidad Central de Procesamiento (CPU o microprocesador) es el componente principal
y es el lugar en donde se realizan las operaciones lógicas y matemáticas siendo sus
elementos principales los siguientes:
- La Unidad de Control : es la responsable de ejecutar las instrucciones y controlar el
computador.
- Unidad Aritmético Lógica (ALU) donde se realizan las operaciones aritméticas y
lógicas.
- Registros, son pequeñas memorias de alta velocidad donde se almacenan datos e
instrucciones que se están ejecutando.
La evolución respecto a la velocidad de estos procesadores ha sido vertiginosa ya
actualmente los Pentium IV tienen velocidades de 2.4 y 3.0 MHz.
La memoria
La memoria de un computador es el lugar donde se almacenan los datos que el
computador usa como son las instrucciones, los valores de las variables, los valores de las
constantes, el código de programa, el código de las funciones y/o métodos, etc.
En forma básica las memorias pueden ser de dos tipos, memoria RAM y memoria ROM.
Existen otros tipos de memoria derivados de estos dos tipos fundamentales, pero para
nuestro estudio solamente trataremos estos dos tipos de memoria.
El tamaño de una memoria se mide o especifica en bytes con sus múltiplos Kilobyte,
Megabyte o Gigabyte que equivalen aproximadamente a mil bytes, un millón de bytes y mil
millones de bytes respectivamente como se ha visto en un tema anterior.
La memoria RAM
La Memoria de Acceso Aleatorio (RAM) es el lugar en donde se almacenan
los datos e instrucciones del programa así como los datos generados durante la ejecución
del programa. Esta memoria es volátil ya que los datos que almacena se pierden si se
interrumpe la fuente de energía eléctrica. Como su nombre lo indica es una memoria de
acceso aleatorio, es decir el programador tiene acceso total a esta memoria para poner
Excelencia Académica
12
datos, modificar sus valores, borrar datos o instrucciones, etc. Por lo que en esta memoria
se pueden leer y escribir datos.
El tamaño actual más difundido de memoria RAM es de 256 Mb.
La memoria ROM
La memoria ROM (Read Only Memory), es la memoria solamente de lectura. En esta
memoria se almacenan datos y programas que solamente pueden ser leídos para su uso
posterior. Esta memoria, como su nombre lo indica, es una memoria solamente de lectura y
los datos que almacena no pueden ser modificados. Esta memoria es permanente o no
volátil, es decir que los datos guardados no desaparecen cuando se interrumpe la fuente
de energía eléctrica como ocurre con las memorias RAM.
Un ejemplo de este tipo de memoria es la BIOS (Basic Input Output System) de la
computadora, que tiene almacenado el programa de arranque inicial de la computadora
que se ejecuta cada vez que prendemos la computadora y nunca puede ser modificado.
Dispositivos de entrada de datos
Los dispositivos de entrada de datos son la base de la comunicación entre el hombre y el
computador, son dispositivos que sirven para convertir las señales analógicas, usadas por
el hombre, en señales digitales entendibles por la computadora.
Los dispositivos de entrada más comunes son el teclado, mouse, lectora óptica, lápiz
óptico, scanner, etc.
Dispositivos de salida de datos
Los dispositivos de salida de datos son las interfases máquina-hombre, son aquellos que
se encargan de convertir las señales digitales en señales analógicas que el ser humano
puede entender.
Los dispositivos de salida más comunes son el monitor de video, las impresoras, ploter,
etc.
Dispositivos y medios de almacenamiento
Los medios de almacenamiento proporcionan almacenamiento permanente de datos, son
más lentos que la memoria RAM pero permiten almacenar gran cantidad de datos
almacenando programas y datos. Estos dispositivos son los diskettes, discos duros, CD
Rom, DVD, etc. Siendo el más común el disco duro de 80 Gb.
Los dispositivos de almacenamiento son los equipos que manejan los medios de
almacenamiento como las lectoras de CD Rom, los disketeras o floppy, etc.
Excelencia Académica
13
Software y lenguaje de programación El hardware solo no puede ejecutar ni hacer nada por lo que es necesario que todo
computador tenga también su software. El software es el llamado programa, es un conjunto
de instrucciones u ordenes con una secuencia definida que el computador ejecuta. Estas
instrucciones se escriben en un lenguaje que el computador entienda.
A medida que la estructura y la programación de los computadores se fue complicando y
creciendo, los fabricantes empezaron a proporcionar utilidades para hacer más fácil la
administración y programación del computador implementando sistemas operativos,
compiladores y programas de usuario.
De acuerdo a este cuadro hay dos capas fundamentales:
Software de sistema o software base, es decir aquel que proporciona los mecanismos de
gestión del hardware como el sistema operativo y las utilidades para desarrollar el software
de aplicación (compiladote, editores, bibliotecas, etc.). Sirven como base para el desarrollo
y la ejecución de otros programas y permite que el software de aplicación pueda acceder al
hardware subyacente. Los sistemas operativos para computadoras personales más
comunes actualmente son Windows y Linux. Además de su software propio incluyen
muchas bibliotecas y utilidades externas al sistema operativo, pero que también se
consideran software del sistema.
Software de aplicación, es decir aplicaciones que facilitan el acceso a los servicios del
computador. A veces como en el caso de Windows son estas aplicaciones las que
caracterizan al sistema de computación como su interfaz grafica, su explorador y sus
herramientas ofimáticas que son software de aplicaron muy útiles para los usuarios.
Además del sistema operativo y sus bibliotecas, el software de sistema incluye editores
para introducir textos y programas en el computador, como compiladores, intérpretes, etc.
Los compiladores permiten traducir un programa escrito en un lenguaje de alto nivel a un
formato intermedio denominado código objeto y este código se traduce a lenguaje de
máquina mediante un enlazador (linker). Cada lenguaje necesita su propio compilador,
pero el enlazador es el mismo para cada arquitectura y tipo de archivo ejecutable.
Hay muchos lenguajes de programación, al igual que hay muchas lenguas en el mundo.
Sin embargo, se pueden clasificar en base a su complejidad en:
- Lenguajes de máquina, cada CPU o procesador entiende su propio lenguaje
denominado lenguaje de máquina. Las instrucciones de este lenguaje están
codificadas en binario y son de muy bajo nivel, siendo muy tedioso y difícil escribir
programas directamente en lenguaje de máquina.
Programas de Usuario, Aplicaciones
Compiladores Editores Bibliotecas …
Sistema Operativo
Hardware
Excelencia Académica
14
- Lenguaje Ensamblador, permite una programación simbólica con instrucciones
lógicas, que posteriormente se traducen a lenguaje de máquina por medio de un
compilador. Escribir programas en lenguaje ensamblador es mucho más rápido,
pero no lo suficiente como para escribir programas complejos.
- Lenguajes de Alto Nivel, permiten a los programadores expresar estructuras de
datos y de control de forma más sencilla y más parecida a la lógica de aplicaciones
que a las necesidades de arquitectura del computador. El primer lenguaje de este
tipo fue FORTRAN, luego COBOL y le siguieron muchos lenguajes entre ellos
Pascal, C y Turbo C, Java y otros.
Toda computadora tiene dos componentes que son el hardware y el software siendo el
hardware la parte física y el hardware la parte lógica o de los programas.
Los datos se representan por medio de bits donde los números son representados
mediante algoritmos que de acuerdo al tipo de número lo convierten a una representación
de bits.
Los caracteres de texto se representan mediante números equivalentes llamados códigos
siendo el más común los Códigos ASCII aunque actualmente por la cantidad de símbolos
que se manejan se ha difundido el UNICODE.
El harware básico de la computadora está formado por las unidades de entrada, unidades
de salida, la unidad central de procesamiento o CPU y la memoria teniendo además
componentes adicionales llamados periféricos que se conectan a la CPU como son las
unidades de almacenamiento y otros.
Fco. Javier Ceballos Curso de Programación Java 2
Alfaomega-Rama, España 2,003 Segunda Edición
Luis Joyanes Aguilar Programación en Java
Prentice Hall, España
José Pérez Mayor Programación en Java Paso a Paso
Thomson, España 2,003
Deitel y Deitel Curso de Programación en Java
Prentice Hall, España, 1,995
Excelencia Académica
15
Habiendo estudiado la representación de datos y los componentes hardware y software de
la computadora, en el siguiente UNIDAD TEMÁTICA se estudiará los fundamentos de la
programación orientada a objetos y la construcción de programas usando el lenguaje Java.
Se debe tener en cuenta que las computadoras solo manejan números, y más
específicamente números binarios por lo que todos los datos que manejan deben ser
representados como números binarios. La programación usando números binarios o
lenguaje de máquina es muy complicada por lo que se usan lenguajes de alto nivel como
Java para escribir los programas de aplicación.
- Investigar como se realiza la representación de números reales con signo.
- Buscar y copiar el código ASCII y verificar el código de las letras, números y signos de
puntuación.
- En una computadora identificar sus componentes de hardware y sus respectivas
características como la velocidad y capacidad de memoria.
Identifica y describe los componentes de hardware y software de la computadora.
Explica en forma clara cómo se representan los datos en la computadora y lo que son los
lenguajes de programación.
Excelencia Académica
16
Nº 1
Nombre__________________________________________________________________
Apellidos_______________________________________Fecha _____________________
Ciudad ______________________________Semestre_____________________________
1.- Describir las partes de un computador referido al hardware del equipo.
2.- Describir la clasificación de los lenguajes de programación de acuerdo a su
complejidad.
3.- Describir los tipos de memoria, sus características, su uso, sus unidades y sus
aplicaciones.
4.- Con ejemplos, explicar lo que son los lenguajes de programación.
5.- Explicar los niveles del software, referido a su construcción y orientación.
Excelencia Académica
17
FUNDAMENTOS DE LA PROGRAMACIÓN
ORIENTADA A OBJETOS
Los avances en el hardware de las computadoras no a correspondido a los avances
equivalentes en el desarrollo de programas o software. Un hardware sin software no
funciona y por lo tanto es importante la implementación de programas de aplicación para
los usuarios.
La producción de aplicaciones más potentes suele significar la presencia de una
complejidad cada vez mayor. Los sistemas orientados a objetos tienen características
adecuadas para expresar la complejidad de un sistema, algunas de las cuales son:
- Adaptabilidad, es decir, facilidad de transporte de unos sistemas a otros. Java se
ejecuta sobre una máquina virtual que es su estándar, por tanto, una aplicación se
puede adaptar y transportar a cualquier sistema que tenga una máquina virtual.
- Reusabilidad, total o parcial, para reducir costos y reutilizar componentes software
cuya fiabilidad esta comprobada.
- Mantenibilidad, los programas son construidos por muchas personas agrupadas en
equipos de trabajo. Con el tiempo estas personas cambian, pero la aplicación
permanece e incluso necesita modificaciones. Por ello es importante que los
programas sean fáciles de comprender y mantener. En caso contrario sería
necesario descartar la aplicación y hacer una nueva. En el caso de Java se tiene un
lenguaje especial para la documentación llamado Javadoc que permite documentar
los programas desarrollados.
Para conseguir estos objetivos se debe aplicar criterios de diseño claros y bien definidos
que permitan hacer frente a la complejidad de las aplicaciones, para lo cual se usan
técnicas de diseño orientado a objetos. El diseño orientado a objetos consiste en averiguar
cuales son los objetos de un sistema, las clases en que se pueden agrupar y las relaciones
entre objetos.
Los conceptos de clase y objeto son los más importantes de la programación orientada a
objetos. Un objeto es cualquier cosa tangible o intangible que se pueda imaginar, definida
frente al exterior mediante unos atributos y las operaciones que permiten modificar dichos
atributos. Por ejemplo una cuenta bancaria, un motor, una carpeta, un alumno son
ejemplos de objetos, pero también lo es una estructura de datos tipo pila, lista, etc. Cada
objeto particular se obtiene como una especificación de una entidad más general
denominada clase.
Excelencia Académica
18
Una clase es una plantilla que permite definir un conjunto de objetos. Por ejemplo alumno
es una clase de objetos caracterizado por tener apellidos, nombres, fecha de nacimiento,
sexo, nacionalidad, facultad, etc. Por ejemplo el alumno Juan Ramos de Ingeniería de
Sistemas, peruano se obtiene instanciando la clase alumno para ese caso particular. La
creación de un objeto a partir de una clase se denomina instanciación. Además, en la
programación orientada a objetos se usa un mecanismo denominado herencia para diseñar
dos o más entidades que son distintas pero comparten muchas características. En
cualquier caso es necesario definir una clase antes de poder crear una instancia
(objeto) de la clase.
En el diseño orientado a objetos, se definen los atributos externos de un objeto y los
métodos que exporta. El resto de la información queda oculta. Además, se pueden
especificar relaciones de herencia y de polimorfismo. El diseño orientado a objetos esta
directamente ligado, aunque no es obligatorio, con los lenguajes de programación
orientado a objetos. La técnica de diseño orientada a objetos más popular es UML (Unified
Modelling Language). Usando estas técnicas se puede conseguir crear clases que tengan
características fundamentales como:
- La modularidad, proceso de dividir un objeto en piezas más pequeñas, o módulos,
para que algún objetivo sea más fácil de conseguir. Los módulos se suelen asociar
a estructuras de datos y las operaciones sobre ellas. Si estos módulos tienen
significado semántico se relacionan con objetos.
- La abstracción, que permite extraer las propiedades más importantes de un objeto,
dejando detalles para el diseño detallado. Estas propiedades varían en función de lo
que un usuario espera de un objeto.
- La encapsulación, que permite ofrecer a los usuarios una visión de caja negra, de
forma que solo se exporte la interfaz de usuario. Esta aproximación, estrechamente
ligada con la ocultación de la información, permite empaquetar la funcionalidad de
un objeto, de forma que se pueda cambiar la funcionalidad interna si afectar a la
visión externa de un componente de un sistema.
- La ocultación de la información, un principio que consiste en no mostrar al
exterior los datos o las funciones que no sean necesarias. Un módulo bien
encapsulado que solo exporta la información necesaria se puede rediseñar
completamente sin afectar a su visión anterior.
Cuando se escriben los programas orientados a objetos es necesario definir primero las
clases. Mientras el programa esta en ejecución, se crean los objetos de estas clases
que van a llevar a cabo las tareas. Una tarea puede ser insertar un elemento en una
pila u ordenar los datos de los alumnos. En general una clase se define como una
estructura de datos y las operaciones que permiten operar con esa estructura de datos
(denominada método). Un método definido para una clase se denomina método de
clase, y un método definido para un objeto se denomina método de instancia. Los
métodos pueden recibir argumentos cuando se les llama. No se puede enviar un
Excelencia Académica
19
mensaje a una clase de objeto a menos que tenga un método para manejarlo. Enviar
un mensaje a una clase objeto es la forma de ejecutar el método correspondiente y si
no hay ningún método conforme, no ocurre nada (o mejor dicho, ocurrirá un error de
compilación).
El Lenguaje de Programación JAVA El lenguaje de Programación Java surgió en los años 90 como un lenguaje orientado a
objetos sencillo, fácil de usar y muy bien adaptado para la programación de aplicaciones en
red. El lenguaje Java fue presentado oficialmente en Mayo de 1995.
Java permite crear o desarrollar programas de aplicación o aplicaciones que se ejecutan en
cualquier computadora que tenga la máquina virtual Java, y también permite crear applets
que son aplicaciones que se ejecutan en un navegador para aplicaciones en Internet.
Pasos para crear un programa en Java
- Aplicaciones
Escribir el programa fuente en cualquier editor y guardarlo con extensión .java
Compilar el fichero fuente mediante: javac miPrograma.java .Esto genera el fichero
.class
Ejecutarlo (interpretar los byte-code) : java miPrograma
- Applets
Escribir el programa fuente en cualquier editor y guardarlo con extensión .java
Compilar el fichero fuente mediante: javac miProgramaApplet.java
Escribir la pagina web que contendrá al applet y guardar el código con extensión
.html
El código mínimo será:
<HTML>
<BODY>
<APPLET code="miProgramaApplet.class" width=400 height=400>
</APPLET>
</BODY>
</HTML>
Se tiene 2 posibilidades para ejecutar el applet:
- Lanzar un navegador y cargar la página html, o bien
- Usar el programa provisto por Sun para ver applets: appletviewer
miProgramaApplet.html
Excelencia Académica
20
Lo que no tiene Java a diferencia de C y C++ es:
a) No hay #define.
b) No hay definición de clases como estructuras.
c) No hay herencia múltiple.
d) No hay goto.
e) No hay apuntadores o punteros.
f ) No hay funciones. Java permite una programación orientada a objetos sin estilo
funcional o procedural. Lo que hace una función en C++ se hace en Java al definir una
clase y creando los métodos para dicha clase.
Debido a estas características, algunas personas definen a Java así:
Java = (C++) - C
Modelamiento de Problemas Modelar un problema es encontrar las partes importantes del problema identificando la
salida o el resultado de la solución del problema.
Para modelar un problema, primero tiene que identificarse y/o definirse bien el problema.
Se dice que un problema esta bien definido cuando se ha identificado la situación inicial del
problema o el punto de partida inicial y la salida a la que se quiere llegar o solución del
problema. La situación a la que se quiere llegar es la respuesta que se debe obtener como
solución del problema y se define como SALIDA, mientras que la situación inicial que son
los datos necesarios para resolver el problema son los datos iniciales que van a llevarnos a
la solución y se define como ENTRADA.
Ejemplo
Se quiere construir una carpeta.
Este es el problema que se quiere resolver, para modelarlo preguntamos sobre la salida o
resultado:
Que se debe obtener como resultado?
Obviamente se necesita UNA CARPETA
Evaluamos los datos necesarios o ENTRADA para este problema preguntando:
Que necesitamos para construir la carpeta?
Se necesita madera, fierros, herramientas, pintura. Con todos estos elementos podemos
transformar esta entrada en la salida requerida que es la carpeta.
Excelencia Académica
21
2.1
Encuentra la Entrada y Salida de cada uno de los siguientes problemas. Determinar si esta
bien definido o no.
1.- Cual es la edad de Mario en años, meses y días.
Entrada Salida Bien Definido
Si No
2.- Encontrar el promedio de dos números.
Entrada Salida Bien Definido
Si No
3.- Encontrar el grado de alegría de una persona.
Entrada Salida Bien Definido
Si No
4.- Encontrar la velocidad con que camina una persona.
Entrada Salida Bien Definido
Si No
Componentes de una Solución
Una solución a un problema es la salida que se obtiene al modelar un problema, por lo
tanto a partir de los datos de Entrada se debe llegar a la Salida. Un programa escrito en
cualquier lenguaje de programación permite, a partir de los datos de entrada, llegar a la
solución generando los datos de salida.
Los pasos ordenados y sucesivos para llegar desde los datos de entrada a la solución o
datos de salida se llama algoritmo.
2.2
Determina la solución para los siguientes problemas:
1.- Llegar a la universidad desde la casa.
Entrada Salida Algoritmo
2.- Obtener el promedio de dos números
Entrada Salida Algoritmo
3.- Pintar mi habitación
Entrada Salida Algoritmo
Excelencia Académica
22
4.- Lavar el automóvil
Entrada Salida Algoritmo
Modelaje Para modelar un problema se debe determinar la Salida requerida y a partir de ello
determinar los datos necesarios para llegar a esa solución (Entrada). Después se debe
traducir la entrada y salida a un modelo computacional.
Un modelo computacional consiste en identificar y detallar cada dato de tal manera que se
diferencie de los demás.
Características de los Datos Los datos tienen cuatro características que identifican y diferencian de los demás. Estas
características son:
Valor : es la situación actual del dato que se almacena. Esta situación puede ser
cambiante durante la ejecución de programa o puede no cambiar nunca.
Clase : Existen dos clases de datos de acuerdo a su uso, las constantes y las variables.
Las constantes son las que no cambian de valor mientras que las variables pueden ir
cambiando de valor al ejecutar el programa.
Identificador : es el nombre que se le pone al dato. Debe ser único para no confundirlo
con otro dato. Cada lenguaje de programación define la forma que tienen sus
identificadores.
Tipo : Es la definición de los valores que puede representar el dato. Los tipos básicos más
comunes son entero, real, caracteres y otros.
Ejemplo:
Calcular el área de un cuadrado.
Solución:
La salida requerida es el área del cuadrado.
Identificador Tipo
Área real
La entrada necesaria es la medida del lado del cuadrado.
Identificador Tipo
Lado real
El algoritmo es multiplicar lado x lado y con ello obtenemos el área.
Especificación Después de haber definido los datos necesarios para resolver un problema y a los cuales
hay que llegar, se deben determinar las restricciones para estos datos que son las
Excelencia Académica
23
limitaciones que se deben tener en cuenta para que no haya errores al momento de
ejecutar el programa, esta es la especificación del problema.
Ejemplo:
Dada las notas de un estudiante definir cuantas asignaturas desaprobó.
Se sabe que se desaprueba un curso cuando se obtiene un promedio final menor a once.
La especificación del dato de entrada que son las notas es que estas notas son datos
enteros cuyo valor mínimo es cero y el valor máximo que pueden tener es de veinte,
además al calcular los promedios se puede tener que la fracción de 0.5 o mayor se
redondea al entero superior.
2.3
Realiza el modelaje para determinar si un número es primo o no.
Refinamiento a Pasos Para resolver un problema se debe determinar las condiciones de entradas y las
restricciones que tenemos para estas {PRE}, al igual que las condiciones de salida o el
resultado al que se debe llegar {POST}.
El algoritmo es una sucesión de pasos que permite llegar desde la entrada hasta la salida.
Entrada
Paso 1
Paso 2
Paso 3
. ALGORITMO
.
.
Paso n
Salida
Refinamiento a pasos es dejar claramente explicado el algoritmo tal que partiendo de la
situación inicial y siguiéndolo paso a paso se llegue a la salida. No siempre el refinamiento
a pasos o algoritmo de un problemas es la solución única.
El algoritmo que se logra, es uno de tal manera que cada paso no se pueda subdividir en
otros pasos más pequeños, si todavía algún paso puede sub dividirse, quiere decir que el
refinamiento a pasos no ha terminado.
Ejemplo:
Describir el algoritmo para PAGAR LA PENSION DE ENSEÑANZA
Solución:
Entrada {PRE} : Se esta en casa y se dispone del dinero para realizar el pago
1. Dirigirse a Caja de la universidad
Excelencia Académica
24
2. Reservar y esperar turno de pago
3. Llegado el turno realizar el pago
4. Recoger el recibo
5. Retornar a casa
Este algoritmo a pesar de solucionar el problema, todavía puede sub dividirse en otros
pasos más específicos, por ejemplo Como dirigirse a la universidad?, Como retornar a
casa?, Como realizar el pago?, Se recibe vuelto o no?, por lo tanto se puede refinar más
este algoritmo para dejarlo más entendible y se puede tener el siguiente algoritmo:
1. Salir de casa
2. Tomar el transporte que nos lleve a la universidad
3. Cuando llegamos a la universidad, bajar del carro
4. Si hay cola en Caja, ponerse a la cola y esperar
5. Al llegar a Caja entregar el código de alumno y el dinero
6. Recoger el recibo de pago y el vuelto si es que corresponde
7. Salir de la universidad
8. Dirigirse a tomar el transporte que nos lleve de regreso
9. Cuando llegamos, bajar del carro
10. Entrar a la casa
Si revisamos este algoritmo podemos, si se desea, refinarlo nuevamente.
2.4
En una hoja aparte, realiza el refinamiento a pasos para los siguientes problemas:
1) Lavar la ropa con una lavadora
2) Vestirse para ir al colegio
3) Pagar el recibo de teléfono.
4) Ver una película en DVD.
Pasos para el Refinamiento de Pasos Para realizar el refinamiento a pasos se puede seguir lo siguiente:
1. Entender correctamente el problema: de donde se inicia y a donde se quiere llegar
2. Encontrar una posible serie de pasos para resolver el problema, dividiéndolo en
problemas más pequeños.
3. Verificar cada paso: para ver si se puede volver a dividir para hacerlo más simple o
explicarlo mejor. Si esto ocurre, incluir los nuevos pasos en donde corresponda en
forma ordenada.
4. Confirmar que al recorrer todos los pasos se llega de la entrada a la salida.
Excelencia Académica
25
Para que el refinamiento a pasos sea de manera formal, es necesario que a cada uno de
los pasos se le determine su Entrada y su Salida. Se notara que para pasos sucesivos, la
salida del paso previo será el entrada del paso siguiente.
- Los sistemas orientados a objetos tienen características adecuadas para expresar
la complejidad de un sistema, algunas de las cuales son: Adaptabilidad,
Reusabilidad y Mantenibilidad.
- El diseño orientado a objetos consiste en averiguar cuales son los objetos de un
sistema, las clases en que se pueden agrupar y las relaciones entre objetos.
- Un objeto es cualquier cosa tangible o intangible que se pueda imaginar, definida
frente al exterior mediante unos atributos y las operaciones que permiten modificar
dichos atributos. Cada objeto particular se obtiene como una especificación de una
entidad más general denominada clase.
- Java permite crear aplicaciones y applets.
- El modelaje consiste en encontrar los limites de un problema, es decir que
esperamos encontrar y que necesitamos para ello.
- Los problemas que podemos resolver son aquellos que se encuentran bien
definidos.
- Un problema bien definido es aquel que se le puede identificar claramente la
Entrada y la Salida.
- La solución a un problema bien definido esta conformada por la Entrada, el
Algoritmo y la Salida.
- El Algoritmo es la sucesión ordenada de pasos que parten de la Entrada y si se
siguen uno a uno, conducen a la salida.
Fco. Javier Ceballos Curso de Programación Java 2
Alfaomega-Rama, España 2,003 Segunda Edición
Luis Joyanes Aguilar Programación en Java
Prentice Hall, España
José Pérez Mayor Programación en Java Paso a Paso
Thomson, España 2,003
Deitel y Deitel Curso de Programación en Java
Prentice Hall, España, 1,995
Excelencia Académica
26
Habiendo descrito los principios de la programación orientada a objetos, en los siguientes
UNIDAD TEMÁTICAs estudiaremos la programación en Java.
Para modelar un problema, primero tiene que identificarse y/o definirse bien el problema.
Se dice que un problema esta bien definido cuando se ha identificado la situación inicial del
problema o el punto de partida inicial y la salida a la que se quiere llegar o solución del
problema.
La especificación es la definición de las restricciones para los datos que son las
limitaciones que se deben tener en cuenta para que no haya errores al momento de
ejecutar el programa.
El algoritmo es la sucesión ordenada de pasos que se tienen que seguir para llegar a partir
de los datos de entrada hasta los datos de salida requeridos.
Identifica en forma clara las entradas, salidas y algoritmo para un problema realizando en
forma correcta su modelo computacional.
Define en forma clara las características de la programación orientada a objetos.
Define las características del lenguaje Java.
Excelencia Académica
27
Nº 2
Nombre__________________________________________________________________
Apellidos_______________________________________Fecha _____________________
Ciudad ______________________________Semestre_____________________________
1.- Defina los siguientes enunciados :
a) Algoritmo
b) Modelaje
c) Problema bien definido
2.- Definir las entradas y salidas para los siguientes problemas :
a) Determinar el mayor de dos números
Entrada Salida Algoritmo
b) Calcular el promedio de los n primeros números
Entrada Salida Algoritmo
c) Escoger los números pares de una lista de números enteros
Entrada Salida Algoritmo
3.- Describir las características de la programación orientada a objetos.
4.- Describir las ventajas de UML.
5.- Describir con ejemplos las características de los datos.
Excelencia Académica
28
Excelencia Académica
29
ESTRUCTURA DE UN PROGRAMA
ORIENTADO A OBJETOS
En lenguaje Java, como en los otros lenguajes de programación, los programas tienen una
estructura definida que siempre debe respetarse.
Un programa simple en Java que solamente muestre en pantalla un saludo al programador
sería el siguiente:
/** Este es primer programa en Java
* Imprime la palabra HOLA AMIGOS por la pantalla
**/
import java.*;
/* La clase principal se denomina ProgramaUno */
public class ProgramaUno
{ public static void main(String args[])
{ // Parte que se ejecuta del programa para mostrar el mensaje
System.out.println(“HOLA AMIGO”);
La primera parte del ProgramaUno se compone de tres elementos: comentarios, sentencia
import y declaración de clases. Estos tres componentes se incluyen siempre en todos los
programas de Java.
Se puede escribir un programa Java que incluya una única declaración de clase, pero eso
no es normal. Vamos a explicar los tres componentes y sus sub componentes.
Gramática de Java
Comentarios Los comentarios son textos que se ponen en el programa para documentar las
instrucciones con la finalidad de hacer más entendible el programa. Los comentarios solo
se tienen en el código fuente y no son tomados en cuenta al momento de realizar la
compilación del programa.
En Java hay tres tipos de comentarios:
Excelencia Académica
30
Los dos primeros tipos de comentarios son los que todo programador conoce y se utilizan
del mismo modo. Los comentarios de documentación, colocados inmediatamente antes de
una declaración (de variable o función), indican que ese comentario ha de ser colocado en
la documentación que se genera automáticamente cuando se utiliza la herramienta de
Java, javadoc. Dichos comentarios sirven como descripción del elemento declarado
permitiendo generar una documentación de nuestras clases escrita al mismo tiempo que se
genera el código.
Identificadores Los identificadores nombran variables, funciones, clases y objetos; cualquier cosa que el
programador necesite identificar o usar.
En Java, un identificador comienza con una letra, un subrayado (_) o un símbolo de dólar
($). Los siguientes caracteres pueden ser letras o dígitos. Se distinguen las mayúsculas de
las minúsculas y no hay longitud máxima.
Ejemplos de identificadores válidos:
Identificador
nombre_usuario
Nombre_Usuario
_variable_de_sistema
$transaccion
y su uso sería, por ejemplo:
int contador_principal;
char _lista_de_ficheros;
float cantidad_en_Ptas;
// comentarios para una sola línea
/* comentarios de una o
más líneas
*/
/** comentario de documentación, de una o más líneas
*/
Excelencia Académica
31
Palabras Reservadas Las siguientes son las palabras clave que están definidas en Java y que no se pueden
utilizar como identificadores, estas palabras sirven para realizar o construir instrucciones y
son las siguientes:
abstact Boolean break byte case
catch char class continue default
do double else extends false
final Finally float for if
implements import instanceof int interface
long native new null package
private protected public return short
static super switch syncroniced this
throw throws transient try void
volatile while
Importación de Clases Los programas orientados a objetos se desarrollan mediante el uso de clases predefinidas
siempre que sea posible. Únicamente se deben incluir clases propias cuando no hayan
clases predefinidas adecuadas. En Java las clases se agrupan en clases. Un paquete
puede incluir sub paquetes, definiendo una jerarquía de paquetes. Para usar los elementos
de un paquete dentro de un programa se puede escribir su nombre completo., pero el
problema es que se debe usar un punto para separar los nombres de los paquetes lo que
puede resultar muy engorroso. Por ejemplo se escribe:
java.InputStream.read
Con una sentencia import al principio del programa elimina la necesidad de usar los
nombres completos, por lo que si se pone en el principio del programa:
import java.InputStream;
Para referirse al método se puede usar simplemente:
read;
El principal problema que genera el uso de la sentencia import es la ambigüedad que se
origina cuando dos métodos tienen el mismo nombre pero pertenecen a clases distintas por
lo que el entorno de programación no sabrá a cual método llamar y llamara a cualquiera de
ellos, esto se evita usando los nombres completos.
Excelencia Académica
32
Declaración de Clases y Métodos Todo programa Java debe tener al menos una clase: la clase principal. En el ejemplo la
clase principal es ProgramaUno. Si se designa una clase como clase principal, entonces se
debe definir un método denominado main, porque, cuando se ejecuta el programa Java, se
ejecuta primero el método main de la clase principal.
La declaración de una clase se realiza usando la palabra reservada class mediante la
sentencia:
public class ProgramaUno
la palabra reservada public indica que esa clase se exporta al exterior. ProgramaUno es el
nombre de la clase principal y por extensión de la aplicación por lo que cuando se guarda
este programa debe guardarse con el nombre ProgramaUno.java
La sintaxis para la declaración de un método es:
<modificadores><tipo devuelto><nombre del método> (<parámetros>)
{
<cuerpo del método>
}
Donde <modificadores> es una secuencia de términos para designar diferentes tipos de
métodos; <tipo devuelto> es el tipo de valor de datos que devuelve el método; <nombre del
método> es el nombre del método; <parámetros> es una secuencia de valores que se
pasan al método, y <cuerpo del método> es una secuencia de instrucciones. La
declaración del método main cumple con este formato:
public static void main (String[] args)
{
…
}
El método main llama a otro método que es el que escribe en la pantalla el mensaje, este
método es:
System.out.println(“HOLA AMIGOS”);
El IDE de JAVA EL IDE (Entorno Integrado de Desarrollo) es una herramienta que permite elaborar los
programas, compilarlos y ejecutarlos mediante el uso de comandos sencillos. Tiene
incorporado un procesador de textos para escribir los programas para después compilar y
ejecutar. Existen varios IDE que se pueden usar con Java entre ellos tenemos el Jcreator,
Eclipse y otros. Vamos a describir en forma rápida los comandos más importantes del
JCreator. Para ingresar se hace doble click en el icono del JCreator y se obtendrá la
siguiente pantalla:
Excelencia Académica
33
Para escribir un programa se debe crear un archivo nuevo, para ello se ejecuta los
comandos File, New, File y se mostrara la siguiente pantalla:
Se selecciona el tipo de programa que se va a construir, en nuestro caso se debe
seleccionar Java File y hacer clic en Next y se mostrara la ventana para escribir el nombre
del programa y después se selecciona el directorio en donde se guardara el archivo (para
realizar esta selección se hace clic en los tres puntos del lado derecho y se busca el
directorio deseado que en nuestro caso será el directorio ejemplo)
Para terminar se hace clic en el botón Finish y se abrirá la ventana de texto al lado derecho
en donde se puede escribir el programa.
Excelencia Académica
34
Se escribe el programa y se compila con los comandos Build, Compile File. Si es la primera
vez se tendrá que definir el directorio donde se encuentra el compilador de Java que por lo
general estará en la raíz del disco C: en el directorio j2sdk1.4.2_03
Si existen errores, estos se mostraran en la ventana de la parte inferior con la indicación de
la línea en donde existe el error y cuando todos los errores se hayan corregido se realizará
la compilación mostrando el mensaje Process Completed en la venta inferior
Después de haber compilado el programa, debemos ejecutarlo, lo que se hace con los
comandos Build, Execute File y aparecerá una ventana con la ejecución del programa para
realizar el ingreso de datos y la salida de los resultados como se muestra
Excelencia Académica
35
Si el programa se ha compilado y ejecutado, también se habrá guardado en el disco. Para
guardar el programa en un archivo con otro nombre se selecciona los comandos File, Save
As y se presentará una ventana para poner el nombre y guardar y se termina de guardar
haciendo clic en el botón Save.
Para recuperar un programa guardado en el disco se selecciona los comandos File, Open y
de la ventana que aparece se selecciona el nombre del archivo deseado y se termina
haciendo clic en el botón Open
Para cerrar la ventana de edición en donde se encuentra un programa se ejecuta los
comandos File, Close.
Tipos de Datos en Java
Todo lenguaje de programación maneja tipos de datos respecto a lo que representa, por lo
general se tienen datos numéricos, datos tipo carácter y datos tipo cadena.
Los datos numéricos representan cantidades y con ellos se pueden realizar operaciones
matemáticas. Son todos los números, por ejemplo 345, 65.38, -78, -8.37
Excelencia Académica
36
Los datos tipo carácter sirven para representar un solo símbolos (letras, dígitos, signos de
puntuación, etc.) y van entre apóstrofos o comillas simples, como por ejemplo ‘a’, ‘F’, ‘5’, ‘.’,
etc. Los apóstrofos no son parte del carácter. Para poder escribir caracteres especiales se
antepone el \ como por ejemplo ‘\”’ para tener las comillas, las secuencias de caracteres
especiales son las siguientes:
Secuencia Significado
\n Nueva línea
\t Tabulador horizontal
\b Retroceso
\r Retorno de carro
\f Alimentación de forma
\\ Diagonal inversa
\' Comilla sencilla
\" Comillas dobles
\ddd Valor en Octal
\xdd Valor en Hexadecimal
\udddd Únicode
Las cadenas de texto son una secuencia de caracteres que van limitados por comillas, pero
las comillas solo son delimitadores y no forman parte de la cadena. Son cadenas de texto,
por ejemplo:
“Hola amigos” “Ingrese un número entero”
“La suma de los números es:” “352.564”
“Vamos a sumar 5 con 43”
Los tipos de datos disponibles en Java son :
Tipo bytes Tipo Datos Rango (positivo) Literal
byte 1 Entero 127 14
short 2 Entero 32767 14
int 4 Entero 2.147.483.647 14
Excelencia Académica
37
long 8 Entero 9.233e15 14
float 4 Coma flotante 1.4e-45 a 3.4e38 36,6
double 8 Coma flotante 4.9e-324 a 1.7e308 3,14e2
char 2 Caracter Únicode 'a' o \064
boolean 1 Booleano true o false true o false
El tipo String es un tipo especial de Java que permite el ingreso y manejo de cadenas de
texto.
Declaración de Datos Para manejar estos datos se usan variables las cuales deben ser declaradas al inicio del
programa. Las variables serán representadas por medio de identificadores y la declaración
de variables se realiza de la siguiente forma:
tipo_de_dato identificador;
Se pueden declarar varias variables y asignarles un valor inicial de la siguiente forma:
tipo_de_dato identificador1, identificador 2,…;
tipo_de_dato identificador = valor;
Por ejemplo son declaraciones validas las siguientes:
int a: int x,y,z;
int E=45; flotat X=4.56, M=0.45;
char V, R==’D’; bolean T;
String CAD=”Este es un mensaje de texto” ;
Instrucciones en JAVA
Las instrucciones son las órdenes que se la da a la computadora para que realicen alguna
acción. En Java las instrucciones siempre finalizan con un punto y coma.
Instrucción ;
Se pueden tener instrucciones compuestas o bloques de instrucciones que se deben
manejar como una única instrucción, en este caso el bloque de instrucciones comienza con
una { y termina con otra }.
{ instruccion1;
Excelencia Académica
38
Instrucción 2;
.
.
Instrucción n;
}
Operadores Aritméticos
Los operadores aritméticos permiten realizar operaciones aritméticas entre dos datos que
pueden ser literales o pueden estar representados por variables. Existen operadores
monarios que son aquellos que se aplican a un solo dato, pero también existen operadores
llamados binarios porque se aplican a dos datos.
Los operadores de comparación se utilizan para comparar dos valores y generan un
resultado de tipo lógico que puede ser VERDADERO o FALSO y se utilizan para formar las
condiciones o controlar la ejecución de ciclos repetitivos.
Los operadores en Java son los siguientes:
Operadores Unarios:
Operador Descripción (prefija) Operador Descripción (pre o
posfija)
+ Convierte el dato a int ++ Incrementa el dato en 1
- Negacion aritmética
oper.
-- Decrementa el dato en 1
Operadores aritméticos (binarios):
Operador Uso Atajo Descripción
+ op1 + op2 op1 += op2 Suma op1 y op2
- op1 - op2 op1 -= op2 Resta op2 de op1
* op1 * op2 op1 *= op2 Multiplica op1 por
op2
/ op1 / op2 op1 /= op2 Divide op1 por op2
% op1 % op2 op1 %= op2 Resto de op1 / op2
El atajo es una operación que asigna el resultado de la operación al mismo operador1.
Excelencia Académica
39
Por ejemplo si se tienen las variables A que tiene un valor de 15 y una variable B que tiene
el valor de 3 se tiene lo siguiente:
A + B será 18, los valores de A y B no
cambian
A * B será 45, los valores de A y B no
cambian
A += B hará que A valga 18 A * B hará que A valga 45
Operadores de comparación (binarios):
Operador Uso Devuelve verdadero 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
&& op1 && op2 AND, condicionalmente evalúa op2
& op1 & op2 AND, siempre evalúa op1 y op2
|| op1 || op2 OR, condicionalmente evalúa op2
| op1 | op2 OR, siempre evalúa op1 y op2
! ! op op es falso
A > B será VERDADERO A < B será FALSO
Operadores de bit (binarios):
Operador Uso Operación
>> op1 >> op2 Desplaza los bits de op1 a la derecha op2 veces
<< op1 << op2 Desplaza los bits de op1 a la izquierda op2 veces
>>> op1 >>> op2 Desplaza los bits de op1 a la derecha op2 veces
(sin signo)
& op1 & op2 AND
| op1 | op2 OR
^ op1 ^ op2 "XOR"
~ ~op2 Complemento
Excelencia Académica
40
Operador terciario:
expresion ? sentencia_si : sentencia_si_no
Precedencia de operadores:
Tipo de operadores Operadores de este tipo
Operadores posfijos [ ] . (parametros) expr++ expr--
Operadores unarios ++expr --expr +expr -expr ~ !
Creación o conversión new (tipo) expr
Multiplicación * / %
Suma + -
Desplazamiento <<
Comparación <<= = instanceof
Igualdad == !=
AND a nivel de bit &
OR a nivel de bit ^
XOR a nivel de bit |
AND lógico &&
OR lógico ||
Condiciónal ? :
Asignación = += -= *= /= %= &= ^= |= <<= = =
Instrucciones de Salida de Datos en JAVA
Las instrucciones de salida de datos sirven para mostrar datos por los dispositivos de
salida de datos. En esta parte trataremos solamente la salida de datos a través del monitor
de video.
Java trata a todos los datos para la salida como si fueran cadenas que pueden
concatenarse por medio del signo + que nos va a permitir combinar en la salida datos
numéricos, caracteres y cadenas de texto.
El método para la salida de datos es:
System.out.print(datos_de_salida);
Por ejemplo para mostrar el valor del número representado por la variable A se pone:
Excelencia Académica
41
System.out.print(“El valor de la variables A es “ + A );
El método println es similar a print solamente que después de imprimir el dato hace un
cambio a la linea siguiente:
System.out.println(“El valor de la variable A es “ + A) ;
Instrucciones de Entrada de Datos en JAVA
La entrada de datos en Java se maneja como el ingreso de un flujo de datos desde una
fuente, en este caso la fuente del flujo de datos será el teclado, aunque puede ser cualquier
otro archivo.
Normalmente Java permite el ingreso de un flujo de caracteres, que seria una cadena de
texto, la que debe ser convertida para representar el dato numérico requerido.
El flujo de datos de entrada se declara de la siguiente forma:
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader e=new BufferedReader(isr);
Donde e es la variable que va a representar el flujo de datos de entrada, otra forma más
corta en una sola instrucción es:
BufferedReader e=new BufferedReader (new InputStreamReader(System.in));
Cuando el programa va a realizar ingreso de datos se debe preveer que no se produzcan
errors durante este ingreso, esto se realice a través del manejo de excepciones que se
tratara posteriormente. Para manejar las
excepciones se debe poner al final de la declaración main las palabras: throws IOException
siendo la declaración completa de la siguiente forma:
public static void main(String[] args) throws IOException
Los métodos para el ingreso de datos, considerando las declaraciones anteriores que usan
la variable e para el flujo de entrada, son los siguientes:
var=System.in.read(); // para el ingreso de números enteros
var_byte=Byte.parseByte(e.readLine()); para el ingreso de datosbyte
var_short=Short.parseShort(e.readLine()); para el ingreso de datos short
var_int=Integer.parseInt(e.readLine()); para el ingrso de datos int
var_long=Long.parseLong(e.readLine()); para el ingreso de datos long
var_float=Float.parseFloat(e.readLine()); para el ingreso de datos float
var_double=Double.parseDouble(e.readLine()); para ingreso de datos double
var_String=e.readLine(); para el ingreso de cadenas de texto
Traducción del Modelaje y Especificación a un Programa JAVA
Excelencia Académica
42
Consiste en realizar todo el modelaje y especificación de datos para llegar desde la entrada
hasta la salida y llevar este algoritmo a código Java para ejecutar el programa.
EJEMPLO 1
Por ejemplo se requiere tener un programa para sumar dos números enteros que se
ingresen por teclado y mostrar la suma. Se tendrá lo siguiente:
Datos de Salida : La asuma los dos números ingresados, representado por la
variable S.
Datos de Entrada : Dos números enteros representados por dos variables de tipo int
(variables A y B) cuyo valor se ingresara desde el teclado al
momento de ejecutar el programa
Algoritmo de Solución:
- Ingresar número A
- Ingresar número B
- Sumar ambos números : S= A + B
- Mostrar el valor de S, que es la suma, por la pantalla
El código del programa será el siguiente:
// Ingreso de dos números y mostrar la suma
import java.io.*;
public class suma {
public static void main(String[] args) throws IOException
{ // se declara el flujo de entrada de caracteres para la variable e
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader e=new BufferedReader(isr);
int A,B,S; //se declaran las variables
// Ingreso de los dos números
System.out.print("Ingresar un número entero ");
A=Integer.parseInt(e.readLine());
System.out.print("Ingresar otro número entero ");
B=Integer.parseInt(e.readLine());
// Se calcula la suma de los números
S = A + B ;
Excelencia Académica
43
// Se muestra la suma por pantalla
System.out.println("La suma de los dos números es : "+S);
EJEMPLO 2
Escribir un programa y su modelo para ingresar los diferentes tipos de datos de Java y
después mostrarlos por pantalla, también mostrar la suma de todos los números
ingresados.
Vamos a dejar como tarea para el estudiante el modelaje de este problema y se muestra a
continuación el código del programa.
//Ejemplo de ingreso de números, cadenas
import java.io.*;
public class números {
public static void main(String[] args) throws IOException
{
// se declara el flujo de entrada de caracteres para la variable e
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader e=new BufferedReader(isr);
// esta es otra forma de declarar el flujo de entrada de caracteres
// BufferedReader e=new BufferedReader (new InputStreamReader(System.in));
byte b;
short s;
int i;
long l;
float f;
double d,suma; //la suma debe ser tipo double
String ca;
System.out.print("Ingresar un entero byte ");
b=Byte.parseByte(e.readLine());
System.out.print("Ingresar un entero short ");
s=Short.parseShort(e.readLine());
System.out.print("Ingresar un entero int ");
i=Integer.parseInt(e.readLine());
System.out.print("Ingresar un entero long ");
l=Long.parseLong(e.readLine());
Excelencia Académica
44
System.out.print("Ingresar un real float ");
f=Float.parseFloat(e.readLine());
System.out.print("Ingresar un real double ");
d=Double.parseDouble(e.readLine());
System.out.print("Ingresar una cadena de texto ");
ca=e.readLine();
System.out.println("El entero byte es "+b);
System.out.println("El entero short es "+s);
System.out.println("El entero int es "+i);
System.out.println("El entero long es "+l);
System.out.println("El float es "+f);
System.out.println("El double es "+d);
System.out.println("La cadena es "+ca);
suma=b+s+i+l+f+d;
System.out.println("La suma de todos es "+suma);
}
En lenguaje Java, como en los otros lenguajes de programación, los programas tienen una
estructura definida que siempre debe respetarse.
La gramática de Java está formada por comentarios, identificadores, palabras reservadas,
importación de clases, declaración de clases y métodos.
Todo programa Java debe tener al menos una clase: la clase principal. Si se designa una
clase como clase principal, entonces se debe definir un método denominado main, porque,
cuando se ejecuta el programa Java, se ejecuta primero el método main de la clase
principal.
EL IDE (Entorno Integrado de Desarrollo) es una herramienta que permite elaborar los
programas, compilarlos y ejecutarlos mediante el uso de comandos sencillos. Tiene
incorporado un procesador de textos para escribir los programas para después compilar y
ejecutar. Las características de su instalación se describen en el apéndice I y II.
Los datos numéricos representan cantidades y con ellos se pueden realizar operaciones
matemáticas. Son todos los números, por ejemplo 345, 65.38, -78, -8.37
Los datos tipo carácter sirven para representar un solo símbolo (letras, dígitos, signos de
puntuación, etc.) y van entre apóstrofos o comillas simples, como por ejemplo ‘a’, ‘F’, ‘5’, ‘.’,
etc. Los apóstrofos no son parte del carácter. Para poder escribir caracteres especiales se
antepone el \ como por ejemplo ‘\”’ para tener las comillas.
Excelencia Académica
45
Las cadenas de texto son una secuencia de caracter
es que van limitados por comillas, pero las comillas solo son delimitadores y no forman
parte de la cadena.
Todo dato, representado por una variable, que se utilice en un programa debe ser
declarado indicando el tipo de dato que representa y el identificador que lo representará.
Java, como los otros lenguajes, trata a las unidades de entrada y salida como elementos
que generan flujo de datos o caracteres y a quienes también se les entrega un flujo de
caracteres.
Fco. Javier Ceballos Curso de Programación Java 2
Alfaomega-Rama, España 2,003 Segunda Edición
Luis Joyanes Aguilar Programación en Java
Prentice Hall, España
José Pérez Mayor Programación en Java Paso a Paso
Thomson, España 2,003
Deitel y Deitel Curso de Programación en Java
Prentice Hall, España, 1,995
Habiendo estudiado la estructura de un programa en Java, sus instrucciones y sus
operadores en los siguientes UNIDAD TEMÁTICAS se tratará sobre la utilización de estas
instrucciones en el taller de programación.
Todo dato que se utilice en un programa Java y que se represente con una variable, debe
ser declarado indicando su tipo de dato y el identificador que lo representará.
Todo programa Java debe tener la declaración de una clase principal que debe llevar el
mismo nombre que tiene el archivo que guarda el programa con extensión .java y después
debe tener una clase de nombre main que es la primera clase que se va a ejecutar.
Excelencia Académica
46
Escribir programas con entrada y salida de datos en forma correcta.
Utilizar los operadores aritméticos para construir programas que requieran realizar estas
operaciones.
Nº 3
Nombre__________________________________________________________________
Apellidos_______________________________________Fecha _____________________
Ciudad ______________________________Semestre_____________________________
1.- Escribir un programa, identificando su salida, entrada (con sus restricciones) y algoritmo
para calcular:
a) el área y perímetro de un rectángulo.
b) el área lateral y volumen de un cilindro.
c) el área lateral y volumen de una esfera.
d) el costo de una factura donde se ingresa el precio unitario del producto, su nombre y
la cantidad comprada considerando el sub total, el IGV (19%= y el total que es la
suma del sub total y del IGV.
Excelencia Académica
47
TALLER DE PROGRAMACIÓN I (Entrada, Salida, Operadores)
En esta parte del curso vamos a desarrollar programas de entrada y salida de datos y
vamos a plantear otros para el desarrollo por parte del estudiante. Tenemos los siguientes
ejemplos:
EJEMPLO1
Escribir un programa que solicite un texto que se ingrese por teclado y que después
muestre por pantalla el texto ingresado.
* Created on 05/04/2005
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
/**
* @author Administrador
*
* To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
import avail.*;
public class Entrada1
{
public static void main(String[] args) throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
PrintStream flujoS = System.out;
String sdato;
try
{
Excelencia Académica
48
flujoS.print("Introduzca un texto: ");
sdato = flujoE.readLine();
System.out.print("El texto ingresado es : ");
flujoS.println(sdato);
}
catch (IOException ignorada){}
}
}
Al compilar y ejecutar el programa se debe ingresar un texto terminando presionando la
tecla Enter y se vera que el programa escribe en pantalla el texto ingresado.
EJEMPLO 2
Escribir un programa para ingresar un dato y leer el dato usando el método
System.in.read();
import java.io.*;
public class Entrada2 {
public static void main(String[] args) throws IOException {
int n,m;
byte b;
float x,y=4;
char ca;
System.out.println("Ingrese un dato");
n=System.in.read();
System.out.println("el valor de ingresado es "+(char)n+"\ningrese otro dato");
m=System.in.read();
System.out.println("el otro dato ingresado es "+m);
System.out.println("Ingrese un caracter");
ca=(char)System.in.read();
System.out.println("El caracter ingresado es "+ca);
}
}
Al ejecutar el programa si se ingresa el texto CAMINAR y se termina presionando Enter, se
tiene la siguiente salida:
Excelencia Académica
49
Como se nota aparece la C después el 65 y al final la letra M
EXPLICACION
El método System.in.read() permite el ingreso de un carácter y almacena en la variable
asociada a este método sin necesidad de presionar Enter para concluir el ingreso. El valor
que se almacena es un número que corresponde al código ASCII del carácter ingresado.
Los demás caracteres que se hayan ingresado permanecen en la memoria intermedia del
teclado y cuando se encuentra otro método de lectura de carácter se asigna el código del
siguiente carácter a la variable asociada al método y así sucesivamente por lo que el
código de la letra C se asigna al primer System.in.read() el código de la letra A al segundo
y el código de la letra M al tercero, los demás caracteres se pierden incluyendo el Enter
(carácter 13) final.
Se debe notar que el método System.in.read() permite el ingreso de un dato numérico que
es el código ASCII del carácter ingresado y si este dato numérico se debe mostrar como
carácter como en la primera salida de datos, se debe convertir con una operación cast que
consiste en anteponer el tipo deseado entre paréntesis antes del dato a convertir, en este
caso se puso (char)n para convertir el entero n a carácter.
Lo mismo se hace si se desea ingresar caracteres usando este método, como en el tercer
ingreso de datos, se lee un número pero con el operador cast este número leído se
convierte en carácter y es asignado a una variable de carácter como en la instrucción:
ca=(char)System.in.read();
La Clase Math
La clase Math representa la librería matemática de Java. Las funciones que contiene son
las que todos los lenguajes tienen, por eso se encapsulan en Math, y lo mismo sucede con
las demás clases que corresponden a objetos que tienen un tipo equivalente (Character,
Float, etc.). El constructor de la clase es privado, por los que no se pueden crear instancias
de la clase. Sin embargo, Math es public para que se pueda llamar desde cualquier sitio y
static para que no haya que inicializarla.
Excelencia Académica
50
Funciones Matemáticas Si se importa la clase, se tiene acceso al conjunto de funciones matemáticas estándar que
son los siguientes:
Math.abs( x ) para int, long, float y double, devuelve el
valor absolute
Math.sin( double a ) devuelve el seno del ángulo a en
radianes
Math.cos( double a ) devuelve el coseno del ángulo a en
radianes
Math.tan( double a ) devuelve la tangente del ángulo a en
radianes
Math.asin( double r ) devuelve el ángulo cuyo seno es r
Math.acos( double r ) devuelve el ángulo cuyo coseno es r
Math.atan( double r ) devuelve el ángulo cuya tangente es r
Math.atan2(double a,double b) devuelve el ángulo cuya tangente es a/b
Math.exp( double x ) devuelve e elevado a x
Math.log( double x )
devuelve el logaritmo natural de x
Math.sqrt( double x ) devuelve la raíz cuadrada de x
Math.ceil( double a ) devuelve el número completo más
pequeño mayor o igual que a
Math.floor( double a ) devuelve el número completo más grande
menor o igual que a
Math.rint( double a ) devuelve el valor double truncado de a
Math.pow( double x,double y ) devuelve y elevado a x
Math.round( x ) para double y float
Math.random() devuelve un double
Math.max( a,b ) para int, long, float y double
Math.min( a,b ) para int, long, float y double
Math.E para la base exponencial,
aproximadamente 2.72
Math.PI para PI, aproximadamente 3.14
A continuación se muestran algunos ejemplos de utilización de estas funciones:
int i = 7;
int j = -9;
double x = 72.3543;
double y = 0.3498;
Excelencia Académica
51
System.out.println("i es " + i);
System.out.println("j es " + j);
System.out.println("x es " + x);
System.out.println("y es " + y);
// Valor absoluto de un número
System.out.println("|" + i + "| es " + Math.abs(i));
System.out.println("|" + j + "| es " + Math.abs(j));
System.out.println("|" + x + "| es " + Math.abs(x));
System.out.println("|" + y + "| es " + Math.abs(y));
// aproximación decimal
//empleando (round)
System.out.println(x + " es " + Math.round(x));
System.out.println(y + " es " + Math.round(y));
System.out.println(x + " es aprox." + (double)Math.round(x*100)/100);
System.out.println(y + " es aprox." + (double)Math.round(y*100)/100);
//empleando floor
System.out.println("The floor of " + x + " es " + (100*Math.floor(x))/100);
System.out.println("The floor of " + y + " es " + (100*Math.floor(y))/100);
// para hallar el menor de dos número
System.out.println("min(" + i + "," + j + ") es " + Math.min(i,j));
System.out.println("min(" + x + "," + y + ") es " + Math.min(x,y));
// Para hallar el mayor de dos números
System.out.println("max(" + i + "," + j + ") es " + Math.max(i,j));
System.out.println("max(" + x + "," + y + ") es " + Math.max(x,y));
// las constantes PI y E
System.out.println("Pi es " + Math.PI);
System.out.println("e es " + Math.E);
//funciones trigonométricas
double angulo = 45.0 * Math.PI/180.0;
System.out.println("cos(" + angulo + ") es " + Math.cos(angulo));
System.out.println("sin(" + angulo + ") es " + Math.sin(angulo));
System.out.println("tan(" + angulo + ") es " + Math.tan(angulo));
Excelencia Académica
52
// Funciones trigonomértricas inversas
double valor = 0.707;
System.out.println("acos(" + valor + ") es " + Math.acos(valor));
System.out.println("asin(" + valor + ") es " + Math.asin(valor));
System.out.println("atan(" + valor + ") es " + Math.atan(valor));
y=6.2; //ordenada
x=-5.4; //abscisa
System.out.println("atan2(" + y+" , "+x + ") es " + Math.atan2(y, x));
//Funciones exponencial y logarítmica
System.out.println("exp(1.0) es " + Math.exp(1.0));
System.out.println("exp(10.0) es " + Math.exp(10.0));
System.out.println("exp(0.0) es " + Math.exp(0.0));
System.out.println("log(1.0) es " + Math.log(1.0));
System.out.println("log(10.0) es " + Math.log(10.0));
System.out.println("log(Math.E) es " + Math.log(Math.E));
// pow(x,y) devuelve x elevado a y.
System.out.println("pow(2.0, 2.0) es " + Math.pow(2.0,2.0));
System.out.println("pow(10.0, 3.5) es " + Math.pow(10.0,3.5));
System.out.println("pow(8, -1) es " + Math.pow(8,-1));
// sqrt(x) devuelve la raíz cuadrada de x.
System.out.println("La raíz cuadrada de " + y + " es " + Math.sqrt(y));
// Devuelve un número pseudo-aleatorio comprendido entre 0.0 y 1.0
System.out.println("Número aleatorio: " + Math.random());
System.out.println("Otro número aleatorio: " + Math.random());
El ejemplo javamath.java, muestra la utilización de algunas de las funciones de la clase
Math:
class javamath {
public static void main( String args[] ) {
int x;
double rand,y,z;
float max;
rand = Math.random();
x = Math.abs( -123 );
y = Math.round( 123.567 );
z = Math.pow( 2,4 );
max = Math.max( (float)1e10,(float)3e9 );
Excelencia Académica
53
System.out.println( rand );
System.out.println( x );
System.out.println( y );
System.out.println( z );
System.out.println( max );
}
La Clase Carácter Al trabajar con caracteres se necesitan muchas funciones de comprobación y traslación.
Estas funciones están en la clase Character. De esta clase sí que se pueden crear
instancias, al contrario que sucede con la clase Math.
Declaraciones La primera sentencia creará una variable carácter y la segunda un objeto Character:
char c;
Character C;
Comprobaciones booleanas Character.isLowerCase( char ) devuelve true si el carácter es una letra
minúscula
Character.isUpperCase( char ) devuelve true si el carácter es una letra
mayúscula
Character.isDigit( char )
devuelve true para caracteres numéricos
Character.isSpace( char ) devuelve true para espacios en blanco
En este caso, si tuviésemos un objeto Character C , no se podría hacer C.isLowerCase(),
porque no se ha hecho un new de Character. Estas funciones son estáticas y no conocen
al objeto, por eso hay que crearlo antes.
Traslaciones de Caracteres Character.toLowerCase( char ) convierte entre mayúscula y minúscula
Character.toUpperCase( char ) convierte entre minúscula y mayúscula
Traslaciones de carácter/dígito
int i = Character.digit( c,base );
char c = Character.forDigit( i,base );
Métodos de la clase Character C = new Character( 'J' );
char c = C.charValue();
String s = C.toString();
Excelencia Académica
54
La Clase Float Cada tipo numérico tiene su propia clase de objetos. Así el tipo float tiene el objeto Float.
De la misma forma que con la clase Character, se han codificado muchas funciones útiles
dentro de los métodos de la clase Float.
Declaraciones
La primera sentencia creará una variable float y la segunda un objeto Float:
float f;
Float F;
Valores de Float
Float.POSITIVE_INFINITY
Float.NEGATIVE_INFINITY
Float.NaN
Float.MAX_VALUE
Float.MIN_VALUE
Conversiones de Clase/Cadena
String s = Float.toString( f );
f = Float.valueOf( "3.14" );
Comprobaciones
boolean b = Float.isNaN( f );
boolean b = Float.isInfinite( f );
Conversiones de Objetos
Float F = new Float( Float.PI );
String s = F.toString();
int i = F.intValue();
long l = F.longValue();
float F = F.floatValue();
double d = F.doubleValue();
La Clase Double Cada tipo numérico tiene su propia clase de objetos. Así el tipo double tiene el objeto
Double. De la misma forma que con la clase Character, se han codificado muchas
funciones útiles dentro de los métodos de la clase Double. La clase Double tiene un
constructor para inicializarla con un valor double o, lo que es muy práctico, con una
representación tipo String del valor. El programa javaDouble.java, demuestra la creación de
una clase Double pasando un valor double y también pasando una cadena que se puede
interpretar como double.
class javaDouble {
public static void main( String args[] ) {
Double d1 = new Double( 3.14159 );
Excelencia Académica
55
Double d2 = new Double( "314159E-5" );
System.out.println( d1 + " = " + d2 + " -> " +
d1.equals( d2 ) );
}
}
Si se ejecuta y observa la salida, se comprueba que ambos constructores han creado
instancias de Double idénticas, como lo demuestra el hecho de que el método equals()
devuelva true.
Declaraciones
La primera sentencia creará una variable double y la segunda un objeto Double:
double d;
Double D;
Valores de Double
Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY
Double.NaN
Double.MAX_VALUE
Double.MIN_VALUE
Métodos de Double
D.isNaN();
Double.isNaN( d );
D.isInfinite();
Double.isInfinite( d );
boolean D.equals();
String D.toString();
int D.intValue();
long D.longValue();
float D.floatValue();
double D.doubleValue();
int i = D.hashCode();
Double V.valueOf( String s );
long l = Double.doubleToLongBits( d );
double d = Double.longBitsToDouble( l );
La Clase Integer El tipo int tiene el objeto Integer. De la misma forma que con la clase Character, se han
codificado muchas funciones útiles dentro de los métodos de la clase Integer.
Excelencia Académica
56
Declaraciones
La primera sentencia creará una variable int y la segunda un objeto Integer:
int i;
Integer I;
Valores de Integer
Integer.MIN_VALUE;
Integer.MAX_VALUE;
MétodosdeInteger
String Integer.toString( int i ) Convierte el int que se
pasa al método en su
representación como
cadena
String Integer.toString(int i,int base)
int I.parseInt( String s ) Convierte la variable String
en el valor int que
representa
int I.parseInt( String s,int base ) Igual que el anterior, a
excepción de que se indica
una base distinta a la
decimal
Integer Integer.valueOf( String s )
Integer Integer.valueOf(String s,int base)
int I.intValue()
float I.floatValue()
String I.toString()
boolean I.equals( Object obj )
long I.longValue()
double I.doubleValue()
int I.hashCode()
En los métodos toString(), parseInt() y valueOf() que no se especifica la base sobre la que
se trabaja, se asume que es base 10.
La Clase Long El tipo long tiene el objeto Long. De la misma forma que con la clase Character, se han
codificado muchas funciones útiles dentro de los métodos de la clase Long.
Declaraciones
La primera sentencia creará una variable long y la segunda un objeto Long:
long l;
Long L;
Excelencia Académica
57
Valores de Long
Long.MIN_VALUE;
Long.MAX_VALUE;
Métodos de Long
String Long.toString( long l,int base );
String Long.toString( long l );
long L.parseLong( String s,int base );
long L.parseLong( String s );
Long Long.valueOf( String s,int base );
Long Long.valueOf( String s );
int L.intValue();
long L.longValue();
float L.floatValue();
double L.doubleValue();
String L.toString();
int L.hashCode();
boolean L.equals( Object obj );
En los métodos toString(), parseInt() y valueOf() que no se especifica la base sobre la que
se trabaja, se asume que es base 10.
La Clase Boolean Los valores boolean también tienen su tipo asociado Boolean, aunque en este caso hay
menos métodos implementados que para el resto de las clases numéricas.
Declaraciones
La primera sentencia creará una variable boolean y la segunda un objeto Boolean:
boolean b;
Boolean B;
Valores de Boolean
Boolean.TRUE;
Boolean.FALSE;
Métodos de Boolean
boolean B.booleanValue();
String B.toString();
boolean B.equals( Object obj );
Excelencia Académica
58
La Clase String Dentro de un objeto de la clases String o StringBuffer, Java crea un array de caracteres de
una forma similar a como lo hace el lenguaje C++. A este array se accede a través de las
funciones miembro de la clase.
Los strings u objetos de la clase String se pueden crear explícitamente o implícitamente.
Para crear un string implícitamente basta poner una cadena de caracteres entre comillas
dobles. Por ejemplo, cuando se escribe
System.out.println("El primer programa");
Java crea un objeto de la clase String automáticamente.
Para crear un string explícitamente escribimos
String str=new String("El primer programa");
También se puede escribir, alternativamente
String str="El primer programa";
Para crear un string nulo se puede hacer de estas dos formas
String str="";
String str=new String();
Un string nulo es aquél que no contiene caracteres, pero es un objeto de la clase String.
Sin embargo,
String str;
está declarando un objeto str de la clase String, pero aún no se ha creado ningún objeto de
esta clase.
Cómo se obtiene información acerca del string
Una vez creado un objeto de la clase String podemos obtener información relevante acerca
del objeto a través de las funciones miembro.
Para obtener la longitud, número de caracteres que guarda un string se llama a la función
miembro length.
String str="El primer programa";
int longitud=str.length();
Podemos conocer si un string comienza con un determinado prefijo, llamando al método
startsWith, que devuelve true o false, según que el string comience o no por dicho prefijo
String str="El primer programa";
boolean resultado=str.startsWith("El");
En este ejemplo la variable resultado tomará el valor true.
De modo similar, podemos saber si un string finaliza con un conjunto dado de caracteres,
mediante la función miembro endsWith.
String str="El primer programa";
boolean resultado=str.endsWith("programa");
Excelencia Académica
59
Si se quiere obtener la posición de la primera ocurrencia de la letra p, se usa la función
indexOf.
String str="El primer programa";
int pos=str.indexOf('p');
Para obtener las sucesivas posiciones de la letra p, se llama a otra versión de la misma
función
pos=str.indexOf('p', pos+1);
El segundo argumento le dice a la función indexOf que empiece a buscar la primera
ocurrencia de la letra p a partir de la posición pos+1.
Otra versión de indexOf busca la primera ocurrencia de un substring dentro del string.
String str="El primer programa";
int pos=str.indexOf("pro");
Vemos que una clase puede definir varias funciones miembro con el mismo nombre pero
que tienen distinto número de parámetros o de distinto tipo.
Comparacióndestrings
La comparación de strings nos da la oportunidad de distinguir entre el operador lógico == y
la función miembro equals de la clase String. En el siguiente código
String str1="El lenguaje Java";
String str2=new String("El lenguaje Java");
if(str1==str2){
System.out.println("Los mismos objetos");
}else{
System.out.println("Distintos objetos");
}
if(str1.equals(str2)){
System.out.println("El mismo contenido");
}else{
System.out.println("Distinto contenido");
}
Esta porción de código devolverá que str1 y str2 son distintos objetos pero con el mismo
contenido. str1 y str2 ocupan posiciones distintas en memoria pero guardan los mismos
datos.
Cambiemos la segunda sentencia y escribamos
String str1="El lenguaje Java";
String str2=str1;
System.out.prinln("Son el mimso objeto "+(str1==str2);
Los objetos str1 y str2 guardan la misma referencia al objeto de la clase String creado. La
expresión (str1==str2) devolverá true.
Excelencia Académica
60
Así pues, el método equals compara un string con un objeto cualquiera que puede ser otro
string, y devuelve true cuando dos strings son iguales o false si son distintos.
String str="El lenguaje Java";
boolean resultado=str.equals("El lenguaje Java");
La variable resultado tomará el valor true.
La función miembro comapareTo devuelve un entero menor que cero si el objeto string es
menor (en orden alfabético) que el string dado, cero si son iguales, y mayor que cero si el
objeto string es mayor que el string dado.
String str="Tomás";
int resultado=str.compareTo("Alberto");
La variable entera resultado tomará un valor mayor que cero, ya que Tomás está después
de Alberto en orden alfabético.
String str="Alberto";
int resultado=str.compareTo("Tomás");
La variable entera resultado tomará un valor menor que cero, ya que Alberto está antes
que Tomás en orden alfabético.
Extraerunsubstringdeunstring
En muchas ocasiones es necesario extraer una porción o substring de un string dado. Para
este propósito hay una función miembro de la clase String denominada substring.
Para extraer un substring desde una posición determinada hasta el final del string
escribimos
String str="El lenguaje Java";
String subStr=str.substring(12);
Se obtendrá el substring "Java".
Una segunda versión de la función miembro substring, nos permite extraer un substring
especificando la posición de comienzo y la el final.
String str="El lenguaje Java";
String subStr=str.substring(3, 11);
Se obtendrá el substring "lenguaje". Recuérdese, que las posiciones se empiezan a contar
desde cero.
Convertirunnúmero a string
Para convertir un número en string se emplea la función miembro estáticavalueOf (más
adelante explicaremos este tipo de funciones).
int valor=10;
String str=String.valueOf(valor);
La clase String proporciona versiones de valueOf para convertir los datos primitivos: int,
long, float, double.
Excelencia Académica
61
Esta función se emplea mucho cuando programamos applets, por ejemplo, cuando
queremos mostrar el resultado de un cálculo en el área de trabajo de la ventana o en un
control de edición.
Convertir un string en número
Cuando introducimos caracteres en un control de edición a veces es inevitable que
aparezcan espacios ya sea al comienzo o al final. Para eliminar estos espacios tenemos la
función miembro trim
String str=" 12 ";
String str1=str.trim();
Para convertir un string en número entero, primero quitamos los espacios en blanco al
principio y al final y luego, llamamos a la función miembro estática parseInt de la clase
Integer (clase envolvente que describe los números enteros)
String str=" 12 ";
int numero=Integer.parseInt(str.trim());
Para convertir un string en número decimal (double) se requieren dos pasos: convertir el
string en un objeto de la clase envolvente Double, mediante la función miembro estática
valueOf, y a continuación convertir el objeto de la clase Double en un tipo primitivo double
mediante la función doubleValue
String str="12.35 ";
double numero=Double.valueOf(str).doubleValue();
Se puede hacer el mismo procedimiento para convertir un string a número entero
String str="12";
int numero=Integer.valueOf(str).intValue();
El siguiente programa muestra el uso de la clase String.
public class Test
{
public static void main(String[] args)
{
String str1 = "La provincia de Santander es muy bonita";
String str2 = "La provincia de SANTANDER es muy bonita";
String strtemp;
int resultado;
resultado = str1.compareToIgnoreCase(str2);
if( resultado > 0 )
strtemp = "mayor que ";
else if( resultado < 0 )
strtemp = "menor que ";
else
Excelencia Académica
62
strtemp = "igual a ";
System.out.println( str1 + " es " + strtemp + str2 );
}
}
Para escribir una aplicación se escribe primero con el editor de textos el programa y
después se compila. Si no existen errores se ejecuta el programa el que se guarda
automáticamente en el disco con el nombre de la clase principal.
La clase math contiene métodos que permite la manipulación de números incluyendo
funciones para convertir y manejar funciones matemáticas con datos numéricos.
Existen clases para realizar el tratamiento de caracteres y cadenas de textos con las cuales
se realiza las conversiones de datos String y otros.
Fco. Javier Ceballos Curso de Programación Java 2
Alfaomega-Rama, España 2,003 Segunda Edición
Luis Joyanes Aguilar Programación en Java
Prentice Hall, España
José Pérez Mayor Programación en Java Paso a Paso
Thomson, España 2,003
Deitel y Deitel Curso de Programación en Java
Prentice Hall, España, 1,995
En el siguiente UNIDAD TEMÁTICA se estudiarán las estructuras de control que nos
permitirán escribir programas más complejos y completos
Excelencia Académica
63
Se debe tener presente que cuando se quiere utilizar los métodos de una clase se deben
importar la clase respectiva al programa que se está construyendo.
Existen métodos que sirven para realizar conversiones de datos y también existen métodos
que sirven para realizar comparaciones y generan un resultado lógico o boleano.
Escribir un programa que permita el ingreso de un número entero tipo byte, un número
entero tipo int, un número entero tipo long, un número real tipo float y un número real tipo
double y que se conviertan a cadenas de texto y se muestre por pantalla una cadena con
todos los número ingresados.
Manejar en forma adecuada las clases math,
Carácter, String, Integer, Flota y sus respectivos métodos.
Excelencia Académica
64
Nº 4
Nombre__________________________________________________________________
Apellidos_______________________________________Fecha _____________________
Ciudad ______________________________Semestre_____________________________
1.- Escribir un programa que solicite un número y que después muestre el número con su
parte decimal redondeado a tres dígitos.
2.- Escribir un programa que solicite un número, que solicite la cantidad de dígitos de la
parte real válidos y que muestre el número con la cantidad de dígitos de la parte real
indicado y redondeado.
3.- Escribir un programa que soliste una cadena de texto y que después solicite otra
cadena de texto y que después por pantalla nos diga en que posición de la primera
cadena se encuentra la segunda cadena.
4.- Escribir un programa que solicite un número entero de hasta tres dígitos y que después
muestre por pantalla cada uno de los dígitos que tiene el número.
Excelencia Académica
65
ESTRUCTURAS DE CONTROL
Durante un programa existen acciones que se van a ejecutar bajo ciertas condiciones de
control o que se van a repetir un número determinado de veces. Por ejemplo, leer 3
caracteres de un flujo de entrada in se codificaría o leer 20 números enteros, etc.
Estructuras de Control
El lenguaje Java soporta las siguientes estructuras de control:
Estructura Sentencia
Toma de decision if-else, switch-case
Bucle for, while, do-while
Otras break, continue, label:, return, goto
Aunque goto es una palabra reservada, actualmente el lenguaje Java no soporta la
sentencia goto. Se puede utilizar las sentencias de bifurcación en su lugar.
Estructura Condicional If y Swicht
La sentencia if-else de Java permite que los programas puedan ejecutar distintos conjuntos
de sentencias según algún criterio o condición.
La sintaxis de la sentencia if-else es:
if ( condición )
Bloque de código a ejecutar si la condición es verdadera
else
Bloque de código a ejecutar si la condición es falsa
La parte del else es opcional, y un bloque de código puede ser simplemente la sentencia
vacía ; para representar que en ese caso no se ha de ejecutar nada. Si se tiene una
sentencia if sin su respectiva parte else, se dice que se tiene una estructura condicional
simple, mientras que si se usa la sentencia else se dice que se tiene una estructura
condicional múltiple.
Supongamos que un programa debe realizar diferentes acciones dependiendo de si el
usuario oprime el botón aceptar o el botón cancelar en una ventana de dialogo. Nuestro
programa puede realizar esto usando la sentencia if - else:
// La respuesta es Aceptar o Cancelar
Excelencia Académica
66
if (respuesta == Aceptar) {
// código para realizar la acción Aceptar
System.out.println( "Su peticion esta siendo atendida" );
}
else {
// código para realizar la acción Cancelar
System.out.println( "Cancelando accion" );
}
Se pueden anidar expresiones if-else, para poder implementar aquellos casos con múltiples
acciones. Esto es lo que se suele denominar como sentencias else if.
Por ejemplo, supongamos que se desea escribir un programa que clasifique según el
contenido de una variable valor, asigne una letra a una variable clasificacion: A para un
valor de 100 a 91, B de 90 a 81, C para 80 a 71 y F si no es ninguno de los anteriores:
int valor;
char clasificacion;
if (valor > 90)
{clasificacion='A';}
else if (valor > 80)
{clasificacion='B';}
else if (valor > 70)
{clasificacion='C';}
else
{clasificacion='F';}
Se pueden escribir los if en las mismas líneas que los else, pero desde se recomienda
utilizar la forma indentada (como se ha podido ver en el ejemplo), pues es más clara para
el lector.
Este sistema de programación (else if) no es demasiado recomendable, y por ello el
lenguaje Java incluye la sentencia switch, que veremos a continuación, para dirigir el flujo
de control de variables con múltiples valores.
Sentencia Switch
Mediante la sentencia switch se puede seleccionar entre varias sentencias según el valor
de cierta expresión.
La forma general de switch es la siguiente:
switch ( expresionMultivalor ) {
case valor1 : conjuntoDeSentencias1; break;
case valor2 : conjuntoDeSentencias2; break;
case valor3: conjuntoDeSentencias3; break;
Excelencia Académica
67
.
.
.
case valorn: conjuntoDeSentenciasn; break;
default: conjuntoDeSentenciasdef; break;
} // fin de la sentencia switch
La sentencia switch evalúa la expresiónMultivalor y ejecuta el conjuntoDeSentenciasX que
aparece junto a la cláusula case cuyo valor corresponda con el de la expresiónMultivalor.
Cada sentencia case debe ser única y el valor que evalúa debe ser del mismo tipo que el
devuelto por la expresiónMultivalor de la sentencia switch.
Las sentencias break que aparecen tras cada conjuntoDeSentencias provocan que el
control salga del switch y continúe con la siguiente instrucción al switch. Las sentencias
break son necesarias porque sin ellas se ejecutarían secuencialmente las sentencias case
siguientes. Existen ciertas situaciones en las que se desea ejecutar secuencialmente
algunas o todas las sentencias case, para lo que habrá que eliminar algúnos break.
Finalmente, se puede usar la sentencia default para manejar los valores que no son
explícitamente contemplados por alguna de las sentencias case. Su uso es altamente
recomendado.
Por ejemplo, supongamos un programa con una variable entera meses cuyo valor indica el
mes actual, y se desea imprimir el nombre del mes en que estemos. Se puede utilizar la
sentencia switch para realizar esta operación:
int meses;
switch ( meses ){
case 1: System.out.println( "Enero" ); break;
case 2: System.out.println( "Febrero" ); break;
case 3: System.out.println( "Marzo" ); break;
//Demás meses
// . . .
case 12: System.out.println( "Diciembre" ); break;
default: System.out.println( "Mes no valido" ); break;
}
Por supuesto, se puede implementar esta estructura como una sentencia if else if:
int meses;
if ( meses == 1 ) {
System.out.println( "Enero" );
}
else
if ( meses == 2 ) {
Excelencia Académica
68
System.out.println( "Febrero" );
}
// Y así para los demás meses
El decidir si usar la sentencia if o switch depende del criterio de cada caso. Se puede
decidir cuál usar basándonos en la legibilidad, aunque se recomienda utilizar switch para
sentencias con más de tres o cuatro posibilidades.
EJEMPLO 1
Escribir un programa que solicite un número entero y muestre por pantalla un mensaje
indicando si el número que se ha ingresado es par, impar o es cero.
import java.io.*;
public class ParImpar
{
public static void main(String[] args) throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
int N;
System.out.print("Ingrese un número entero : ");
N=Integer.parseInt(flujoE.readLine());
//verificacion si es par o impar
if (N==0) System.out.println("El número es cero");
else if (N%2==0) System.out.println("El número es par");
else System.out.println("El número es impar");
}
}
EJEMPLO 2
Escribir un programa que solicite un carácter y que muestre el carácter ingresad, su código
ASCII y si este código es par o impar.
import java.io.*;
public class Caracter
{
Excelencia Académica
69
public static void main(String[] args) throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader flujoE = new BufferedReader(isr);
int N;
System.out.print("Ingrese un caracter y presione Enter : ");
N=System.in.read();
System.out.print("EL caracter es "+(char)N+" su código ASCII es "+N);
//verificacion si el código es par o impar
if (N%2==0) System.out.println(" y es par");
else System.out.println(" y es impar");
}
}
5.1
1.- Ingresar un número cualquiera e informar si es o no es mayor de 100.
2.- Ingresar un número entero cualquiera e informar si es o no es múltiplo de 4 ( recordar
el operador modulo o residuo (%), analizado en el tema de operadores aritméticos).
3.- Ingresar los cinco datos más importantes de un Empleado, incluyendo el sueldo diario
y los días trabajados desplegarle su cheque semanal solo si ganó más de $500.00 en
la semana, en caso contrario desplegarle un bono de despensa semanal de $150.00.
4.- Ingresar los datos más importantes de un estudiante incluyendo tres calificaciones
construir una boleta de calificaciones si el estudiante es de la carrera de medicina, en
caso contrario construir una pantalla más bonita todavía que despliega un oficio
citando a los padres del estudiante a una platica amistosa con los maestros de la
universidad.
5.- Ingresar los datos más importantes de un producto cualquiera, incluyendo cantidad,
precio, etc. desplegar una orden de compra, solo si el producto es de origen nacional,
en caso contrario no hacer nada.
Ciclos Repetitivos
Excelencia Académica
70
Los ciclos repetitivos, llamados también ciclos, anillos o lazos se utilizan como una
estructura que repite una instrucción o grupo de instrucciones bajo una condición.
a) Bucle while
El bucle while sirve para realizar una acción sucesivamente mientras se cumpla una
determinada condición.
La forma general del bucle while es la siguiente:
while ( condición ) {
sentencias que se repiten;
};
Las sentencias se ejecutan mientras la condición tenga un valor verdadero, cuando la
condición es falsa se termina el ciclo repetitivo y se pasa a la siguiente sentencia.
Se utiliza, por ejemplo para estar en un bucle del que no hay que salir hasta que no se
cumpla una determinada condición. Por ejemplo, multiplicar un número por 2 hasta que sea
mayor que 100:
int i = 1;
while ( i <= 100 ) {
i = i * 2;
}
Con él se podrían eliminar los bucles do-while y for por ser extensioones de éste, pero que
se incluyen en el lenguaje para facilitar la programación.
b) Bucle do-while
El bucle do-while es similar al bucle while, pero en el bucle while la expresión se evalúa al
principio del bucle y en el bucle do-while la evaluación se realiza al final.
La forma general del bucle do-while es la siguiente:
do {
sentencias que se repiten;
} while ( condición );
La sentencia do-while es el constructor de bucles menos utilizado en la programación, pero
tiene sus usos, cuando el bucle deba ser ejecutado por lo menos una vez. En esta
estructura el bucle se repite si la condición es verdadera y se termina cuando la condición
es falsa.
Por ejemplo, cuando se lee información de un archivo, se sabe que siempre se debe leer
por lo menos un carácter:
Excelencia Académica
71
int c;
do {
c = System.in.read( );
// Sentencias para tratar el carácter c
} while ( c != -1 ); // No se puede leer más (Fin fichero)
c) Bucle for
Mediante la sentencia for se resume un bucle do-while con una iniciación previa. Es muy
común que en los bucles while y do-while se inicien las variables de control de número de
pasadas por el bucle, inmediatamente antes de comenzar los bucles. Por eso el bucle for
está tan extendido.
La forma general de la sentencia for es la siguiente:
for ( iniciación ; terminación ; incremento )
sentencias;
La iniciación es una sentencia o varias sentencias separadas por comas, que se ejecuta
una sola vez antes de entrar en el bucle.
La terminación es una expresión o condición lógica que determina cuándo se debe terminar
el bucle. Esta condición se evalúa al final de cada iteración del bucle. Cuando la expresión
se evalúa como falso, el bucle termina.
El incremento es una expresión que es invocada en cada iteración del bucle después de
verificar la condición. En realidad puede ser una acción cualquiera, aunque se suele utilizar
para incrementar una o varias variables contador:
for ( i = 0 ; i < 10 ; i++ )
Algunos (o todos) estos componentes pueden omitirse, pero los puntos y coma siempre
deben aparecer (aunque sea sin nada entre sí).
Se debe utilizar el bucle for cuando se conozcan las restricciones del bucle (su instrucción
de iniciación, criterio de terminación e instrucción de incremento).
Por ejemplo, los bucles for son utilizados comúnmente para iterar sobre los elementos de
una matriz, o los caracteres de una cadena:
// cad es una cadena (String)
for ( int i = 0; i < cad.length() ; i++){
// hacer algo con el elemento i-ésimo de cad
}
Sentencias de salto: break, continue y return a.) Sentencia break
Excelencia Académica
72
La sentencia break provoca que el flujo de control salte a la sentencia inmediatamente
posterior al bloque en curso. Ya se ha visto anteriormente la sentencia break dentro de la
sentencia switch.
El uso de la sentencia break con sentencias etiquetadas es una alternativa al uso de la
sentencia goto, que no es soportada por el lenguaje Java.
Se puede etiquetar una sentencia poniendo una identificador Java válido seguido por dos
puntos antes de la sentencia:
nombreSentencia: sentenciaEtiquetada
La sentencia break se utiliza para salir de una sentencia etiquetada, llevando el flujo del
programa al final de la sentencia de programa que indique:
break nombreSentencia2;
Un ejemplo de esto sería el programa:
void gotoBreak() {
System.out.println("Ejemplo de break como 'goto' ");
a: for( int i=1; i<10; i++ ){
System.out.print(" i="+i);
for( int j=1; j<10; j++ ){
if ( j==5 )
break a; //Sale de los dos bucles!!!
System.out.print(" j="+j);
}
System.out.print("No llega aquí");
}
}
Al ejecutar break a, no solo se rompe la ejecución del bucle interior (el de j), sino que se
salta al final del bucle i, obteniéndose:
i=1 j=1 j=2 j=3
Nota: No se recomienda esta forma de programación, basada en goto, y con saltos de flujo
no controlados.
b.) Sentencia continue
Del mismo modo que en un bucle se puede desear romper la iteración, también se puede
desear continuar con el bucle, pero dejando pasar una determinada iteración.
Se puede usar la sentencia continue dentro de los bucles para saltar a otra sentencia,
aunque no puede ser llamada fuera de un bucle.
Excelencia Académica
73
Tras la invocación a una sentencia continue se transfiere el control a la condición de
terminación del bucle, que vuelve a ser evaluada en ese momento, y el bucle continúa o no
dependiendo del resultado de la evaluación. En los bucles for además en ese momento se
ejecuta la cláusula de incremento (antes de la evaluación). Por ejemplo el siguiente
fragmento de código imprime los números del 0 al 9 no divisibles por 3:
for ( int i = 0 ; i < 10 ; i++ ) {
if ( ( i % 3 ) == 0 )
continue;
System.out.print( " " + i );
}
Del mismo modo que break, en las sentencias continue se puede indicar una etiqueta de
bloque al que hace referencia. Con ello podemos referirnos a un bloque superior, si
estamos en bucles anidados. Si dicha etiqueta no es indicada, se presupone que nos
referimos al bucle en el que la sentencia continue aparece.
Por ejemplo, el siguiente fragmento de código:
void gotoContinue( ) {
f: for ( int i=1; i <5; i++ ) {
for ( int j=1; j<5; j++ ) {
if ( j>i ) {
System.out.println(" ");
continue f;
}
System.out.print( " " + (i*j) );
}
}
}
En este código la sentencia continue termina el bucle de j y continua el flujo en la siguiente
iteración de i. Ese método imprimiría:
1
2 4
3 6 9
4 8 12 16
c.) Sentencia return
Excelencia Académica
74
La última de las sentencias de salto es la sentencia return, que puede usar para salir del
método en curso y retornar a la sentencia dentro de la cual se realizó la llamada.
Para devolver un valor, simplemente se debe poner el valor (o una expresión que calcule el
valor) a continuación de la palabra return. El valor devuelto por return debe coincidir con el
tipo declarado como valor de retorno del método.
Cuando un método se declara como void se debe usar la forma de return sin indicarle
ningún valor. Esto se hace para no ejecutar todo el código del programa:
int contador;
boolean condición;
int devuelveContadorIncrementado(){
return ++contador;
}
void métodoReturn(){
//Sentencias
if ( condición == true )
return;
//Más sentencias a ejecutar si condición no vale true
}
5.2
1.- Construir un programa que muestre por pantalla los números del 20 al 30. Hacer un
programa usando for, otro con while y otro con do.
2.- Desplegar los enteros entre 50 y 30 acompañados de su potencia cuadrada y raíz
cúbica respectiva (revisar el tema de operadores aritméticos).
3.- Desplegar los múltiplos de 5, entre 10 y 50, acompañados de su factorial y logaritmo
respectivo (revisar el tema de operadores aritméticos también).
4.- Desplegar la tabla de multiplicar del número que se ingrese por teclado.
Las estructuras de control permiten controlar o
variar el flujo del programa para poder ejecutar instrucciones de acuerdo a ciertas
condiciones.
Para implementar condiciones en un programa se usan los operadores de relación
descritos en el Apéndice II los que pueden combinarse con operadores lógicos con la
finalidad de construir condiciones más amplias para mejorar los programas.
Excelencia Académica
75
La estructura if es una estructura condicional simple que evalúa la condición y si es cierta o
se cumple ejecuta una instrucción.
La instrucción if-else evalúa la condición y si se cumple se ejecuta una instrucción, si no se
cumple ejecuta otra instrucción diferente.
La instrucción switch evalúa el valor de una variable ordinal y de acuerdo a este valor
ejecuta una instrucción.
Los ciclos repetitivos son instrucciones que repiten la ejecución de una instrucción mientras
se cumpla una condición. Existen tres formas de ciclos repetitivos que son:
Ciclo while que evalúa la condición y si es cierta ejecuta la instrucción que se repite, en
caso de que desde el inicio la condición sea falsa no se ejecuta ninguna vez la instrucción.
Ciclo while-do evalúa la condición cuando ya se ha ejecutado la instrucción que se repite,
en este tipo de bucle se garantiza que por lo menos una vez se repite la instrucción.
Ciclo for tiene instrucciones de inicialización de contadores que se realiza una sola vez,
después se verifica el cumplimiento de la condición y si es verdadero se ejecuta la
instrucción que se repite después de lo cual se realiza las instrucciones de incremento si es
que existen y se vuelve a verificar la condición. Este bucle es preferible usarlo cuando se
conoce el número de repeticiones.
Fco. Javier Ceballos Curso de Programación Java 2
Alfaomega-Rama, España 2,003 Segunda Edición
Luis Joyanes Aguilar Programación en Java
Prentice Hall, España
José Pérez Mayor Programación en Java Paso a Paso
Thomson, España 2,003
Deitel y Deitel Curso de Programación en Java
Prentice Hall, España, 1,995
En el próximo UNIDAD TEMÁTICA estudiaremos los métodos de Java que permiten crear
módulos independientes que van a usar las estructuras de control estudiadas y que pueden
ser reutilizados como componentes de un nuevo programa que se desarrolle.
Excelencia Académica
76
Cuando se usan estructuras de control se
debe tener cuidado al usar las sentencias de salto que son break, continue y return que
permiten salir de los ciclos repetitivos o instrucción switch los que deben usarse en forma
adecuada para evitar saltos o salidas de la estructura no deseadas.
Escribir programas usando estructuras condicionales con operadores de relación.
Escribir programas usando ciclos repetitivos.
Escribir programas usando estructuras condicionales y ciclos repetitivos que tengan varias
condiciones.
Nº 5
Nombre__________________________________________________________________
Apellidos_______________________________________Fecha _____________________
Ciudad ______________________________Semestre_____________________________
1.- Construir un programa que solicite un número cualquiera e informe si es o no es mayor
de 50 y múltiplo de tres. ( solo escribir el mensaje de respuesta de manera muy clara y
esto resuelve el problema )
2.- Construir un programa que indique si un número que se ingresa por teclado es un par
positivo.
3.- Ingresar los datos de un producto incluyendo su cantidad en existencia, desplegar una
orden de compra si la cantidad en existencia del producto es menor que el punto de
reorden, o si el origen del producto es nacional.
4.- Evaluar la función Y=5X^2 + 3X + 8 cuando X--> -3...10 (Rango de -3 hasta 10)
5.- Desplegar los múltiplos de 4 entre 60 y 20 acompañados de su logaritmo en base 10 y
de su logaritmo natural.
Excelencia Académica
77
6.- Evaluar una función cualesquiera para el rango de valores de x de -3 a +5
MÉTODOS Y CARACTERÍSTICAS Y
PROPIEDADES
Los métodos establecen el comportamiento de los objetos, por lo que su definición es
esencial. En Java, los métodos son lo que en otros lenguajes se conoce como funciones,
procedimientos, o subrutinas por lo que su definición es muy similar.
La sintaxis para definir un método es :
[modificador][tipo] nombreDeMétodo ( [tipo arg1,tipo arg2, ..., tipo argN] )
{
/* Cuerpo del método */
}
donde :
tipo es el tipo o clase del valor que devuelve el método. Puede ser cualquiera de los tipos
básicos ( primitivos ) o la palabra reservada void que indica que el método no regresa valor
alguno.
La lista de argumentos que aparece entre paréntesis y entre corchetes es opcional y
representan los valores que se pasan al método cuando es invocado. Si el argumento es
una variable de alguno de los tipos primitivos, el paso se hace por valor, lo que significa
que al método se le envía una copia del valor almacenado en la variable. En caso de que el
argumento sea un objeto, el paso se hace por referencia, lo que significa que se pasa la
dirección de memoria donde se almacena el objeto y que cualquier cambio realizado en el
método ( con el nombre de la variable donde se recibe el argumento ) afectará al objeto
original referenciado.
Ejemplo :
class PropiedadEnVenta
{
boolean credito = true;
void informa(String direccion, String tipo, float precio )
{
if(credito==true)
System.out.println("Esta propiedad tiene
atractivos planes de crédito.\n\n");
else
Excelencia Académica
78
System.out.println("Lo sentimos. Esta propiedad
solo se vende al contado.");
System.out.println("Dirección : "
+direccion) ;
System.out.println("Tipo : "+tipo) ;
System.out.println("Precio : $ "precio) ;
}
}
En este ejemplo se ha definido la clase propiedadEnVenta , que contiene un método
denominado informa . Este método no retorna ningún valor, puesto que se utiliza la
palabra void como tipo de retorno, y recibe tres argumentos que almacena en las
variables direccion, tipo y precio.
dirección almacena una referencia a un objeto de la clase String.
tipo almacena una referencia a un objeto de la clase String.
precio almacena un valor de tipo float.
El código aquí mostrado no es una aplicación completa, pues requiere de una invocación al
método informa( ) perteneciente a un objeto de la clase propiedadEnVenta, por ejemplo :
objeto.informa( "Balandra # 48", "Colonial", 250000.00F) ;
Con esto, se desplegaría :
Esta propiedad tiene atractivos planes de crédito.
Dirección : Balandra #48
Tipo : Colonial
Precio : $ 250000.00
Clases y métodos abstractos. Una clase abstracta es aquella que no puede ser instanciada, (no pueden crearse objetos
de esa clase) y que solo sirve como una plantilla para sus subclases.
En su definición, una clase abstracta se distingue porque su nombre está prefijado por la
palabra clave abstract y/o porque tiene al menos un método abstracto.
Los métodos abstractos son aquellos cuya declaración está prefijada por la palabra clave
abstract . Además, los métodos abstractos no cuentan con un cuerpo o definición en la
clase donde fueron declarados.
Ejemplo :
class abstract Figuras
{
abstract double área( ) ;
abstract double perimetro( ) ;
}
Excelencia Académica
79
En la clase abstracta Figuras se han declarado dos métodos abstractos : área y
perimetro. Ambos regresan valores de tipo double a sus invocadores.
Las clases abstractas no pueden utilizarse para crear nuevos objetos ya que sus métodos
no son capaces de establecer comportamientos. Esto se debe a que solo existen los
nombres de los métodos, pero no sus cuerpos (definiciones).
Para utilizar los métodos de una clase abstracta, es necesario crear una subclase de ella,
donde se definan los métodos abstractos.
Por ejemplo, con base a la clase Figuras , se pueden definir nuevas clases para diferentes
figuras geométricas. Esto se logra utilizando la palabra extends , como se muestra en el
siguiente código :
1 : class Circulo extends Figuras
2 : {
3 : double radio ;
4 : protected static final double PI = 3.14159265 ;
// PI es una constante
5 : Circulo( ) { radio = 1.0 ;}
6 : Circulo( double r) {radio = r ;}
7 : double área( ) { return PI * radio * radio ; }
8 : double perimetro( ) { return PI * 2 * radio ; }
9 : }
Analicemos cada una de las líneas del código anterior :
En la línea 1 se establece que la clase Circulo extiende a la clase Figuras.
En la línea 3 se define la variable radio como del tipo double.
En la línea 4 se define la variable PI como del tipo double y se le asigna un valor
inicial.
En la línea 5 se define un método constructor para la clase Circulo ( Obsérvese que el
nombre del constructor es el mismo que el de la clase ). En este caso, el método no tiene
argumentos y el cuerpo solo consta de la instrucción : radio = 1.0 ; , encerrada entre llaves.
En la línea 6 se define otro constructor para la clase, solo que este método recibe un valor
de tipo double en la variable r.
En este punto, conviene observar algunas características de los métodos constructores.
No devuelven ningún valor.
Pueden sobrecargarse, esto es, definirse con diferentes argumentos.
Cuando existen varias definiciones de un método, ¿Como saber cuál código
ejecutar cuando se invoca al método ?. El mecanismo consiste en la elaboración
de una "firma" para cada una de las definiciones. Dependiendo de la cantidad y
los tipos de los argumentos utilizados en la invocación, se podrá determinar cual
código ejecutar, a pesar de que los nombres de métodos utilizados en las
definiciones sean iguales.
Por ejemplo, al crear el objeto miCirculo ,de la clase Circulo,
Excelencia Académica
80
con la instrucción :
Circulo miCirculo = new Circulo( ) ;
se utilizará la definición de la línea 5 y el radio será igual a 1.0 .
En cambio, si el objeto se crea con la instrucción :
Circulo miCirculo = new Circulo( 1.5 ) ;
será utilizada la definición de la línea 6 y a radio se le asignará el valor 1.5 .
Obsérvese que la creación de un objeto se rige por la sintaxis :
nombreClase nombreObjeto = new nombreConstructor( [argumentos]) ;
La sobrecarga de métodos no solamente se aplica a los constructores, sino a
todos los métodos ( salvo las excepciones establecidas por los modificadores
que se describen más adelante ).
Las líneas 7 y 8 definen a los métodos área( ) y perimetro( ) declarados como abstractos
en la clase Figuras.
Las reglas correspondientes a la abstracción de clases y métodos se pueden resumir de la
siguiente manera :
Cualquier clase con un método abstracto es automáticamente abstracta ; una clase
abstracta debe contener al menos un método abstracto.
Una clase abstracta no puede utilizarse para crear objetos.
Una subclase de una clase abstracta puede utilizarse para crear objetos si
sobrepone cada uno de los métodos abstractos de la superclase y provee una
definición (cuerpo) para cada uno de ellos.
Si una subclase de una clase abstracta no implementa ( define ) todos los métodos
abstractos que hereda, esa subclase es abstracta.
Modificadores de visibilidad. Los modificadores de visibilidad especifican la posibilidad de acceder a las clases, métodos
y variables de otros paquetes, clases ,y métodos ; como se describe en la siguiente tabla:
Modificador Significado
public
Una clase o interfaz public es visible en cualquier
lugar. Un método o una variable public son visibles
en cualquier lugar donde su clase es visible.
protected
Las clases no pueden ser protected.
Un método o una variable protected son visibles a
través del paquete de su clase, y en cualquier
subclase de su clase.
Una subclase en un paquete diferente al de la
superclase puede acceder a los campos protected
Excelencia Académica
81
heredados por sus instancias, pero no puede acceder
a esos campos en instancias de la superclase.
private
Las clases no pueden ser private.
Un método o una variable private solamente es
visible dentro de su propia clase.
private protected
Una clase no puede ser private protected.
Una subclase puede acceder a los campos private
protected heredados por sus instancias, pero no
puede acceder a esos campos en instancias de la
superclase.
Un método o variable private protected es visible
solamente dentro de su propia clase y dentro de
cualquier subclase.
predeterminación
Al no especificarse algún modificador, una clase,
interfaz, método, o variable es visible solamente
dentro de su paquete.
Otros modificadores.
Además de los modificadores de visibilidad, existen otros modificadores que se utilizan
para especificar varios atributos de clases, métodos y variables. Estos modificadores se
describen a continuación
Modificador Utilizado en : Significado
clase La clase contiene métodos no implementados y no puede
instanciarse (utilizarse para crear objetos).
abstract interfaz Todas las interfaces son abstractas. El modificador es
opciónal en las declaraciónes de interfaces.
método No se provee el cuerpo ( definición, implementación)
del método.
clase La clase no puede extenderse.
final método El método no puede sobreponerse.
variable El valor de la "variable" no puede cambiar.
método
El método es un "método de clase", es implícitamente
final, y puede ser invocado por medio del nombre de la
Excelencia Académica
82
static clase.
variable
La variable es una "variable de clase". Existe solo una
instancia de la variable. Puede accederse por medio del
nombre de la clase.
Synchronized método
El método hace modificaciones no atómicas a la clase o
instancia. Debe asegurarse que dos hilos no puedan
modificar a la clase o instancia, al mismo tiempo.
Transient variable La variable no es parte del estado persistente del objeto.
( Este modificador no está implementado )
Volatile variable La variable cambia asincrónicamente. El compilador no
tratará de salvar su valor en los registros.
Conceptos básicos de arreglos. Un arreglo es una colección de objetos numerados del mismo tipo, en donde cada variable
o celda en el arreglo tiene un índice. Las celdas están numeradas del 0 al N-1, donde N es
el número de celdas del arreglo es decir su capacidad o tamaño.
Los índices de un arreglo en Java deben estar dentro de los límites, 0 hasta N-1, de lo
contrario se generará un error durante la ejecución.
Los arreglos tienen las siguientes características:
Son manipulados por referencia.
Se crean dinámicamente por medio de la palabra clave new.
Son destruidos automáticamente por el recolector de basura.
Java implementa los arreglos como objetos que pueden ser tratados como cualquier otro
objeto.
Para utilizar un arreglo en Java se debe hacer lo siguiente:
1. Declarar una variable para que contenga el arreglo
2. Crear un nuevo arreglo de objeto y asignarlo a la variable de arreglo
3. Almacenar la información en el arreglo
4. Realizar operaciones de almacenamiento y recuperación con los elementos del
arreglo
Declaración: Para declarar un arreglo se agrega un par de corchetes vacíos [ ] al objeto o tipo de datos,
o al nombre de variable.
Excelencia Académica
83
Ejemplos:
String palabrasDificiles [ ];
Point hits [ ];
int donaciones [ ];
o bien:
String [ ] palabrasDificiles;
Point [ ] hits;
int [ ] donaciones;
Creación de objetos de arreglos:
Después de haber declarado la variable arreglo, el siguiente paso es crear un arreglo de
objetos y asignarlo a esa variable. Las formas de hacerlo son:
a través del operador new
inicializando directamente el contenido del arreglo
Ejemplos:
String [ ] nombreJugadores = new String [10];
int [ ] temps = new int [99];
Todas las posiciones se inicializan automáticamente (0 para arreglos numéricos, false para
booleanos, ‘\0’ para arreglos de carácter y null para objetos)
También se puede crear e inicializar un arreglo al mismo tiempo. Encierre los elementos
del arreglo entre llaves,
separándolos con comas:
String [ ] flores = {“clavel”, “rosas”, “alheli”, “cantuta”};
int arregloDeCincoEnteros[ ] = { 10, 15, 20, 25, 30 } ;
Al crear elementos con valores iniciales, el arreglo es del mismo tamaño que la cantidad de
elementos que ha incluido en las llaves.
Ejemplo:
class ArregloNombres
{
String[] nombres = { "Daniel", "Mary", "Alberto", "Juan"};
String[] apellidos = new String[nombres.length];
Excelencia Académica
84
void imprime()
{
int i = 0;
System.out.println(nombres[i] + " " + apellidos[i]);
i++;
System.out.println(nombres[i] + " " + apellidos[i]);
i++;
System.out.println(nombres[i] + " " + apellidos[i]);
i++;
System.out.println(nombres[i] + " " + apellidos[i]);
}
public static void main (String arguments[])
{
ArregloNombres a = new ArregloNombres();
a.imprime();
System.out.println("-----");
a.apellidos[0] = "Rivera";
a.apellidos[1] = "Hinojosa";
a.apellidos[2] = "Sedano";
a.apellidos[3] = "Gomero";
a.imprime();
}
}
El tamaño de un arreglo se almacena en la variable length, que puede ser accesada a
través del operador . y el nombre del arreglo:
nombreArreglo.length
Acceso a los elementos de un arreglo.
Para acceder a los elementos de un arreglo, deben especificarse el nombre del arreglo y el
índice que identifica al elemento.
Los índices son números enteros positivos que representan la posición de cada elemento
en el arreglo. Al índice del primer elemento en el arreglo le corresponde el valor cero.
Así, del ejemplo anterior tenemos que :
arregloDeCincoEnteros[0] tiene un valor igual a 10,
arregloDeCincoEnteros[1] tiene un valor igual a 15,
arregloDeCincoEnteros[2] tiene un valor igual a 20,
arregloDeCincoEnteros[3] tiene un valor igual a 25 y
arregloDeCincoEnteros[4] tiene un valor igual a 30.
Excelencia Académica
85
Observe que el valor del índice del último elemento es igual al tamaño del arreglo menos
uno (esto se debe a que la numeración empieza en cero ).
EJEMPLO
Escribir un programa que solicite el ingreso de una cadena y después muestre la cadena
convertida a mayúsculas.
import java.io.*;
public class CCadenas
{
public static void main(String[] args)
{
char[] cadena = new char[80]; // matriz de caracteres
int car, i = 0; // un carácter y el subíndice para la matriz
int desp=’a’ – ‘A’;
try
{
System.out.println("Escriba una cadena de caracteres:");
while ((car = System.in.read()) != '\r' && i < cadena.length)
cadena[i++] = (char)car;
// Convertir minúsculas a mayúsculas
for (i = 0; i < cadena.length && cadena[i] != '\0'; i++)
if (cadena[i] >= 'a' && cadena[i] <= 'z')
cadena[i] = (char)(cadena[i] - desp);
}
System.out.println(cadena);
}
catch(IOException ignorada) {}
}
}
Explicación : Se ingresa la cadena de texto a un arreglo que como máximo va a tener 80
caracteres terminando el ingreso cuando se presiona la tecla Enter. La conversión a
mayúsculas se realiza restando a las minúsculas el valor desp ya que los códigos ASCII de
las minúsculas son mayores a los de las mayúsculas en este valor. No se realizará la
conversión de las vocales acentuadas ni de la letra ñ.
Arreglos multidimensionales.
Si definimos un arreglo multidimensional como aquel que permite el uso de varios índices
(donde cada índice representa una dimensión), entonces podemos afirmar que Java
Excelencia Académica
86
soporta arreglos multidimensionales y que los implementa con arreglos de arreglos, de
manera similar a como lo hacen otros lenguajes.
Ejemplo :
byte arregloBidimensional[][] = new byte [20][30] ;
Esto crea un arreglo de arreglos de bytes, al reservar dinámicamente ( en tiempo de
ejecución) 600 bytes de memoria ( en el montículo - heap - de la memoria RAM ). La
dirección de ese bloque de memoria se asigna a la variable arregloBidimensional.
No es necesario especificar los valores de cada una de los índices de un arreglo, por lo que
podemos escribir el ejemplo anterior como :
byte arregloBidimensional[][] = new byte [600][] ;
Lo importante es que se especifique el total de elementos y señalar las dimensiones
necesarias.
La regla para este caso es que las primeras n dimensiones ( n > = 1 ) deben tener el
número de elementos especificados, y que esas dimensiones deben estar seguidas por m
dimensiones adicionales, las cuales no tendrán valores específicos.
De acuerdo a esta regla, es correcto escribir :
String quinceCadenas[][][][] = new String[5][3][][] ;
pero no :
String quinceCadenas[][][][] = new String[5][][][3] ;
En Java, los métodos son lo que en otros lenguajes se conoce como funciones,
procedimientos, o subrutinas por lo que su definición es muy similar.
Los modificadores de visibilidad especifican la posibilidad de acceder a las clases, métodos
y variables de otros paquetes, clases ,y métodos
Un arreglo es una colección de objetos numerados del mismo tipo, en donde cada variable
o celda en el arreglo tiene un índice. Las celdas están numeradas del 0 al N-1, donde N es
el número de celdas del arreglo es decir su capacidad o tamaño.
Los índices de un arreglo en Java deben estar dentro de los límites, 0 hasta N-1, de lo
contrario se generará un error durante la ejecución.
Los arreglos tienen las siguientes características:
Son manipulados por referencia.
Se crean dinámicamente por medio de la palabra clave new.
Son destruidos automáticamente por el recolector de basura.
Excelencia Académica
87
Los arreglos primero deben ser declarados y luego deben ser creados, estas dos
operaciones pueden realizarse simultáneamente en una sola instrucción.
Los arreglos multidimensionales declaran en el primer índice el número de filas y en el
segundo índice el número de columnas.
Fco. Javier Ceballos Curso de Programación Java 2
Alfaomega-Rama, España 2,003 Segunda Edición
Luis Joyanes Aguilar Programación en Java
Prentice Hall, España
José Pérez Mayor Programación en Java Paso a Paso
Thomson, España 2,003
Deitel y Deitel Curso de Programación en Java
Prentice Hall, España, 1,995
En el siguiente UNIDAD TEMÁTICA se realizará el estudio de las aplicaciones de arreglos
con los algoritmos de búsqueda y selección y los algoritmos de ordenamientos de datos
aplicados a arreglos unidimensionales y multidimensionales.
Cuando se declara un método se debe especificar el alcance y visibilidad ya que de lo
contrario no podrá usarse el método en donde se requiera.
Se debe tener cuidado con los índices de los arreglos que se manejan ya que si se pasa el
valor máximo, el programa se compilará, pero no se ejecutará mostrando un error.
En los arreglos bidimensionales el primer índice especifica la fila de la matriz, mientras que
el segundo índice hace referencia a la columna de la matriz. Recuerde siempre que los
índices deben ser números o variables enteras.
Escribir un programa para ingresar 20 números enteros y probar que funcione
correctamente. A continuación modificar el bucle de ingreso de datos para ingresar 25
datos para observar y explicar lo que ocurre.
Excelencia Académica
88
Escribir un programa para ingresar el nombre y tres notas de 25 alumnos, calcular el
promedio entero redondeado con 0.5 a favor del alumno y finalmente mostrar todos los
datos ingresados y calculados.
Escribir programas que manejen arreglos y métodos para la construcción de programas.
Manejar en forma adecuada la declaración, escritura y llamado a los métodos pasando los
argumentos que sean necesarios.
Manejar en forma adecuada los índices de los arreglos usando ciclos repetitivos.
Nº 6
Nombre__________________________________________________________________
Apellidos_______________________________________Fecha _____________________
Ciudad ______________________________Semestre_____________________________
1.- Escribir un programa que elabore una factura donde solicite el nombre del producto, el
costo unitario y la cantidad despachada, datos que se solicitan en forma repetitiva y se
almacenan en arreglos, el ingreso de datos termina cuando se solicita el nombre del
producto y se ingresa el cero después de lo cual se muestra la factura con todos los datos
y los costos incluyendo un sub total y el IGV (19%) y un total general de la factura.(No es
necesario manejar formatos)
2.- Escribir un programa que solicite 5 números enteros y los almacene en un arreglo y
después que cambie los datos del mismo arreglo dividiéndolos entre dos y sumando 5 a
cada número. Por ejemplo si se ingresa:
1
2
3
4
5
El arreglo debe ser cambiado a
5.5
6
6.5
7
7.5
En el ingreso se debe verificar que los números ingresados son enteros.
3.- Escribir un programa que ingrese 20 números enteros a un arreglo y que después por
medio de un método llamado buscaPar seleccione y muestre los números pares y por
medio de otro método llamado buscaImpar seleccione y muestre los impares.
Excelencia Académica
89
4.- Escribir un programa para que se ingrese a un arreglo de caracteres un texto de hasta
80 caracteres y que después muestre el texto todo en mayúscula, todo en minúscula,
los caracteres de posiciones pares en mayúscula. Se debe tener en cuenta las vocales
con tilde y la letra ñ.
CONCEPTOS BÁSICOS DE LA PROGRAMACIÓN
ORIENTADA A OBJETOS
Cuando se escribe un programa en un lenguaje orientado a objetos, definimos una plantilla
o clase que describe las características y el comportamiento de un conjunto de objetos
similares. La clase automóvil describe las características comunes de todos los
automóviles: sus atributos y su comportamiento. Los atributos o propiedades se refieren a
la marca o fabricante, el color, las dimensiones, si tienen dos, tres, cuatro o más puertas, la
potencia, si utiliza como combustible la gasolina o gas natural, etc. El comportamiento se
refiere a la posibilidad de desplazarse por una carretera, frenar, acelerar, cambiar de
marcha, girar, etc.
Luego, tenemos automóviles específicos, por ejemplo el automóvil propio de una
determinada marca, color, potencia, etc, el automóvil del vecino de otra marca, de otro
color, etc, , el automóvil 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 representación concreta y específica de una
clase y que reside en la memoria de la computadora.
Atributos Los atributos son las características 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 también denominados miembros dato, son declaradas en la
clase pero sus valores son fijados y cambiados en el objeto.
Además de las variables de instancia hay variables de clase, las cuales se aplican a la
clase y a todas sus instancias. Por ejemplo, el número de ruedas de un automóvil es el
para todos los automóviles ya que es cuatro.
Excelencia Académica
90
Comportamiento El comportamiento de los objetos de una clase se implementa mediante funciones miembro
o métodos. Un método es un conjunto de instrucciones que realizan una determinada tarea
y son similares a las funciones de los lenguajes estructurados.
Del mismo modo que hay variables de instancia y de clase, también hay métodos de
instancia y de clase. En el primer caso, un objeto llama a un método para realizar una
determinada tarea, en el segundo, el método se llama desde la propia clase.
El proyecto El proyecto consta de dos archivos, el primero contiene la clase Rectangulo que se guarda
en el archivo Rectangulo.java y no tiene el método main. La última casilla del asistente de
creación de clases New Java File debe de estar desactivada.
La otra clase, es la que describe la aplicación RectanguloApp1 y se guarda en el archivo
RectanguloApp1.java, esta clase tiene que tener el método main, por lo tanto, la última
casilla del asistente de creación de clases New Java File debe de estar activada.
Un proyecto puede constar de varias clases (normalmente se sitúa cada clase en un
archivo) pero solamente una tiene el método main y representa la aplicación. Para
distinguir la clase que describe la aplicación de las demás por conveniencia se le pone el
sufijo App.
La clase Para crear una clase se utiliza la palabra reservada class y a continuación el nombre de la
clase. La definición de la clase se pone entre las llaves de apertura y cierre. El nombre de
la clase empieza por letra mayúscula.
class Rectangulo{
//miembros dato
//funciones miembro
}
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 minúscula.
Vamos a crear una clase denominada Rectangulo, que describa las características
comunes a estas figuras planas que son las siguientes:
El origen del rectángulo: el origen o posición de la esquina superior izquierda del
rectángulo en el plano determinado por dos números enteros x e y.
Las dimensiones del rectángulo: ancho y alto, otros dos números enteros.
Excelencia Académica
91
class Rectangulo{
int x;
int y;
int ancho;
int alto;
//faltan las funciones miembro
}
Las funciones miembro
En el lenguaje Java las funciones miembro o métodos solamente se definen y se llaman.
El nombre de las funciones miembro o métodos comienza por letra minúscula y deben
sugerir acciones (mover, calcular, etc.). La definición de una función tiene el siguiente
formato:
tipo nombreFuncion(tipo parm1, tipo parm2, tipo parm3){
//...sentencias
}
Entre las llaves de apertura y cierre se coloca la definición de la función. tipo indica el tipo
de dato que puede ser predefinido int, double, etc, o definido por el usuario, una clase
cualquiera.
Para llamar a un función miembro o método que devuelve un valor se escribe
retorno=objeto.nombreFuncion(arg1, arg2, arg3);
Cuando se llama a la función, los argumentos arg1, arg2, arg3 se copian en los parámetros
parm1, parm2, parm3 y se ejecutan las sentencias dentro de la función. La función finaliza
cuando se llega al final de su bloque de definición o cuando encuentra una sentencia
return. Cuando se llama a la función, el valor devuelto mediante la sentencia return se
asigna a la variable retorno.
Cuando una función no devuelve nada se dice que es de tipo void. Para llamar a este tipo
de funciones se escribe
objeto.nombreFuncion(arg1, arg2, arg3);
Una función suele finalizar cuando llega al final del bloque de su definición
void funcion(....){
//sentencias...
}
Una función puede finalizar antes del llegar al final de su definición
Excelencia Académica
92
void funcion(....){
//sentencias...
if(condicion) return;
//sentencias..
}
Una función 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 función tiene una vida temporal, existiendo en
memoria, mientras la función esté activa. Se trata de variables locales a la función. Por
ejemplo:
void nombreFuncion(int parm){
//...
int i=5;
//...
}
La variable parm, existe desde el comienzo hasta el final de la función. La variable local i,
existe desde el punto de su declaración hasta el final del bloque de la función.
Se ha de tener en cuenta que las funciones miembro tienen acceso a los miembros dato,
por tanto, es importante en el diseño 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. Los ejemplos nos ayudarán a entender esta distinción.
Hemos definido los atributos o miembros dato de la clase Rectangulo, ahora le vamos
añadir un comportamiento: los objetos de la clase Rectangulo o rectángulos sabrán calcular
su área, tendrán capacidad para trasladarse a otro punto del plano, sabrán si contienen en
su interior un punto determinado del plano.
La función que calcula el área realizará la siguiente tarea, calculará el producto del ancho
por el alto del rectángulo y devolverá el resultado. La función 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 laanchuray la altura de un rectángulo concreto.
class Rectangulo{
int x;
int y;
int ancho;
int alto;
int calcularArea(){
return (ancho*alto);
Excelencia Académica
93
}
}
A la función que desplaza el rectángulo 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 función 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 función que determina si un punto está o no en el interior del rectángulo, devolverá true
si el punto se encuentra en el interior del rectángulo y devolverá false si no se encuentra,
es decir, será una función del tipo boolean. La función necesitará conocer las coordenadas
de dicho punto. Para que un punto de coordenadas x1 e y1 esté dentro de un rectángulo
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
También 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
lógico 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;
}
}
Excelencia Académica
94
En el lenguaje Java, si la primera condición es falsa no se evalúan 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.
Los constructores Un objeto de una clase se crea llamando a una función especial denominada constructor
de la clase. El constructor se llama de forma automática cuando se crea un objeto, para
situarlo en memoria e inicializar los miembros dato declarados en la clase. El constructor
tiene el mismo nombre que la clase. Lo específico del constructor es que no tiene tipo de
retorno.
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 números que guardan los parámetros x1, y1, w y h, y con ellos
inicializa los miembros dato x, y, ancho y alto.
Una clase puede tener más de un constructor. Por ejemplo, el siguiente constructor crea un
rectángulo 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;
}
}
Este constructor crea un rectángulo de dimensiones nulas situado en el punto (0, 0),
class Rectangulo{
int x;
Excelencia Académica
95
int y;
int ancho;
int alto;
Rectangulo(){
x=0;
y=0;
ancho=0;
alto=0;
}
}
Con estas porciones de código definimos la clase, y la guardamos en un archivo que tenga
el mismo nombre que la clase Rectangulo y con extensión .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; } 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; } }
Excelencia Académica
96
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 rectángulo 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 rectángulo 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 rectángulo estará situado en el punto de coordenadas x=0, y=0; y tendrá una anchura
de ancho=0 y una altura de alto=0.
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 rectángulo.
rect1.ancho=100;
El rectángulo rect1 que tenía 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 rectángulo rect1 llamamos a la función calcularArea para calcular el
área de dicho rectángulo.
rect1.calcularArea();
La función miembro area devuelve un entero, que se puede guardar en una variable entera
medidaArea, para luego usar este dato.
int medidaArea=rect1.calcularArea();
System.out.println("El área del rectángulo es "+medidaArea);
Para desplazar el rectángulo rect2, 10 unidades hacia la derecha y 20 hacia abajo,
escribiremos
rect2.desplazar(10, 20);
Podemos verificar mediante el siguiente código si el punto (20, 30) está en el interior del
rectángulo rect1.
if(rect1.estaDentro(20,30)){
Excelencia Académica
97
System.out.println("El punto está dentro del rectángulo"); }
else
{System.out.println("El punto está fuera del rectángulo"); }
rect1.dentro() devuelve true si el punto (20, 30) que se le pasa a dicha función miembro
está en el interior del rectángulo rect1, ejecutándose la primera sentencia, en caso
contrario se ejecuta la segunda.
Como veremos más 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 rectángulo es "+medidaArea); rect2.desplazar(10, 20); if(rect1.estaDentro(20,30)){ System.out.println("El punto está dentro del rectángulo"); }else{ System.out.println("El punto está fuera del rectángulo"); } } }
La vida de un objeto
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 más 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 función
main, aunque solamente es necesario hasta el bucle while. En C o en C++ eliminariamos
Excelencia Académica
98
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 ocupen mucha memoria tan pronto como no sean
necesarios.
Creamos dos objetos de la clase rectángulo, 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 destrucción de un objeto es una tarea (thread) de baja prioridad que lleva a cabo la
Máquina 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 estén cerrados cuando dicho objeto desaparece. Se puede definir en la clase un
método denominado finalize que realice esta tarea. Este método es llamado por el
recolector de basura inmediatamente antes de que el objeto sea destruido.
Identificadores
La forma de definir los nombres de la variables, de las clases, de las funciones, etc., es un
asunto muy importante para la comprensión y el mantenimiento de código. El código debe
de ser tanto más fácil de leer y de entender como sea posible. Alguien que lea el código,
incluso después de cierto tiempo, debe ser capaz de entender lo que hace a primera vista,
aunque los detalles internos, es decir, cómo lo hace, precise un estudio detallado.
Vemos primero un ejemplo que muestra un código poco legible y por tanto, muy difícil de
mantener
Excelencia Académica
99
public class Cuen{
private int ba;
Cuen(int ba){
this.ba=ba;
}
public void dep(int i){
ba+=i;
}
public boolean ret(int i){
if(ba>=i){
ba-=i;
return true;
}
return false;
}
public int get(){
return ba;
}
}
Las abreviaciones empleadas solamente tienen significado para el programador en el
momento de escribir el código, 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 función. El tiempo extra que se gasta en escribir con claridad el nombre
de los diversos elementos que entran en el programa, se ahorra más adelante durante su
desarrollo, depuración, y mejora, es decir, durante todo el ciclo de vida del programa.
Tenemos el siguiente código que facilita el entendimiento.
Excelencia Académica
100
public class CuentaBancaria{
private int balance;
CuentaBancaria(int balance){
this.balance=balance;
}
public void depositar(int cantidad){
balance+=cantidad;
}
public boolean retirar(int cantidad){
if(balance>=cantidad){
balance-=cantidad;
return true;
}
return false;
}
public int obtenerBalance(){
return balance;
}
}
Este es una programa sencillo de una cuenta bancaria. El tipo de dato puede ser entero
(int o long), si la unidad monetaria tiene poco valor como los centavos, o un número
decimal (double) si la unidad monetaria es de gran valor como el Euro y el Dólar.
El código de las funciones miembro es muy sencillo y su significado se hace evidente al
leer el programa. La función retirar es de tipo boolean, ya que no (false) estamos
autorizados a retirar una cantidad mayor que la existente en ese momento en el banco. Sin
embargo, si (true) estamos autorizados a retirar una cantidad menor que la que tenemos
en la cuenta.
Composición Hay dos formas de reutilizar el código, mediante la composición y mediante la herencia. La
composición significa utilizar objetos dentro de otros objetos. Por ejemplo, un applet es un
objeto que contiene en su interior otros objetos como botones, etiquetas, etc. Cada uno de
los controles está descrito por una clase.
Vamos a estudiar una nueva aproximación a la clase Rectangulo definiendo el origen, no
como un par de coordenadas x e y (números enteros) sino como objetos de una nueva
clase denominada Punto.
Excelencia Académica
101
Definimos una clase llamada Punto
La clase Punto tiene dos miembros dato, la abscisa x y la ordenada y de un punto del
plano. Definimos dos constructores uno por defecto que sitúa el punto en el origen, y otro
constructor explícito que proporciona las coordenadas x e y de un punto concreto.
public class Punto {
int x;
int y;
//funciones miembro
}
El constructor explícito de la clase Punto podemos escribirlo de dos formas
public Punto(int x1, int y1) {
x = x1;
y = y1;
}
Cuando el nombre de los parámetros es el mismo que el nombre de los miembros datos
escribimos
public Punto(int x, int y) {
this.x = x;
this.y = y;
}
this.x que está a la izquierda y que recibe el dato x que se le pasa al constructor se refiere
al miembro dato, mientras que x que está a la derecha es el parámetro. this es una palabra
reservada que guarda una referencia al objeto propio, u objeto actual.
La función miembro desplazar simplemente cambia la posición del punto desde (x, y) a
(x+dx, y+dy). La función desplazar cuando es llamada recibe en sus dos parámetros dx y
dy el desplazamiento del punto y actualiza las coordenadas x e y del punto. La función no
retorna ningún valor
public void desplazar(int dx, int dy){
x+=dx;
y+=dy;
}
Para crear un objeto de la clase Punto cuyas coordenadas x e y valgan repectivamente 10
y 23 escribimos
Punto p=new Punto(10, 23);
Para desplazar el punto p 10 unidades hacia la izquierda y 40 hacia abajo, llamamos desde
el objeto p a la función desplazar y le pasamos el desplazamiento horizontal y vertical.
p.desplazar(-10, 40);
El código completo de la clase Punto, es el siguiente
public class Punto {
int x = 0;
int y = 0;
Excelencia Académica
102
public Punto(int x, int y) {
this.x = x;
this.y = y;
}
public Punto() {
x=0;
y=0;
}
void desplazar(int dx, int dy){
x+=dx;
y+=dy;
}
}
Definimos una claseRectangulo
La clase Rectangulo tiene como miembros dato, el origen que es un objeto de la clase
Punto y las dimensiones ancho y alto.
public class Rectangulo {
Punto origen;
int ancho ;
int alto ;
//funciones miembro
}
El constructor por defecto, crea un rectángulo situado en el punto 0,0 y con dimensiones
nulas
public Rectangulo() {
origen = new Punto(0, 0);
ancho=0;
alto=0;
}
El constructor explícito crea un rectángulo situado en un determinado punto p y con unas
dimensiones que se le pasan en el constructor
public Rectangulo(Punto p, int w, int h) {
origen = p;
ancho = w;
alto = h;
}
Podemos definir otros constructores en términos del constructor explícito usando la palabra
reservada this.
public Rectangulo(Punto p) {
this(p, 0, 0);
}
Excelencia Académica
103
public Rectangulo(int w, int h) {
this(new Punto(0, 0), w, h);
}
El primero crea un rectángulo de dimensiones nulas situado en el punto p. El segundo, crea
un rectángulo de unas determinadas dimensiones situándolo en el punto 0, 0. Dentro del
cuerpo de cada constructor se llama al constructor explícito mediante this pasándole en
sus parámetros los valores apropiados.
Para desplazar un rectángulo, trasladamos su origen (esquina superior izquierda) a otra
posición, sin cambiar su anchura o altura. Desde el objeto origen, llamamos a la función
desplazar miembro de la clase Punto
void desplazar(int dx, int dy) {
origen.desplazar(dx, dy);
}
El código completo de la nueva clase Rectangulo, es el siguiente.
public class Rectangulo {
Punto origen;
int ancho ;
int alto ;
public Rectangulo() {
origen = new Punto(0, 0);
ancho=0;
alto=0;
}
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;
}
void desplazar(int dx, int dy) {
origen.desplazar(dx, dy);
}
int calcularArea() {
Excelencia Académica
104
return ancho * alto;
}
}
Objetos de la claseRectangulo
Para crear un rectángulo rect1 situado en el punto (0, 0) y cuyas dimensiones son 100 y
200 escribimos
Rectangulo rect1=new Rectangulo(100, 200);
Para crear un rectángulo rect2, situado en el punto de coordenadas 44, 70 y de
dimensiones nulas escribimos
Punto p=new Punto(44, 70);
Rectangulo rect2=new Rectangulo(p);
O bien, en una sóla línea
Rectangulo rect2=new Rectangulo(new Punto(44, 70));
Para desplazar el rectángulo rect1 desde el punto (100, 200) a otro punto situado 40
unidades hacia la derecha y 20 hacia abajo, sin modificar sus dimensiones, escribimos
rect1.desplazar(40, 20);
Para hallar y mostrar el área del rectángulo rect1 podemos escribir
System.out.println("el área es "+rect1.calcularArea());
Para hallar el área de un rectángulo de 100 unidades de largo y 50 de alto y guardar el
resultado en la variable entera areaRect, escribimos en una sóla línea.
int areaRect=new Rectangulo(100, 50).calcularArea();
public class RectanguloApp {
public static void main(String[] args) {
Rectangulo rect1=new Rectangulo(100, 200);
Rectangulo rect2=new Rectangulo(new Punto(44, 70));
Rectangulo rect3=new Rectangulo();
rect1.desplazar(40, 20);
System.out.println("el área es "+rect1.calcularArea());
int areaRect=new Rectangulo(100, 50).calcularArea();
System.out.println("el área es "+areaRect);
}
}
}
Los paquetes Los paquetes son grupos relacionados de clases e interfaces y proporcionan un
mecanismo conveniente para menejar un gran juego de clases e interfaces y evitar los
conflictos de nombres. Además de los paquetes de Java puede crear tus propios paquetes
y poner en ellos definiciones de clases y de interfaces utilizando la sentencia package.
Excelencia Académica
105
Supongamos que se está implementando un grupo de clases que representan una
colección de objetos gráficos como círculos, rectángulos, líneas y puntos. Además de estas
clases tendrás que escribir un interface Draggable para que en las clases que lo
implementen pueda moverse con el ratón. Si quieres que estas clases estén disponibles
para otros programadores, puedes empaquetarlas en un paquete, digamos, graphics y
entregar el paquete a los programadores (junto con alguna documentación de referencia,
como qué hacen las clases y los interfaces y qué interfaces de programación son públicos).
De esta forma, otros programadores pueden determinar fácilmente para qué es tu grupo de
clases, cómo utilizarlos, y cómo relacionarlos unos con otros y con otras clases y paquetes.
Los nombres de clases no tienen conflictos con los nombres de las clases de otros
paquetes porque las clases y los interfaces dentro de un paquete son referenciados en
términos de su paquete (técnicamente un paquete crea un nuevo espacio de nombres).
package graficos;
interface Dibujar {
. . .
}
class Circulo {
. . .
}
class Rectangulo {
. . .
}
La primera línea del código anterior crea un paquete llamado graficos. Todas las clases e
interfaces definidas en el fichero que contiene esta sentencia son miembros del paquete.
Por lo tanto, Dibujar, Circulo,y Rectangulo son miembros del paquete graficos.
Los ficheros .class generados por el compilador cuando se compila el fichero que contiene
el código fuente para Dibujar, Circulo y Rectangulo debe situarse en un directorio llamado
graficos en algún lugar del path CLASSPATH. CLASSPATH es una lista de directorios
que indican al sistema donde ha instalado varias clases e interfaces compiladas Java.
Cuando busque una clase, el intérprete Java busca un directorio en su CLASSPATH cuyo
nombre coincida con el nombre del paquete del que la clase es miembro. Los ficheros
.class para todas las clases e interfaces definidas en un paquete deben estar en ese
directorio de paquete.
Los nombres de paquetes pueden contener varios componentes (separados por puntos).
De hecho, los nombres de los paquetes de Java tienen varios componentes: java.util,
java.lang, etc...
Excelencia Académica
106
Cada componente del nombre del paquete representa un directorio en el sistema de
ficheros. Así, los ficheros .class de java.util están en un directorio llamado util en otro
directorio llamado java en algún lugar del CLASSPATH.
CLASSPATH Para ejecutar una aplicación Java, se especifica el nombre de la aplicación Java que se
desea ejecutar en el intérprete Java. Para ejecutar un applet, se especifica el nombre del
applet en una etiqueta <APPLET> dentro de un fichero HTML. El navegador que ejecute el
applet pasa el nombre del applet al intérprete Java. En cualquier caso, la aplicación o el
applet que se está ejecutando podría estar en cualquier lugar del sistema o de la red.
Igualmente, la aplicación o el applet pueden utilizar otras clases y objetos que están en la
misma o diferentes localizaciones.
Como las clases pueden estar en cualquier lugar, se debe indicar al intérprete Java donde
puede encontrarlas. Se puede hacer esto con la variable de entorno CLASSPATH que
comprende una lista de directorios que contienen clases Java compiladas. La construcción
de CLASSPATH depende de cada sistema.
Cuando el intérprete obtiene un nombre de clase, desde la línea de comandos, desde un
navegador o desde una aplicación o un applet, el intérprete busca en todos los directorios
de CLASSPATH hasta que encuentra la clase que está buscando.
Se deberá poner el directorio de nivel más alto que contiene las clases Java en el
CLASSPATH. Por convención, mucha gente tiene un directorio de clases en su directorio
raíz donde pone todo su código Java.
Las clases incluidas en el entorno de desarrollo Java están disponibles automáticamente
porque el intérprete añade el directorio correcto al CLASSPATH cuando arranca.
Observa que el orden es importante. Cuando el intérprete Java está buscando una clase,
busca por orden en los directorios indicados en CLASSPATH hasta que encuentra la clase
con el nombre correcto. El intérprete Java ejecuta la primera clase con el nombre correcto
que encuentre y no busca en el resto de directorios. Normalmente es mejor dar a las clases
nombres únicos, pero si no se puede evitar, se debe asegurar de que el CLASSPATH
busca las clases en el orden apropiado.
El paquete (package)
Los paquetes son una forma de organizar grupos de clases. Un paquete contiene
un conjunto de clases relacionadas bien por finalidad, por ámbito o por herencia.
Los paquetes resuelven el problema del conflicto entre los nombres de las clases.
Al crecer el número de clases crece la probabilidad de designar con el mismo
nombre a dos clases diferentes.
Las clases tienen ciertos privilegios de acceso a los miembros dato y a las
funciones miembro de otras clases dentro de un mismo paquete.
Excelencia Académica
107
En el Entorno Integrado de Desarrollo (IDE) JBuilder de Borland, un proyecto nuevo se
crea en un subdirectorio que tiene el nombre del proyecto. A continuación, se crea la
aplicación, un archivo .java que contiene el código de una clase cuyo nombre es el mismo
que el del archivo. Se pueden agregar nuevas clases al proyecto, todas ellas contenidas en
archivos .java situadas en el mismo subdirectorio. La primera sentencia que encontramos
en el código fuente de las distintas clases que forman el proyecto es package o del nombre
del paquete.
//archivo MiApp.java
package nombrePaquete;
public class MiApp{
//miembros dato
//funciones miembro
}
//archivo MiClase.java
package nombrePaquete;
public class MiClase{
//miembros dato
//funciones miembro
}
La palabra reservadaimport
Para importar clases de un paquete se usa el comando import. Se puede importar una
clase individual
import java.awt.Font;
o bien, se puede importar las clases declaradas públicas de un paquete completo,
utilizando un arterisco (*) para reemplazar los nombres de clase individuales.
import java.awt.*;
Para crear un objeto fuente de la clase Font podemos seguir dos alternativas
import java.awt.Font;
Font fuente=new Font("Monospaced", Font.BOLD, 36);
O bien, sin poner la sentencia import
java.awt.Font fuente=new java.awt.Font("Monospaced", Font.BOLD, 36);
Normalmente, usaremos la primera alternativa, ya que es la más económica en código, si
tenemos que crear varias fuentes de texto.
Se pueden combinar ambas formas, por ejemplo, en la definición de la clase BarTexto
import java.awt.*;
public class BarTexto extends Panel implements java.io.Serializable{
//...
}
Excelencia Académica
108
Panel es una clase que está en el paquete java.awt, y Serializable es una interface que
está en el paquete java.io
Los paquetes estándar
Paquete Descripción
java.applet Contiene las clases necesarias para crear applets que se ejecutan
en la ventana del navegador
java.awt Contiene clases para crear una aplicación GUI independiente de la
plataforma
java.io Entrada/Salida. Clases que definen distintos flujos de datos
java.lang Contiene clases esenciales, se importa implícitamente sin
necesidad de una sentencia import.
java.net Se usa en combinación con las clases del paquete java.io para leer
y escribir datos en la red.
java.util Contiene otras clases útiles que ayudan al programador
Interface
Una interface es una colección de definiciones de métodos (sin implementaciones) y de
valores constantes.
Los interfaces se utilizan para definir un protocolo de comportamiento que puede ser
implementado por cualquier clase del árbol de clases.
Los interfaces son útiles para.
capturar similitudes entre clases no relacionadas sin forzar una relación entre ellas.
declarar métodos que una o varias clases que necesitan implementar.
revelar la interface de programación de un objeto sin revelar sus clases (los objetos
de este tipo son llamados objetos anónimos y pueden ser útiles cuando se
comparte un paquete de clases con otros desarrolladores).
En Java, una interface es un tipo de dato de referencia, y por tanto, puede utilizarse en
muchos de los sitios donde se pueda utilizar cualquier tipo (como en un argumento de
métodos y una declaración de variables).
Los Interfaces No Proporcionan Herencia Múltiple
Algunas veces se tratará a las interfaces como una alternativa a la herencia múltiple en las
clases. A pesar de que las interfaces podrían resolver algunos problemas de la herencia
múltiple, son temas bastantes diferentes. En particular tienen las siguientes características:
No se pueden heredar variables desde una interface.
Excelencia Académica
109
No se pueden heredar implementaciones de métodos desde una interface.
La herencia de una interface es independiente de la herencia de la clase--las clases
que implementan la misma interface pueden o no estar relacionadas a través del
árbol de clases.
Definir un Interface
Para crear una Interface, se debe escribir tanto la declaración como el cuerpo de la
interface.
declaraciondeInterface {
cuerpodeInterface
}
La declaracióndeInterface declara varios atributos de la interface, como su nombre o si se
extiende desde otra interface. El cuerpodeInterface contiene las constantes y las
declaraciones de métodos de la Interface.
La Declaración de Interface
Como mínimo, una declaración de interface contiene la palabra clave interface y el nombre
de la interface que se va a crear.
interface Contable {
. . .
}
Nota: Por convención, los nombres de interfaces empiezan con una letra mayúscula al
igual que las clases. Frecuentemente los nombres de interfaces terminan en "able" o "ible".
Una declaración de interface puede tener otros dos componentes: el especificador de
acceso public y una lista de "superinterfaces". Un interface puede extender otros interfaces
como una clase puede extender o subclasificar otra clase. Sin embargo, mientras que una
clase sólo puede extender una superclase, las interfaces pueden extender de cualquier
número de interfaces. Así, una declaración completa de interface se parecería a esto.
[public] interface Nombredenterface [extends listadeSuperInterfaces] {
. . .
}
El especificador de acceso public indica que la interface puede ser utilizado por todas las
clases en cualquier paquete. Si la interface no se especifica como pública, sólo será
accesible para las clases definidas en el mismo paquete que la interface.
La clausula extends es similar a la utilizada en la declaración de una clase, sin embargo,
un interface puede extender varios interfaces (mientras una clase sólo puede extender
una), y un interface no puede extender clases. Esta lista de superinterfaces es una lista
delimitada por comas de todos los interfaces extendidos por la nuevo interface.
Excelencia Académica
110
Una interface hereda todas las constantes y métodos de sus superinterfaces a menos que
la interface oculte una constante con el mismo nombre o redeclare un método con una
nueva declaración.
El cuerpo del Interface
El cuerpo del interface contiene las declaraciones de métodos para los métodos definidos
en la interface. Implementar Métodos muestra cómo escribir una declaración de método.
Además de las declaraciones de los métodos, una interface puede contener declaraciones
de constantes.
Todos los valores constantes definidos en una interface son implícitamente públicos,
estáticos y finales. El uso de estos modificadores en una declaración de constante en una
interface está desaconsejado por falta de estilo. Similarmente, todos los métodos
declarados en una interface son implícitamente públicos y abstractos.
Este código define una nueva interface llamado coleccion que contiene un valor constante
y tres declaraciones de métodos.
interface coleccion {
int MAXIMO = 500;
void añadir(Object obj);
void borrar(Object obj);
Object buscar(Object obj);
int contadorActual();
}
La interface anterior puede ser implementado por cualquier clase que represente una
colección de objetos como pueden ser pilas, vectores, enlaces, etc...
Observa que cada declaración de método está seguida por un punto y coma (;) porque una
interface no proporciona implementación para los métodos declarados dentro de él.
Utilizar un Interface
Para utilizar una interface se debe escribir una clase que lo implemente. Una clase declara
todos los interfaces que implementa en su declaración de clase. Para declarar que una
clase implementa uno o más interfaces, se utiliza la palabra clave implements seguida por
una lista delimitada por comas con los interfaces implementados por la clase.
Por ejemplo, consideremos la interface coleccion presentado antes. Ahora, supongamos
que queremos escribir una clase que implemente una pila FIFO (primero en entrar, primero
en salir). Como una pila FIFO contiene otros objetos tiene sentido que implemente el
interface coleccion. La clase PilaFIFO declara que implementa el interface coleccion de
esta forma.
class PilaFIFO implements coleccion {
. . .
Excelencia Académica
111
void añadir(Object obj) {
. . .
}
void borrar(Object obj) {
. . .
}
Object buscar(Object obj) {
. . .
}
int contadorActual() {
. . .
}
}
así se garantiza que proporciona implementación para los métodos añadir(), borrar(),
buscar() y contadorActual().
Por convención, la cláusula implements sigue a la cláusula extends si es que ésta existe.
Observa que las firmas de los métodos del interface coleccion implementados en la clase
PilaFIFO debe corresponder exactamente con las firmas de los métodos declarados en la
interface coleccion.
Utilizar un Interface como un Tipo
Como se mencionó anteriormente, cuando se define una nueva interface, en esencia se
está definiendo un tipo de referencia. Se pueden utilizar los nombres de interface en
cualquier lugar donde se usaría un nombre de dato de tipos primitivos o un nombre de
datos del tipo de referencia.
Por ejemplo, supongamos que se ha escrito un programa de hoja de cálculo que contiene
un conjunto tabular de celdas y cada una contiene un valor. Querríamos poder poner
cadenas, fechas, enteros, ecuaciones, en cada una de las celdas de la hoja. Para hacer
esto, las cadenas, las fechas, los enteros y las ecuaciones tienen que implementar el
mismo conjunto de métodos. Una forma de conseguir esto es encontrar el ancestro común
de las clases e implementar ahí los métodos necesarios. Sin embargo, esto no es una
solución práctica porque el ancestro común más frecuente es Object. De hecho, los objetos
que puede poner en las celdas de su hoja de cálculo no están relacionadas entre sí, sólo
por la clase Object. Pero no puede modificar Object.
Una aproximación podría ser escribir una clase llamada ValordeCelda que representara los
valores que pudiera contener una celda de la hoja de cálculo. Entonces se podrían crear
distintas subclases de ValordeCelda para las cadenas, los enteros o las ecuaciones.
Además de ser mucho trabajo, esta aproximación arbitraria fuerza una relación entre esas
Excelencia Académica
112
clases que de otra forma no sería necesaria, y debería duplicar e implementar de nuevo
clases que ya existen.
Se podría definir una interface llamado CellAble que se parecería a esto.
interface CellAble {
void draw();
void toString();
void toFloat();
}
Ahora, supongamos que existen objetos Linea y Columna que contienen un conjunto de
objetos que implementan el interface CellAble. El método setObjectAt() de la clase Linea
se podría parecer a esto.
class Linea {
private CellAble[] contents;
. . .
void setObjectAt(CellAble ca, int index) {
. . .
}
. . .
}
Como se observa el uso del nombre del interface en la declaración de la variable miembro
contents y en la declaración del argumento ca del método. Cualquier objeto que
implemente el interface CellAble, sin importar que exista o no en el árbol de clases, puede
estar contenido en el array contents y podría ser pasado al método setObjectAt().
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 representación concreta y específica de una
clase y que reside en la memoria de la computadora.
Los atributos son las características individuales que diferencian un objeto de otro y
determinan su apariencia, estado u otras cualidades. Los atributos se guardan en variables
denominadas de instancia llamadas también miembros datos que son declarados en la
clase pero sus valores son fijados y cambiados en el objeto.
Un método es un conjunto de instrucciones que realizan una determinada tarea y son
similares a las funciones de los lenguajes estructurados.
Un objeto de una clase se crea llamando a una función especial denominada constructor
de la clase. El constructor se llama de forma automática cuando se crea un objeto, para
Excelencia Académica
113
situarlo en memoria e inicializar los miembros dato declarados en la clase. El constructor
tiene el mismo nombre que la clase. Lo específico del constructor es que no tiene tipo de
retorno.
Para crear un objeto de una clase se usa la palabra reservada new.
Para crear una Interface, se debe escribir tanto la declaración como el cuerpo de la
interface.
Fco. Javier Ceballos Curso de Programación Java 2
Alfaomega-Rama, España 2,003 Segunda Edición
Luis Joyanes Aguilar Programación en Java
Prentice Hall, España
José Pérez Mayor Programación en Java Paso a Paso
Thomson, España 2,003
Deitel y Deitel Curso de Programación en Java
Prentice Hall, España, 1,995
En el siguiente UNIDAD TEMÁTICA se estudiarán los gráficos en Java en donde se hará
un uso extenso de los paquetes.
Se debe tener cuidado al implementar paquetes con los nombres que se asignen al
proyecto y a los directorios que contienen los paquetes.
Las interfaces son similares a los punteros del lenguaje C.
Crear un paquete llamado gráficos que permita dibujar figuras geométricas planas y que
permita calcular su área, perímetro, desplazarse cierta cantidad de posiciones y borrar la
figura generada
Excelencia Académica
114
.
Construir paquetes que puedan ser utilizados y reutilizados desde cualquier aplicación que
se desarrolle.
Excelencia Académica
115
Nº 7 Nombre__________________________________________________________________
Apellidos_______________________________________Fecha _____________________
Ciudad ______________________________Semestre_____________________________
1.- Describir cómo se crean y utilizan los paquetes en Java y para qué sirven.
2.- Describir cómo se crean y utilizan las interfaces en Java y para qué sirven.
3.- Escribir un paquete que contenga rutinas de ingreso e datos y que permita terminar el
ingreso de diferentes formas como podría ser preguntar si continua o no, ingresar una
clave para terminar que puede ser un número o texto o carácter y demostrar su
funcionamiento con una aplicación.
Excelencia Académica
116
FUNDAMENTOS PARA EL DIBUJO CON
JAVA El componente GUI es de nivel alto en el paquete awt, y se construye utilizando los
componentes de nivel bajo del paquete, es decir, las primitivas gráficas y los sucesos.
Pensemos, por ejemplo, en un botón. Éste, gráficamente, no es otra cosa que una caja con
un texto dentro, que cambia de aspecto cuando se aprieta, es decir, cuando escucha su
suceso ActionEvent.
Utilizando las características de bajo nivel podemos construir nuestros GUI personalizados
o modificar los que ya existen según nuestras necesidades. No solamente podemos
extender un componente particular, un componente lienzo, en el que podemos dibujar lo
que queramos y ponerlo en nuestras interfaces como cualquier otro GUI.
Si utilizamos los apliques más que las aplicaciones, podemos evitar utilizar el lienzo porque
el aplique trae implícitamente un lienzo. De todas formas, empecemos a ver en concreto
cómo se puede dibujar en un componente cualquiera o en un aplique. Primero hablaremos
de los apliques y luego pasaremos a los componentes en general.
Las funciones saint, repaint y update... En el lenguaje Java es posible dibujar en un aplique simplemente volviendo a definir el
método paint. Este método se invoca automáticamente por el sistema cuando la ventana
que incluye el aplique pasa a un primer plano. Por lo tanto cada orden gráfica al aplique se
dará en el método paint del aplique.
void paint (Graphics g)
{
// Dibujo
}
Cuando el aplique haya dibujado y se quiera visualizar posibles cambios, es posible invocar
el método repaint() o el método update(Graphics g) que borra el área en el que el aplique
ha dibujado y vuelve a invocar a paint.
El método paint(Graphics g) no se puede invocar directamente.
El aplique no sólo tiene el método paint que se puede volver a definir, sino también los
objetos de tipo Component, es decir, todos los GUI. Por lo tanto, para cambiar el aspecto
gráfico de cualquier componente gráfico, basta con volver a definir el método paint.
Entre todos los componentes está el ya citado lienzo sobre el que es posible dibujar. Es un
objeto de la clase Canvas. Los que están acostumbrados a programar con otros lenguajes
Excelencia Académica
117
esperan que en paint haya un inicializador del device (dispositivo) en el que se va a dibujar
y, después, una serie de instrucciones de tipo drawLine, drawBox etc., sin embargo, esto
no siempre es verdad, es decir, que en los componentes y en los apliques no hay ningún
método gráfico.
Llegados a este punto, queda claro incluso que el parámetro g de tipo Graphics de paint
incluye los métodos gráficos que Java puede utilizar y representar, por decirlo de alguna
forma, el área en el que se dibujarán las primitivas.
Graphics es una clase que no se puede incluir, sino que es recibida por paint como
parámetro. Por lo tanto se puede utilizar sólo en ella y sus métodos son:
abstract void clearRect(int x, int y, int width, int height)
abstract void clipRect(int x, int y, int width, int height)
abstract void copyArea(int x, int y, int width, int height, int dx, int dy)
abstract Graphics create()
Graphics create(int x, int y, int width, int height)
abstract void dispose()
void draw3DRect(int x, int y, int width, int height,boolean raised)
abstract void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)
void drawBytes(byte[] data, int offset, int length, int x, int y)
void drawChars(char[] data, int offset, int length, int x, int y)
abstract boolean drawImage(…) Ne esistono varie versioni
abstract void drawLine(int x1, int y1, int x2, int y2)
abstract void drawOval(int x, int y, int width, int height)
abstract void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
void drawPolygon(Polygon p)
abstract void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
void drawRect(int x, int y, int width, int height)
abstract void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
abstract void drawString(AttributedCharacterIterator iterator, int x, int y)
abstract void drawString(String str, int x, int y)
void fill3DRect(int x, int y, int width, int height, boolean raised)
abstract void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)
abstract void fillOval(int x, int y, int width, int height)
abstract void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
void fillPolygon(Polygon p)
abstract void fillRect(int x, int y, int width, int height)
abstract void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
void finalize()
abstract Shape getClip()
abstract Rectangle getClipBounds()
Rectangle getClipBounds(Rectangle r)
abstract Color getColor()
Excelencia Académica
118
abstract Font getFont()
FontMetrics getFontMetrics()
abstract FontMetrics getFontMetrics(Font f)
boolean hitClip(int x, int y, int width, int height)
abstract void setClip(int x, int y, int width, int height)
abstract void setClip(Shape clip)
abstract void setColor(Color c)
abstract void setFont(Font font)
abstract void setPaintMode()
abstract void setXORMode(Color c1)
String toString()
abstract void translate(int x, int y)
Dentro de poco veremos con detalle todos estos métodos.
En Java2 la clase Graphics ha sido potenciada añadiendo la clase Graphics2D, que la
amplía añadiendo muchas posibilidades a la gráfica de Java.
Para tener una pequeña muestra de las potencialidades de Java se puede ver la Demo que
está junto a JDK. Si, por ejemplo, se tiene el JDK1.3 y se ha instalado en c:\jdk1.3, la demo
está en:
c:\jdk1.3\demo\jfc\Java2D
y para ponerla en marcha hay que escribir del prompt:
java -jar Java2Demo.jar
Excelencia Académica
119
Visualización de las imágenes Empezamos viendo los métodos drawImage de la clase Graphics con los que es posible
visualizar unas imágenes guardadas con formato gif o jpg.
En la clase Graphics hay varios métodos drawImage que son:
abstract boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver
observer)
abstract boolean drawImage(Image img, int x, int y, ImageObserver observer)
abstract boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor,
ImageObserver observer)
abstract boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver
observer)
abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int
sx2, int sy2, Color bgcolor, ImageObserver observer)
abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int
sx2, int sy2, ImageObserver observer)
Todos los métodos requieren dos parámetros Image y ImageObserver.
Image representa la imagen que hay que visualizar. Es una clase abstracta que permite un
acceso independiente del formato de imágenes gráficas. Los objetos de esta clase se
Excelencia Académica
120
crean utilizando los métodos de otras clases que crean imágenes, según el contexto en el
que se quieran utilizar.
Por ejemplo, si quiero dibujar una imagen en un componente Gui, puedo usar el método
createImage() de la clase Component.
En cambio, si quiero dibujar una imagen en un aplique, es posible usar el método
getImage() de la clase Applet.
La clase Toolkit tiene tanto createImage() como getImage().
El otro parámetro que necesitan las drawImage() es un objeto que implementa la interfaz
ImageObserver, y en la práctica representa el objeto gráfico sobre el que se visualizará la
imagen.
Component implementa la interfaz ImageObserver y, consecuentemente, la implementan
todas sus extensiones:
Todos los GUI
Los Apliques
Todas las ventanas (incluso los Frames)
Los demás parámetros son:
la posición x en la que se visualizará la imagen en el componente
la posición y en la que se visualizará la imagen en el componente el color del fondo
Vamos a poner un ejemplo de visualización de una imagen. En primer lugar creamos una
imagen como la siguiente:
y la guardamos en formato gif usando un editor cualquiera de imágenes llamándola, por
ejemplo, pietro.jpg.
Ahora creamos el siguiente aplique:
import java.awt.*; // Para la clase Graphics
import java.applet.*; // Para la clase Applet
import java.net.*; // Para las URL
/*
Como hemos tenido ya la ocasión de decir, los archivos para los apliques no son otra cosa
que unas URL
*/
public class VisualizaImagen extends Applet
{ Image ImagenPietro;
public void init()
Excelencia Académica
121
{ setBackground(Color.white);
ImagenPietro=getImage(getDocumentBase(),"pietro.jpg");
}
public void paint(Graphics g)
{
g.drawImage(ImagenPietro,0,0,this);
getAppletContext().showStatus("Visualizo la imagen pietro.jpg, Applet creadaen
Paint ");
}
}
La ponemos en un archivo llamado VisualizaImagen.java y la invocamos usando el
documento html siguiente (Imagen.html):
<html>
<head>
<title>
Applet VisualizaImagen, visualiza la imagen pietro.jpg
</title>
</head>
<body>
<APPLET code="VisualizaImagen.class" width=385 height=100>
</APPLET>
<BR>
La de arriba es un aplique, sin embargo el código de abajo no lo es.
<BR>
<IMG SRC="pietro.jpg">
</body>
</html>
Si ponemos en marcha el aplique nos damos cuenta de que no hay ninguna diferencia
entre la imagen cargada en el aplique y la que hemos cargado usando el tag IMG SRC del
html, sino el mensaje que aparece cuando pasamos por encima el ratón. Puede parecer
incluso un trabajo inútil para las páginas html.
Esto es absolutamente falso porque la imagen cargada en el aplique pertenece a un
programa que puede hacer incluso cosas complejas. Por ejemplo, es posible añadir otros
componentes GUI al aplique, o elaborar las imágenes mismas, como se ve en el ejemplo
sucesivo (VisualizaImagen2.java):
Excelencia Académica
122
import java.awt.*; // Para la clase Graphics
import java.applet.*; // Para la clase Applet
import java.net.*; // Para las URL
import java.awt.event.*; // Para los sucesos
/*
Como ya hemos dicho, los archivos para los apliques no son otra cosa que unas URL
*/
public class VisualizaImagen2 extends Applet
{
Image ImagenPietro;
CheckboxGroup gruppo=new CheckboxGroup();
Checkbox b1=new Checkbox("Parar",grupo,true);
Checkbox b2=new Checkbox("Animada",grupo,false);
Panel p=new Panel(new GridLayout(1,3));
public void init()
{
setBackground(Color.white);
setLayout(new BorderLayout());
ImagenPietro=getImage(getDocumentBase(),"pietro.jpg");
p.add(new Label());
p.add(b1);
p.add(b2);
b1.addItemListener(new IL());
b2.addItemListener(new IL());
add(p,BorderLayout.SOUTH);
}
boolean MOVIMIENTO=false;
ent número=0;
ent inc=1;
public void paint(Graphics g)
{
if (!MOVIMIENTO)
{ g.drawImage(ImagenPietro,0,0,this);
Excelencia Académica
123
getAppletContext().showStatus("Visualizo la imagen pietro.jpg, Imagen inmóvil, Applet
creada Pietro Castellucci");
número=0;
}
else
{ g.setPaintMode();
g.drawImage(Elabora(ImagenPietro,número),0,0,this);
for (int k=0;k<=99;k++) getAppletContext().showStatus("Visualizo la imagen pietro.jpg,
Frame "+número+", Applet creada en Painti");
getAppletContext().showStatus("Visualizo la imagen pietro.jpg, Frame "+número+",
Applet creada por Pietro Castellucci");
if (número>=10) inc=-1;
if (número<=0) inc=1;
número+=inc;
}
repaint();
}
Image Elabora (Image img, int frm)
{ return img.getScaledInstance(324-(frm*20), 85-(frm*4),img.SCALE_FAST);
}
public class IL implements ItemListener
{ public void itemStateChanged(ItemEvent e)
{ if (b1.getState()) MOVIMIENTO=false;
else MOVIMIENTO=true;
repaint();
}
}
}
Cargada por el archivo html siguiente:
<html>
<head>
<title>
Applet VisualizaImagen, visualiza la imagen pietro.jpg
Excelencia Académica
124
</title>
</head>
<body>
<APPLET code="VisualizaImagen2.class" width=385 height=100>
</APPLET>
<BR>
La de arriba es un aplique, sin embargo elcódigo de abajo no lo es
<BR>
<IMG SRC="pietro.jpg">
</body>
</html>
La nueva clase Graphics2D pone a disposición otros métodos drawImage, entre los que
hay algunos que tienen un parámetro de tipo AffineTransform que, como dice el nombre, es
una transformación parecida a la de la imagen, una rotación o una traslación, o una
combinación de todas.
Para tener una versión sin revoloteo basta con añadir la función:
public void update(Graphics g)
{ paint(g);
}
Dibujos Entendido el funcionamiento de paint() podemos dibujar cualquier cosa en un aplique o en
un componente en general.
La cosa más simple que se puede dibujar es la línea. Para hacerlo, utilizamos el método
drawLine() de Graphics:
drawLine(Iniciox, Inicioy, Finx, Finy)
Este método dibuja una línea que parte de un punto (Iniciox, Inicioy) y llega a otro punto
(Finx, Finy).
Antes de utilizar drawLine() tenemos que comprender cómo se pueden cambiar los colores
de las cosas que dibujamos.
Los colores se cambian utilizando el método setColor(Color c) de la clase Graphics.
Color es otra clase de awt que permite definir un color. Algunos de sus constructores son:
Color(float r, float g, float b) crea un color especificando los valores RGB (Red - Green -
Blue, es decir, Rojo - Verde - Azul) con unos valores entre 0 y 1.
Excelencia Académica
125
Color(float r, float g, float b, float a) como el anterior, sólo que permite definir incluso el
valor alfa
Color(int r, int g, int b) crea un color especificando los valores RGB (Red - Green - Blue,
es decir, Rojo - Verde –
Azul) con valores entre 0 y 255.
Color(int r, int g, int b, int a) como el anterior, sólo que permite definir incluso el valor alfa
Algunos colores simples se dan a través de unas constantes en la clase color:
Color.black
Color.blue
Color.cyan
Color.darkGray
Color.gray
Color.green
Color.lightGray
Color.magenta
Color.orange
Color.pink
Color.red
Color.white
Color.yellow
En el siguiente aplique se dibujan unas líneas de colores.
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Button;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.applet.*;
public class líneas extends Applet
{ final ent SI=14;
final ent NO=0;
Button R=new Button("Rojo");
Excelencia Académica
126
Button G=new Button("Verde");
Button B=new Button("Azul");
ent r_=0;
ent g_=0;
ent b_=0;
ent ir=0;
ent ig=0;
ent ib=0;
public void init()
{
setLayout(new BorderLayout());
Panel np=new Panel(new GridLayout(1,3));
np.add(R);
np.add(G);
np.add(B);
R.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
ir=SÍ;
ig=NO;
ib=NO;
repaint();
}
}
);
G.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
ir=NO;
ig=SÍ;
ib=NO;
repaint();
}
}
);
B.addActionListener(new ActionListener()
{
Excelencia Académica
127
public void actionPerformed(ActionEvent e)
{
ir=NO;
ig=NO;
ib=SÍ;
repaint();
}
}
);
add(np,BorderLayout.SOUTH);
}
public void paint(Graphics g)
{
for (ent e=0;e<200;e+=10)
{
g.setColor(new Color(r_,g_,b_));
r_=r_+ir;
g_=g_+ig;
b_=b_+ib;
g.drawLine(0,i,i,200);
}
g.setColor(Color.black);
g.drawLine(0,0,0,200);
g.drawLine(0,200,200,200);
r_=0;
g_=0;
b_=0;
}
}
Al archivo lo llamamos líneas.java y lo cargamos con el archivo html siguiente (líneas.html):
<html>
<head>
<title>
Applet Líneas (líneas.class)
</title>
</head>
<body>
<APPLET code="lineas.class" width=200 height=300>
</APPLET>
</body>
Excelencia Académica
128
</html>
En el lenguaje Java es posible dibujar en un aplique simplemente volviendo a definir el
método paint. Este método se invoca automáticamente por el sistema cuando la ventana
que incluye el aplique pasa a un primer plano. Por lo tanto cada orden gráfica al aplique se
dará en el método paint del aplique.
Cuando el aplique haya dibujado y se quiera visualizar posibles cambios, es posible invocar
el método repaint() o el método update(Graphics g) que borra el área en el que el aplique
ha dibujado y vuelve a invocar a paint.
El método paint(Graphics g) no se puede invocar directamente.
Graphics es una clase que no se puede incluir, sino que es recibida por paint como
parámetro.
En Java2 la clase Graphics ha sido potenciada añadiendo la clase Graphics2D, que la
amplía añadiendo muchas posibilidades a la gráfica de Java.
Fco. Javier Ceballos Curso de Programación Java 2
Alfaomega-Rama, España 2,003 Segunda Edición
Luis Joyanes Aguilar Programación en Java
Prentice Hall, España
José Pérez Mayor Programación en Java Paso a Paso
Thomson, España 2,003
Deitel y Deitel Curso de Programación en Java
Prentice Hall, España, 1,995
En los siguientes cursos se usaran los métodos referidos a los gráficos usando applets
para ponerlos en páginas web que se pueden visualizar desde Internet.
Excelencia Académica
129
Verificar cada uno de los métodos de Graphic, su forma de uso y para que sirven
explicando sus detalles.
El estudiante debe ser capaz de escribir programas que muestren gráficos usando líneas y
otros componentes.
Excelencia Académica
130
Nº 8
Nombre__________________________________________________________________
Apellidos_______________________________________Fecha _____________________
Ciudad ______________________________Semestre_____________________________
1.- Escribir un programa en Java que dibuje un cuadrado cuando se ingresa por teclado
las dimensiones de su lado y el punto de origen. El interior debe estar pintado.
2.- Escribir un programa que dibuje líneas en forma aleatoria, el programa termina cuando
se presiona la tecla Enter.
3.- Escribir un programa que dibuje círculos en forma secuencial desde la parte superior
hasta la parte inferior, al llegar a la parte superior vuelve a la parte superior avanzando
cierta posición horizontal.
4.- Escribir un programa que muestre una pelota que cae de la parte superior y rebota en
forma secuencial hasta quedar en reposo en la parte inferior.
Excelencia Académica
131
Apéndice I
INSTALACIÓN DE J2SDK-1_4_2, JCREATOR310 Y ECLIPSE
El orden de instalación que se debe seguir es:
1.- j2sdk-1_4_2 que es el compilador de Java.
2.- jcreator310 que es el IDE para programar.
3.- Instalación de Eclipse que es otro IDE de desarrollo.
1) Instalación de j2sdk-1_4_2
En el CD buscar el archivo j2sdk-1_4_2_03-windows-i586 y darle “doble clic”. Aparecerá
la siguiente ventana:
Excelencia Académica
132
Aquí se puede ver la ventana en la que se acepta la licencia. Marcar la primera opción.
En esta ventana se puede cambiar de unidad para la instalación. Si se desea el cambio,
presionar el botón “change” y elegir otra carpeta; sino, elegir la señalada por defecto.
Excelencia Académica
133
Presionar “Install”.
Aquí se inicia la instalación.
Al aparecer esta ventana, presionar “Finish” para terminar la instalación del j2sdk.
Una vez hecho esto, buscamos la carpeta c:\ j2sdk1.4.2_03 (en nuestro ejemplo instalamos
en “C”) que se creó en la instalación. En esta carpeta debemos crear una carpeta llamada
“docs” , en la que vamos a colocar los archivos que se encuentran dentro del archivo
comprimido j2sdk-1_4_2-doc, que está en el CD. Entonces, ubicamos en el CD el archivo
comprimido (zip) j2sdk-1_4_2-doc y procedemos como se indicó. Después de esto,
nuestras carpetas en
c:\ j2sdk1.4.2_03 quedan así:
Excelencia Académica
134
2) Instalación de Jcreator
Ahora procederemos a instalar el Jcreator. Buscar en el CD el archivo jcreator310.exe
y
Darle “doble clic”. Aparecerá la siguiente ventana.
Presionamos “Yes”. Luego aparece la siguiente ventana de bienvenida. Presionamos
“Next”.
Excelencia Académica
135
Presionamos en “Next” para aceptar la licencia.
En esta ventana podemos elegir la ruta en la que se desea instalar Jcreator. Es
recomendable elegir la señalada por defecto. Presionamos “Next”.
Esta ventana aparece si se ha hecho antes ya una instalación de Jcreator. Nos pregunta si
queremos reemplazar la carpeta que ya está creada. Presionamos “Yes”.
Nota: En lo sucesivo, si aparecen más ventanas como ésta, avisando que ya existe
alguna carpeta creada, sólo presionar “aceptar” o “yes” para sobrescribir en ella.
Excelencia Académica
136
Presionamos “Next”.
Aquí se adiciona un ícono de JCreator en el escritorio para un rápido acceso. Presionamos
“Next”.
Presionar en “Install” para iniciar la instalación.
Dejar avanzar el proceso de instalación, hasta que aparezca la siguiente ventana.
Excelencia Académica
137
Presionar “Finish” para terminar la instalación. Luego aparecerá el Jcreator activo.
Ahora adicionamos las plantillas o templates. Buscamos en el CD el archivo
“Templates.zip” y le damos “doble clic”.
Aparecerá la siguiente ventana. Elegimos la unidad (sólo la unidad) en la que se instaló
el jCreator. En nuestro caso elegimos “C” y presionamos en “Unzip”.
Excelencia Académica
138
En esta ventana se señala que las plantillas se instalaron exitosamente. Ya estamos
listos para usar Jcreator.
3) Instalación de Eclipse
En realidad, Eclipse no se “instala”. Se debe descomprimir el archivo eclipse-SDK-2.1.3-
win32
y su contenido se copia a alguna carpeta preparada por nosotros. Para esto, ubicamos el
archivo zip eclipse-SDK-2.1.3-win32 en el CD, lo copiamos en alguna unidad y lo
descomprimimos.
En nuestro caso, descomprimimos todo en una carpeta llamada “eclipse” y la colocamos en
“C”, con todo su contenido.
Buscamos el ícono “eclipse” y le damos “doble clic”. De esta forma, se activará y podremos
trabajar con el software.
Excelencia Académica
139
Apéndice II
GUÍA DE REFERENCIA DEL LENGUAJE JAVA
A. Fundamentos
Palabras reservadas (funcionales):
abstact boolean break byte case
catch char class continue default
do double else extends false
final finally float for if
implements import instanceof int interface
long native new null package
private protected public return short
static super switch syncroniced this
throw throws transient try void
volatile while
Tipos de comentarios:
/*comentario*/ // Hasta fin de línea //* javadoc */
Bloques de código:
{ // conjunto de sentencias
}
Separadores Java:
{ } , : ;
Excelencia Académica
140
Propuestas de estilo de nombres de identificadores:
Las clases: Clase o MiClase.
Los métodos: metodo() o metodoLargo().
Las variables: altura o alturaMedia.
Las constantes: CONSTATE o CONSTANTE_LARGA.
Los paquetes: java.paquete.subpaquete.
B. Tipos de datos
Tipo bytes Tipo Datos Rango (positivo) Literal
byte 1 Entero 127 14
short 2 Entero 32767 14
int 4 Entero 2.147.483.647 14
long 8 Entero 9.233e15 14
float 4 Coma flotante 1.4e-45 a 3.4e38 36,6
double 8 Coma flotante 4.9e-324 a 1.7e308 3,14e2
char 2 Caracter Unicode 'a' o \064
boolean 1 Booleano true o false true o false
Vectores:
int vectorNumeros[]=new int[numero];
Cadenas Constates:
String nombreBonito = "Amelia";
Cadenas Variables:
StringBuffer cadenaVariable = "Cambiante";
C. Operadores
Excelencia Académica
141
Operadores Unarios:
Operador Descripción (prefija) Operador Descripción (pre o
posfija)
+ Convierte el operador a
int
++ Incrementa operador
- Niega aritméticamente
oper.
-- Decrementa operador
Operadores aritméticos (binarios):
Operador Uso Atajo Descripción
+ op1 + op2 op1 += op2 Suma op1 y op2
- op1 - op2 op1 -= op2 Resta op2 de op1
* op1 * op2 op1 *= op2 Multiplica op1 por
op2
/ op1 / op2 op1 /= op2 Divide op1 por op2
% op1 % op2 op1 %= op2 Resto de op1 / op2
Operadores de comparación (binarios):
Operador Uso Devuelve verdadero 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
&& op1 && op2 AND, condicionalmente evalúa op2
Excelencia Académica
142
& op1 & op2 AND, siempre evalúa op1 y op2
|| op1 || op2 OR, condicionalmente evalúa op2
| op1 | op2 OR, siempre evalúa op1 y op2
! ! op op es falso
Operadores de bit (binarios):
Operador Uso Operación
>> op1 >> op2 Desplaza los bits de op1 a la derecha op2 veces
<< op1 << op2 Desplaza los bits de op1 a la izquierda op2 veces
>>> op1 >>> op2 Desplaza los bits de op1 a la derecha op2 veces (sin
signo)
& op1 & op2 AND
| op1 | op2 OR
^ op1 ^ op2 "XOR"
~ ~op2 Complemento
Operador terciario:
expresion ? sentencia_si : sentencia_si_no
Precedencia de operadores:
Tipo de operadores Operadores de este tipo
Operadores posfijos [ ] . (parametros) expr++ expr--
Operadores unarios ++expr --expr +expr -expr ~ !
Creación o conversión new (tipo) expr
Excelencia Académica
143
Multiplicación * / %
Suma + -
Desplazamiento <<
Comparación <<= = instanceof
Igualdad == !=
AND a nivel de bit &
OR a nivel de bit ^
XOR a nivel de bit |
AND lógico &&
OR lógico ||
Condicional ? :
Asignación = += -= *= /= %= &= ^= |= <<= = =
D. Estructuras de control
Toma de decisión (if-else y switch):
if ( condición ) {
Bloque de código a ejecutar si la condición es cierta
}
else {
Bloque de código a ejecutar si no
}
switch ( expresionMultivalor ) {
case valor1 : conjuntoDeSentencias; break;
case valor2 : conjuntoDeSentencias; break;
case valor3 : conjuntoDeSentencias; break;
default : conjuntoDeSentencias; break;
}
Bucles iterativos (while, do-while, for):
Excelencia Académica
144
while ( expresiónBooleana )
{
sentencias;
};
do {
sentencias;
} while ( expresiónBooleana );
for(inicio; condicion_continuacion;sentencia_actualizacion) {
sentencias;
}
Sentencias de saltos:
etiquetaSentencia: sentenciaEtiquetada
break nombreEtiqueta; // Sale del último bucle
continue; // Hace otra pasada al último bucle
return valor; // Sale del método devolviendo valor
E. Clases
Definición de clase:
acceso class NombreDeClase herencia{
acceso tipo nombreAtributo1;
NombreDeClase{ // Constructor
}
// . . .
finalize { //Recogida de basura
}
acceso tipo_devuelto nombreMétodo1( parámetros ) {
cuerpo_del_método1;
}
}
Tipos de acceso de las clases:
final: Sin subclases
abstract: Clase abstracta, luego no se permiten instancias de esta clase.
Excelencia Académica
145
public: Accesible desde fuera de su paquete
Herencia:
extends: Clase padre. La clase Object es superclase de todas las clases Java (raíz
del árbol de herencia).
implements: Interfaces padres, separadas por comas; Interface1, Interface2.
class MiClase extends SuPadre implements Interface0,Interface1;
F. Atributos
Acceso (igual que para métodos):
public: Los miembros declarados public son accesibles en cualquier lugar en que
sea accesible la clase, y son heredados por las subclases.
private: Los miembros declarados private son accesibles sólo en la propia clase.
protected: Los miembros declarados protected son accesibles sólo para sus
subclases
Composición:
class claseCompuesta {
claseComponente referenciaAObjetoComponente.
}
G. Métodos
Referencias válidas en los métodos:
this: Referencia al objeto actual.
super: Referencia a la clase padre en el árbol de herencia.
Modificadores permitidos:
Acceso: publicprivate o protected. Igual que para los atributos.
abstract: Método abstractos, sin cuerpo. Sólo se permiten en clases abstractas.
final: No se puede sobreescribir el método.
static: Método de la clase (no de los objetos).
native: Método implementado con métodos nativos (específicos de una plataforma).
synchronized: Solamente permite un hilo de ejecución.
Sobrecarga del método: Varias implementaciones en función de los parámetros.
Sobreescritura del método: Un cuerpo en cada nivel de herencia.
H. Objetos
Instanciación:
Excelencia Académica
146
NombreDeClase referenciaAObjeto = new NombreDeClase();
Acceso al objeto:
referenciaAObjeto.método( parámetros );
referenciaAObjeto.atributo;
Destrucción: Cuando la referencia a objeto sale de ámbito en el programa.
I. Interfaces
Declaración de una interfaz:
interface MiInterfaz {
int CONSTANTE = 100;
int metodoAbstracto( int p ); // Por definir
}
Implementación de interfaces:
class ImplementaInterfaz implements MiInterfaz{
int m=CONSTANTE;
int metodoAbstracto( int p ){ return ( p*m ); }
}
Herencia múltiple entre interfaces:
interface InterfazMultiple extends Interfaz0,Interfaz1;
Clases de envoltura de tipos simples:
Clases de envoltura de tipos simples
Double double
Float float
Integer int, short, byte
Long long
Character char
Boolean boolean
Excelencia Académica
147
J. Paquetes
Creación de un paquete (primera sentencia de un fichero fuente):
package NombrePaquete;
Importación de un paquete o parte de él:
import Paquete.Subpaquete1.Subpaquete2.Clase1;
Paquete.Subpaquetes1.Subpaquete2.Clase_o_Interfaz.elemento
Visibilidad en los paquetes:
Situación del elemento privatepor
defecto protected public
En la misma clase Sí Sí Sí Sí
En una clase
en el mismo paquete No Sí Sí Sí
En una clase hija
en otro paquete No No Sí Sí
En una clase no hija
en otro paquete No No No Sí
K. Excepciones
Tipos de excepciones:
Error: Excepciones que indican problemas muy graves, que suelen ser
irrecuperables y no deben casi nunca ser capturadas.
Exception: Excepciones no definitivas, pero que se detectan fuera del tiempo de
ejecución.
RuntimeException: Excepciones que se dan durante la ejecución del programa.
Lanzamiento de una excepción:
metodoLanzador() throws MiException{
throw MiException:
}
Excelencia Académica
148
Tratamiento de una excepción:
try {
// Código posiblemente problematico
} catch( tipo_de_excepcion e) {
// Código para solucionar la excepcion e
} catch( tipo_de_excepcion_mas_general e)
// Código para solucionar la excepcion e
} finally {
// Se ejecutara tras try o catch
}
L. Threads
Creación:
1. Para crear un thread, se ha de implementar una clase, extendiendo la clase base
Runnable, y crear un objeto de la clase Thread.
2. Este objeto representará un nuevo hilo de control, que será accionado cuando
invoquemos al método start() del thread.
3. En ese momento este hilo se activará, ejecutando (si el planificador de hilos
considera que es el momento), el método run() de la clase en que todo esto suceda.
Sincronización de procesos:
1. Durante la ejecución de un programa, muchas veces varios procesos han de
realizar tareas de una forma sincronizada, actuando en un determinado orden.
2. Para ello se han de declarar métodos como syncronized.
3. Mediante la utilización de excepciones, y de las funciones wait() y notifiy(),
respectivamente esperarán a que otro proceso acabe antes de continuar su ejecución.