Manual Java Básico
Manual Java Básico
Manual Java Básico
3.2 Objetos.................................................................................................................... 15
3.3 Métodos.................................................................................................................. 16
3.6 Polimorfismo........................................................................................................... 20
3
MODULO II ............................................................................................................................ 45
1.3 Métodos.................................................................................................................. 50
3.2 Condicionales.......................................................................................................... 65
6. Arreglos...................................................................................................................... 81
4
1.3 Uso de la clase Math............................................................................................... 91
3. Excepciones ............................................................................................................... 94
5
MODULO I
1. Java como lenguaje de programación
1.1 ¿Qué es Java?
Hacia 1990, James Gosling, quien trabajaba para Sun Microsystems, fue el encargado de
crear programas para controlar aparatos electrónicos domésticos. Originalmente Gosling y
su equipo empezaron el diseño de su software usando C++, debido a su orientación a
objetos. Sin embargo, se dieron cuenta que C++ no satisfacía los proyectos que se tenían en
mente; encontraron dificultades con aspectos complicados de C++ como la herencia
múltiple de clases, errores de programación (bugs) relacionados con huecos de memoria.
De esta manera Gosling decidió que tenía que empezar por escribir un lenguaje
simplificado que le evitara todos los problemas que se encontró con C++.
Oak se usó por primera vez en un proyecto llamado Proyecto Green, donde el equipo de
desarrollo intentó diseñar un sistema de control para usar dentro del hogar. Este sistema de
control permitiría al usuario manipular distintos dispositivos, como televisiones, video
caseteras, luces caseras y teléfonos, todo desde una computadora de mano llamada *7 (Star
Seven). El sistema *7 incluía una pantalla sensible para que el dueño seleccionara y
controlara estos dispositivos.
La pantalla del *7 tenía diversas figuras, entre las que se encontraba Duke (la actual
mascota de Java). Duke ha sido incluido en muchos ejemplos de applets en la página de
Sun Microsystems.
El siguiente paso para Oak fue el proyecto Video En Demanda (VOD), en el que el
lenguaje era usado como la base para el software que controlaría un sistema de televisión
interactivo. Aunque ni *7 ni el proyecto VOD concluyeron en productos actuales, le dieron
a Oak una oportunidad de crecer y madurar. Con el tiempo Sun Microsystems descubrió
que el nombre Oak ya había sido usado y le cambió el nombre por Java, y vio nacer un
lenguaje poderoso y sencillo.
6
En 1993, después de que Internet se transformó de un ambiente basado en texto a un
ambiente gráfico, el equipo de Java se dio cuenta de que el lenguaje sería perfecto para la
programación en el Web. Así nació la idea de los applets, que son pequeños programas que
pueden ser incluidos en páginas de Web, y también surgió la idea de escribir un navegador
de Web que demostraría el poder del lenguaje, este navegador es el HotJava.
Finalmente, hacia mayo de 1995, Sun Microsystems anunció oficialmente a Java. El nuevo
lenguaje fue aceptado como una poderosa herramienta para el desarrollo de aplicaciones
para Internet. Netscape Communications, el creador del navegador Netscape Navigator, dio
soporte a Java desde su versión 2.0. Otros desarrolladores de software también incluyeron
soporte para Java, incluyendo al Internet Explorer 3 de Microsoft. Actualmente, Java puede
correr en máquinas con procesadores SPARC, Intel, Digital.
Es orientado a objetos, porque como C++, Java usa clases para organizar el código en
módulos. En tiempo de ejecución, un programa crea objetos a partir de las clases. Las
clases en Java pueden heredar de otras clases, pero la múltiple herencia, donde una clase
hereda métodos y datos de varias clases, no está permitida.
Es tipificado estáticamente porque todos los objetos usados en un programa deben ser
declarados antes de que puedan ser usados. Esto permite al compilador de Java localizar y
reportar conflictos con los tipos de datos.
Es compilado porque antes de que se pueda correr un programa, primero tiene que ser
compilado por el compilador de Java. El resultado de la compilación es el archivo "byte-
code", que, similar a un archivo con código máquina, puede ser ejecutado bajo cualquier
sistema operativo que tenga un intérprete de Java. Este intérprete lee el archivo byte-code y
traduce los comandos en comandos de lenguaje máquina que pueden ser ejecutados
directamente por la computadora.
Todas las aplicaciones tienen al menos un proceso (llamado thread) que representa la
ejecución del programa.
7
Tiene recolector de basura, ya que los programas de Java no se encargan de liberar de
memoria los objetos, esto es una tarea del administrador de memoria y el recolector de
basura.
Es robusto porque el intérprete de Java revisa todos los accesos al sistema dentro de un
programa, por esto, los programas desarrollados en Java no pueden bloquear el sistema.
Esto es, cuando un error serio es encontrado, los programas en Java crean una excepción.
Esta excepción puede ser capturada y manejada por el programa sin el riesgo de bloquear el
sistema.
Es seguro porque el compilador no sólo verifica todos los accesos a memoria, sino que
también se asegura que no entren virus en un applet en ejecución. Ya que los apuntadores
no son soportados por el lenguaje, los programas no pueden acceder a áreas del sistema a
las que no tienen autorización.
Es ampliable porque los programas en Java soportan métodos nativos, que son funciones
escritas en otros lenguajes, generalmente C++. Este soporte a métodos nativos permite a los
programadores escribir funciones que pueden ser ejecutadas más rápido que las funciones
equivalentes escritas en Java. Los métodos nativos son ligados a los programas en forma
dinámica, es decir, son asociados con los programas en tiempo de ejecución.
8
1.3 ¿Qué es el JRE?
El JRE (Java Runtime Environment) Entorno en Tiempo de Ejecución de Java, en español,
consta de la Máquina Virtual de Java, Java bibliotecas, y todos los demás componentes
necesarios para ejecutar aplicaciones Java y applets.
Se puede decir que es prácticamente la versión reducida del JDK que permite simplemente
ejecutar código Java, no permite compilar ni utilizar el Debugger.
Viene incluido en el JDK, pero también puede instalarse por separado y también es de libre
distribución. En este caso simplemente conviene instalarlo por separado cuando no se desea
programar en Java, sino que simplemente eres una persona común y corriente que navega
por la Web.
Una vez compilados los programas en Java, en el momento de ejecución se lleva a cabo una
9
tarea de carga, revisión y ejecución. La carga consta de cargar en memoria el archivo byte-
code, puede cargarse desde la máquina local o remotamente a través de la red. La revisión
consta de verificar que no haya: violaciones de acceso, operaciones que conduzcan a
"overflow" o "underflow", tipos de parámetros incorrectos, conversiones de datos
incorrectas, acceso a objetos sin inicializar, entre otras funciones. En el proceso de
ejecución ya se corren las instrucciones del programa.
10
11
2. Entendiendo el paradigma de la POO (Programación Orientada
a Objetos)
Antes de establecer los elementos del lenguaje, es necesario tener presentes los conceptos
básicos de la programación orientada a objetos porque la sintaxis y el formato de Java están
plenamente apegados a ellos.
Para empezar, todo parte del hecho de que el desarrollo de la programación de
computadoras entró en crisis en los años 60 y 70 del s. XX, porque las aplicaciones a
menudo hacían cosas raras. Un caso es el del Centro de Cómputo Noruego en Oslo en el
que desarrollaban simuladores de vuelo; sucedía, cuando los ejecutaban, que las naves
colisionaban.
Un análisis del problema probó que la aplicación confundía las características entre uno y
otro objeto simulado; es decir, que la cantidad de combustible, la posición en el espacio o la
velocidad de una nave eran atribuidas a otra. Se concluyó que esto se debía al modo como
programaban y que los lenguajes de entonces eran incapaces de resolver el problema.
Ante esto, los expertos del Centro Noruego desarrollaron Simula 67 que fue el primer
lenguaje orientado a objetos.
Así que la POO es una manera de diseñar y desarrollar software que trata de imitar la
realidad tomando algunos conceptos esenciales de ella; el primero de éstos es,
precisamente, el de objeto, cuyos rasgos son la identidad, el estado y el comportamiento.
Se debe tener presente que los objetos, sean reales o su proyección en software, se abstraen
en clases. Por ejemplo: de la clase perro pueden existir dos objetos Fido y Firuláis (esta es
su identidad). Fido es un san bernardo enorme, pinto, de 5 años; mientras que Firuláis es
un labrador, negro, de 3 años (este es su estado). Ambos perros ladran, merodean,
juguetean, comen y duermen (este es su comportamiento).
Si nos pidieran que hiciéramos un programa orientado a objetos que simulara lo anterior
haríamos la clase Perro que tendría las variables raza, color y edad, y los métodos
ladrar(), merodear(), juguetear(), comer() y dormir(). Firuláis y Fido son
los identificadores que podríamos usar en una aplicación que pretenda mostrar dos objetos
de la clase Perro.
12
Para llevar esto al ámbito del software analicemos el caso del programa Hola Mundo.
Hagamos el proceso de abstracción para encapsular sus características y su
comportamiento.
El primer Hola Mundo lo popularizó Brian Kernighan en los años 70 del siglo XX, en un
libro que causó mucho interés en su tiempo y que escribió junto a Dennis Ritchie: The C
Programming Language. Hoy en día, es una tradición presentar los lenguajes con un
programa de este tipo, que lo que debe hacer es mostrar la frase “Hola mundo” en la
pantalla, y sirve para probar que el lenguaje está debidamente instalado y funcionando.
Entonces, abstrayendo esto, podemos decir que el comportamiento de los objetos del tipo
Hola Mundo es mostrar un mensaje y su característica, el mensaje mismo.
Lo que sigue es mostrar cómo los elementos de lenguaje Java nos permiten apegarnos a la
orientación a objetos; para eso es necesario conocer dichos elementos, pero antes, para
finalizar, un breve resumen.
3. El comportamiento, que indica los métodos que se deben programar para que los objetos
realicen acciones
5. El encapsulamiento, que exige que sus características y métodos estén bien definidos y
no se confundan con los de otros
Faltan dos conceptos muy importantes: la herencia y el polimorfismo, que veremos más
adelante.
3. Conceptos de la POO
3.1 Clases
Una clase es la definición de las tareas que se van a realizar. Incluye las variables
necesarias y los métodos, tanto públicos como privados. En lenguajes estructurados, los
métodos equivalen a las funciones y procedimientos, como en C o Pascal.
Una clase es la unidad fundamental de programación en Java, dado que un programa Java
está formado por un conjunto de clases.
Una clase es una “plantilla” que describe un conjunto de objetos con atributos y
13
comportamiento similares.
Puede considerarse como una plantilla o prototipo de objetos: define los atributos que
componen ese tipo de objetos y los métodos que pueden emplearse para trabajar con esos
objetos.
Las clases incluyen por tanto atributos y métodos. Los atributos definen el estado de cada
objeto de esa clase y los métodos su comportamiento.
Los atributos debemos considerarlos como la zona más interna, oculta a los usuarios del
objeto. El acceso a esta zona se realizará a través de los métodos.
// calcular el día
siguiente
Como hemos visto antes, el concepto de clase incluye la idea de ocultación de datos, que
básicamente consiste en que no se puede acceder a los datos directamente (zona privada),
sino que hay que hacerlo a través de los métodos de la clase.
14
De esta forma se consiguen dos objetivos importantes:
Que el usuario no tenga acceso directo a la estructura interna de la clase, para no poder
generar código basado en la estructura de los datos.
Si en un momento dado alteramos la estructura de la clase todo el código del usuario
no tendrá que ser retocado.
El modificador de acceso se utiliza para definir el nivel de ocultación o visibilidad de los
miembros de la clase (atributos y métodos) y de la propia clase.
3.2 Objetos
Un objeto es la instancia de una clase. Con un objeto se pueden ejecutar las tareas definidas
en la clase.
Una objeto o instancia es un elemento tangible (ocupa memoria durante la ejecución del
programa) generado a partir de una definición de clase. Todos los objetos empleados en un
programa han de pertenecer a una clase determinada. Aunque el término a veces se emplea
de una forma imprecisa, un objeto es una instancia de una clase predefinida en Java o
declarada por el usuario y referenciada por una variable que almacena su dirección de
memoria. Cuando se dice que Java no tiene punteros simplemente se indica que Java no
tiene punteros que el programador pueda ver, ya que todas las referencias a objeto son de
hecho punteros en la representación interna.
En general, el acceso a los atributos se realiza a través del operador punto, que separa al
identificador de la referencia del identificador del atributo (idReferencia.idAtributo).
Las llamadas a los métodos para realizar las distintas acciones se llevan a cabo separando
los identificadores de la referencia y del método correspondiente con el operador punto
(idReferencia.idMetodo(parametros))
Por ejemplo, para que se puedan realizar las tareas que define la clase Fecha, se tiene que
hacer una instancia de la clase:
Fecha fecha;
Si definimos otra variable de tipo Fecha y le asignamos el valor de fecha, Java no crea un
nuevo objeto, sino que ambas variables apuntan a la misma localidad de memoria:
Fecha fecha1, fecha2;
fecha1 = new Fecha();
fecha2 = fecha1;
fecha1 Fecha
15
fecha2
En Java la palabra reservada this se usa para accesar variables y métodos del mismo objeto
(ya creado) para facilitar la programación (this no se puede usar con llamadas static de
métodos)
this.day = this.day + 1;
// más código
3.3 Métodos
Los métodos son subrutinas que manipulan los datos definidos por la clase y, en muchos
casos, brindan acceso a esos datos. En la mayoría de los casos, otras partes de tu programa
interactuarán con una clase a través de sus métodos.
Un método contiene una o más declaraciones. En un código Java bien escrito, cada
método realiza solo una tarea. Cada método tiene un nombre, y es este el que se usa para
llamar al método. En general, puede dar el nombre que desee a un método cualquiera. Sin
embargo, recuerde que main() está reservado para el método que comienza ejecución de su
programa. Además, no use las palabras clave de Java para nombres de métodos.
Donde, tipo-retorno especifica el tipo de datos devueltos por el método. Puede ser
cualquier tipo válido, incluidos los tipos de clase que cree. Si el método no devuelve un
16
valor, su tipo de devolución debe ser void.
El nombre del método se especifica por nombre. Puede ser cualquier identificador legal que
no sea el que ya utilizan otros elementos dentro del alcance actual.
La lista de parámetros es una secuencia de tipos e identificadores separados por comas.
Los parámetros son esencialmente variables que reciben el valor de los argumentos pasados
al método cuando se llama. Si el método no tiene parámetros, la lista de parámetros estará
vacía.
Métodos de instancia: Son todos los métodos no static. Operan sobre las variables de
instancia de los objetos pero también tienen acceso a los atributos estáticos.
La sintaxis de llamada a un método de instancia es:
idObjeto.metodo(parametros); // Llamada típica a un método de instancia
Todas las instancias de una clase comparten la misma implementación para un método de
instancia.
Dentro de un método de instancia, el identificador de una variable de instancia hace
referencia al atributo de la instancia concreta que hace la llamada al método (suponiendo
que el identificador del atributo no ha sido ocultado en el método).
Métodos de clase: Son los métodos declarados como static. Tienen acceso solo a los
atributos estáticos de la clase. No es necesario instanciar un objeto para poder utilizar un
método estático.
Para acceder a un método de clase se escribe:
NombreClase.metodo;
3.4 Constructores
Un método constructor, es el que se encarga de dar ciertos valores iniciales a las variables
de la clase.
// variables de la
//clase
public Clase()
17
}
public Clase(int x)
Clase c,d;
c = new Clase();
d = new Clase(1);
Cada clase tiene al menos un constructor. Si no se define uno, Java lo crea automáticamente
sin parámetros ni código. De no ser así, se tendría que definir al menos un constructor para
poder crear la instancia del objeto.
Si en una clase se definen constructores con parámetros, se pierde el constructor que crea
Java, por lo que una llamada a new Clase() generaría un error de compilación.
3.5 Herencia
La herencia es una propiedad que permite la declaración de nuevas clases a partir de otras
ya existentes. Esto proporciona una de las ventajas principales de la Programación
Orientada a Objetos: la reutilización de código previamente desarrollado ya que permite a
una clase más específica incorporar la estructura y comportamiento de una clase más
general.
Cuando una clase B se construye a partir de otra A mediante la herencia, la clase B hereda
todos los atributos, métodos y clases internas de la clase A, exceptuando los constructores
(accedemos a ellos usando el método de Java super()). Además, la clase B puede redefinir
los componentes heredados y añadir atributos, métodos y clases internas específicas.
Para indicar que la clase B (clase descendiente, derivada, hija o subclase) hereda de la
clase A (clase ascendiente, heredada, padre, base o superclase) se emplea la palabra
reservada extends en la cabecera de la declaración de la clase descendiente. La sintaxis es
la siguiente:
18
public class ClaseB extends ClaseA {
// Declaracion de atributos y metodos especificos de ClaseB
// y/o redeclaracion de componentes heredados
}
class A {
int i;
}
class B extends A {
int i; // esta i oculta la i de A
B(int a, int b) {
super.i = a; // i in A
i = b; // i in B
}
void show() {
System.out.println("i en la superclase: " + super.i);
System.out.println("i en la subclase: " + i);
}
}
class UseSuper {
19
public static void main(String args[]) {
B subOb = new B(1, 2);
subOb.show();
}
}
3.6 Polimorfismo
El polimorfismo es una de las características fundamentales de la Programación Orientada a
Objetos y está estrechamente relacionado con la herencia.
Se puede definir como la cualidad que tienen los objetos para responder de distinto modo a
un mismo mensaje.
Ejemplo:
La clase Phone es una clase normal usada paar representar las caracteristicas de un
teléfono. La clase tiene un método callNumber() que es usado para llamar al número que es
pasado como argumento. El método isRinging es usado para determinar si el teléfono está
actualmente sonando. Esta clase imprime por la salida estandar el nombre de la clase y
acción que está realizando cuando entra a cada método. La clase Phone es la clase base para
la clase SmartPhone:
La clase SmartPhone representa un smartphone. Esta clase es extendida por la clase Phone
20
y hereda su funcionalidad. La clase SmartPhone tiene un método sendEmail() que es usado
para enviar un mensaje por email. Tiene un método llamado retrieveEmail() que retornará
como un String todos los mensajes que se han recuperado. Esta clase también contiene el
método isRinging() que sustituye el método isRinging() de la superclase Phone. Similar a la
clase Phone, la clase SmartPhone imprime por la salida estándar el nombre de la clase y la
función que realizará cuando entre al método.
public class SmartPhone extends Phone{
En una clase abstracta es posible definir métodos abstractos, los cuales se caracterizan por
el hecho de que no pueden ser implementados en la clase base. De ellos, solo se escribe su
signatura en la superclase, y su funcionalidad –polimórfica– tiene que indicarse en las
clases derivadas (subclases).
21
las encargadas de agregar la funcionalidad a los métodos abstractos. Si no lo hacen así, las
clases hijas deben ser también abstractas.
Las interrfaces son una forma de especificar qué debe hacer una clase sin especificar
el cómo.
Las interfaces tienen una semejanza con las clases abastractas, en el sentido que no tiene
sentido definir objetos instancia de una interfaz. Igual que las clases abstractas, la clase
asociada se compromete a implementar todos los métodos en ellas definidos, pero en este
caso la relación no es de herencia en plenitud, dado que no hay atributos en la definición de
una interfaz.
Las interfaces no son clases, sólo especifican requerimientos para la clase que las
implementa o, desde su uso, los servicios para la función que manipula un objeto que se
dice cumplir con la interfaz.
Java sólo permite heredar de una clase, pero permite implementar múltiples interfaces.
Ejemplo:
La otra modificación es que la clase Employee debe implementar esta función. Por
ejemplo:
public int compareTo(Object otroObject)
{
Employee otro=(Employee) otroObject;
if (salary < otro.salary) return -1;
if (salary > otro.salary) return 1;
return 0;
}
22
4. Estructura y ejecución de un programa Java
Un programa en Java por lo regular tiene la siguiente estructura:
Existen varias herramientas que nos permiten desarrollar en Java, siendo los más conocidos
Eclipse y NetBeans., en esta ocasión usaremos este último.
23
Cada proyecto además está dividido en:
Paquetes de fuentes
Paquetes de prueba
Bibliotecas
Bibliotecas de pruebas
4.2 Paquetes
Un package es una agrupación de clases. Es parecido a una "caja" que contiene las clases
que queramos mantener en un solo lugar.
24
Dentro de los paquetes de fuentes se pueden crear distintos tipos de archivos. Por ejemplo,
se pueden crear Clases Java, que contendrán únicamente código en Java para realizar una
determinada tarea.
Para crear un nuevo archivo dentro de un paquete de fuentes se puede utilizar el menú
"Archivo > Archivo nuevo ..." o bien usar el menú contextual del paquete de fuentes.
Un mismo proyecto puede tener varias clases e incluso varios paquetes de fuentes como
se puede ver en el siguiente ejemplo:
25
4.3 Servidores de aplicaciones
Básicamente, un servidor de aplicaciones consiste en un contenedor que abarca la lógica de
negocio de un sistema, y que provee respuestas a las peticiones de distintos dispositivos que
tienen acceso a ella. Son un claro ejemplo del modelo cliente-servidor, cuyo lado cliente
ejecuta requerimientos de procesamiento al otro lado, donde el servidor se encarga de
procesar y responder.
Un servidor puede ser mejor o peor según nuestras necesidades, es decir cada servidor sabe
cubrir unas necesidades mejor que otras, por dar un ejemplo Tomcat es ligero y
ampliamente utilizado, pero da un soporte muy básico al estándar JEE por lo que si
desarrollas aplicaciones que hagan uso de EJB o CDI Tomcat parecerá un servidor malo
porque no los soporta.
Siguiendo con los ejemplos, GlassFish y JBoss (ahora WildFly) soportan y están
certificados como servidores completos de JEE, esto los hace más competentes pero
complejos, complejidad que muchos desarrolladores no necesitaran y consideraran molesta;
Incluso entre estos 2 hay matices importantes, GlassFish es la implementación de referencia
de JEE por lo que está disponible apenas se libera la nueva versión, estamos hablando de
una ventaja de varios meses donde el único servidor compatible es GlassFish lo que es
crítico para algunas empresas que necesitan ejecutar sus proyectos lo antes posible, por el
contrario JBoss es respaldado por RedHat y aunque es Open Source también ofrece una
versión con soporte comercial ideal para muchos clientes donde su negocio es muy
importante para arriesgarse solo con el soporte de la comunidad.
Hasta ahora hemos hablado de servidores Open Source, pero también hay dos pesos
pesados que solo trabajan con licencias comerciales, WebSphere y WebLogic, ambos son
los servidores comerciales más exitosos, diseñados para soportar aplicaciones grandes y
complejas, aunque estos los hace a su vez servidores muy pesados y complejos, su uso en
producción es muy común en grandes empresas pero en ambientes de desarrollo su
complejidad juega mucho en contra de los desarrolladores, siendo más difícil desarrollar
sobre ellos que en los servidores anteriormente nombrados.
26
4.5 Método Main
Toda aplicación básica de consola en Java contiene una clase principal con un método
main, al igual que en C++. El método main es lo primero que se ejecuta cuando se inicia la
aplicación desde la línea de comandos, es decir que la ejecución del programa comienza
desde allí. De esta forma podemos deducir que cualquier llamado, declaración o método
que no sea utilizado de manera directa o indirecta desde el método main nunca se ejecutará,
con lo de manera indirecta me refiero a que no se haga directamente desde el main sino
desde un método que llama a otros el cual es llamado desde el main, así se ejecutaría de
manera indirecta.
En Java el método main recibe como argumento un arreglo de String (más adelante
hablaremos sobre arreglos). Este arreglo contiene los argumentos enviados por la línea de
comandos para la invocación del programa. Generalmente en una aplicación de Java básica,
no se hace uso de éste argumento, sin embargo hay algunos casos especificos en los que sí.
Un programa puede construirse empleando varias clases. En el caso más simple se utilizará
una única clase. Esta clase contiene el programa, rutina o método principal: main() y en
éste se incluyen las sentencias del programa principal. Estas sentencias se separan entre sí
por caracteres de punto y coma. La estructura de un programa simple en Java es la
siguiente:
class CuentaBancaria
Interfaces.- Los nombres de las interfaces deberían tener la primera letra mayúscula, como
en los nombres de clase.
27
interface Cuenta
Métodos.- Los nombres de los métodos deberían ser verbos, todo el verbo en minúscula. Se
pueden agregar sustantivos con la primera letra en mayúscula. Evitar el uso de subrayas.
void revisarCuenta()
primerUsuario
Las variables deben tener significado e indicar su uso. Las variables de una letra deberían
evitarse, excepto las que suelen usarse en ciclos (x, y, i, j) para controlarlo.
El espaciado ayuda en la comprensión del programa. Se sugiere escribir una instrucción por
línea y usar indentación de uno o dos espacios.
28
4.7 Separadores
Existen algunos caracteres que tienen un significado especial en el lenguaje Java. En la
siguiente tabla se resumen los diferentes separadores que pueden encontrarse en el código
fuente de un programa.
Práctica Módulo I
1. Instalar el JDK versión 1.8
Para poder instalar el JDK lo primero que hemos de hacer es descargar el correspondiente
paquete. Lo habitual es que obtengamos un ejecutable (.exe para Windows), una imagen
(.dmg para OS X) o un paquete (tar.gz para GNU/Linux) comprimido.
El primer paso es ejecutar el archivo descargado, recuerde que no importa la versión del
JDK que haya descargado, puede ser una versión anterior o posterior.
29
Al ejecutar este archivo nos desplegará la siguiente ventana de bienvenidos al instalador de
actualización del JDK.
30
Una vez leído el archivo nos desplegará la ventana inicial al instalar el JDK, donde
debemos elegir las opciones que queremos instalar en nuestro pc, regularmente se instala
todo pero usted puede elegir que instalar (JVM, Código, Ejemplos).
Al dar clic en siguiente nos muestra una pantalla del progreso de descarga según a instalar
Productos de Java que es la primera ventana del menú, lo cual desplegará la siguiente
ventana.
31
Posteriormente comenzará a instalarse la máquina virtual de java que habíamos descargado
en los pasos anteriores, este procedimiento puede tardar dependiendo de los recursos de
nuestro equipo de cómputo.
32
Comenzará a instalar los componentes del JDK, esto puede tardar varios minutos.
33
Hasta este momento tenemos instalado nuestro JDK, pero esto no es suficiente si queremos
que nuestro equipo de cómputo pueda realizar sistemas informáticos, por esa razón tenemos
que decirle a nuestro pc que pueda generar archivos .class de la siguiente manera.
Primero damos clic derecho en equipo y elegimos propiedades, como en la siguiente
imagen:
Nos mostrara un cuadro de dialogo en el cual del lado izquierdo contiene un menú donde
nosotros seleccionaremos Configuración Avanzada del Sistema.
34
En el siguiente cuadro de diálogo tenemos que tener mucho cuidado ya que cada vez que
iniciamos nuestro pc estas variables de entorno son las que se encargan de cargar nuestro
sistema operativo así es que si llegáramos a borrar una variable de esta sección podría no
cargar la próxima vez nuestro sistema operativo, pero no se angustien si siguen estos pasos
no habrá de que preocuparse:
Primero debemos de ubicar la variable Path, la seleccionamos y damos clic en el botón
Editar.
35
Debemos de copiar la ruta donde se instaló nuestro JDK para poder agregarla a las
variables de entorno así que vamos a copiar la ruta.
En las variables de entorno vamos a agregar un punto y coma ";" pegamos la ruta que
copiamos en el paso anterior y agregamos nuevamente punto y coma ";" como nota
importante no debemos de borrar ninguna variable de entorno por lo explicado
anteriormente.
36
Una vez realizado los pasos descritos anteriormente es hora de verificar que los hayamos
realizado correctamente.
Abrimos una ventana de consola para ello vamos a inicio --> accesorios --> símbolo de
sistema y escribimos el comando java y damos enter. Nos debe de mostrar muchas líneas
describiendo el comando java como se muestra a continuación. Si nos arrojara un error
repetir los pasos anteriores hasta lograr el objetivo.
Ahora escribiremos el comando javac y de la misma manera que el comando anterior nos
debe de describir este comando, si nos arrojara un error repetir los pasos anteriores hasta
lograr el objetivo.
37
3. Haciendo uso del block de notas, crear primer programa Bienvenido.
Los programas en Java se escriben en cualquier editor de texto, esto puede ser en un Bloc
de Notas y para ejemplificarlo primero abriremos uno, en donde escribiremos el siguiente
código.
Algo muy importante que debes tener en cuenta es que los nombres de los archivos con
código creados en un editor de texto se guardan con la extensión “.java” así que no olvides
guardar tu archivo con esta extensión y en la carpeta bin en donde instalaste el compilador,
si no cambiaste la ruta, debe ser esta:
C:\Archivos de programa\Java\jdk1.6.0_10\bin
Para compilar nuestra clase, abrimos una consola de Windows y nos vamos a la ruta donde
se instaló la jdk y ejecutamos el comando javac nombreclase.class, para nuestro caso sería
javac Bienvenido.class
Para ejecutar la clase compilada ejecutamos el comando java Bienvenido, nos debe
mostrar el mensaje como se muestra en la imagen
38
4. Instalar Netbeans.
39
Y al final quizá se nos pregunte si queremos permitir que se recopile estadísticas sobre
nuestro uso:
Todo listo. Tendremos un nuevo programa en nuestro menú de Inicio. Podemos hacer doble
clic para comprobar que se ha instalado correctamente, y debería aparecer la pantalla de
40
carga:
41
Como ya tenemos instalado el entorno de Java y el IDE NetBeans, una vez listo este paso
comenzamos:
Ejecutamos el NetBeans y vamos al menú File > New Project, se abrirá una ventana en la
cual seleccionaremos el tipo de proyecto que crearemos, a la izquierda hay varias carpetas
con nombre: Java, JavaFX, Java EE, Java Web, … seleccionaremos solamente Java, y en el
segundo cuando vemos Java Aplication, Java Class Library, …. seleccionamos Java
Aplication y damos click en el boton inferior que dice “Next”.
En este caso le vamos a dar que si, ósea vamos a dejar marcado el checkbox y
posteriormente damos click en el botón “Finish”.
42
Así es esta atemorizante pantalla es la interfaz del NetBeans, básicamente está dividida en:
Menú Principal: File, Edit, View, Source, Refactor, Run, Debun, Profile, Team, Tools,
Window, Help
Barra de herramientas: New file, New project, Open Project, Undo, Redo, Build
Project, Clean Project, Run Project, Debug Project.
Projects: Aqui podemos navegar por todos los proyectos creados en NetBeans.
Navigator: Aqui podemos navegar por las diferentes variables y métodos de la clase
que tengamos en el editor.
Editor: La parte principal de todo IDE es donde escribimos el código y podemos ver el
resaltado por colores.
Consola: Aqui podemos ver los resultados de entrada y salida del programa.
El código inicial es creado por NetBeans cuando optamos por seleccionar la opción “Create
Main Class”, me voy a tomar la libertad de eliminar los comentarios, todo el texto en Gris
son comentarios que podemos borrar y al final quedamos un este código.
Ahora explicare brevemente el codigo:
package hello;
public class Hello {
public static void main(String[] args) {
}
}
package hello;
Todo proyecto de Java esta dividido en paquetes, de esta manera podemos modularizar los
43
proyectos, en este caso al llamar al paquete hello, también llamamos o incluimos a todas las
clases que se encuentren en el paquete.
public class Hello
Todo archivo de clase Java debe contener una clase que se define con la palabra reservada
class seguida del mismo nombre del archivo que la contenga, respetando las mayúsculas y
minúsculas.
public static void main(String[] args) {
}
Esta es una función o método de la clase, pero mas específicamente, la función main() solo
debe estar en la clase principal y la función main() es la función principal y la primera
función que se ejecuta, mas adelante veremos mas datos sobre los métodos y funciones
Todo el código que queremos que se ejecute debe estar dentro de las llaves {} de la función
main(){}.
Para escribir o imprimir texto usaremos la función System.out.print(String) que lleva como
parámetro una cadena de Texto que se imprimirá o mostrara en la consola.
System.out.print(“Hola Mundo!”);
La función que usamos imprime el texto y si despues decidimos publicar mas texto, este se
imprimira en la misma linea. ya que si queremos hacer un salto de linea debemos usar la
cadena de salto de linea \n.
System.out.println(“Hola Mundo!”);
Similar a System.out.print, pero esta funcion introduce un salto de linea automáticamente al
final y siempre que se ejecute la funcion println las cadenas se imprimirán en lineas
separadas.
44
MODULO II
1. Objetos y Clases
Java es un lenguaje totalmente orientado a objetos, eso representa que posee instrucciones y
sintaxis específicas para la programación orientada a objetos. Además, en java existe el
concepto de jerarquía de herencia, es decir, que todas las clases deben de heredar de otra
clase para formar todas ellas un árbol invertido. La clase raíz de este árbol es la clase
java.lang.Object y todas las clases heredan de ella directa o indirectamente. Adicionalmente
las clases son colocadas en carpetas para facilitar su ordenación y el trabajo con ellas,
dichas carpetas (paquetes es el término más exacto) formarán parte del nombre de la propia
clase, por ejemplo, java.lang.Object significa que existe una carpeta llamada lang, dentro de
la cuál existe otra carpeta llamada lang, dentro de la cuál existe una clase llamada Object.
public: indica que la clase es pública, y por tanto que puede ser utilizada desde
cualquier otra clase, con independencia de si están en el mismo paquete o no.
Sin especificar: indica que la clase tiene visibilidad de paquete, es decir, sólo la
pueden usar las clases que se encuentren en el mismo paquete que dicha clase.
abstract: indica que a la clase le falta, al menos uno, el código de algún método.
Posee el método (abstracto), pero no tiene el código de ese método, siendo
responsabilidad de las clases derivadas proporcionar el código de dicha clase. Una
clase abstracta no se puede instanciar.
final: se emplea para evitar que esta clase pueda ser derivada.
45
nombreClase es el nombre de la clase, cualquier nombre, pero respetando las reglas de
nomenclatura del lenguaje.
extends se utiliza para indicar que la clase hereda de nombreBase, en java sólo se permite
heredar de una única clase base. En caso de no incluir la cláusula extends se asumirá que se
está heredando directamente de la clase java.lang.Object
implements indica que esta clase es de los tipos de interfaz indicados por
listaInterfaces, pudiendo existir tantos como queramos separados por comas. Esta
cláusula es opcional.
modifVisibilidad indica desde que parte del código se puede acceder a la variable.
modifAtributos son características específicas del atributo, son:
Por convención, en Java, los nombres de las variables empiezan con una letra
minúscula (los nombres de las clases empiezan con una letra mayúscula).
Un nombre de variable Java: debe ser un identificador legal de Java comprendido en
una serie de caracteres Unicode. Unicode es un sistema de codificación que soporta
texto escrito en distintos lenguajes humanos. Unicode permite la codificación de
34.168 caracteres. Esto le permite utilizar en sus programas Java varios alfabetos
como el Japonés, el Griego, el Ruso o el Hebreo. Esto es importante para que los
programadores pueden escribir código en su lenguaje nativo.
No puede ser el mismo que una palabra clave
No deben tener el mismo nombre que otras variables cuyas declaraciones aparezcan
en el mismo ámbito
tipo es el tipo de la variable, pudiendo ser un tipo básico o un objeto de una clase o de un
interfaz. También puede ser una matriz o vector.
46
valorInicial permite inicializar la variable con un valor.
Se permite definir más de una variable, separándolas por coma, por ejemplo:
public int a = 5, b, c = 4;
En java definir un atributo de un tipo básico o tipo String significa que podemos acceder a dichas
variables de forma directa:
int a = 25;
a = 34;
en cambio intentemos definir y emplear una variable del tipo, por ejemplo, Thread:
Socket c=null;
c.close();
Esto nos quiere indicar que hemos intentado emplear una variable que no apuntaba a un
objeto válido, sino a null, y hemos intentado llamar a una función del objeto inexistente.
Es decir, en java las variables de tipo básico son el nombre de una zona de memoria en la
cuál podemos almacenar valores, pero que en cambio, las variables de tipo objeto son en
realidad referencias (punteros o alias) de objetos.
Lo mismo sucede con los objetos, podemos tener una variable para referirnos a objetos,
pero la variable puede que no apunte a ningún objeto y por tanto no la puedo emplear para
intentar acceder a un método o a un atributo del objeto referenciado por la variable,
sencillamente porque no existe el objeto referenciado.
Una variable que no apunta a un objeto se asume que tiene un valor especial llamado null, e
incluso podemos asignar el valor null a la variable:
Thread t = null;
Es por ello por lo que se deben de construir objetos y asignárselos a las referencias, usando
la palabra clave new. new permite crear un objeto a partir de la descripción de la clase que
le pasamos como argumento, por ejemplo:
new Persona()
Conseguimos crear un objeto de la clase Persona, los paréntesis permiten especificar que
constructor estamos llamando al crear al objeto (veremos constructores más adelante).
Pero al crear un objeto persona como en el código anterior lo estamos creando como un
objeto anónimo, es decir sin asignar el objeto a una variable de tipo referencia, desde la
47
cuál poder referirnos al objeto y poder llamar a sus métodos y atributo, por ello lo más
habitual sería asignar el objeto a una variable como en:
Persona p = new Persona();
Veamos ahora que tipos de datos básicos existen en el lenguaje y sus características
Java define ocho tipos de datos primitivos y uno especial. Se pueden agrupar en: lógicos,
textuales, integrales y de punto flotante.
El tipo de dato boolean sólo tiene dos valores: false y true. En C/C++ se permite que
valores numéricos sean interpretados como valores lógicos, pero no es el caso de Java; sólo
se permiten valores lógicos.
El tipo String, que no es primitivo, es usado para representar secuencias de caracteres. Una
cadena de caracteres se encierra entre comillas.
"Esto es un mensaje"
Los tipos integrales son: byte, short, int y long. Todos son números con signo. Los números
se pueden representar en forma decimal, octal o hexadecimal.
Para especificar un valor long se debe poner L al final del número. Se puede usar l o L,
pero en minúscula se puede confundir con el número 1 en algunos casos.
A continuación, se presenta una tabla con los cuatro tipos de datos. La representación del
48
rango es definida por la especificación del lenguaje como un complemento a dos y es
independiente de la plataforma.
Los tipos de dato para número de punto flotante son: float y double. Un valor en punto
flotante puede incluir el punto decimal, una parte exponente (letra E), o es seguido por la
letra F (float) o la letra D (double).
Tamaño Tipo
32 bits float
64 bits double
En Java, todos los valores de punto flotante son double, a menos que se indique
explícitamente que sean float. Por lo tanto, en los ejemplos anteriores:
49
Podemos usar la siguiente tabla como resumen para recordar los usos, pero una vez se
asimilan los conceptos es muy fácil de recordar.
Clase Paquete Subclases Subclases Otros
(Mismo (Diferente
paquete) paquete)
private X
default (Sin X X
especificar)
protected X X X X
public X X X X X
1.3 Métodos
Cuando se llama a un método, el control del programa se transfiere al método.
Cuando el método finaliza, el control se transfiere de vuelta a quién lo llama, y la ejecución
se reanuda con la línea de código que sigue a la llamada.
Cuando un método usa una variable de instancia que está definida por su clase, lo hace
directamente, sin referencia explícita a un objeto y sin el uso del operador de punto.
Esto es fácil de entender si lo piensas mejor.
Un método siempre se invoca en relación con algún objeto de su clase. Una vez que se ha
producido esta invocación, se conoce el objeto. Por lo tanto, dentro de un método, no hay
necesidad de especificar el objeto por segunda vez.
Ejemplo de Métodos
/* Un programa que usa la clase Vehiculo
*/
class Vehiculo {
int pasajeros; //números de pasajeros
int capacidad; //capacidad del combustible en galones
int mpg; //combustible consumido en millas por galon
}
//Esta clase declara un objeto de tipo Vehiculo
class DemoVehiculo {
public static void main(String[] args) {
Vehiculo minivan = new Vehiculo();
int rango;
//asignando valores a los campos de minivan
minivan.pasajeros = 9;
minivan.capacidad = 15;
minivan.mpg = 20;
50
//Calcular el rango asumiendo un tanque lleno
rango = minivan.capacidad * minivan.mpg;
System.out.println("La Minivan puede llevar " + minivan.pasajeros + "
pasajeros con un rango de " + rango + " millas");
}
}
Retorno de un Método
Una cuando usa métodos con la palabra void (aquellos que no devuelven un valor) y
otra para devolver valores. Veremos la primera forma y luego pasaremos a retornar
valores.
Cuando se ejecuta esta instrucción, el control del programa regresa a quién lo llama,
omitiendo cualquier código restante en el cuerpo del método. Por ejemplo, considere este
método:
public void miMetodo(){
int i;
for (i=0; i<10; i++){
if (i == 5) return; //Se detiene antes de llegar a 5
System.out.println(i);
}
}
Aquí, el bucle for solo se ejecutará de 0 a 5, porque una vez que sea igual a 5, el
método retornará (Ojo, no devuelve sino que finaliza).. Es permisible tener múltiples
instrucciones return en un método, especialmente cuando hay dos o más rutas fuera de él.
Por ejemplo:
void miMetodo(){
// ...
if (hecho) return;
// ...
if (error) return;
51
// ...
}
Aquí, el método retorna si está hecho o si ocurre un error. Tenga cuidado, sin embargo,
porque tener demasiados puntos de salida en un método puede desestructurar tu código; así
que evita usarlos casualmente. Un método bien diseñado tiene puntos de salida bien
definidos.
Recuerde: un método void puede retornar (regresa a quién lo llama) de una de las dos
maneras: cuando alcanza su llave de cierre, o cuando se ejecuta una declaración return.
1.4 Constructores
Los constructores de una clase son fragmentos de código que sirven para inicializar un
objeto a un estado determinado. Una clase puede carecer de constructor, pero esto no es lo
más habitual. Normalmente todas nuestras clases llevarán constructor. En un constructor es
frecuente usar un esquema de este tipo:
public MismoNombreQueLaClase (tipo parámetro1, tipo parámetro2 …,
tipo parámetro n ) {
campo1 = valor o parámetro;
campo2 = valor o parámetro;
.
.
.
campo n = valor o parámetro;
}
Los constructores tienen el mismo nombre que la clase en la que son definidos y nunca
tienen tipo de retorno, ni especificado ni void.
Tenemos aquí un aspecto que nos permite diferenciar constructores de métodos: un
constructor nunca tiene tipo de retorno mientras que un método siempre lo tiene.
Es recomendable que en un constructor se inicialicen todos los atributos de la clase aunque
su valor vaya a ser nulo o vacío.
- Si un atributo se quiere inicializar a cero (valores numéricos) siempre lo
declararemos específicamente: nombreAtributo = 0;.
- Si un atributo se quiere inicializar a contenido nulo (atributos que son objetos)
siempre lo declararemos específicamente: nombreAtributo = null;.
- Si un atributo tipo texto se quiere inicializar vacío siempre lo declararemos
específicamente: nombreAtributo = “”;.
El motivo para actuar de esta manera es que declarando los atributos como nulos o vacíos,
dejamos claro que esa es nuestra decisión como programadores. Si dejamos de incluir uno o
varios campos en el constructor puede quedar la duda de si hemos olvidado inicializar ese
campo o inducir a pensar que trabajamos con malas prácticas de programación.
52
Un constructor puede:
Ejemplo:
public class Taxi { //El nombre de la clase
matricula = valorMatricula;
distrito = valorDistrito;
tipoMotor = valorTipoMotor;
53
método
} //
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.*;
A partir de J2SE 5.0 en adelante podemos “importar estáticamente”, con esto podemos
referenciar un valor estático sin escribir el nombre de la clase a la cual pertenece y así
reducir nuestro código, un ejemplo seria:
Tenemos una clase de constantes numéricas en el paquete matematicas.numeros:
package matematicas.numeros;
Ahora imprimiremos por pantalla todos los valores accediendo a ellos importando
normalmente la clase Numero:
package mipaquete;
import matematicas.numeros.Numero;
54
class MiClase {
Pero haciendo un static import de la clase Numero el código nos quedaría así:
package mipaquete;
class MiClase {
En el caso anterior usamos el comodín “*” para importar todo el contenido estático de la
clase Numero, pero también podríamos importar directamente cada valor:
...
import static matematicas.numeros.Numero.CERO;
import static matematicas.numeros.Numero.UNO;
import static matematicas.numeros.Numero.DOS;
import static matematicas.numeros.Numero.TRES; //... y asi
sucesivamente...
...
Como podemos ver la forma en la que funcionan los imports normales es igual a los static
imports, mientras que en el primero importamos para no tener que especificar la ubicación
(el paquete) de la clase cada vez que queremos usarla en el segundo importamos
estáticamente para no tener que especificar la clase a la cual pertenece el valor que
queremos usar.
Los static imports pueden ayudarnos a tener un código más simple y conciso si son usados
55
debidamente, ya que su abuso podría también confundirnos en el aspecto de no saber de
qué clase provienen los valores dejándonos un código ambiguo. Sun Microsystems
recomienda usarlos en forma equilibrada por ejemplo cuando se necesita de acceso
constante a valores estáticos de una o dos clases.
Palabras reservadas
Las siguientes palabras no se pueden utilizar como identificadores
2. Herencia y polimorfismo
Herencia en la programación orientada a objetos es la habilidad de extender una
funcionalidad existente definiendo una nueva clase que hereda funcionalidad de una clase
existente. Lo cual nos ahorrara mucho tiempo a los programadores.
Si contamos con una clase que se acerca a lo que necesitamos; no es necesario crear una
clase desde cero. Podemos aprovecharla y extenderla para crear nuestra nueva clase. Esta
nueva clase se llamará subclase y la clase que ya teníamos se llamara superclase.
La subclase heredara todos los atributos y los métodos que fueron definidos en la clase
padre.
Si necesitamos cambiar algún método, se puede sobrescribir el comportamiento en nuestra
subclase; utilizando el mismo nombre y los mismos argumentos del método que se
encuentra en la subclase. O bien si se requiere crear un nuevo método lo podemos incluir en
nuestra subclase.
Una clase puede heredar atributos por dos superclases (clases padres). La herencia múltiple
puede ser usada para agrupar atributos y métodos de distintas clases en una sola.
56
Por ejemplo, imaginemos que estamos haciendo el análisis de un Sistema para una tienda
que vende comida para aves.
En general, podemos tener una gran jerarquía de Clases tal y como vemos en el siguiente gráfico:
Ejemplos:
Teniendo la clase Vehiculo como super clase, heredar de ella a una clase llamada Coche.
// atributos
private int color;
private int numSerie;
/**
* Obtener el numero de serie
57
*/
public int numSerie()
{
return numSerie;
}
/**
* Obtener el color
*/
public int color()
{
return color;
}
/**
* Cambiar el numero de serie
*/
public void cambiaNumSerie(int numSerie)
{
this.numSerie=numSerie;
}
/**
* Pintar el vehículo de un color
*/
public void pinta(int nuevoColor)
{
color = nuevoColor;
}
}
public class Coche extends Vehículo
{
// cilindrada del coche
private int cilindrada;
/** Obtiene la cilindrada del coche */
public int cilindrada(){
return cilindrada;
}
/** Cambia la cilindrada del coche */
public void cambiaCilindrada(int nuevaCilin) {
this.cilindrada=nuevaCilin;
}
}
La diferencia entre herencia y polimorfismo es que herencia está relacionada con clases y
polimorfismo con métodos.
58
Existen funciones con el mismo nombre pero se usan diferentes parámetros (nombre o
tipo). Se selecciona el método dependiendo del tipo de datos que se mande.
-Inclusión:
Es cuando se puede llamar a un método sin tener que conocer su tipo, así no se toma en
cuenta los detalles de las clases especializadas, utilizando una interfaz común.
Agreguemos a la clase los atributos de persona (en este caso seleccionaremos dos
atributos):
Ahora vamos a crear una clase que emplearemos única y exclusivamente para que tenga la
59
función main, y así poder escribir código que queremos ejecutar. Llamaremos a dicha clase
Arranque, por tanto:
en el cuál declaramos una variable de tipo Persona y la damos el valor de un nuevo objeto
de la clase Persona, en la segunda línea asignamos al atributo nombre del objeto per1 el
valor Luis, y en la tercera línea mostramos por pantalla (gracias al método
System.out.println) el valor de dicha variable. La segunda y tercera líneas están
comentadas, debido a que el atributo nombre está definido como privado en la clase
Persona.
Ejercicios:
2. Define una clase Bombero considerando los siguientes atributos de clase: nombre
(String), apellidos (String), edad (int), casado (boolean), especialista (boolean).
Define un constructor que reciba los parámetros necesarios para la inicialización y
los métodos para poder establecer y obtener los valores de los atributos. Compila el
código para comprobar que no presenta errores, crea un objeto y comprueba que se
inicializa correctamente consultando el valor de sus atributos después de haber
creado el objeto.
60
metodo de la clase padre.
4. Crear una clase Animal con el atributo especie, con un metodo que imprima el
mensaje “soy una animal de la especie”, luego crear dos clases hijas perro y gato
con el atributo de nombre y consumir el metodo de la clase padre
El lenguaje de programación Java tiene varios operadores aritméticos para los datos
numéricos enteros y reales. En la siguiente tabla se resumen los operadores aritméticos.
61
El resultado exacto depende de los tipos de operando involucrados. Es conveniente tener en
cuenta las siguientes peculiaridades:
- El resultado es de tipo long si, al menos, uno de los operandos es de tipo long y
ninguno
es real (float o double).
- El resultado es de tipo int si ninguno de los operandos es de tipo long y tampoco es
real
(float o double).
- El resultado es de tipo double si, al menos, uno de los operandos es de tipo double.
- El resultado es de tipo float si, al menos, uno de los operandos es de tipo float y
ninguno es double.
- El formato empleado para la representación de datos enteros es el complemento a
dos. En la aritmética entera no se producen nunca desbordamientos (overflow)
aunque el resultado sobrepase el intervalo de representación (int o long).
- La división entera se trunca hacia 0. La división o el resto de dividir por cero es una
operación válida que genera una excepción ArithmeticException que puede dar
lugar a un error de ejecución y la consiguiente interrupción de la ejecución del
programa.
- La aritmética real (en coma flotante) puede desbordar al infinito (demasiado grande,
overflow) o hacia cero (demasiado pequeño, underflow).
- El resultado de una expresión inválida, por ejemplo, dividir infinito por infinito, no
genera una excepción ni un error de ejecución: es un valor NaN (Not a Number).
Los operadores aritméticos incrementales son operadores unarios (un único operando). El
operando puede ser numérico o de tipo char y el resultado es del mismo tipo que el
operando. Estos operadores pueden emplearse de dos formas dependiendo de su posición
con respecto al operando. En la siguiente tabla se resume los operadores aritméticos
incrementales.
62
Estos operadores suelen sustituir a veces al operador asignación y también suelen aparecer
en bucles for.
En el caso de los operadores aritméticos pueden tener operandos numéricos enteros o reales
y el tipo específico de resultado numérico dependerá del tipo de éstos. En la siguiente se
resumen los diferentes operadores aritméticos combinados.
Tenemos también los operadores de relación que realizan comparaciones entre datos
compatibles de tipos primitivos (numéricos, carácter y booleanos) teniendo siempre un
resultado booleano. Los operandos booleanos sólo pueden emplear los operadores de
igualdad y desigualdad. En la siguiente tabla se resumen los diferentes operadores de esta
categoría.
Todos los valores numéricos que se comparan con NaN dan como resultado false excepto el
operador != que devuelve true. Esto ocurre incluso si ambos valores son NaN.
63
La sentencia de asignación:
valor = (expresionLogica ? expresion_1 : expresion_2);
como se verá más adelante es equivalente a:
if (expresionLogica)
valor = expresion_1;
else
valor = expresion_2
64
3.2 Condicionales
Las estructuras condicionales nos permiten ejecutar una serie de instrucciones si cumple
una determinada condición que nosotros le indiquemos. Es importante recordar que la
condición debe dar un resultado booleano, por lo que lo más normal es usar operadores
relacionales y condicionales.
65
sintaxis es: if (condición){ instrucciones }
Por ejemplo:
int precio=300;
if (precio>100){
System.out.println("El precio es mayor que 100");
}
}
Donde colocamos la condición, podemos colocar una variable booleana, ya que su valor
puede ser true o false.
if – else: es como el anterior solo que después de cerrarse la llave de if, se añade
else sin indicarle ninguna condición. Esto sirve para que si la condicióndel if no es
verdadera, ejecute otras instrucciones que estarán dentro de else. Se suele traducir
como “Si se cumple esta condición haz esto y sino haz esto”.
Veamos un ejemplo:
int precio=50;
if (precio>100){
System.out.println("El precio es mayor que 100");
}else{
System.out.println("El precio es menor que 100");
}
}
Veamos un ejemplo:
66
public class PruebaApp {
int precio=50;
if (precio>100){
System.out.println("El precio es mayor que 100");
}else if(precio>80){
System.out.println("El precio es mayor que 80");
}else{
System.out.println("El precio es menor que 80");
}
}
}
int precio=50;
if (precio>100){
System.out.println("El precio es mayor que 100");
}else {
if(precio>80){
System.out.println("El precio es mayor que 80");
}else{
System.out.println("El precio es menor que 80");
}
}
}
}
Switch: esta estructura condicional de selección múltiple, le damos un valor (puede ser
una variable) y una lista de casos y si cumple alguno de los casos ejecuta las instrucciones
asociadas a ella, en caso de que ninguna sea podemos indicarle que hace por defecto,
normalmente se usa para indicar de un error con un mensaje. Su sintaxis es:
switch (valor){
case caso1:
Instrucciones
break;
case caso2:
Instrucciones
break;
case caso N:
Instrucciones
break;
default:
Instrucciones
}
67
Veamos un ejemplo:
String dia="Lunes";
switch (dia){
case "Lunes":
System.out.println("Hoy es "+dia);
break;
case "Martes":
System.out.println("Hoy es "+dia);
break;
case "Miercoles":
System.out.println("Hoy es "+dia);
break;
case "Jueves":
System.out.println("Hoy es "+dia);
break;
case "Viernes":
System.out.println("Hoy es "+dia);
break;
case "Sabado":
System.out.println("Hoy es "+dia);
break;
case "Domingo":
System.out.println("Hoy es "+dia);
break;
default:
System.out.println("No has introducido un dia correcto");
}
}
}
Como vemos en el caso anterior, como los valores son String debemos poner dobles
comillas a los casos. En caso de que sean números, se pondrán como tal, también
podríamos usar constantes.
Una cosa más, si haya varios casos que tienen ejecuta las mismas instrucciones, podemos
agruparlas. Veamos un ejemplo:
import javax.swing.JOptionPane;
public class PruebaApp {
68
switch(dia){
case "lunes":
case "martes":
case "miercoles":
case "jueves":
case "viernes":
System.out.println("Es un dia laboral");
break;
case "sabado":
case "domingo":
System.out.println("Es un dia festivo");
default:
System.out.println("Introduce un dia de la semana");
}
}
}
3.3 Bucles
Un bucle en lenguajes de programación es una característica que facilita la ejecución de un
conjunto de instrucciones/funciones repetidamente, mientras que algunas condiciones se
evalúan como verdaderas.
Java proporciona tres formas de ejecutar los bucles. Si bien todas las formas proporcionan
una funcionalidad básica similar, difieren en su sintaxis y el tiempo de comprobación de la
condición. Veamos las 3 formas:
WHILE
Un bucle while es una sentencia de control de flujo que permite que el código se ejecute
repetidamente en función de una condición booleana dada. El bucle while se puede
considerar como una instrucción if repetitiva.
Sintaxis:
69
El while comienza con la verificación de la condición. Si se evalúa como verdadero, las
instrucciones del cuerpo del bucle se ejecutan; de lo contrario, se ejecuta la primera instrucción
que le sigue al bucle. Por esta razón, también se llama bucle de control de entrada.
Una vez que la condición se evalúa como verdadera, se ejecutan las instrucciones en el cuerpo
del bucle.
Normalmente, las declaraciones contienen un valor de actualización para la variable que se
procesa para la siguiente iteración.
Cuando la condición se vuelve falsa, el ciclo finaliza y marca el final de su ciclo de vida.
Ejemplo
class whileLoopDemo
int x = 1;
while (x <= 4)
70
{
x++;
Salida
Valor de x: 1
Valor de x: 2
Valor de x: 3
Valor de x: 4
FOR
El bucle for proporciona una forma concisa de escribir la estructura de bucle. A diferencia
de un ciclo while, una sentencia for consume la inicialización, la condición y el
incremento/decremento en una línea, proporcionando así una estructura de bucle más corta
y fácil de depurar.
Sintaxis:
incremento / decremento)
declaracion(es)
71
Condición de inicialización: Aquí, inicializamos la variable en uso. Marca el inicio de un
ciclo for. Se puede usar una variable ya declarada o se puede declarar una variable, solo local
para el bucle.
Condición de prueba: se usa para probar la condición de salida de un bucle. Debe devolver un
valor booleano. También es un bucle de control de entrada cuando se verifica la condición
antes de la ejecución de las instrucciones de bucle.
Ejecución de instrucción: una vez que la condición se evalúa como verdadera, se ejecutan las
instrucciones en el cuerpo del bucle.
Terminación de bucle: cuando la condición se vuelve falsa, el bucle termina marcando el final
de su ciclo de vida.
Ejemplo
class forLoopDemo
72
{
Salida
Valor de x: 2
Valor de x: 3
Valor de x: 4
FOR EACH
Java también incluye otra versión del bucle for introducido en Java 5. La mejora del
bucle for proporciona una forma más sencilla de iterar a través de los elementos de una
colección o matriz. Es inflexible y debe usarse solo cuando existe la necesidad de recorrer
los elementos de forma secuencial sin conocer el índice del elemento procesado
actualmente.
Tomemos un ejemplo para demostrar cómo se puede utilizar “for each” para simplificar el
trabajo. Supongamos que hay una matriz de nombres y queremos imprimir todos los
nombres en esa matriz. Veamos la diferencia con estos dos ejemplos:
73
for (String x:array)
{
System.out.println(x);
}
Salida
Ron
Harry
Hermoine
DO WHILE
El bucle do while es similar al while con la única diferencia de que comprueba la condición
después de ejecutar las instrucciones, y por lo tanto es un ejemplo de Exit Control Loop (Salir
del bloque de control).
74
vida.
Es importante tener en cuenta que el bucle do-while ejecutará sus declaraciones al
menos una vez antes de que se verifique cualquier condición, y por lo tanto es un
ejemplo de bucle de control de salida.
Ejemplo
class dowhileloopDemo
{
public static void main(String args[])
{
int x = 21;
do
{
//El código dentro del do se imprime incluso
//si la condición es falsa
System.out.println("Valor de x :" + x);
x++;
}
while (x < 20);
}
}
Salida
Valor de x: 21
Otro inconveniente es que puede estar agregando algo en su objeto de colección a través de
75
un bucle y puede quedarse sin memoria. Si intenta ejecutar el siguiente programa, después
de un tiempo, se producirá una excepción de falta de memoria.
import java.util.ArrayList;
public class Integer1
{
public static void main(String[] args)
{
ArrayList<Integer> ar = new ArrayList<>();
for (int i = 0; i < Integer.MAX_VALUE; i++)
{
ar.add(i);
}
}
}
Salida
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.util.Arrays.copyOf(Unknown Source)
at java.util.ArrayList.grow(Unknown Source)
at java.util.ArrayList.ensureCapacityInternal(Unknown Source)
at java.util.ArrayList.add(Unknown Source)
at article.Integer1.main(Integer1.java:9)
76
Salida esperada por pantalla del programa anterior:
*Operandos enteros: i = 7 ; j = 3
Operador suma: i + j = 10
Operador resta: i - j = 4
Operador producto: i * j = 21
Operador division: i / j = 2
Operador resto: i % j = 1
*Operandos reales: a = 12.5 ; b = 4.3
Operador suma: a + b = 16.8
Operador resta: a - b = 8.2
Operador producto: a * b = 53.75
Operador division: a / b = 2.906976744186047
Operador resto: a % b = 3.9000000000000004
/**
* Demostracion de los operadores incrementales
*/
class opIncrementales {
public static void main(String[] args) {
int i,j; // Variables enteras. Podrian ser reales o char
i = 7;
System.out.println("* Operando entero: i = " + i + ";");
System.out.println(" Operador ++: j = i++; ");
j = i++;
System.out.println(" // i vale " + i + "; j vale " + j);
i = 7;
System.out.println(" i = " + i + ";");
System.out.println(" j = ++i; ");
j = ++i;
System.out.println(" // i vale " + i + "; j vale " + j);
i = 7;
System.out.println("* Operando entero: i = " + i + ";");
System.out.println(" Operador --: j = i--; ");
j = i--;
System.out.println(" // i vale " + i + "; j vale " + j);
i = 7;
System.out.println(" i = " + i + ";");
System.out.println(" j = --i; ");
j = --i;
System.out.println(" // i vale " + i + "; j vale " + j);
}
}
77
// i vale 8; j vale 8
* Operando entero: i = 7;
Operador --: j = i--;
// i vale 6; j vale 7
i = 7;
j = --i;
// i vale 6; j vale 6
*/
public class OpCombinados {
public static void main(String[] args) {
int i,j; // Variables enteras. Podrian ser reales
i = 7;
j = 3;
System.out.println("* Operandos enteros: i = "+ i +" ; j = "+ j);
i += j;
System.out.println(" Suma combinada: i += j " + " // i vale " + i);
i = 7;
i -= j;
System.out.println(" Resta combinada: i -= j " + " // i vale " + i);
i = 7;
i *= j;
System.out.println(" Producto combinado: i *= j " + " // i vale " + i);
i = 7;
i /= j;
System.out.println(" Division combinada: i /= j " + " // i vale " + i);
i = 7;
i %= j;
System.out.println(" Resto combinada: i %= j " + " // i vale " + i);
}
}
78
System.out.println(" true | false es : " + (true | false));
System.out.println(" true | true es : " + (true | true));
System.out.println("Producto: false & false es : " + (false & false));
System.out.println(" false & true es : " + (false & true));
System.out.println(" true & false es : " + (true & false));
System.out.println(" true & true es : " + (true & true));
}
}
79
6. Programa que emplea el operador condicional:
/**
* Demostracion del operador condicional
*
*/
public class opCondicional {
public static void main(String[] args) {
int i,j,k;
i = 1;
j = 2;
k = i > j ? 2*i : 3*j+1;
System.out.println("i = " + i);
System.out.println("j = " + j);
System.out.println("k = " + k);
i = 2;
j = 1;
k = i > j ? 2*i : 3*j+1;
System.out.println("i = " + i);
System.out.println("j = " + j);
System.out.println("k = " + k);
}
}
11. Leer números hasta que se introduzca un 0. Para cada uno indicar si es par o
impar.
12. Realizar un juego para adivinar un número. Para ello pedir un número N, y
luego ir pidiendo números indicando “mayor” o “menor” según sea mayor o
menor con respecto a N. El proceso termina cuando el usuario acierta.
80
6. Arreglos
Se pueden declarar arreglos de cualquier tipo de dato:
char
letras[];
Point
punto[];
char [] letras;
Ambas declaraciones son válidas, pero la segunda tiene la ventaja de que, si se declaran
más arreglos, sólo basta con poner el nombre de cada arreglo:
por:
letras = new
char[20]; punto =
new Point[100];
La primera línea crea un arreglo de 20 valores char. La segunda línea crea un arreglo de
100 variables de tipo Point, que es un objeto. Sin embargo, no crea los 100 objetos Point.
Se tiene que crear separadamente cada objeto:
punto[0] = new
Point(); punto[1] =
new Point();
punto[2] = new
Point();
...
Cuando se crea un arreglo, cada elemento es inicializado. En el caso del arreglo letras de
tipo char, cada valor es inicializado al carácter nulo (\u0000). En el caso del arreglo punto,
cada valor fue inicializado a null, indicando que no hay referencia al objeto Point. Después
de la asignación punto[0] = new Point(), el primer elemento del arreglo se refiere a un
81
objeto Point.
Java permite una manera fácil de crear arreglos con valores iniciales:
String nombres[];
nombres = new
String[3]; nombres[0]
= "Juan"; nombres[1]
= "Pedro"; nombres[2]
= "Luis";
Esta forma se puede aplicar tanto a tipos de datos primitivos como a objetos, por ejemplo:
Primero se declara un arreglo de arreglos de int. Luego se crea el arreglo con cuatro
arreglos de int. Finalmente, se crea cada arreglo con cinco valores int.
Debido a que no hay arreglos multidimensionales, se pueden crear arreglos de arreglos no-
rectangulares, por ejemplo:
dosDim[0] = new
int[2]; dosDim[1] =
new int[5];
dosDim[2] = new
int[8];
82
4.2 Control del tamaño del arreglo
En Java todos los índices de los arreglos empiezan en cero. El número de elementos en un
arreglo es almacenado como parte del objeto arreglo. El valor es usado para realizar
evaluaciones de límite en todos los accesos en tiempo de ejecución. Si hay un acceso fuera
del límite del arreglo, se crea una excepción.
lista[x] = x;
El límite del ciclo se determina por la comparación con lista.length, en vez de comparar
directamente contra el valor 10. Esto es más robusto cuando se trata de dar mantenimiento
al programa.
De esta manera, se pierden los seis valores del arreglo elementos, a menos que se hayan
almacenado en otro lugar. Java provee un método en la clase System para copiar arreglos.
Este método es arraycopy(). Por ejemplo:
// arreglo original
// arreglo destino
En este punto, el arreglo más números, tiene los siguientes valores: 1,2,3,4,5,6,4,3,2,1.
83
Ejemplo de arreglos:
import
java.io.*;
import
java.lang.*;
thisArray = thirdArray;
System.out.print("thisArray ");
System.out.println("");
84
}
System.out.print("thisArray ");
{ // presenta el contenido de
thisArray
System.out.print(thisArray[x]+" ");
System.out.println("");
thatArray = thisArray;
System.out.println("thatArray ");
{ // presenta el contenido de
thatArray
System.out.print(thatArray[x]+" ");
System.out.println("");
System.out.println("thatArray ");
{ // presenta el contenido de
thatArray
System.out.print(thatArray[x]+" ");
System.out.println("");
thatArray = fourthArray;
System.out.println("thatArray
");
85
for(int x = 0; x < thatArray.length; x++)
{ // presenta el contenido de
thatArray
System.out.print(thatArray[x]+" ");
System.out.println("");
System.out.println("fourthArray
");
{ // presenta el contenido de
fourthArray
System.out.print(fourthArray[x]+" ");
System.out.println("");
System.arraycopy(thisArray,0,thatArray,0,thisArray.length);
{ // presenta el contenido de
thatArray
System.out.print(thatArray[x]+" ");
System.out.println("");
{ // cambiar valores de
thatArray thatArray[x] = 29;
System.out.println("thisArray ");
System.out.println("");
System.out.println("thatArray
");
{ // y de thatArray
System.out.print(thatArray[x]+"
86
");
System.out.println("");
87
MODULO III
1. Clases útiles
La clase objeto es la cima de todas las clases en java. De ella derivan todas las clases, por lo
tanto todas heredan sus métodos.
Observe dos métodos ahora: equals() y toString(). El método equals() compara dos objetos.
Devuelve true si los objetos son equivalentes, y false de lo contrario. El
método toString() devuelve una cadena que contiene una descripción del objeto al que se
88
llama. Además, este método se invoca automáticamente cuando se genera un objeto
utilizando println().
String cuenta con varios contructores (15) el que siempre usamos es:
public String(String original)
Que crea un objeto string con la misma secuencia de caracteres que cuenta en sus
parámetros
Además, cuenta con más de 60 métodos que hereda de object, no hay que saberlos de
memoria simplemente recurrir a la especificación api de java. Lo más útil e interesante de
los objetos son sus atributos y métodos para poder usarlos y hacer que el código haga algo.
Métodos String
Ejemplo
89
public static void main(String[] args) {
String str = "El hombre que se levanta es aun más grande que el
que no ha caído. ";
out.println(str.replace('a', 'x'));
out.println(strn.replaceAll("alto", "bajo"));
out.println(str.substring(5, 20));
out.println(str.toUpperCase());
90
out.print("\nEl segundo String transformado en minúsuculas es:
");
out.println(strn.toLowerCase());
91
Ejemplo:
import java.lang.Math.*;
public class Ejemplo{
public static void main(String[ ]args){
System.out.println( Math.round(3.8) );
}
}
import java.lang.Math.*;
System.out.println( Math.min(8,3) );
System.out.println( Math.max(8,3) );
92
}
El resultado para min() será 3, y el resultado para max() sera 8. Los números se pueden
sustituir por variables.
import java.lang.Math.*;
Aquí, lo que le hemos indicado es que nos muestre por consola un numero aleatorio
comprendido entre el 0 y el 30. Cada vez que ejecutaras el programa, te mostrara un
numero diferente comprendido entre los números 0 y el 30.
93
3. Excepciones
En Java, la clase Exception define condiciones de error leves que los programas pueden
encontrar. En vez de dejar que el programa termine, el programador puede escribir código
para manejar esas excepciones y continuar con la ejecución del programa.
Java implanta el estilo de C++ de las excepciones para construir código flexible. Cuando
ocurre un error en el programa, el código que encuentra el error "lanza" una excepción.
Este proceso de lanzar una excepción indica al proceso actual en ejecución que ha ocurrido
un error. El programador puede atrapar la excepción y, cuando sea posible, recuperar el
control del programa.
Ejemplo
"HOLA MUNDO!"};
while(i < 4)
{
System.out.println(saludo
s[i]); i++;
}
}
}
$java
94
HelloWorld2
Hola mundo!
java.lang.ArrayIndexOutOfBoundsExcept
ion: 3 at
HelloWorld.main(HelloWorld.java)
:12)
Como se ve, la importancia de manejar las excepciones es poder escribir código para
atrapar las excepciones, manejarlas, y continuar con la ejecución del programa.
try
{
// código que puede lanzar una excepción en particular
}
catch(ExceptionType e)
{
// código a ejecutar si ExceptionType es lanzada
La palabra finally sirve para definir el bloque de código que se ejecutara siempre, sin
importar si la excepción fue atrapada o no.
try
{
...
}
catch(Exception e)
{
...
}
95
finally
{
// esto se ejecuta aunque no se atrape la excepción
"HOLA MUNDO!"};
while(i < 4)
{
try
{
System.out.println(saludos[i]);
}
catch(ArrayOutOfBoundsException e)
{
System.out.println("Ha ocurrido la excepción: "+e.toString());
}
finally
{
System.out.println("Esto siempre se ejecutara");
}
i
+
+
;
96
}
Hay dos cosas que el programador puede hacer para cumplir este requisito: el primero es
usar el bloque try{}catch(){} donde se va a usar una subclase de Exception, aunque el
bloque catch quede vacío; la segunda, es indicar que la excepción no es manejada en este
método, y que por lo tanto será lanzada al método que hace la llamada. Esto se hace
indicando la declaración del método como sigue:
Después de la palabra reservada throws va una lista de todas las excepciones que pueden
ser lanzadas por el método, pero no tratar de manejarla en este lugar. Aunque solamente
una excepción se muestra aquí, una lista separada por comas puede ser usada si hay
múltiples posibles excepciones que no serán manejadas en el método.
97
(CantidadException - Subclase de Exception para crear una excepción. DemoException -
Clase que genera una excepción y la atrapa)
// CantidadException.java
public class CantidadException extends Exception
{
private String
mensaje; private
int cantidad;
this.mensaje=mensaje;
this.cantidad=cantidad
;
}
public String toString()
{
return mensaje+" "+cantidad;
}
//
DemoException.java
import java.lang.*;
import
CantidadException;
}
public void imprimeNumero(int n) throws CantidadException
{
if(n > 10)
{
98
throw new CantidadException("Imposible imprimir el número",n);
}
else
{
System.out.println("x="+n);
}
}
public static void main(String argv[])
{
int x;
for(x=0;x<15;x++)
{
try
{
demo.imprimeNumero(x);
}
catch(CantidadException e)
{
System.out.println(e.toString());
}
}
}
}
99
ArithmeticException
100