resumen java

82
Teresa Sastre Toral Alberto Ruiz Cristina I.S.B.N.: 84-690-3077-9 FUNDAMENTOS DE PROGRAMACIÓN EN JAVA

Upload: javier-infantes-granados

Post on 25-Jul-2015

190 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Resumen Java

Teresa Sastre Toral

Alberto Ruiz Cristina

I.S.B.N.: 84-690-3077-9

FUNDAMENTOS

DE PROGRAMACIÓN

EN JAVA

Page 2: Resumen Java
Page 3: Resumen Java

Fundamentos de Programación en Java

1 INTRODUCCIÓN............................................................................................................................ 1

2 ELEMENTOS BÁSICOS DEL LENGUAJE JAVA..................................................................... 2

2.1 ESTRUCTURA DE UN PROGRAMA EN JAVA ................................................................................. 2 2.2 ELEMENTOS BÁSICOS PARA EMPEZAR A PROGRAMAR................................................................ 3

3 ESTRUCTURAS DE CONTROL DE FLUJO.............................................................................. 6

3.1 OBJETIVOS................................................................................................................................. 6 3.2 ESTRUCTURAS DE SELECCIÓN.................................................................................................... 6

3.2.1 if ........................................................................................................................................... 6 3.2.2 if-else.................................................................................................................................... 6 3.2.3 Operador condicional .......................................................................................................... 7 3.2.4 switch ................................................................................................................................... 7

3.3 ESTRUCTURAS DE REPETICIÓN................................................................................................... 8 3.3.1 while..................................................................................................................................... 8 3.3.2 do-while ............................................................................................................................... 8 3.3.3 for......................................................................................................................................... 9 3.3.4 Ruptura del flujo ................................................................................................................ 10 3.3.5 Manejo de excepciones ...................................................................................................... 10

3.4 PROGRAMA DE EJEMPLO .......................................................................................................... 11

4 CLASES Y OBJETOS (PRIMERA PARTE) .............................................................................. 16

4.1 OBJETIVOS............................................................................................................................... 16 4.2 CLASE...................................................................................................................................... 16

4.2.1 Atributos............................................................................................................................. 17 4.2.2 Métodos.............................................................................................................................. 17 4.2.3 Autorefencia this ................................................................................................................ 18 4.2.4 Método constructor............................................................................................................ 19 4.2.5 Sobrecarga......................................................................................................................... 20

4.3 OBJETOS .................................................................................................................................. 20 4.3.1 Referencias compartidas: alias.......................................................................................... 21

5 CLASES Y OBJETOS (SEGUNDA PARTE).............................................................................. 22

5.1 OBJETIVOS............................................................................................................................... 22 5.2 ELEMENTOS DE CLASE ............................................................................................................. 22 5.3 CLASES PREDEFINIDAS ............................................................................................................ 22 5.4 ÁMBITOS ................................................................................................................................. 22 5.5 PAQUETES ............................................................................................................................... 23 5.6 DERECHOS DE ACCESO ............................................................................................................ 25 5.7 PROGRAMAS DE EJEMPLO ........................................................................................................ 25 5.8 ENUMERADOS.......................................................................................................................... 28

6 ESTRUCTURAS DE ALMACENAMIENTO............................................................................. 30

6.1 OBJETIVOS............................................................................................................................... 30 6.2 COMPARACIÓN ENTRE UN ARRAY Y UN ARRAYLIST................................................................ 30 6.3 ARRAY .................................................................................................................................... 30 6.4 ARRAYLIST ............................................................................................................................. 31 6.5 RECORRIDO DE ESTRUCTURAS ................................................................................................. 32 6.6 CÓDIGO DE EJEMPLO ............................................................................................................... 33

7 COMPOSICIÓN, HERENCIA Y POLIMORFISMO................................................................ 35

7.1 OBJETIVOS............................................................................................................................... 35 7.2 COMPOSICIÓN.......................................................................................................................... 35 7.3 HERENCIA ............................................................................................................................... 36

7.3.1 Compatibilidad de tipos ..................................................................................................... 38 7.3.2 Ámbitos y visibilidad.......................................................................................................... 38

Page 4: Resumen Java

7.3.3 Reescritura......................................................................................................................... 38 7.3.4 Los constructores ............................................................................................................... 38

7.4 TABLA DE COMPATIBILIDAD .................................................................................................... 39 7.5 COMPATIBILIDAD DE TIPOS...................................................................................................... 39 7.6 REESCRITURA Y LIGADURA DINÁMICA .................................................................................... 40 7.7 POLIMORFISMO........................................................................................................................ 41 7.8 CLASES ABSTRACTAS .............................................................................................................. 41

8 EJERCICIOS DE PROGRAMACIÓN EN JAVA...................................................................... 42

8.1 EJEMPLO BÁSICO DE UN PROGRAMA EN JAVA .......................................................................... 42 8.1.1 Solución ............................................................................................................................. 42

8.2 EJERCICIOS SOBRE ESTRUCTURAS DE CONTROL....................................................................... 43 8.2.1 Ejercicio 1.......................................................................................................................... 43 8.2.2 Ejercicio 2.......................................................................................................................... 43 8.2.3 Ejercicio 3.......................................................................................................................... 43 8.2.4 Solución a los ejercicios de estructuras de control del 1 al 3............................................ 43

8.3 EJERCICIOS SOBRE CLASES Y OBJETOS ..................................................................................... 47 8.3.1 Ejercicio 1.......................................................................................................................... 47 8.3.2 Ejercicio 2.......................................................................................................................... 49 8.3.3 Ejercicio 3.......................................................................................................................... 52

8.4 EJERCICIOS SOBRE ESTRUCTURAS DE ALMACENAMIENTO....................................................... 57 8.4.1 Ejercicio 1.......................................................................................................................... 57 8.4.2 Ejercicio 2.......................................................................................................................... 57 8.4.3 Ejercicio 3.......................................................................................................................... 58

8.5 EJERCICIOS DE COMPOSICIÓN, HERENCIA Y POLIMORFISMO..................................................... 59 8.5.1 Ejercicio 1.......................................................................................................................... 59 8.5.2 Ejercicio 2.......................................................................................................................... 63 8.5.3 Ejercicio 3.......................................................................................................................... 64 8.5.4 Ejercicio 4.......................................................................................................................... 67 8.5.5 Ejercicio 6.......................................................................................................................... 69 8.5.6 Ejercicio 7.......................................................................................................................... 73 8.5.7 Ejercicio 8.......................................................................................................................... 75

Page 5: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 1

1 Introducción Este texto pretende ser una iniciación sencilla al lenguaje de programación Java. Se ha concebido como un apoyo para los estudiantes de la asignatura “Fundamentos de Informática” de Ingeniería Industrial en la Universidad Nacional de Educación a Distancia (UNED). Se trata de una asignatura de primer curso, y por tanto nos dirigimos a estudiantes que tienen conocimientos de informática a nivel de usuario pero poca o ninguna experiencia en el mundo de la programación. A lo largo de los siguientes capítulos el estudiante aprenderá gradualmente a diseñar sus programas y programarlos de forma correcta.

El texto combina la explicación de los elementos propios del lenguaje Java con la progresiva incorporación de conceptos teóricos propios del paradigma orientado a objetos. Se trata por tanto de conseguir que el alumno avance paralelamente tanto en el dominio del lenguaje como en la capacidad para diseñar correctamente los programas. El desarrollo equilibrado de ambas habilidades es necesario para lograr una visión global de la programación: este texto pretende ser un apoyo para conseguirlo.

El último apartado, y el más extenso, incluye una colección de ejercicios de programación resueltos que ayudan a practicar y comprobar los avances. Recomendamos estudiar la teoría y los ejercicios simultáneamente.

Para comenzar a trabajar es necesario instalar Java en el ordenador, así como un entorno de desarrollo para compilar los programas de forma cómoda. Se ha incluido un anexo que explica cómo realizar la instalación y presenta un entorno de desarrollo sencillo, llamado JGrasp, que resulta recomendable para que el alumno comience a programar.

Esperamos que este texto sea de utilidad y facilite al alumno el acercamiento al mundo de la programación en Java.

Teresa Sastre Toral y Alberto Ruiz Cristina (profesores de Universidad)

Page 6: Resumen Java

2 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

2 Elementos básicos del lenguaje Java

2.1 Estructura de un programa en Java En Java se llama programa a un conjunto de clases. Una clase es un archivo de extensión “.java” que normalmente describe un concepto, como “Triangulo” o “Alumno”. De momento no entramos en el concepto de clase, que se abordará más adelante.

Una de las clases (archivos) del programa debe tener un método llamado “main”. Un método describe una acción que realiza la clase. Por ejemplo, “calcularArea” podría ser un método de la clase Triangulo, mientras que “obtenerDni” podría ser un método de la clase Persona. De nuevo nos remitimos a capítulos posteriores para ahondar en el concepto de método.

De momento nos quedamos, por tanto, con que el programa más sencillo que podamos escribir estará compuesto por una sola clase, que tendrá un método llamado “main” (principal en inglés) por donde el programa empezará a ejecutar. A continuación se escribe el programa más sencillo que se puede escribir en Java, y que iría escrito en un archivo llamado “Ejemplo.java”:

1 public class Ejemplo 2 { 3 public static void main(String[] args) 4 { 5 System.out.println("Hola"); 6 } 7 }

Los números se han incluido para poder referirnos a cada línea, pero en el programa no se escribirían. Sugerimos al alumno que adquiera una visión general de este programa pero que aún no se preocupe por no comprender los detalles. Los elementos fundamentales que vemos en este programa son:

• Línea 1: formalizamos la clase (“class”) Ejemplo (el nombre debe coincidir con el del archivo, incluidas las mayúsculas y minúsculas).

• Línea 3: declaramos el método “main”.

• Línea 5: aquí vendrían las acciones del programa. En este caso sólo tenemos una acción, que imprime en pantalla el mensaje “Hola”.

Obsérvese que en Java se utilizan las llaves para delimitar los distintos elementos. Así, las llaves de las líneas 2 y 7 delimitan la clase “Ejemplo”, mientras que las llaves más internas de las líneas 4 y 6 delimitan el método “main”.

Es una buena costumbre utilizar los tabuladores para que el programa se lea de forma más sencilla y agradable. Así, cada vez que se abra una llave, conviene escribir las líneas siguientes con una tabulación más que la anterior.

El resto del capítulo tratará de introducir de forma eminentemente práctica los conceptos fundamentales para poder empezar a programar. Recomendamos al alumno que, una vez estudie este capítulo, acuda al anexo para aprender a poner en marcha el entorno de trabajo en su ordenador y trate de reproducir en su máquina los programas de ejemplo que se irán mostrando a continuación.

Page 7: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 3

2.2 Elementos básicos para empezar a programar Ya hemos visto cómo dar forma a un programa de prueba, y cómo imprimir en pantalla un texto. También es posible escribir en pantalla operaciones numéricas:

System.out.println((15 -2 + 7)/2);

Sin embargo, la programación no sería muy útil si siempre fuese necesario utilizar valores numéricos sobre la marcha: lo que nos interesa es poder almacenarlos y volver a ellos cuando lo necesitemos, bien sea para consultarlos o bien para recuperarlos. Es lo que hacemos, de forma muy básica, al pulsar la tecla “Memoria” de nuestra calculadora tradicional.

Surge así el concepto de variable. Al igual que en Matemáticas, las variables son representaciones simbólicas de un valor numérico que puede variar a lo largo de la ejecución del programa.

Sin embargo, en Java vamos un paso más allá y establecemos que las variables no sólo pueden ser números, sino que también pueden contener, por ejemplo, cadenas de texto. Surge así el concepto de tipo de datos. En Matemáticas, cuando decimos “x = 6”, se asume que x es un número. En Java hay que hacerlo explícito:

int x; x = 6;

En la primera línea declaramos la variable, que significa que comunicamos a Java que queremos poder referenciar el nombre “x” y que con él nos referimos a un valor de tipo entero (int viene de Integer). Existe una serie de tipos predefinidos como “int y “double”, y otros adicionales como String, que representa las cadenas de texto. Así, podemos definir variables de otros tipos:

double area = 3.56; String texto = "Este es un texto";

Obsérvese que en la propia línea de declaración también podemos darle valores iniciales con el operador “=”. A eso se le llama asignación. Más adelante se verá que puede haber variables de muchos más tipos.

También podemos definir constantes, indicando mediante la palabra “final” que el valor no puede ser modificado:

final double PI = 3.1416;

Es importante respetar una serie de convenciones de nombres. Es fácil acostumbrarse a hacerlo y redunda en unos programas más sencillos y fáciles de leer. Las reglas básicas son:

• Los tipos predefinidos, variables y métodos se escriben en minúscula, como “int”, “area” y “main”.

• Las constantes se escriben en mayúsculas, como “PI”.

• Las clases se escriben con la inicial en mayúscula, como “Ejemplo”.

Otro elemento interesante son los comentarios. Se trata de texto que Java no interpretará, y que sólo sirve para que nosotros escribamos información sobre el programa que consideremos interesante. Por ejemplo:

Page 8: Resumen Java

4 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

/* Ejemplos de comentarios: */ double area; // representa el area de la figura final double PI = 3.1416; // esta constante es el numero PI

Existen dos tipos de comentarios. El primero se llama comentario de bloque y está delimitado por “/*” y “*/”. Este tipo de comentario puede abarcar varias líneas.

El segundo tipo se llama comentario de línea y sólo afecta al texto que va detrás de los símbolos “//” hasta terminar la línea.

¿Es posible asignar a una variable el valor de otra variable de distinto tipo? La respuesta es sí, pero con precaución. En caso de que no haya pérdida de información, se puede hacer sin problemas:

int i = 6; double d = i;

Así, la variable de tipo “double” puede almacenar sin problemas el valor 6. No ocurre lo mismo al contrario:

double d2 = 4.56; int i2 = d2; // ERROR

En este caso existe pérdida de información, ya que la variable entera podrá almacenar únicamente el valor “4”, perdiendo los decimales. Por ello Java exige que le indiquemos que queremos proceder a pesar del riesgo. Para ello se utiliza la conversión forzada de tipo:

double d2 = 4.56; int i2 = (int) d2; // correcto

Ahora nos atrevemos a hacer un pequeño programa:

double base; double altura; double areaRectangulo; base = 5.4 ; altura = 2.3; areaRectangulo = base * altura ; System.out.println("El área del rectángulo es: " + areaRectangulo) ;

Obsérvese que al escribir por pantalla podemos concatenar valores de texto con valores numéricos o variables, a través del operador “+”. El alumno puede comprobar que al escribir texto entrecomillado, se escribe el texto literalmente, mientras que al escribir el nombre de una variable, se escribe su contenido.

Finalizamos el capítulo de introducción destacando que tanto “2+4*7” como “base*altura” son expresiones numéricas. Existe otro tipo de expresiones, llamadas lógicas, cuyo resultado no es un valor numérico sino un valor lógico: cierto (“true”) o falso (“false”). La utilidad de este tipo de expresiones se verá en el próximo capítulo: de momento basta con aprender a escribirlas. Para ello se utilizan operadores lógicos como “>” (mayor), “<=” (menor o igual), “==” (igual, obsérvese que es distinto del operador de asignación, “=”), o

Page 9: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 5

“!=” (distinto). También se usan los operadores AND (“Y”, representado por “&&”) y OR (“O”, representado por “||”). Por ejemplo, la expresión:

(x>=0)&&(x<5)

sólo será cierta si x es mayor o igual que 0 y además x es menor que 5. Es decir, deben cumplirse ambas condiciones para que la expresión sea cierta. Sin embargo, la expresión

(x<0)||(x>1000)

será cierta si x es negativo o bien si x es mayor que 1000. Es decir, basta que se cumpla una de las condiciones para que el resultado de la expresión sea cierto.

Page 10: Resumen Java

6 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

3 Estructuras de control de flujo

3.1 Objetivos En este capítulo se intentará que el alumno aprenda la utilidad de las sentencias de control de flujo, fundamentales en todo programa. Su misión es impedir que cada vez que ejecutemos un programa se haga exactamente lo mismo, es decir, queremos poder hacer unas cosas u otras distintas en función de determinadas condiciones. Dichas condiciones vendrán expresadas mediante expresiones lógicas.

Existen dos tipos de estructuras de control de flujo:

• Las estructuras de selección permiten ejecutar una u otra porción de código según una determinada condición.

• Las estructuras de repetición permiten ejecutar una misma porción de código repetidas veces, hasta que se cumpla una determinada condición.

3.2 Estructuras de selección Este tipo de estructuras permite ramificar el flujo de ejecución temporalmente según se cumpla o no se cumpla una condición lógica. Hay diferentes modalidades, que se estudian a continuación. En todas ellas, tras las posibles ramificaciones, el flujo se vuleve a reunir.

3.2.1 if Si se cumple una condición, se ejecuta una serie de sentencias. Si no se cumplen, el programa las salta y continúa.

Sintaxis en java:

if (condición) { sentencias; }

3.2.2 if-else Si se cumple una condición, se ejecuta una serie de sentencias. Si no se cumplen, se ejecuta otro conjunto de sentencias.

condición

sentencias

true

false

Page 11: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 7

Sintaxis en java:

if (condición) { sentencias; } else { sentencias; }

3.2.3 Operador condicional Se trata de una reescritura resumida del if-else. No se usa habitualmente.

Sintaxis en java:

expresión booleana ? expresión1 : expresión2

3.2.4 switch Es una estructura que puede parecer compleja en un principio, pero es realmente sencilla. Está indicada para casos en que no hay una o dos alternativas, sino más. Funciona de la siguiente manera: se parte de un número entero y, según su valor, se salta a una u otra rama. Existe una última rama especial (su aparición es opcional) llamada “default”, que se ejecuta si el número no coincide con ninguno de los valores previstos por el programador.

Es fácil caer en la tentación de pensar que si el valor de la expresión entera es “2” y tenemos una rama etiquetada como “case 2:”, sólo se ejecutará dicha rama, y el flujo continuará después tras la sentencia “switch”. Sin embargo, esto sólo es así si incluimos la sentencia “break;” después de cada rama. De lo contrario, después de la rama correspondiente al “2”, se ejecutará la del 3, y después todas las siguientes, incluida la rama “default”, que es la última. De lo anterior se deduce que después de la rama “default” no es necesario poner “break”, puesto que ya no hay nada después.

Esto parece bastante incómodo, pero se ha planteado así porque a veces resulta interesante (ver programa de ejemplo).

condición

sentencias 2

truefalse

sentencias 1

Page 12: Resumen Java

8 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

Sintaxis en java:

switch (expresión) { case valor1: sentencias; break; case valor2: sentencias; // ¡cuidado con el break! case valor3: sentencias; break; default: sentencias; }

3.3 Estructuras de repetición Este tipo de estructuras se usa cuando queremos que una sentencia o conjunto de sentencias se ejecuten varias veces. Todas se basan en el cumplimiento de una condición, de forma que existe el peligro de caer en ciclos infinitos si el programador no se asegura de que la condición deje de cumplirse en algún momento. Existen diferentes tipos:

3.3.1 while Ejecuta las sentencias mientras se cumpla la condición. Si la condición no se cumple, nunca se ejecutarán las sentencias.

Sintaxis en java:

while (condición) { sentencias; }

3.3.2 do-while Similar al anterior, pero en este caso las sentencias se ejecutan antes de comprobar la condición, de forma que necesariamente habrá al menos una ejecución de las sentencias.

Sintaxis en java:

do { sentencias; } while (condición);

condición sentenciastrue

false

Page 13: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 9

3.3.3 for Esta estructura está pensada para ejecutar las sentencias un número determinado y conocido de veces. Resulta especialmente útil, como se verá en clases posteriores, para recorrer estructuras de almacenamiento.

Se utiliza una variable como contador, que se inicializa en la propia sentencia “for”: es más, habitualmente la variable de contador se suele declarar en dicha sentencia. También en la sentencia se indica la condición de parada y el código de actualización, que suele consistir simplemente en incrementar en una unidad la variable contador. Por ejemplo:

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

Esta cabecera indica que en la primera ejecución el contador “i” valdrá 0, que en cada ejecución el contador se incrementará en 1, y que las sentencias se ejecutarán mientras el contador sea menor que 5.

Sintaxis en java:

for (inicialización; condición de salida; actualización) { sentencias; }

La relación entre “while” y “for” es muy estrecha y se muestra en la siguiente tabla:

for (inicialización; condición; actualización) { sentencias; }

inicialización; while (condición) { sentencias; actualización; }

¿Cómo elegir la estructura de repetición adecuada?

• Si es posible que el bucle no se ejecute, usar “while”.

• Si queremos que al menos se ejecute una vez, usar “do-while”.

• Si sabemos cuántas veces queremos ejecutarlo, usar “for”.

• Si queremos recorrer todos los elementos de un vector, usar “for”.

condicióntrue

false

sentencias

Page 14: Resumen Java

10 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

3.3.4 Ruptura del flujo Las instrucciones “break” y “continue” nos permiten abandonar en un momento determinado la ejecución de un bucle. Se trata de un recurso poco elegante y que rompe la estructura de los programas: por tanto, deberá evitarse siempre que sea posible.

La diferencia entre ambas instrucciones es que “break” salta al punto de salida del bucle, continuando con la ejecución de programa sin volver a comprobar la condición de entrada al bucle. Por el contrario, “continue” salta hacia el punto donde se evalúa la condición, permitiendo volver a entrar en el bucle si la condición se cumple.

En resumen: “continue” abandona la ejecución actual de las sentencias del bucle, mientras que “break” abandona el bucle definitivamente.

3.3.5 Manejo de excepciones Algunas operaciones pueden provocar fallos que el ordenador no puede manejar y que el programador debe detectar mientras escribe un programa. Estos fallos suelen tener que ver con eventualidades que en el momento de programar no se conocen: por ejemplo, que un usuario escriba un texto cuando se le pide un número, que se intente abrir un archivo que no se encuentra…

Las excepciones son la forma en que el programador “previene” dichos fallos y avisa al ordenador de cómo comportarse cuando éstos se produzcan.

El funcionamiento es el siguiente: cuando se vaya a ejecutar una operación “de riesgo”, las sentencias implicadas se envuelven en un bloque “try”. Dicho bloque debe ir seguido de un bloque “catch” que recoge el código que queremos que se ejecute cuando el fallo ocurra. La idea es “intentar” (try) hacer algo y “capturar al vuelo” (catch) el posible error antes de que provoque que el programa “se cuelgue” o dé resultados inesperados.

Opcionalmente se puede incluir un bloque “finally” que se ejecutará tanto si el error ha aparecido como si no.

Sintaxis en java:

try { sentencias de riesgo; } catch (TipoDeExcepcion e) { código a ejecutar si ocurre el fallo; } finally // opcional { código a ejecutar tanto si hay error como si no }

Page 15: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 11

3.4 Programa de ejemplo

1 import java.util.InputMismatchException; 2 import java.util.Scanner; 3 4 public class SegundaClase { 5 6 public static void main() 7 { 8 /* COMENTARIOS 9 Ya conocemos los comentarios de bloque, 10 que pueden ocupar varias líneas */ 11 // Y también los comentarios de línea 12 13 /* DECLARACIÓN DE VARIABLES 14 * Para declarar una variable se indica su tipo y su nombre. 15 * Es posible dar un valor inicial a la variable en el momento 16 * de su declaración. */ 17 int entero1; 18 double doblePrecision1 = 3.54; 19 String miCadenaDeCaracteres1 = "Valor inicial de la variable"; 20 /* Podemos declarar más de una variable separándolas mediante 21 * "," siempre que sean del mismo tipo. Sin embargo, como es 22 * conveniente describir la variable con un comentario, 23 * resulta más claro declarar cada variable en una línea 24 * y describirla con un comentario de línea.*/ 25 double baseTriangulo; // base del triángulo 26 double alturaTriangulo; // altura del triángulo 27 int temp1, temp2, temp3; 28 29 /* SALIDA POR PANTALLA */ 30 /* Consideraremos únicamente los métodos print y println. 31 * La diferencia es que println escribe el texto y cambia 32 * después a la línea siguiente. Obsérvese también que para 33 * representar las comillas en una cadena es necesario 34 * usar el carácter de escape "\". */ 35 System.out.print("Esto "); 36 System.out.print("se escribirá en "); 37 System.out.println("una sola línea, porque usamos print"); 38 System.out.print("Este texto será la segunda línea, ya que " + 39 "el \"println\" anterior produjo un cambio de línea."); 40 /* Podemos concatenar elementos con el símbolo "+". También 41 * podemos escribir el contenido de una variable y, en 42 * general, de cualquier expresión. */ 43 System.out.println(" El valor de " + " la variable es: " + 44 doblePrecision1); 45 46 /* EXPRESIONES NUMÉRICAS 47 * Podemos construirlas mediante los diferentes operadores: */ 48 entero1 = (3 + 5 - 7) * 10 / 2; // operaciones básicas 49 entero1 = -1 - 1; /* los símbolos "+" y "-" también se usan 50 * como operadores unarios para representar los signos */ 51 /* Operadores de incremento y decremento: pueden situarse 52 * antes o después de la variable, según se quiera realizar 53 * antes o después de su uso. */ 54 temp1 = 1; 55 temp1--; 56 ++temp1; // temp1 vuelve a valer 1 57 System.out.println("Se escribirá 0: " + --temp1);

Page 16: Resumen Java

12 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

58 temp1 = 1; 59 System.out.println("Se escribirá 1: " + temp1--); 60 /* Otros operadores de asignación */ 61 temp1=10; 62 temp1+=20; // temp1 valdrá ahora 30 63 64 /* ESTRUCTURAS DE SELECCION: IF */ 65 boolean flag=true; 66 67 if ((flag!=true) || (7<(1+7))) 68 { 69 System.out.println("Se cumple la condición."); 70 } 71 72 /* ESTRUCTURAS DE SELECCION: IF-ELSE */ 73 74 if (flag!=true) 75 { 76 System.out.println("Se cumple la condición."); 77 } 78 else 79 { // no hacen falta las llaves si sólo hay una sentencia 80 System.out.println("No se cumple la condición."); 81 } 82 83 /* Se puede declarar variables en cualquier punto del 84 * programa, aunque no es recomendable hacerlo */ 85 int x=1, y=2, z=3; 86 if (z<4) 87 { 88 if (6>x) 89 { 90 if (8>y) 91 { 92 System.out.println("Estructuras de control anidadas"); 93 } 94 } 95 } 96 97 int dia=2; 98 if (dia==1) 99 { 100 System.out.println("Lunes"); 101 } 102 else if (dia==2) 103 { 104 System.out.println("Martes"); 105 } 106 else if (dia==3) 107 { 108 System.out.println("Miércoles"); 109 } 110 else if (dia==4) 111 { 112 System.out.println("Jueves"); 113 } 114 else if (dia==5) 115 { 116 System.out.println("Viernes"); 117 } 118

Page 17: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 13

119 /* ESTRUCTURAS DE SELECCIÓN: SWITCH */ 120 switch(dia) 121 { 122 case 1: 123 System.out.println("Lunes"); 124 break; 125 case 2: 126 System.out.println("Martes"); 127 break; 128 case 3: 129 System.out.println("Miércoles"); 130 break; 131 case 4: 132 System.out.println("Jueves"); 133 break; 134 case 5: 135 System.out.println("Viernes"); 136 default: 137 System.out.println("Ninguno de los anteriores"); 138 } 139 140 switch(dia) 141 { 142 case 1: 143 case 2: 144 case 3: 145 case 4: 146 case 5: 147 System.out.println("Día Laborable"); 148 break; 149 case 6: 150 case 7: 151 System.out.println("Fin de Semana"); 152 break; 153 default: 154 System.out.println("Error. No es un día de la semana"); 155 } 156 157 /* ESTRUCTURAS DE SELECCIÓN: OPERADOR CONDICIONAL */ 158 System.out.print("El mayor es "); 159 System.out.println(x>y ? x: y); 160 161 /* ESTRUCTURAS DE REPETICIÓN: WHILE */ 162 int i = 5; 163 while (i>0) 164 { 165 System.out.println("Paso por el bucle while 5 veces."); 166 i--; 167 } 168 i = 5; 169 while (i-->0) 170 { 171 System.out.println("Paso por el 2do bucle while 5 veces."); 172 } 173 i = 4; 174 while (--i>0) 175 { 176 System.out.println("Paso por el 3er bucle while 3 veces."); 177 } 178 179 /* ESTRUCTURAS DE REPETICIÓN: DO-WHILE */

Page 18: Resumen Java

14 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

180 i=4; 181 do 182 { 183 System.out.println("Paso por el bucle do-while 5 veces."); 184 } 185 while (i-->0); 186 187 do 188 { 189 System.out.println("El do-while ejecuta al menos 1 vez."); 190 } 191 while (10>100); 192 193 /* ESTRUCTURAS DE REPETICIÓN: FOR */ 194 for (int k=1; k<6; k++) 195 { 196 System.out.println("Esta es la ejecución número " + k + 197 " del primer bucle for."); 198 } 199 200 /* ROMPER EL FLUJO: break (evitarlo siempre que se pueda) */ 201 int miNumero = 1853; 202 i=0; 203 do 204 { 205 if (i==miNumero) 206 { 207 System.out.println("Tu número era el " + i); 208 break; // se rompe el flujo. 209 } 210 i++; 211 } 212 while(true); 213 214 /* ROMPER EL FLUJO: continue(evitarlo siempre que se pueda) */ 215 for (int k=1;k<11;k++) 216 { 217 if (k%2!=0) 218 { 219 continue; 220 } 221 else 222 { 223 System.out.println("El número " + k + " es par."); 224 } 225 } 226 227 /* MANEJO DE EXCEPCIONES */ 228 int numero = 0, intentos = 0; 229 Scanner teclado = new Scanner(System.in); 230 do { 231 try { 232 System.out.println("Introduce un número entre 0 y 10: "); 233 numero = teclado.nextInt(); 234 } 235 catch(InputMismatchException e) 236 { 237 System.out.println("Error en la lectura."); 238 } 239 finally 240 {

Page 19: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 15

241 intentos++; 242 } 243 } 244 while (numero<0 || numero>10); 245 System.out.println("Ha habido " + intentos + " intentos."); 246 247 /* CONVERSIÓN DE TIPOS */ 248 float base; 249 //base = 3.4; // esto sería un error 250 base = 3.4f; // indica que 3.4 es un valor de simple precisión 251 base = (float) 3.4; // conversión forzada de tipo, "casting" 252 int baseEntera; 253 // baseEntera = base; // esto sería un error 254 baseEntera = (int) base; // conversión forzada de tipo 255 //(puede haber pérdida de información) 256 double baseDoblePrecision=base;//conversión automática de tipo 257 //(no hay riesgo de pérdida de información) 258 // ¿Cómo pasar de cadena de texto a un número entero? 259 int enteroConvertido = Integer.parseInt("356"); 260 double realConvertido = Double.parseDouble("43.32"); 261 System.out.println("Números convertidos: " + enteroConvertido 262 + " y " + realConvertido); 263 } // main 264 } // SegundaClase

Page 20: Resumen Java

16 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

4 Clases y Objetos (primera parte)

4.1 Objetivos Durante este capítulo se intentará que el alumno aprenda conceptos teóricos esenciales para poder programar con un lenguaje orientado a objetos como es Java. En concreto en esta clase se estudiará el concepto de clase, su estructura (atributos, métodos y métodos constructores), y la forma de crear objetos.

4.2 Clase Se puede definir una clase como una descripción de un tipo de objeto. También podemos definir una clase como un molde que permite crear objetos. Igual que declaramos variables de un determinado tipo, podemos declarar objetos de una determinada clase. Obsérvese la analogía entre tipo y clase, y entre variable y objeto:

variable ≈ objeto

tipo ≈ clase

Por ejemplo:

int x; � declaro la variable ‘x’ del tipo entero

Cliente c; � declaro el objeto ‘c’ de la clase Cliente

Las clases nos permiten definir nuestros propios tipos, más elaborados y con más funcionalidades.

La clase está formada por las características que la definen, también llamadas atributos, y las acciones que puede llevar a cabo, que pasaremos a llamar métodos.

La estructura que tiene una clase se muestra en el siguiente ejemplo:

tipoAcceso class NombreClase {

tipoAcceso TipoAtributo nombreAtributo; tipoAcceso TipoDevuelto nombreMétodo (TipoParametro1 nombreParametro1, TipoParametroN nombreParametroN) {

Tipo nombreVariableLocal; sentencias; /* Si el tipo de retorno es distinto del void tendrá que tener

la palabra reservada return */ }

}

Las clases se crean cuando:

• Hay un concepto nuevo de un problema a solucionar. • Cuando hay un tipo de datos nuevo. • A veces se puede crear una clase sólo para contener el método “main” del

programa, sin responder a ningún concepto o tipo de datos.

Page 21: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 17

4.2.1 Atributos Como se pudo ver en la estructura de la clase los atributos son variables, y se declaran de la misma forma que éstas. Su estructura es:

tipoAcceso tipoAtributo nombreAtributo;

Por ejemplo:

private int baseTriangulo;

El tipo de acceso puede ser de varios tipos: public, protected o private. Si no se pone nada, se interpreta que es tipo paquete (se explicará en la siguiente clase).

Si declaramos un atributo con tipo de acceso public se puede acceder libremente al atributo cuando se declare un objeto.

Si declaramos un atributo con tipo de acceso private sólo se puede acceder a dicho atributo desde dentro de la clase que define dicho atributo.

Si no se pone nada se puede acceder libremente al atributo cuando se declare un objeto, pero siempre desde el mismo paquete (esto se verá más adelante).

El tipo de acceso protected se explicará cuando se estudie el tema de la herencia.

Además los atributos se pueden inicializar directamente en la declaración o a través de los métodos. Si se hiciera en la declaración se haría de la siguiente manera:

tipoAcceso tipoAtributo nombreAtributo = valorInicial;

Por ejemplo:

public int contador = 0;

Si no se inicializan los atributos ni de la anterior forma ni mediante métodos, se inicializan por defecto, esto quiere decir que los atributos que sean numéricos se iniciarán a 0, el booleano false y los otros a null, siendo null lo equivalente a un valor nulo.

4.2.2 Métodos Los métodos determinan el comportamiento de los objetos. Se declaran como se vio en la estructura de clase. Los objetos creados de una clase tendrán disponibles los métodos declarados en ella. Los métodos se pueden clasificar en tres tipos:

• Métodos de consulta, que sirven para extraer información (de los atributos) de los objetos. Son los llamados métodos “get”.

• Métodos de modificación, que sirven para modificar uno o varios atributos de de los objetos. Son los llamados métodos “set”.

• Métodos de comportamiento, que realizan operaciones relacionadas con los objetos.

Page 22: Resumen Java

18 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

En cuanto a la estructura de método, se declara dentro de la estructura de clase:

tipoAcceso TipoDevuelto nombreMétodo (TipoParametro1 nombreParametro1, TipoParametroN nombreParametroN) {

Tipo nombreVariableLocal; sentencias; /* Si el tipo de retorno es distinto del void tendrá que tener

la palabra reservada return */ }

Por ejemplo:

public int suma (int sumando1, int sumando2, int sumando3) {

int resultado; // variable local resultado = sumando1 + sumando2 + sumando3; return resultado; }

El tipo de acceso en los métodos es idéntico al de los atributos. Se recomienda a los alumnos que utilice los métodos con el tipo de acceso público, a no ser que quieran realizar una acción que sólo sea necesaria dentro de la clase. En este caso cuando se cree un objeto no se podrá hacer la llamada al método que sea creado como acceso privado.

El TipoMetodo puede ser void, que significa que el método no devuelve ningún valor, o cualquier otro tipo o clase (int, String, Persona, etc.). Si se pone esto es necesario que dentro del método se defina una sentencia de esta forma:

return valorADevolver;

La variable valorADevolver tiene que ser del mismo tipo que el tipo que devuelve el método.

Dentro de un método se pueden pasar valores mediante los parámetros (comportándose como variables). Si los valores que se introducen son de tipo primitivo (int, float, double, etc) se pasan los parámetros por valor, mientras que si los parámetros son objetos (Persona) se pasan por referencia.

Paso por valor quiere decir que lo que se pasa es una copia de la variable, de forma que la modificación de dicho parámetro en el método no afectará a la variable original.

Paso por referencia quiere decir que lo que se pasa es la referencia a la posición de memoria donde está almacenada la variable, de forma que cualquier modificación que se haga al valor del parámetro se estará haciendo en realidad en la variable original.

Las variables locales son variables que se declaran dentro de la estructura del método y sólo se usan dentro de éste.

4.2.3 Autorefencia this Es una referencia especial para que se pueda nombrar a los elementos de la propia clase dentro de ella. Es útil utilizarla cuando puede haber problemas de ambigüedad. Por ejemplo, supongamos que el atributo de una clase y un parámetro se denominan de igual

Page 23: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 19

forma. ¿Cómo se puede saber dentro del método que tiene ese parámetro si estamos hablando del parámetro o del atributo? Ejemplo:

... private int edad; // atributo edad ... public void setEdad(int edad) { this.edad = edad; // distinguimos el atributo de la clase, “edad”, del parámetro }

4.2.4 Método constructor Son métodos que realizan la construcción del objeto. Cuando declaramos una variable entera, por ejemplo:

int x;

El compilador de Java reserva memoria para dicha variable y ‘x’ pasa a ser una referencia (apuntador) a ese espacio de memoria. Por tanto la variable ya puede comenzar a usarse, por ejemplo dándole valores:

x = 5;

Sin embargo, con los objetos no ocurre lo mismo, y no podemos escribir lo siguiente:

Persona juan; juan.setEdad(34); juan.setNombre(“Juan Rodríguez”);

Esto es así porque lo que estamos declarando es una referencia a un objeto de la clase Persona (un apuntador), pero no hemos reservado el espacio en memoria para este objeto.

Para reservar este espacio debemos utilizar el constructor de la clase. El constructor es un método especial que se llama igual que la clase en cuestión y que no tiene tipo de retorno. Aparte de reservar espacio en memoria, se suele aprovechar el método constructor para dar valores iniciales a los atributos del objeto, y por tanto particularizarlo. Por ejemplo:

public Persona(String nombre, int edad, long dni) { this.nombre = nombre; this.edad = edad; this.dni = dni; }

Si no nos interesa dar valores iniciales, escribiríamos:

public Persona() { }

Sin embargo este constructor es tan sencillo que Java no exige que lo escribamos, sino que lo utilizará automáticamente en caso de que no aportemos ningún otro constructor (como el del ejemplo anterior). Con este constructor por defecto se asignarán a los atributos de estos los valores por defecto explicados anteriormente (null, 0, false, etc.). Es importante

Page 24: Resumen Java

20 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

destacar que este constructor por defecto que nos ofrece Java sin necesidad de escribirlo no estará disponible en caso de que nosotros escribamos nuestro propio constructor. Nota: Si dentro del constructor se produce una excepción el objeto no se crea.

4.2.5 Sobrecarga Hay sobrecarga cuando existen varios métodos que se llaman igual pero que pueden usar parámetros distintos y/o devuelven resultados distintos.

4.3 Objetos Los objetos son elementos que se forman a partir de las clases. Van a tener todos los atributos o cualidades que se definieron en las clases de forma particularizada y van a poder realizar las acciones definidas en las clases.

Para crear objetos es necesario ejecutar está sentencia, llamando al método constructor:

TipoClase nombreObjeto = new TipoClase();

Por ejemplo:

Persona juan = new Persona(“Juan Jiménez”, 54, 2535434);

Esta sentencia lo que haría es declarar una variable (juan) del tipo de la clase (Persona). Para que se cree un objeto hay que llamar al constructor. En el ejemplo de arriba se llama al constructor por defecto ya que no se incluyen los parámetros. Si no se escribiera la parte correspondiente al new TipoClase() no se crearía el objeto y por tanto daría un error de compilación al utilizarlo.

Una vez creado el objeto para poder acceder a sus atributos se podría realizar de dos maneras:

• Si los atributos se han declarado “public” o no se ha puesto nada en el tipo de acceso, se podrá acceder al valor del atributo de esta forma:

nombreObjeto.atributo

• Si el atributo se ha declarado con el tipo de acceso “private” no se puede acceder al atributo directamente desde el objeto. Entonces es necesario crear métodos “set” y “get” que permitan acceder al atributo (tanto para modificarlo como para leer su valor). Por ejemplo, si creamos el siguiente método:

int getEdad() { return edad; }

Entonces podremos acceder al valor del atributo de esta forma:

int edad = juan.getEdad();

Page 25: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 21

Como norma de encapsulación se suelen declarar los atributos como “private” y se accede a la información de éstos a través de los métodos set y get.

4.3.1 Referencias compartidas: alias Es posible que dos variables del TipoClase referencien (apunten) a un único objeto. Por ejemplo si declaramos una variable:

Persona juan = new Persona();

Y a continuación declaramos otra variable y le asignamos el valor de la primera:

Persona raul = juan;

En este caso no tenemos dos objetos juan y raul, sino dos referencias al mismo objeto, ya que como se explicó antes, sólo se crea el objeto en memoria cuando se ejecuta el constructor Persona().

Por tanto puede haber muchas referencias distintas que apunten a un solo objeto.

Page 26: Resumen Java

22 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

5 Clases y Objetos (segunda parte)

5.1 Objetivos En este capítulo se profundizará en el manejo y organización de las clases, trabajando los conceptos de elementos de clase, ámbitos, paquetes, derechos de acceso y clases predefinidas.

5.2 Elementos de clase Existen elementos de una clase (entendiendo por elementos tanto métodos como atributos) que están disponibles cuando creamos un objeto de una determinada clase:

miObjeto.atributo

Pero también existen elementos que están disponibles acudiendo directamente a la clase, y no al objeto (que puede no existir), por ejemplo el método main, o:

System.out.println(“hola”);

¿Cómo es posible esto? Porque llevan el modificador “static”, lo que significa que son elementos de clase. Estos elementos son compartidos por todas las instancias de las clases, por tanto su particularidad es que no existe un elemento por cada objeto, sino un único elemento para toda la clase.

5.3 Clases predefinidas Java aporta muchas clases predefinidas, que no necesitan ser importadas y que están siempre disponibles para el programador.

Las primeras que vamos a estudiar son las clases “envoltorio” (wrappers), que corresponden a cada tipo primitivo y que aportan interesantes métodos de clase, habitualmente relacionados con la conversión de datos a dicho tipo. Ya vimos algún ejemplo en las primeras clases, como cuando convertíamos una cadena de texto leída por el usuario a un número entero:

Integer.parseInt("345");

El otro tipo de clases predefinidas no tiene que ver con tipos primitivos, sino que simplemente ofrece funcionalidades que nos serán de interés, por ejemplo la de elementos matemáticos (Math). Así, en lugar de describir nosotros mismos la constante PI, podemos tomarla de la clase predefinida Math:

double perimetro = 2 * Math.PI * radio;

5.4 Ámbitos Los bloques, delimitados en Java por los símbolos “{“ y “}”, definen ámbitos de declaración. Esto significa que en cada bloque tendremos acceso a un determinado conjunto de elementos (ya sean clases, atributos, métodos, variables locales…). Trabajemos con un ejemplo:

Page 27: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 23

1 class c1 2 { 3 int x , y ; 4 public void m1 ( ) 5 { 6 x = y; 7 this.m2 (y) ; 8 } //m1 9 public void m2 ( int y ) 10 { 11 int z; 12 x = y; 13 this.m1 ( ) ; 14 } //m2 15 } //c1

Las llaves de las líneas 2 y 14 delimitan el ámbito más general: el de la clase c1. Toda clase determina, pues, un ámbito de declaración. Dentro de esta clase estarán accesibles los símbolos c1, x, y, m1 y m2.

El método m1 define un nuevo ámbito, que abarca las líneas 4 á 8. En este ámbito están accesibles los identificadores anteriores. El método m2, por su parte, abarca las líneas 9 á 13, y en él están disponibles los mismos símbolos anteriores, pero con dos particularidades: por un lado, este ámbito incluye la variable z. Por otra parte (y esto es muy importante) está disponible el parámetro “y”, que en este caso sobreescribe al atributo de clase. Es decir, ante la coincidencia de nombres se interpreta que cualquier referencia a “y” se referirá al símbolo más cercano, en este caso el parámetro. Sin embargo, obsérvese que el atributo de la clase seguiría en este caso accesible mediante el uso de “this.y”.

Obsérvese que en Java no podemos referenciar una variable si no se ha declarado antes, pero en el caso de atributos y métodos es diferente y puedo, por ejemplo, llamar a un método cuya especificación se hace más adelante en el código (línea 7). También podríamos, si quisiéramos, poner la línea 3 al final, entre las líneas 14 y 15; sin embargo la lectura de una clase se hace más fácil si declaramos los atributos primero y los métodos después.

5.5 Paquetes Los paquetes son una forma de agrupación de clases, y contribuyen a conseguir la encapsulación, uno de los principios fundamentales de la programación orientada a objetos. El primer nivel de encapsulación es la clase, que agrupa datos y funciones (atributos y métodos). El paquete constituye un segundo nivel, permitiendo la agrupación de clases y también de otros paquetes (llamados subpaquetes).

El uso de paquetes facilita la reutilización de ciertos componentes que ya han sido escritos, y mejora también la organización y estructura de nuestro código. Al igual que otros lenguajes, esta organización se realiza mediante librerías o, si hablamos de Java, "packages".

Los paquetes no son sólo una agrupación conceptual, sino que se corresponden con una agrupación física. En concreto, en la mayoría de entornos de programación cada paquete se corresponde con un directorio, y las clases incluidas en el paquete se encuentran almacenadas en dicho directorio. De igual forma, un subpaquete se correspondería con un subdirectorio.

Para indicar que una clase pertenece a un paquete se incluye una primera línea en el archivo de clase indicando “package” y el nombre del paquete.

Page 28: Resumen Java

24 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

En el ejemplo de las áreas y perímetros podríamos crear un paquete llamado “figuras”: para ello insertaríamos la siguiente línea en la cabeza de los archivos Triangulo.java y Circulo.java:

package figuras;

El nombre del paquete debe tener algún sentido según las clases que agrupa, de forma que un programador pueda hacerse una idea de lo que encontrará al importarlo.

¿Y cómo se importa un paquete, independientemente de si lo hemos programado nosotros o no? Para ello están las sentencias de importación, que se incluyen también en la cabecera (conviene ponerlas después de la sentencia “package”, para que lo primero que se vea siempre es el paquete al que pertenece la clase que estamos programando). Hay diferentes formas de importación:

1. Importar un solo elemento: sólo estará disponible la clase indicada.

import figuras.Triangulo;

...

Triangulo t1 = new Triangulo();

// Circulo c1 = new Circulo(); error!!

...

2. Importar el paquete: hay que identificar cada elemento importado.

import figuras;

...

figuras.Triangulo t1 = new Triangulo();

figuras.Circulo c1 = new Circulo();

...

3. Importar todos los elementos del paquete.

import figuras.*;

...

Triangulo t1 = new Triangulo();

Circulo c1 = new Circulo();

...

Sólo se admite una línea package, por tanto una clase no puede pertenecer simultánteamente a dos paquetes. Si por algún motivo quisiéramos incluir la clase Triangulo en otro paquete habría que hacer una copia del archivo y cambiar la instrucción “package”. Sin embargo la solución natural será dejar Triangulo en el paquete “figuras” y, en caso de necesitar dicha clase en otro programa, importar el paquete “figuras” al completo.

Hay muchas empresas y programadores desarrollando paquetes, por lo que se hizo necesario gestionar su organización para que los nombres no coincidieran, y también para conocer el origen del paquete. En este sentido Java hereda las convenciones del mundo de Internet, en el que se garantiza que cada dominio es único, representando cada paquete por el dominio web de la empresa que lo ha desarrollado. Para ello se utiliza el delimitador “.”,

Page 29: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 25

que nos sirve también para “navegar” por paquetes y subpaquetes. El dominio web, para localizarse más fácilmente, se pone al revés.

Algunos ejemplos:

package com.empresa.mi.figuras;

import com.sun.eng.*;

import com.apple.quicktime.v2;

5.6 Derechos de acceso Los modificadores de visibilidad ya se vieron en clases anteriores, y se resumen en la siguiente tabla:

Modificador Sintaxis Visibilidad

Privada private int x; Sólo dentro de la clase

Por defecto int x; Clases dentro del paquete

Protegida protected int x; Clases dentro del paquete y subclases dentro o fuera del paquete

Pública public int x; Todas las clases

Ahora podemos entender los privilegios relacionados con los paquetes, pero aún no hemos visto el concepto de subclases, que se reserva para la siguiente clase.

5.7 Programas de ejemplo Creación de la clase alumno:

1 public class Alumno 2 { 3 /*A continuación se observan las cualidades 4 o atributos que tienen los alumnos*/ 5 6 private String nombre; 7 private String apellidos; 8 private int añoDeNacimiento; 9 private int numeroPersonal; // identificativo único 10 /*Cuando se cree el objeto se inicializarán 11 por defecto los siguientes atributos*/ 12 private String grupo = "OTROS"; 13 private char horario = 'T'; // 'M' mañana 'T' tarde 14 15 /* se crean los métodos constructores si es necesario, 16 si no cuando se cree un 17 bjeto se utilizara el constructor por defecto. 18 Nota: si declaramos aquí un constructor el constructor 19 por defecto dejara de funcionar */ 20 21 public Alumno (String parNombre, String parApellidos, 22 int parAñoDeNacimiento,int parNumeroPersonal) 23 { 24 nombre = parNombre; 25 apellidos = parApellidos; 26 añoDeNacimiento = parAñoDeNacimiento ;

Page 30: Resumen Java

26 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

27 numeroPersonal = parNumeroPersonal; 28 29 } 30 31 /* En la estructura de la clase se declara 32 a continuación las acciones o 33 métodos que pueden llevar a cabo */ 34 35 // Estos son los métodos modificadores 36 public void setNombre(String nombre) 37 { 38 /* Se utiliza la autorefencia this para 39 discernir entre el atributo y el parámetro */ 40 this.nombre = nombre; 41 } 42 43 public void setApellidos(String parApellidos) 44 { 45 apellidos = parApellidos; 46 } 47 48 public void setAñoDeNacimiento(int parAñoDeNacimiento) 49 { 50 añoDeNacimiento = parAñoDeNacimiento; 51 } 52 53 public void setNumeroPersonal(int parNumeroPersonal) 54 { 55 numeroPersonal = parNumeroPersonal; 56 } 57 58 public void setGrupo(String parGrupo) 59 { 60 grupo = parGrupo; 61 } 62 63 public void setHorario(char parHorario) 64 { 65 horario = parHorario; 66 } 67 68 public void ponCurso (String parGrupo, char parHorario) 69 { 70 grupo = parGrupo; 71 if (numeroPersonal > 35 ) 72 { 73 horario = 'T';_ 74 } 75 else 76 { 77 horario = parHorario; 78 } 79 80 } 81 82 /* Este método está sobrecargado ya que 83 se crea dos veces con distintos parametros */ 84 85 public void ponCurso (String parGrupo) 86 { 87 grupo = parGrupo;

Page 31: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 27

88 if (numeroPersonal > 70 ) 89 { 90 horario = 'M'; 91 } 92 93 } 94 95 // Estos son los métodos de consulta 96 public String getNombre() 97 { 98 return this.nombre; 99 } 100 101 public String getApellidos() 102 { 103 return apellidos; 104 } 105 106 public int getAñoDeNacimiento() 107 { 108 return añoDeNacimiento; 109 } 110 111 public int getNumeroPersonal() 112 { 113 return numeroPersonal; 114 } 115 116 public String getGrupo() 117 { 118 return grupo; 119 } 120 121 public char getHorario() 122 { 123 return horario; 124 } 125 126 // métodos de comportamiento 127 public void imprime () 128 { 129 System.out.println("Nombre: " + nombre + 130 + " Apellidos: " + apellidos); 131 System.out.println("Año de nacimiento: " + añoDeNacimiento); 132 System.out.println("Número personal: " + numeroPersonal); 133 /* Se puede acceder desde la clase 134 al atributo o llamando al método*/ 135 System.out.println("Grupo: " + grupo + " horario: " 136 + getHorario()); 137 System.out.println(); 138 } 139 } // fin de la clase Alumno

Page 32: Resumen Java

28 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

Una vez creada la clase Alumno ya podemos crear objetos de dicha clase para poder trabajar con alumnos concretos, para ello vamos a crearnos otra clase llamada TerceraClase que tendrá un método main. Esta clase se almacenará en la misma carpeta que la clase Alumno porque de lo contrario no funcionaría con lo estudiado hasta ahora. Esta clase creará alumnos y realizará varias acciones con ellos. Si se hubiera querido se hubiera podido crear el método main en la misma clase Alumno, pero para ver la utilidad de la reutilización de clases hemos decidido no realizar el método main en dicha clase.

1 public class TerceraClase 2 { 3 4 public static void main (String []args) 5 { 6 /* Declaramos un objeto de tipo Alumno y lo creamos, 7 observar que no podriamos utilizar el constructor 8 por defecto Alumno() ya que en la clase Alumno ya hemos 9 definido un constructor nuevo con parametros */ 10 Alumno objAlumno1 = new Alumno("Guillermo","Puertas",1955,36); 11 objAlumno1.ponCurso("FUND_INF",'M'); 12 objAlumno1.imprime(); 13 /*Al declarar una nueva referencia al objeto y asignarle 14 el antiguo objeto no se crea un objeto nuevo sino que las 15 dos referencias objAlumno1 y objAlumno2 apuntan al mismo 16 objeto. Se puede observar al imprimir el alumno2*/ 17 18 Alumno objAlumno2 = objAlumno1; 19 objAlumno2.imprime(); 20 /* Si queremos que el objAlumno2 tenga unos datos distintos 21 tendremos que crear otro objeto distinto al de objAlumno1, 22 de la siguiente forma */ 23 24 objAlumno2 = new Alumno("Linus","Torvalds",1969,22); 25 objAlumno1.ponCurso("FUND_INF",'M'); 26 objAlumno2.imprime(); 27 } 28 } // fin de la clase TerceraClase

5.8 Enumerados Existe un tipo de clase un poco especial, que define tipos de datos enumerados.

Supongamos que queremos describir en un atributo un día de la semana, o el turno en que un alumno de un curso está matriculado. Para facilitar esta tarea existen los tipos enumerados, que sólo admiten un rango determinado de valores.

Estos tipos constituyen clases. Para definir los tipos correspondientes a los ejemplos anteriores crearíamos dos clases: Turno y DiasSemana. Su contenido sería distinto al de las clases que hemos visto hasta ahora:

Page 33: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 29

Contenido del archivo Turno.java:

public enum Turno {MAÑANA, TARDE, NOCHE}

Contenido del archivo DiasSemana.java:

public enum DiasSemana {LUNES, MARTES, MIERCOLES, JUEVES, VIERNES}

A propósito del ejemplo del turno, obsérvese la siguiente clase de ejemplo y el uso de los tipos enumerados: el atributo “turno” se declara como un objeto de la clase Turno que acabamos de definir.

public class Alumno { private String nombre; private String apellido; private Turno turno; public Alumno(String nom,String ape, Turno tur) { nombre = nom; apellido = ape; turno = tur; } public static void main (String[] args) { Alumno al = new Alumno("Sergio","López",Turno.MAÑANA); } }

Page 34: Resumen Java

30 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

6 Estructuras de almacenamiento

6.1 Objetivos Una variable u objeto puede representar un número, una cadena de caracteres, un alumno… ¿Qué pasa cuando queremos representar un vector, una matriz o, en general, un conjunto de valores y no un único valor? El objetivo de este capítulo es dar a conocer diferentes estructuras de almacenamiento. En concreto, vamos a estudiar los arrays y los ArrayList.

6.2 Comparación entre un array y un ArrayList La diferencia fundamental entre ambas estructuras es que el array es una colección de tamaño fijo, mientras que el ArrayList es una colección de tamaño dinámico. Es decir, al declarar un array tenemos que conocer de antemano el tamaño que queremos que tenga la colección, mientras que en el caso del ArrayList no hace falta que le indiquemos el tamaño, sino que será él quien automáticamente vaya adaptando su tamaño al número de elementos.

Por lo demás en ambos casos se trata de objetos, por tanto ambos deben inicializarse mediante el operador new, sólo que los arrays son un tipo predefinido y los ArrayList hay que importarlos del paquete java.util.

Nota: de la Física heredamos el nombre del vector para los array de tamaño fijo con valores numéricos; sin embargo no recomendamos utilizar este término en ningún caso ya que Java implementa una clase Vector (no estudiada en la asignatura) que se parece mucho a ArrayList y por tanto es de tamaño dinámico. El uso de la palabra vector en programación, por tanto, no está claro y conviene evitar dicho término para evitar confusiones.

6.3 Array Cuando se trabaja con varios elementos del mismo tipo podemos declarar un array de dos formas : int [ ] arrayEnteros; String diasSemana[ ];

Todos los elementos del array tendrán que ser del mismo tipo. Observa que el array es un objeto y debe inicializarse: arrayEnteros = new int[20]; diasSemana = new String [100];

El número entre los corchetes indica el tamaño que tendrá el array, es decir, el número máximo de elementos que podrá contener.

Existe una forma de juntar en una sola sentencia la inicialización y el relleno del array: int [] arrayEnteros = {1, 2, 3, 4, 5}; String [] diasSemana = {“Lunes”, “Martes”, “Miércoles”, “Jueves”, “Viernes”};

Con estas sentencias fijamos también el tamaño del vector; este sistema sólo es recomendable si el tamaño del array va a ser reducido.

Ahora si queremos acceder e imprimir, según el ejemplo anterior al martes, tendríamos que hacer lo siguiente: System.out.println(“El día es: ” + diasSemana[1]);

Page 35: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 31

Obsérvese que pedimos la posición 1: esto es debido a que los elementos de los arrays empiezan a contar desde 0 y terminan, por tanto, en (número de elementos – 1).

Para asignar un valor a un elemento de un array sólo es necesario decir en que posición se encuentra el elemento al que se le quiere asignar el valor. arrayEnteros[2] = 5;

Esto indica que en la tercera posición del array “arrayEnteros” se ha introducido el valor 5.

Además de los arrays de una dimensión puede haber arrays de dos, tres, cuatro ó n dimensiones. Por ejemplo, un array de dos dimensiones y valores numéricos representa lo que conocemos como matriz. Este tipo de arrays se declararían, por ejemplo, de la siguiente forma: int [ ][ ] tabla;

y se iniciarían de la siguiente manera: tabla = new int [5][7];

6.4 ArrayList A diferencia de los arrays, cuyo tamaño es fijo, las colecciones en Java (de las que ArrayList es un ejemplo) son estructuras de almacenamiento que crecen dinámicamente. Esto quiere decir que no tienen un tamaño determinado: se les puede asignar un tamaño de inicio, pero éste variará automáticamente si se introducen más elementos a la estructura.

Otra diferencia de los arrays con las colecciones, como ya avanzamos antes, es que estas últimas deben importarse del paquete java.util. Dentro de las posibles colecciones a estudiar vamos a centrarnos en la clase ArrayList, que se declara así:

ArrayList<Integer> arrayEnteros = new ArrayList<Integer>();

ArrayList<Alumno> alumnos = new ArrayList<Alumno>();

Observa que tanto al crear como al inicializar un ArrayList hay que indicar su tipo entre símbolos de menor y mayor.

En ArrayList no hay forma de inicializar valores como hacíamos con los arrays, pero sin embargo tenemos la opción de crear un ArrayList copiando en él todos los elementos de otro. Ejemplo:

ArrayList<Integer> miNuevoArray = new ArrayList<Integer>(otroArray);

A continuación se resumen algunos de los métodos más interesantes que nos ofrece la clase ArrayList:

• boolean add(Object o) � Este método añade un nuevo elemento al final de la lista.

• boolean remove(Object o) � Este método borra el objeto que se pasa como parámetro si éste está presente dentro de la lista. Si no está el método devuelve false.

• boolean remove(int i) � Este método borra el objeto que se encuentra en la posición i de la lista. Si no está el método devuelve false.

• int size() � Este método es similar al atributo length del array y devuelve el tamaño del ArrayList.

Page 36: Resumen Java

32 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

• boolean contains(Object elem) � Devuelve true si el ArrayList contiene el elemento especificado.

• int indexOf(Object elem) � Como el anterior, pero devuelve la posición en que se encuentra el elemento. Si no está devuelve -1.

• boolean isEmpty() � Este método comprueba si hay elementos en el ArrayList.

• void clear()� Borra todos los elementos del ArrayList.

• Object get(int index) � Devuelve el elemento especificado en la posición del ArrayList.

El resto de los métodos pueden encontrarse en la documentación que aporta la web de Java:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/ArrayList.html

6.5 Recorrido de estructuras Al trabajar con estructuras es inevitable que surja el problema de cómo recorrer sus elementos y hacer algo con ellos. Para ello utilizamos la estructura de control de flujo iterativa for; sin embargo, para establecer los índices del bucle for necesitamos conocer el tamaño de la estructura. Para ello:

• En arrays tenemos disponible el atributo “length”

• En ArrayList tenemos el método “size()”

Recuerda la diferencia porque uno es atributo y el otro es método, aunque representen exactamente lo mismo (el tamaño de la estructura).

Ejemplo con arrays: for (int i=0; i < diasSemana.length; i++) { System.out.println(“El día ” + i + “ es ” + diaSemana[i]);

}

Ejemplo con ArrayList:

for (int i=0; i < diasSemana.size(); i++) { System.out.println(“El día ” + i + “ es ” + diaSemana.get(i));

}

Por ser una acción tan frecuente, Java ofrece una alternativa para recorrer estructuras de forma más cómoda y operar con cada uno de sus elementos. Esta alternativa está disponible tanto para arrays como para ArrayList. Ejemplo:

for (Integer i_dia: diasSemana) { System.out.println(“El día es ” + i_dia);

}

Page 37: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 33

Esta sentencia se entiende como: “Sea i_dia cada uno de los elementos de tipo entero de la estructura diasSemana. Para cada uno de ellos ejecuta el código contenido en el bucle”.

Para evitar confusiones sugerimos llamar de la forma “i_nombre” a estas variables que no son exactamente índices sino que contienen el valor de cada elemento de la estructura, aunque no existe un convenio definido al respecto.

Esta alternativa suele ser más cómoda en todos los casos, pero es posible que prefiramos la opción clásica, por ejemplo si necesitamos conocer en cada momento el índice i.

Obsérvese que a la hora de recorrer colecciones multidimensionales tenemos que manejar dos, tres o n índices. Veamos como ejemplo la inicializadión a “0” de los valores de una matriz:

int matrizEnteros = new int [3][4]; for (int i =0; i < matrizEnteros.length;i++) { for (int j=0;j < matrizEnteros[i].length;j++) { matrizEnteros[i][j] = 0; } }

6.6 Código de ejemplo // ejemplo de uso de arrays Circunferencia cir1 = new Circunferencia(10);cir2 = new Circunferencia(20); Circunferencia cir3 = new Circunferencia(30); Circunferencia [] circunferencias; circunferencias = new Circunferencia[3]; circunferencias[0] = cir1; circunferencias[1] = cir2; circunferencias[2] = cir3; // recorrido tradicional de estructuras for (int i = 0; i < circunferencias.length; i++) { System.out.println("El radio de la circunferencia " + i + " es: " + circunferencias[i].getRadio()); } ArrayList<Cuadrado> cuadrados = new ArrayList<Cuadrado>(); Cuadrado c1 = new Cuadrado(10); Cuadrado c2 = new Cuadrado(20); cuadrados.add(c1); cuadrados.add(c2); cuadrados.add(new Cuadrado(30)); // recorrido abreviado de estructuras for (Cuadrado i_cuadrado: cuadrados) { System.out.println("Lado del cuadrado: " + i_cuadrado.getLado()); }

Page 38: Resumen Java

34 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

// siempre podemos usar números como elementos: ArrayList<Integer> arrayEnteros = new ArrayList<Integer>(); arrayEnteros.add(5); arrayEnteros.add(7); // recorrido abreviado for (Integer numero: arrayEnteros) { System.out.println(numero); }

// recorrido tradicional for (int i=0; i<arrayEnteros.size(); i++) { System.out.println(arrayEnteros.get(i)); } // uso de los métodos que ofrece la clase ArrayList // get: recuperar un elemento dado su índice Cuadrado cua = cuadrados.get(2); // contains: indica si el elemento está contenido if (cuadrados.contains(c2)) { System.out.println("Sí está contenido"); } // indexOf: indica si el elemento está contenido, y en qué posición System.out.println("Posición: " + cuadrados.indexOf(c2)); // isEmpty: indica si la colección está vacía if (cuadrados.isEmpty()) { System.out.println("La colección está vacía"); } else { System.out.println("La colección no está vacía"); } // remove: eliminar un elemento dado cuadrados.remove(c2); // remove: eliminar el elemento en la posición dada cuadrados.remove(0); // clear: borra todos los elementos cuadrados.clear();

Page 39: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 35

7 Composición, herencia y polimorfismo

7.1 Objetivos El objetivo de este capítulo es poder presentar dos mecanismos básicos para construir nuevas clases a partir de las ya existentes: la composición y la extensión.

Para extender clases se hace uso de dos conceptos fundamentales de la programación orientada a objetos que son: la herencia y el polimorfismo.

7.2 Composición La composición es la creación de una clase nueva agrupando objetos de clases preexistentes. Se encuentra la composición cuando en una clase se tienen atributos que corresponden con el tipo de una clase.

Por ejemplo, supongamos que se quiere crear una clase denominada Billete: esta clase tiene como atributos el número de billete, la fecha de salida y hora, el asiento ocupado, la localidad de salida y la de llegada y, por último, los datos del viajero. La clase tendría la siguiente forma:

1 import java.util.Calendar; 2 3 public class Billete 4 { 5 private long numBillete; 6 private Calendar fechaHora; 7 private int numAsiento; 8 private String locSalida; 9 private String locLlegada; 10 private Cliente cliente; 11 private int precio; 12 13 public Billete (long numBillete, Calendar fechaHora, 14 int numAsiento,String locSalida, String locLlegada, 15 Cliente cliente, int precio) 16 { 17 this.numBillete = numBillete; 18 this. fechaHora = fechaHora; 19 this.numAsiento = numAsiento; 20 this.locSalida = locSalida; 21 this.locLlegada = locLlegada; 22 this.cliente = cliente; 23 this.precio = precio; 24 } 25 }

Ejemplo 1

Los datos del cliente (dni, nombre, apellido) quedarían recogidos en la clase Cliente.

Page 40: Resumen Java

36 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

Gráficamente la composición se representaría de esta forma:

Para reconocer la composición podemos preguntarnos si, por ejemplo, el billete “tiene-un” cliente (en este caso el billete “tiene” los datos del cliente). Si esto se corresponde entonces puede que necesitemos composición cuando desarrollemos aplicaciones.

7.3 Herencia Una de los pilares de la programación orientada a objetos es la herencia. Esta se define como la capacidad de una clase de heredar tanto los métodos como los atributos de otra clase. Para que una clase herede de otra la sintaxis que se debe usar en el código es la siguiente:

public class ClaseHijo extends ClasePadre { tipoAcceso TipoAtributo nombreAtributo; tipoAcceso TipoDevuelto nombreMetodo (TipoParametro1 nombrePar1) { TipoVarLocal nombreVarLocal; sentencias; } }

Ejemplo 2

La clase ClaseHijo está formada, además de los atributos y métodos que se declaran, de los que se heredan de la ClasePadre. Es, por tanto, la herencia una relación de jerarquía.

Billete

private long numBillete;private Calendar fechaHora;private int numAsiento;private String locSalida;private String locLlegada;private Cliente cliente;Private int precio;

public Billete (long numBillete, Calendar fechaHora, int numAsiento, String locSalida, String locLlegada, Cliente cliente, int precio)

Cliente

private long dni;private String nombre;private String apellido;

public Cliente (long dni,, Stringnombre, String apellido)

Billete

private long numBillete;private Calendar fechaHora;private int numAsiento;private String locSalida;private String locLlegada;private Cliente cliente;Private int precio;

public Billete (long numBillete, Calendar fechaHora, int numAsiento, String locSalida, String locLlegada, Cliente cliente, int precio)

Billete

private long numBillete;private Calendar fechaHora;private int numAsiento;private String locSalida;private String locLlegada;private Cliente cliente;Private int precio;

public Billete (long numBillete, Calendar fechaHora, int numAsiento, String locSalida, String locLlegada, Cliente cliente, int precio)

Cliente

private long dni;private String nombre;private String apellido;

public Cliente (long dni,, Stringnombre, String apellido)

Cliente

private long dni;private String nombre;private String apellido;

public Cliente (long dni,, Stringnombre, String apellido)

Page 41: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 37

Ejemplo:

La clase Billete Tren tiene los mismos atributos y métodos que la clase Billete. La diferencia es que el billete del tren tiene un atributo adicional: la categoría. Por eso la clase BilleteTren sería de la siguiente forma:

1 import java.util.Calendar; 2 3 public class BilleteTren extends Billete 4 { 5 private String categoria; 6 7 public BilleteTren (long numBillete, Calendar fechaHora, 8 int numAsiento, String locSalida, String locLlegada, 9 Cliente cliente, int precio, String categoria) 10 { 11 super(numBillete,fechaHora,numAsiento, 12 locSalida,locLlegada,cliente,precio); 13 } 14 }

Ejemplo 3

En el anterior ejemplo todos los billetes de tren son también billetes, pero no ocurre lo mismo al revés: no todos los billetes son billetes de tren.

Para reconocer la herencia podemos preguntarnos si, por ejemplo, el billete de tren “es-un” billete. Si esto se corresponde entonces puede que necesitemos herencia cuando desarrollemos aplicaciones.

Un ejemplo gráfico de cómo quedaría la herencia (incluyendo la composición anterior) sería:

Billete

private long numBillete;private Calendar fechaHora;private int numAsiento;private String locSalida;private String locLlegada;private Cliente cliente;Private int precio;

public Billete (long numBillete, Calendar fechaHora, int numAsiento, String locSalida, String locLlegada, Cliente cliente, int precio)

Cliente

private long dni;private String nombre;private String apellido;

public Cliente (long dni,, Stringnombre, String apellido)

BilleteTren

private String categoria;

public BilleteTren (long numBillete, Calendar fechaHora, int numAsiento, String locSalida, String locLlegada, Cliente cliente, int precio, StringCategoria)

Billete

private long numBillete;private Calendar fechaHora;private int numAsiento;private String locSalida;private String locLlegada;private Cliente cliente;Private int precio;

public Billete (long numBillete, Calendar fechaHora, int numAsiento, String locSalida, String locLlegada, Cliente cliente, int precio)

Cliente

private long dni;private String nombre;private String apellido;

public Cliente (long dni,, Stringnombre, String apellido)

Billete

private long numBillete;private Calendar fechaHora;private int numAsiento;private String locSalida;private String locLlegada;private Cliente cliente;Private int precio;

public Billete (long numBillete, Calendar fechaHora, int numAsiento, String locSalida, String locLlegada, Cliente cliente, int precio)

Billete

private long numBillete;private Calendar fechaHora;private int numAsiento;private String locSalida;private String locLlegada;private Cliente cliente;Private int precio;

public Billete (long numBillete, Calendar fechaHora, int numAsiento, String locSalida, String locLlegada, Cliente cliente, int precio)

Cliente

private long dni;private String nombre;private String apellido;

public Cliente (long dni,, Stringnombre, String apellido)

Cliente

private long dni;private String nombre;private String apellido;

public Cliente (long dni,, Stringnombre, String apellido)

BilleteTren

private String categoria;

public BilleteTren (long numBillete, Calendar fechaHora, int numAsiento, String locSalida, String locLlegada, Cliente cliente, int precio, StringCategoria)

BilleteTren

private String categoria;

public BilleteTren (long numBillete, Calendar fechaHora, int numAsiento, String locSalida, String locLlegada, Cliente cliente, int precio, StringCategoria)

Figura 1

Page 42: Resumen Java

38 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

7.3.1 Compatibilidad de tipos Cuando se crea un objeto de una clase hija, se puede hacer una asignación directa a un referencia de la clase padre debido a que la clase hija hereda tanto los atributos como los métodos de la clase padre. Al revés esto necesita de un “casting”, ya que la clase derivada podría no ser compatible debido a que la clase padre no tiene por qué tener todos los atributos que tiene la hija ni todos sus métodos.

Ejemplo

Asignación directa Billete billete = billeteTren;

Realización de casting BilleteTren billeteTren = (BilleteTren) billete;

Ejemplo 4

Todas las clases heredan de una clase preexistente en el entorno java y denominada Object. Esto es así siempre, de forma que no es necesario tenerlo en cuenta ni especificarlo en el código.

7.3.2 Ámbitos y visibilidad La clase que hereda puede utilizar de forma normal los atributos de la clase base a no ser que estos tengan el acceso de tipo “private”. Recordemos la tabla:

Modificador Sintaxis Visibilidad

Privada private int x; Sólo dentro de la clase

Por defecto int x; Clases dentro del paquete

Protegida protected int x; Clases dentro del paquete y subclases dentro o fuera del paquete

Pública public int x; Todas las clases

7.3.3 Reescritura Supongamos que se tiene una clase base con ciertos atributos y métodos. Cuando se crea una clase hija esta puede tener un método con el mismo nombre que la clase base. Este método se puede reescribir si, por ejemplo, queremos realizar un comportamiento especial si se trata de la clase hija (como al imprimir los datos en pantalla).

7.3.4 Los constructores Como se vio en el ejemplo 3 para crear objetos de clases hijas se puede (además de asignar como siempre los atributos a sus valores) llamar al constructor de la clase padre mediante la palabra reserva super. Esto se tendría que realizar en la primera línea del código del constructor. Además si los atributos de la clase base tienen un acceso no “private” se puede hacer las llamadas a sus atributos también poniendo la sentencia super.

super.numAsiento;

Page 43: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 39

7.4 Tabla de compatibilidad

Esta tabla aclara cuándo podemos utilizar los conceptos de composición y herencia:

Composición Clase contendora <<tiene-un>> Clase contenida

Herencia Clase hijo <<es-un>> Clase base o padre

Ejemplos:

Composición Aula <<tiene-un>> Profesor

Herencia Profesor <<es-una>> Persona

7.5 Compatibilidad de tipos Retomemos la propiedad “es-un”: un Alumno es una Persona. A la hora de considerar la compatibilidad de tipos se sigue la misma política, existiendo compatibilidad hacia arriba, pero no hacia abajo. ¿Qué significa esto? Un alumno es una persona, pero una persona no es siempre un alumno.

Esto es interesante porque en Java podemos asignar un mismo objeto a referencias de distintas clases, según cómo nos interese ver ese objeto. Ejemplo:

Alumno al = new Alumno(); Persona p = al; Persona p2 = new Alumno();

La referencia “al”, de la clase Alumno, alude a un objeto de la clase Alumno.

La referencia “p”, de la clase Persona, alude a un objeto de la clase Alumno. Esto es posible por lo que acabamos de comentar: un alumno es también (se puede ver como) una persona.

La referencia “p2”, de la clase Persona, alude a un objeto de la clase Alumno (misma explicación). ¿Tiene esto sentido? Sí, si imaginamos por ejemplo que yo quiero unificar las distintas personas para, por ejemplo, hacer una lista con ellas. ¿Qué pasará con las características propias del alumno en este caso? ¿Podremos acceder a ellas más adelante? Es decir, ¿podremos ver el objeto apuntado por “p2” como un alumno?

La respuesta es sí, pero con reservas. Hemos dicho que no toda persona es un alumno, por tanto no podremos decir directamente:

Alumno al2 = p2; // error

Para ello hay que hacer la conversión forzada o casting, que ya conocemos:

Alumno al2 = (Alumno) p2;

Esto funcionará sólo si el objeto apuntado por “p2” es realmente un alumno. En este caso es cierto, pero si queremos hacer un código seguro que nos permita cerciorarnos de que la conversión se hará correctamente podemos utilizar este sencillo método:

if (p2 instanceof Alumno)

Page 44: Resumen Java

40 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

{ Alumno al2 = (Alumno) p2; } else { System.out.println(“ERROR: no es un alumno”); }

7.6 Reescritura y ligadura dinámica Recordemos que la reescritura consiste en que podemos implementar un método llamado “imprimir” en la clase Persona, y reescribir el mismo método en la clase Alumno con la misma cabecera pero una implementación distinta. Así, el método “imprimir” de la clase alumno escribirá, además de los datos personales, el número de expediente del alumno.

La reescritura es posible porque Java utiliza ligadura dinámica. En casi todos los lenguajes existe ligadura estática, que asocia el nombre de un método (por ejemplo “imprimir”) de forma definitiva a un trozo de código. Por el contrario, Java permite que existan varias implementaciones asociadas a un mismo método, y que se decida en tiempo de ejecución cuál utilizar. ¿Cómo sabrá Java cuál debe ejecutarse?

Alumno al = new Alumno(); al.imprimir(); // se usa el método imprimir de la clase Alumno Persona p = new Persona(); p.imprimir(); // se usa el método imprimir de la clase Persona p = al; //conversión ascendente, permitida p.imprimir(); // se usa el método imprimir de la clase Alumno

La respuesta es la siguiente: la ligadura dinámica en Java escoge el método de la clase a la que pertenezca el objeto, independientemente de su referencia. Así, aunque en el último caso trabajamos con una referencia de la clase Persona, lo cierto es que el objeto al que apunta dicha referencia es un alumno.

Una última cosa sobre reescritura: a la hora de programar el método “imprimir” de la clase Alumno, quizá nos interese reutilizar el método “imprimir” de la clase Persona, puesto que los datos personales deben imprimirse igualmente. Para ahorrarnos trabajo y no repetir las sentencias que ya hemos programado, podemos hacer lo siguiente:

class Alumno { . . . void imprimir() { super.imprimir(); System.out.println(“El número de expediente es “ + nexp); } . . . }

Es decir, mediante “super” llamamos al método imprimir de la clase padre y luego completamos el trabajo con la parte específica que queremos imprimir para un alumno.

Page 45: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 41

7.7 Polimorfismo La combinación de herencia y ligadura dinámica se denomina polimorfismo. El polimorfismo permite que un objeto sea visto de distintas formas (con distintas referencias, aunque hemos visto que su comportamiento irá determinado por el objeto), y permite que se puedan defimir e invocar métodos idénticos en su signatura (nombre y parámetros) pero diferentes en su implementación. La relación con la herencia es evidente, ya que Java sólo permite definir métodos idénticos en el caso de existir relación padre-hijo.

7.8 Clases abstractas Si consideramos una clase Mamífero que agrupe las clases Perro, Gato, etc, es posible que no queramos que un usuario pueda instanciar un objeto de la clase Mamífero, es decir, que queramos obligarle a instanciar objetos únicamente de las clases hijas. ¿Es eso posible? Sí, declarando la clase mamífero como abstracta:

public abstract class Mamífero { . . . }

A esto se le llama herencia forzada, puesto que estamos forzando la herencia al no dar opción a crear objetos de la clase padre.

Esto puede extenderse a los métodos: queremos que todas las clases implementen un método que sea “numeroDePatas” que no reciba ningún parámetro y devuelva un número entero. ¿Cómo lo haré?

public abstract class Mamífero { . . . public abstract int numeroDePatas(); . . . }

Es decir, pongo únicamente la cabecera (tipo devuelto, nombre, parámetros, punto y coma) y obligo así a que todas las clases hijas tengan que implementar dicho método, encontrando de lo contrario un error de compilación:

public class Perro { . . . public int numeroDePatas() { return 4; } . . . }

Page 46: Resumen Java

42 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

8 Ejercicios de programación en java

8.1 Ejemplo básico de un programa en java Completar en él el siguiente código:

/* Crear un programa que calcule el área de un triángulo, el perímetro de una circunferencia y su área, e imprimir el resultado por pantalla. */ public class Ejemplo2 { public static void main (String [] args) { /*implementar el metodo main*/ } }

8.1.1 Solución 5 public class Ejemplo2 { 6 7 public static void main (String [] args) 8 { 9 final double PI = 3.1416; //declaramos la pi como constante */ 10 double base, altura, areaTriangulo; 11 12 // área de un triángulo, suponemos cantidades reales 13 base = 10.5; 14 altura = 12.3; 15 16 areaTriangulo = base * altura / 2; 17 18 System.out.println("El área de un triángulo cuya base es " + 19 base + " y cuya altura es " + altura + " es " + 20 areaTriangulo); 21 22 /* perímetro de la circunferencia, suponemos cantidades reales 23 double radio, perimetroCircunferencia; 24 25 radio = 3.4; 26 27 perimetroCircunferencia = 2*PI*radio; 28 29 System.out.println("El perímetro de la circunferencia de radio" 30 + radio + " es " + perimetroCircunferencia); 31 32 // área de una circunferencia, suponemos cantidades reales 33 double area_circunferencia; 34 35 radio = 2.5; 36 37 area_circunferencia = PI*radio*radio; 38 39 System.out.println("El área de una circunferencia de radio " 40 + radio + " es " + area_circunferencia); 41 } 42 }

Page 47: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 43

8.2 Ejercicios sobre estructuras de control

8.2.1 Ejercicio 1 Reescribir los ejemplos de ruptura de flujo con “continue” y “break” incluidos en el programa de muestra para que no necesiten utilizar estos mecanismos.

8.2.2 Ejercicio 2 Resolver estos tres ejercicios justificando la elección de la estructura o estructuras de control utilizadas en cada uno:

• Dado un mes (representado por un número del 1 al 12) escribir su número de días contando con una variable booleana “bisiesto”, previamente declarada e inicializada, que indica si el año en curso es bisiesto.

• Pedir al usuario cinco cadenas de texto y generar una sola cadena uniéndolas todas. Escribir esa cadena por pantalla.

• Ir pidiendo por teclado una serie de números enteros e irlos sumando. Se deja de pedir números al usuario cuando la cantidad supera el valor 50. Escribir por pantalla la suma de todos los números introducidos.

• Pedir al usuario dos números “a” y “b” entre el 1 y el 10. Mientras uno de ellos sea menor que el otro, escribir un símbolo “*” en la pantalla e incrementar en una unidad el número menor.

8.2.3 Ejercicio 3 Pedir al usuario un número entero y calcular el factorial de dicho número usando la estructura “do-while”. Repetir el ejercicio usando la estructura “while”, y repetirlo una vez más usando la estructura “for”.

8.2.4 Solución a los ejercicios de estructuras de control del 1 al 3 1 import java.util.Scanner; 3 public class Soluciones 4 { 5 public static void main(String [] args) 6 { 7 Scanner teclado = new Scanner(System.in); 8 9 // Ejercicio 1: 10 11 // Eliminar el continue: 12 for (int k=1; k<11; k++) 13 { 14 if (k%2==0) 15 { 16 System.out.println("El número " + k + " es par."); 17 } 18 } 19 20 // Eliminar el break (solución 1): 21 int miNumero = 1853; 22 int temp1=0; 23 while (temp1!=miNumero) 24 { 25 temp1++;

Page 48: Resumen Java

44 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

26 } 27 System.out.println("Tu número era el " + temp1); 28 29 // Eliminar el break (solución 2): 30 miNumero = 1853; 31 int temp2=0; 32 boolean encontrado = false; 33 while (!encontrado) 34 { 35 if (miNumero == temp2) 36 { 37 System.out.println("Tu número era el " + temp2); 38 encontrado = true; 39 } 40 else 41 { 42 temp2++; 43 } 44 } 45 46 // Ejercicio 2: 47 48 // Averiguar el número de días de cada mes 49 int mes = 6; 50 boolean bisiesto = false; 51 switch (mes) 52 { 53 case 1: 54 case 3: 55 case 5: 56 case 7: 57 case 8: 58 case 10: 59 case 12: 60 System.out.println("El mes "+mes+" tiene 31 días."); 61 break; 62 case 2: 63 if (bisiesto) 64 { 65 System.out.println("El mes 2 tiene 29 días."); 66 } 67 else 68 { 69 System.out.println("El mes 2 tiene 28 días."); 70 } 71 break; 72 default: 73 System.out.println("El mes "+mes+" tiene 30 días."); 74 } // switch 75 76 // Pedir cadenas de texto y concatenarlas 77 String cadena=""; 78 for (int i=0;i<5;i++) 79 { 80 System.out.println("Introduce un texto: "); 81 cadena+= teclado.next(); 82 } 83 System.out.println("La cadena completa es: " + cadena); 84 85 //Ir sumando números hasta llegar a 50 86 int suma=0;

Page 49: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 45

87 do 88 { 89 System.out.println("Introduce un número: "); 90 suma+=teclado.nextInt(); 91 } while(suma<=50); 92 System.out.println("La suma es " + suma); 93 94 //Pedir números entre 1 y 10 95 int a, b, mayor, menor; 96 System.out.println("Introduce un número entre 1 y 10: "); 97 a = teclado.nextInt(); 98 System.out.println("Introduce otro número entre 1 y 10: "); 99 b = teclado.nextInt(); 100 if (a>b) 101 { 102 mayor = a; 103 menor = b; 104 } 105 else 106 { 107 mayor = b; 108 menor = a; 109 } 110 while (menor<mayor) 111 { 112 System.out.println("*"); 113 menor++; 114 } 115 116 // Ejercicio 3: 117 System.out.println("Introduce un número: "); 118 int numero = teclado.nextInt(); 119 int factorial; // Resultado 120 121 // Factorial con "for" 122 factorial = 1; 123 for(int i=numero; i>0; i--) 124 { 125 factorial*=i; 126 } 127 System.out.println("El factorial de " + numero + 128 " calculado con \"for\" da: " + factorial); 129 130 // Factorial con "while" (opción 1) 131 factorial = 1; 132 int i = 0; 133 while(i<numero) 134 { 135 i++; 136 factorial*=i; 137 } 138 System.out.println("El factorial de " + numero + 139 " calculado con \"while\" da: " + factorial); 140 141 // Factorial con "while" (opción 2) 142 factorial = 1; 143 int copiaNumero = numero; 144 while(copiaNumero>0) 145 { 146 factorial*=copiaNumero; 147 copiaNumero--;

Page 50: Resumen Java

46 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

148 } 149 System.out.println("El factorial de " + numero + 150 " calculado con \"while\" da: " + factorial); 151 152 // Factorial con "do-while" 153 factorial = 1; 154 copiaNumero = numero; 155 do 156 { 157 factorial *= copiaNumero; 158 copiaNumero --; 159 } while (copiaNumero>0); 160 System.out.println("El factorial de " + numero + 161 " calculado con \"do-while\" da: " + factorial); 162 163 } // main 164 } // Soluciones Obsérvese que había un error en el programa de ejemplo de la clase anterior. El código correspondiente a la ruptura de flujo con “continue” sería: /* ROMPER EL FLUJO: continue(evitarlo siempre que se pueda) */ for (int k=1; k<11; k++) { if (k%2!=0) { continue; } System.out.println("El número " + k + " es par."); }

Page 51: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 47

8.3 Ejercicios sobre clases y objetos

8.3.1 Ejercicio 1 Resolver el ejercicio planteado en la primera clase utilizando clases y objetos: es decir, definiendo clases que representen los conceptos de triángulo y circunferencia. Programaremos una tercera clase que será la que tenga el método main. Desde este método crearemos objetos concretos de triángulos y circunferencias, y utilizando los atributos y métodos de dichas clases obtendremos área y perímetro

8.3.1.1 Solución

1 public class PrimeraClase { 2 3 public static void main(String [] args) 4 { 5 // TRIÁNGULO 6 Triangulo t = new Triangulo(); 7 t.setAltura(4.34); 8 t.setBase(3); 9 double areaTriangulo = t.getArea(); 10 System.out.println("El área del triángulo de lado " + t.getBase() + " y altura " + 11 + t.getAltura() + " es " + areaTriangulo); 12 // CIRCUNFERENCIA 13 Circunferencia c = new Circunferencia(2.34); 14 System.out.println("El perímetro de la circunferencia de radio" + c.getRadio() + " es " + 15 c.getPerimetro() + " y su área es " + c.getArea()); 16 } 17 }

Triangulo

private double base;private double altura;

public double getAltura();public double getBase();public double getArea();public void setBase(double base);public void setAltura(double altura);

Circunferencia

private double radio;private double area;private double perimetro;private final double PI = 3.1416;

public Circunferencia(double radio);public double getRadio();public double getArea();public void getPerimetro();

PrimeraClase

public static void main(String [] args)

Triangulo

private double base;private double altura;

public double getAltura();public double getBase();public double getArea();public void setBase(double base);public void setAltura(double altura);

Triangulo

private double base;private double altura;

public double getAltura();public double getBase();public double getArea();public void setBase(double base);public void setAltura(double altura);

Circunferencia

private double radio;private double area;private double perimetro;private final double PI = 3.1416;

public Circunferencia(double radio);public double getRadio();public double getArea();public void getPerimetro();

Circunferencia

private double radio;private double area;private double perimetro;private final double PI = 3.1416;

public Circunferencia(double radio);public double getRadio();public double getArea();public void getPerimetro();

PrimeraClase

public static void main(String [] args)

PrimeraClase

public static void main(String [] args)

Page 52: Resumen Java

48 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

1 public class Triangulo { 2 3 private double base; 4 private double altura; 5 6 public double getAltura() 7 { 8 return altura; 9 } 10 public void setAltura(double altura) 11 { 12 this.altura = altura; 13 } 14 public double getBase() 15 { 16 return base; 17 } 18 public void setBase(double base) 19 { 20 this.base = base; 21 } 22 23 public double getArea() 24 { 25 return ((this.base * this.altura) / 2); 26 } 27 }

1 public class Circunferencia { 2 3 private double radio; 4 private double area; 5 private double perimetro; 6 private final double PI = 3.1416; 7 8 public Circunferencia(double radio) { 9 super(); // no es necesario 10 this.radio = radio; 11 this.area = this.PI * this.radio * this.radio; 12 this.perimetro = 2 * this.PI * this.radio; 13 } 14 15 public double getRadio() { 16 return radio; 17 } 18 19 public double getArea() { 20 return area; 21 } 22 23 public double getPerimetro() { 24 return perimetro; 25 } 26 }

Page 53: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 49

8.3.2 Ejercicio 2 Se pide que creéis una clase Tarjeta que tiene como características el número de cuenta que se asocia con la tarjeta, el saldo de la cuenta asociada a la tarjeta, el número secreto de la tarjeta y la cantidad máxima diaria a sacar. Con la clase Tarjeta se puede realizar movimientos como sacar dinero, ingresar dinero y consultar el saldo, también se puede realizar cambios en la cantidad máxima a sacar y realizar comprobaciones como introducir el número secreto y comprobar que sea el mismo que el de la tarjeta.

Dentro del método de sacar dinero se tiene que tener en cuenta dos condiciones: la primera es que no se puede dejar la cuenta en menos de 200 euros y la segunda que no se puede pedir sacar cantidades superiores a la cantidad máxima diaria.

Si esto sucediera se tendría que sacar por pantalla un mensaje que dijera porqué no se ha podido realizar la operación.

Se pide también crear un programa principal main (puede ser dentro de la clase Tarjeta o en otra clase) donde se cree un objeto tarjeta (o varios) y se añadan unas serie de datos. Por ejemplo: numero de cuenta 135, saldo disponible 2320 €, saldo máximo a sacar 500 € y el número secreto 3212. Después realizar los pasos que supuestamente realizarías en un cajero:

• Introducir el código clave y comprobar que es el correcto, si no dar un mensaje de error (esto se realiza llamando al método de la clase Tarjeta que implemente esta acción).

• Si no da error sacar dinero de la cuenta. Podéis probar a sacar una cantidad superior a la permitida, etc.

• Ir pidiendo por teclado una serie de números enteros e irlos sumando. Se deja de pedir números al usuario cuando la cantidad supera el valor 50. Escribir por pantalla la suma de todos los números introducidos.

• Pedir al usuario dos números “a” y “b” entre el 1 y el 10. Mientras uno de ellos sea menor que el otro, escribir un símbolo “*” en la pantalla e incrementar en una unidad el número menor.

8.3.2.1 Solución

1 import java.util.Scanner; 2 import java.util.InputMismatchException; 3 4 public class Tarjeta 5 { 6 private double numCuenta; 7 private double saldoCuenta; 8 private int numSecreto; 9 private double cantidadMaximaDiaria; 10 private double limiteCuenta = 200; 11 12 public Tarjeta (double numCuenta, double saldoCuenta, int numSecreto, double cantidadMaximaDiaria) 13 { 14 this.numCuenta = numCuenta; 15 this.saldoCuenta = saldoCuenta; 16 this.numSecreto = numSecreto; 17 this.cantidadMaximaDiaria = cantidadMaximaDiaria;

Page 54: Resumen Java

50 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

18 } 19 20 public void ingresarDinero(double ingreso) 21 { 22 saldoCuenta += ingreso; 23 } 24 25 public void sacarDinero (double dinero) 26 { 27 if (dinero <= cantidadMaximaDiaria) 28 { 29 if ((saldoCuenta - dinero) >= limiteCuenta) 30 saldoCuenta -=dinero; 31 else 32 System.out.println("La cantidad no puede estar por debajo de 200"); 33 } 34 else 35 System.out.println("La cantidad máxima diaria que puede sacar con la tarjeta es:" + cantidadMaximaDiaria); 36 } 37 38 public double consultarSaldo() 39 { 40 return saldoCuenta; 41 } 42 43 public void cambiarCantidadMaxDiaria (double cantidad) 44 { 45 cantidadMaximaDiaria = cantidad; 46 } 47 48 public boolean comprobarNumeroSecreto(int numIntroducido) 49 { 50 return (this.numSecreto == numIntroducido); 51 } 52 53 public static void main (String [] args) 54 { 55 Scanner scn = new Scanner(System.in); 56 Tarjeta tarj = new Tarjeta(135,2320,3212,500); 57 // Pasos para sacar introducir sacar dinero de una tarjeta en un cajero 58 // 1. introducir el número clave y ver si es el correcto 59 int numSecreto = 0; 60 // cuenta el número de intentos de número secreto 61 int contador = 0; 62 // operación que se realiza sobre la tarjeta 63 int operacion = 0; 64 // cantidad necesaria para realizar las operaciones 65 int cantidad = 0; 66 do 67 { 68 try 69 { 70 System.out.println("Introduzca el número clave por pantalla"); 71 numSecreto = scn.nextInt(); 72 // Al ponerlo el contador detrás de la lectura de pantalla hace que no cuente los errores no númericos 73 contador++;

Page 55: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 51

74 } 75 catch(InputMismatchException e) 76 { 77 System.out.println("Error se ha introducido el caracter: " + scn.next()); 78 numSecreto = 0; 79 } 80 } while ((!tarj.comprobarNumeroSecreto(numSecreto)) && (contador < 3)); 81 82 if (contador >=3) 83 System.out.println("Ha realizado tres intentos y el número no es el correcto, por favor, retire la tarjeta."); 84 else 85 { 86 do 87 { 88 // Texto para elegir la opcion a realizar 89 System.out.println("Teclee 1 si quiere sacar dinero."); 90 System.out.println("Teclee 2 si quiere introducir dinero."); 91 System.out.println("Teclee 3 si quiere consultar saldo."); 92 System.out.println("Teclee 4 si quiere cambiar la cantidad máxima a sacar."); 93 System.out.println("Teclee 5 si quiere salir."); 94 try 95 { 96 operacion = scn.nextInt(); 97 switch(operacion) 98 { 99 case 1: 100 try 101 { 102 System.out.println("Introduzca la cantidad a sacar:"); 103 cantidad = scn.nextInt(); 104 tarj.sacarDinero (cantidad); 105 } 106 catch(InputMismatchException e) 107 { 108 System.out.println("Error se ha introducido el caracter: " + scn.next()); 109 cantidad = 0; 110 } 111 break; 112 _ case 2: 113 _ try 114 _ { 115 System.out.println("Introduzca la cantidad a ingresar:"); 116 cantidad = scn.nextInt(); 117 tarj.ingresarDinero(cantidad); 118 } 119 catch(InputMismatchException e) 120 { 121 System.out.println("Error se ha introducido el caracter: " + scn.next()); 122 cantidad = 0; 123 } 124 break; 125 case 3:

Page 56: Resumen Java

52 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

126 System.out.println("Su saldo es de: " + tarj.consultarSaldo() + " euros"); 127 break; 128 case 4: 129 try 130 { 131 System.out.println("Introduzca la cantidad máxima diaria:"); 132 cantidad = scn.nextInt(); 133 tarj.cambiarCantidadMaxDiaria(cantidad); 134 } 135 catch(InputMismatchException e) 136 { 137 System.out.println("Error se ha introducido el caracter: " + scn.next()); 138 cantidad = 0; 139 } 140 break; 141 case 5: 142 break; 143 default: 144 System.out.println("El número introducido no corresponde con ninguna opción."); 145 } // end del switch 146 } 147 catch(InputMismatchException e) 148 { 149 System.out.println("Error se ha introducido el caracter: " + scn.next()); 150 operacion = 0; 151 } 152 }while (operacion != 5); // end del while 153 } // end del if (contador > 3) 154 } // end metodo main 155 } // end class

8.3.3 Ejercicio 3 Parte 1

Desarrollar una clase "Director" dentro de un paquete llamado "ejercicios". La clase tendrá tres atributos privados que representan el nombre, el país de origen y el año de nacimiento de un director. Añadir un constructor con tres argumentos correspondientes a sus tres atributos. Añadir un método público llamado "imprimir", que escriba en pantalla los datos del director.

Parte 2

Desarrollar una clase "Pelicula" dentro del mismo paquete "ejercicios".La clase tendrá tres atributos privados que representan el título, el año de producción y el director de una película. Añadir tres constructores: uno que reciba únicamente el título, otro que reciba únicamente el director, y uno que no reciba argumentos. Añadir un método público llamado "imprimir", que escriba en pantalla los datos de la película incluyendo los datos del director.

Parte 3

Añadir a la clase "Película" los métodos públicos getTitulo, setTitulo, getAño, setAño, getDirector y setDirector. Los métodos "get" permitirán obtener el valor del atributo en

Page 57: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 53

cuestión, por lo que el tipo de retorno coincidirá con el del atributo. Los métodos "set" permitirán actualizar el valor del atributo, para lo que recibirán un argumento cuyo tipo coincidirá con el del atributo. Añadir un método "main" a la clase "Pelicula" y realizar los siguientes experimentos:

Experimento1

- Crear un objeto director para Woody Allen, nacido en Francia en 1935.

- Crear un objeto película con el constructor vacío para "Manhattan".

- Añadir al objeto los datos de su título, año de producción (1979) y director (Woody Allen).

- Imprimir los datos de la película por pantalla.

Experimento2

- Crear un objeto director para Peter Jackson, nacido en Nueva Zelanda en 1961.

- Crear un objeto película sabiendo únicamente que se titula "El Señor de los Anillos".

- Completar el objeto actualizando el año de producción (2001) y director (Peter Jackson).

- Imprimir los datos de la película por pantalla.

Experimento3

- Crear un objeto película sabiendo únicamente que será del director Woody Allen.

- Completar los datos de título ("Días de Radio") y año de producción (1987).

- Imprimir los datos de la película por pantalla.

Experimento4

- Actualizar el siguiente dato exactamente de la siguiente forma: "el lugar de nacimiento del director de "Días de Radio" es Estados Unidos".

- Imprimir de nuevo en pantalla los datos de las tres películas y observar los resultados.

Objetivos de los ejercicios

* Practicar con conceptos básicos de una clase: paquete, atributos, constructor y métodos.

* Practicar con diferentes constructores.

* Aclarar que los atributos de clase pueden ser objetos de otras clases.

* Practicar con el concepto de sobrecarga al presentar métodos con el mismo número de argumentos pero distinto tipo.

* Demostrar la utilidad de los métodos get y set para consultar y actualizar atributos privados.

Page 58: Resumen Java

54 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

8.3.3.1 Solución

1 package ejercicios; 2 3 public class Director { 4 5 private String nombre; 6 private String paisOrigen; 7 private int añoNacimiento; 8 9 10 public Director(String nombre, String pais, int año) { 11 this.nombre = nombre; 12 this.paisOrigen = pais; 13 this.añoNacimiento = año; 14 } 15 16 public int getAñoNacimiento() { 17 return añoNacimiento; 18 } 19 20 public void setAñoNacimiento(int añoNacimiento) { 21 this.añoNacimiento = añoNacimiento; 22 } 23 24 public String getNombre() { 25 return nombre; 26 } 27 28 public void setNombre(String nombre) { 29 this.nombre = nombre; 30 } 31 32 public String getPaisOrigen() { 33 return paisOrigen; 34 } 35 36 public void setPaisOrigen(String paisOrigen) { 37 this.paisOrigen = paisOrigen; 38 } 39 40 public void imprimir() { 41 System.out.println(this.nombre + ", nacido en " + 42 this.paisOrigen + " en " + this.añoNacimiento + "."); 43 } 44 }

Page 59: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 55

1 package ejercicios; 2 3 public class Pelicula { 4 5 private String titulo; 6 private int año; 7 private Director director; 8 9 public Pelicula() { 10 } 11 12 public Pelicula(String titulo) { 13 this.titulo = titulo; 14 } 15 16 public Pelicula(Director director) { 17 this.director = director; 18 } 19 20 public int getAño() { 21 return año; 22 } 23 24 public void setAño(int año) { 25 this.año = año; 26 } 27 28 public Director getDirector() { 29 return director; 30 } 31 32 public void setDirector(Director director) { 33 this.director = director; 34 } 35 36 public String getTitulo() { 37 return titulo; 38 } 39 40 public void setTitulo(String titulo) { 41 this.titulo = titulo; 42 } 43 44 public void imprimir() { 45 System.out.print("La película \"" + this.titulo + "\" fue realizada en " + 46 this.año + " por el director "); 47 this.director.imprimir(); 48 } 49 50 public static void main(String[] args) { 51 52 // Experimento 1__ 53 Director woodyAllen = new Director ("Woody Allen", "Francia", 1935); 54 55 Pelicula manhattan = new Pelicula(); 56 manhattan.setTitulo("Manhattan"); 57 manhattan.setAño(1979); 58 manhattan.setDirector(woodyAllen); 59

Page 60: Resumen Java

56 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

60 manhattan.imprimir() ; 61 62 // Experimento 2 63 Director peterJackson = new Director ("Peter Jackson", "Nueva Zelanda", 1961); 64 65 Pelicula señorAnillos = new Pelicula("El Señor de los Anillos"); 66 señorAnillos.setAño(2001); 67 señorAnillos.setDirector(peterJackson); 68 69 señorAnillos.imprimir(); 70 71 //Experimento 3 72 Pelicula diasDeRadio = new Pelicula(woodyAllen); 73 diasDeRadio.setTitulo( "Días de Radio"); 74 diasDeRadio.setAño(1987); 75 76 diasDeRadio.imprimir() ; 77 78 //Experimento 4 79 diasDeRadio.getDirector().setPaisOrigen("Estados Unidos"); 80 81 manhattan.imprimir(); 82 señorAnillos.imprimir(); 83 diasDeRadio.imprimir() ; 84 } 85 } 86

Page 61: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 57

8.4 Ejercicios sobre estructuras de almacenamiento

8.4.1 Ejercicio 1 Escribir un programa que calcule la diagonal de una matriz cuadrada de lado “n”. Puedes darle valores fijos o pedirlos al usuario por teclado.

8.4.1.1 Solución 1 public class Diagonal 2 { 3 public static void main (String[] args) 4 { 5 // En la solución a este ejercicio nosotros proponemos dar valores a la matriz 6 // mediante un pequeño algoritmo para no tener que insertar uno a uno los valores 7 // en la siguiente matriz que nos creamos de tamaño N = 3. 8 // La matriz siguiente quedaría de la siguiente forma 1 2 3 9 // 2 4 6 10 // 3 6 9 11 12 final int N = 3; 13 14 int [][] matriz = new int [N][N]; 15 for (int i= 0 ; i < matriz.length ; i++) 16 for (int j = 0; j < matriz[i].length; j++) 17 matriz[i][j] = (i+ 1)*(j + 1); 18 19 // calculo de la diagonal multiplicando todos 20 // los elementos de la diagonal de la matriz 21 22 int resDiagonal = 1; 23 for (int i= 0 ; i < matriz.length ; i++) 24 resDiagonal = resDiagonal * matriz[i][i]; 25 26 System.out.println(resDiagonal); 27 28 } 29 }

8.4.2 Ejercicio 2 Escribir un programa que pida al usuario por teclado números que introducirá en una estructura de almacenamiento hasta que el usuario introduzca un “0”. Sumar todos los números que se han almacenado en dicha estructura de control y mostrar el resultado por pantalla.

8.4.2.1 Solución 1 import java.util.Scanner; 2 import java.util.ArrayList; 3 public class SumaEstructura 4 { 5 public static void main (String[] args) 6 { 7 // Al no saber a priori el número de elementos 8 // que se van a recibir del alumno la estructura 9 // de almacenamiento a utilizar tiene que poder 10 // ser dinamica. Nosotros proponemos el uso del

Page 62: Resumen Java

58 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

11 // ArrayList para resolver este ejercicio. 12 13 ArrayList <Integer> almacenNum = new ArrayList <Integer> (); 14 15 Scanner teclado = new Scanner (System.in); 16 17 // incializo el num a un valor que no sea 0 para que si 18 // el usuario no introduce un número sino por ejemplo un 19 // caracter pueda seguir pidiendole número y no salirse 20 // asi del bucle. 21 int num = -1; 22 do { 23 try 24 { 25 System.out.println ("Introduce un número por teclado: "); 26 num = teclado.nextInt(); 27 almacenNum.add(num); 28 } 29 catch (Exception e) 30 { 31 System.out.println("Se necesita introducir un número para poder realizar la suma."); 32 teclado.nextLine(); // con esta sentencia hace que no se vuelva a leer de teclado el mismo valor que no es numérico 33 } 34 } 35 while (num != 0); 36 37 int suma = 0; 38 for (Integer a_num :almacenNum) 39 suma += a_num; 40 41 System.out.println("El resultado de todos los números insertados es: " + suma ); 42 43 } 44 }

8.4.3 Ejercicio 3 Razona qué estructura (array o ArrayList) has escogido para resolver los problemas anteriores.

8.4.3.1 Solución Se elige una estructura ArrayList puesto que a priori no se sabe la cantidad de números que va a introducir el usuario. Si lo hiciéramos con un Array necesitaríamos saber antes de insertar los números que cantidad va a insertar el usuario y parar la petición de entrada de números cuando se haya llenado el Array.

Page 63: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 59

8.5 Ejercicios de composición, herencia y polimorfismo

8.5.1 Ejercicio 1 Un gran almacén se dedica a la venta de productos de alimentación, ropa y electrónica. Cada producto se caracteriza por un precio, un nombre y un código de barras. Los productos de alimentación tiene a su vez una fecha de caducidad (se puede crear con enteros para el día, el mes y la hora). Los productos electrónicos tienen un plus adicional por ser tener todos 3 años de garantía y los productos de ropa tienen como característica el material en que han sido elaborados (sólo el material principal). El almacén realiza ventas, cada venta puede estar formada un código de venta y por varios productos. Se desea:

1. Realizar un diagrama donde se vean las relaciones entre clases, junto a los atributos y métodos de cada una.

2. Se desea que la clase venta tenga un método que realice la suma de 3 productos: una pizza de 3,5 euros, un pijama de 30 euros y un reproductor de mp3 de 80 euros con un plus de 8,5.

3. Implementar todas las clases con sus atributos y métodos.

4. Ejecutar el ejemplo del apartado 2 para ver que precio da la suma de la compra.

8.5.1.1 Solución Diagrama de clases

Producto

private String codigoBarras;

private String nombre;

private double precio;

public Producto(String codigoBarras, String nombre, double precio)

public double calcularPrecio()

Alimentacion

private GregorianCalendar fechaCad;

public Alimentacion(StringcodigoBarras, String nombre, doubleprecio, GregorianCalendar fecha)

Electrónica

private double plus;

public Ropa(String codigoBarras, String nombre, double precio, doubleplus)

public double calcularPrecio()

Ropa

private String material;

public Ropa(String codigoBarras, String nombre, double precio, Stringmaterial)

Venta

private static long codVenta = 0;

private Vector productos;

public Venta()

public void añadirProducto(Productopr)

Public double calcularVenta()

Producto

private String codigoBarras;

private String nombre;

private double precio;

public Producto(String codigoBarras, String nombre, double precio)

public double calcularPrecio()

Producto

private String codigoBarras;

private String nombre;

private double precio;

public Producto(String codigoBarras, String nombre, double precio)

public double calcularPrecio()

Alimentacion

private GregorianCalendar fechaCad;

public Alimentacion(StringcodigoBarras, String nombre, doubleprecio, GregorianCalendar fecha)

Alimentacion

private GregorianCalendar fechaCad;

public Alimentacion(StringcodigoBarras, String nombre, doubleprecio, GregorianCalendar fecha)

Electrónica

private double plus;

public Ropa(String codigoBarras, String nombre, double precio, doubleplus)

public double calcularPrecio()

Electrónica

private double plus;

public Ropa(String codigoBarras, String nombre, double precio, doubleplus)

public double calcularPrecio()

Ropa

private String material;

public Ropa(String codigoBarras, String nombre, double precio, Stringmaterial)

Ropa

private String material;

public Ropa(String codigoBarras, String nombre, double precio, Stringmaterial)

Venta

private static long codVenta = 0;

private Vector productos;

public Venta()

public void añadirProducto(Productopr)

Public double calcularVenta()

Page 64: Resumen Java

60 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

1 public class Producto 2 { 3 private String codigoBarras; 4 private String nombre; 5 private double precio; 6 7 public Producto(String codigoBarras, String nombre, double precio) 8 { 9 this.codigoBarras = codigoBarras; 10 this.nombre = nombre; 11 this.precio = precio; 12 } 13 14 15 public double calcularPrecio() 16 { 17 return precio; 18 } 19 20 // El resto de los métodos que se necesitan son los get y set de cada atributo 21 // el getPrecio correspondería con calcularPrecio 22 23 }

1 import java.util.GregorianCalendar; 2 3 public class Alimentacion extends Producto 4 { 5 private GregorianCalendar fechaCaducidad; 6 7 public Alimentacion(String codigoBarras, String nombre, Double precio, GregorianCalendar fecha) 8 { 9 super(codigoBarras,nombre,precio); 10 fechaCaducidad = fecha; 11 12 } 13 14 // El resto de los métodos que se necesitan son los get y set del atributo material, el resto los hereda 15 16 }

Page 65: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 61

1 2 public class Ropa extends Producto 3 { 4 5 private String material; 6 7 public Ropa(String codigoBarras, String nombre, double precio, String material) 8 { 9 super(codigoBarras,nombre,precio); 10 this.material = material; 11 12 } 13 14 // El resto de los métodos que se necesitan son los get y set del atributo material, el resto los hereda 15 16 }

1 public class Electronica extends Producto 2 { 3 4 private double plus; 5 6 7 public Electronica(String codigoBarras, String nombre, double precio, double plus) 8 { 9 super(codigoBarras,nombre,precio); 10 this.plus = plus; 11 12 } 13 public double calcularPrecio() 14 { 15 return super.calcularPrecio() + plus; 16 17 } 18 19 20 // El resto de los métodos que se necesitan son los get y set del atributo material, el resto los hereda 21 22 23 }

Page 66: Resumen Java

62 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

1 import java.util.Vector; 2 import java.util.GregorianCalendar; 3 4 public class Venta 5 { 6 7 private static long codVenta = 0; 8 private Vector productos = new Vector(); 9 10 public Venta(Producto pr) 11 { 12 codVenta++; 13 productos.add(pr); 14 15 } 16 17 public double calcularVenta() 18 { 19 double total = 0; 20 Producto pr; 21 for (int i=0; i< productos.size(); i++) 22 { 23 pr = (Producto) productos.elementAt(i); 24 total += pr.calcularPrecio(); 25 } 26 return total; 27 } 28 29 30 public void añadirProducto(Producto pr) 31 { 32 productos.add(pr); 33 } 34 35 // El resto de los métodos que se necesitan son los get y set 36 37 38 // Vamos a crear un método main aquí como punto de entrada al programa 39 // Podriamos crearnos otra clase que llamará a ventas y en ella poder tener el main 40 41 public static void main (String [] args) 42 { 43 44 GregorianCalendar fechaCadPizza = new GregorianCalendar(2006,12,23); 45 46 Alimentacion pizza = new Alimentacion("1111","Pizza Buitone 4 quesos", 3.5,fechaCadPizza); 47 Ropa pijama = new Ropa("2222","Pijama caballero",30,"algodon"); 48 Electronica mp3 = new Electronica("3333","mp3",80,8.5); 49 Venta v1 = new Venta(pizza); 50 v1.añadirProducto(pijama); 51 v1.añadirProducto(mp3); 52 System.out.println("El total de la compra es: " + v1.calcularVenta()); 53 54 } 55 }

Page 67: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 63

8.5.2 Ejercicio 2 La librería “Nuevo Mundo” ha decidido gestionar las ventas de sus libros, revistas y cómic. Las ventas pueden ser de varias obras a la vez, ya sean libros, revistas o cómic. Cada obra se caracteriza por tener en común el identificador, el nombre, el nombre del autor (supongamos que sólo hay un autor), la editorial, el año de edición y el precio. Las revistas a su vez tienen el número de serie. Los cómic también tienen el número del dibujante. Además cada obra dispone del IVA que se tiene que aplicar. Éste será siempre el mismo en función del tipo de obra: las revistas el 7%, los libros el 3% y los cómics el 10%. También se podrá realizar el cálculo del precio final sumando al precio de la obra el IVA correspondiente. Se pide:

1. Dibujar un esquema con las clases necesarias para este programa, indicando los atributos y los métodos en caso de haberlos.

2. Implementar la clase Venta. ¿Qué estructura sería la más adecuada para poder almacenar todas las obras que se venden?

3. Suponiendo que la clase venta tiene un método que sea importe de la venta. Implementar dicho método para que calcule el coste total de la venta.

8.5.2.1 Solución Solución apartado 1

No se han puesto en el esquema pero también serían necesarios los métodos get y set de cada atributo en cada clase.

Ventaprivate Vector obras_vendidas = new Vector();

public Venta ()

public Venta (Vector obras_vendidas)

public void addObra(Obra obra)

public double importeVenta()

Obra (Abstract)private int id;

private String nombre;

private String autor;

private String editorial;

private int añoEdiccion;

private double precio;

public Obra(int id, String nombre,

String autor, String editorial, int

añoEdiccion, double precio)

public abstract double

calcularImporte()

Comicprivate String nDibujante;

private static final double iva = 10;

public Obra(int id, String nombre,

String autor, String editorial, int

añoEdiccion, double precio,

String nDibujante)

public double calcularImporte()

Libroprivate static final double iva = 3;

public Libro(int id, String nombre,

String autor, String editorial, int

añoEdiccion, double precio)

public double calcularImporte()

Revistaprivate int numSerie;

private static final double iva = 7;

public Revista(int id, String

nombre, String autor, String

editorial, int añoEdiccion, double

precio, int numSerie)

public double calcularImporte()

No se han puesto en el esquema pero también serían necesarios los métodos get y set de cada atributo en cada clase.

Ventaprivate Vector obras_vendidas = new Vector();

public Venta ()

public Venta (Vector obras_vendidas)

public void addObra(Obra obra)

public double importeVenta()

Ventaprivate Vector obras_vendidas = new Vector();

public Venta ()

public Venta (Vector obras_vendidas)

public void addObra(Obra obra)

public double importeVenta()

Obra (Abstract)private int id;

private String nombre;

private String autor;

private String editorial;

private int añoEdiccion;

private double precio;

public Obra(int id, String nombre,

String autor, String editorial, int

añoEdiccion, double precio)

public abstract double

calcularImporte()

Obra (Abstract)private int id;

private String nombre;

private String autor;

private String editorial;

private int añoEdiccion;

private double precio;

public Obra(int id, String nombre,

String autor, String editorial, int

añoEdiccion, double precio)

public abstract double

calcularImporte()

Comicprivate String nDibujante;

private static final double iva = 10;

public Obra(int id, String nombre,

String autor, String editorial, int

añoEdiccion, double precio,

String nDibujante)

public double calcularImporte()

Comicprivate String nDibujante;

private static final double iva = 10;

public Obra(int id, String nombre,

String autor, String editorial, int

añoEdiccion, double precio,

String nDibujante)

public double calcularImporte()

Libroprivate static final double iva = 3;

public Libro(int id, String nombre,

String autor, String editorial, int

añoEdiccion, double precio)

public double calcularImporte()

Libroprivate static final double iva = 3;

public Libro(int id, String nombre,

String autor, String editorial, int

añoEdiccion, double precio)

public double calcularImporte()

Revistaprivate int numSerie;

private static final double iva = 7;

public Revista(int id, String

nombre, String autor, String

editorial, int añoEdiccion, double

precio, int numSerie)

public double calcularImporte()

Revistaprivate int numSerie;

private static final double iva = 7;

public Revista(int id, String

nombre, String autor, String

editorial, int añoEdiccion, double

precio, int numSerie)

public double calcularImporte()

Page 68: Resumen Java

64 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

Solución apartados 2 y 3.

import java.util.Vector; public class Venta { private Vector obras_vendidas = new Vector();

public Venta (){} public Venta (Vector obras_vendidas) {this.obras_vendidas = obras_vendidas;}

public void addObra(Obra obra) {obras_vendidas.addElement(obra);}

public Vector getObras_vendidas() {return obras_vendidas;}

public void setObras_vendidas(Vector obras_vendidas) {this.obras_vendidas = obras_vendidas;}

public double importeVenta() { double costeTotal = 0; Obra ob; for(int i=0; i < obras_vendidas.size();i++) {

ob = (Obra)obras_vendidas.elementAt(i); costeTotal += ob.calcularImporte(); } return costeTotal; }

}

La estructura más adecuada sería la del Vector ya que no se sabe a priori las ventas que se van a realizar.

8.5.3 Ejercicio 3

Se desea diseñar un programa que tendrá que ser capaz de gestionar obras cinematográficas, literarias y musicales, permitiendo la creación, modificación y acceso de las diferentes obras y sus autores, así como la impresión por pantalla de sus datos más característicos. De todas las obras necesitamos saber su título, su autor y año de edición. Además, en concreto, de los libros nos interesa su editorial y su número de páginas; de los discos queremos saber la discográfica que lo edita y el número de canciones; y de las películas interesan los intérpretes y la productora. Todos los autores de una obra, así como los intérpretes de una película, se consideran artistas. De cada artista queremos saber su nombre y su año de nacimiento. Por último, se desea poder imprimir en pantalla todos los datos de cada obra..

Se pide:

1. Dibujar un esquema con las clases necesarias para este programa, indicando los atributos y métodos que tiene cada una (sólo indicarlos, sin escribir su código). El esquema debe reflejar gráficamente la herencia de clases en caso de que la haya.

2. Codificar la clase correspondiente a las películas.

Page 69: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 65

Supongamos a partir de ahora que estamos programando el método “main”, y que hemos creado los siguientes objetos:

Clase Nombre objeto Datos

Artista gonzaloSuarez Nombre: “Gonzalo Suárez”; Año de nacimiento: 1954

Artista carmeloGomez Nombre: “Carmelo Gómez”; Año de nacimiento: 1962

Artista maribelVerdu Nombre: “Maribel Verdú”; Año de nacimiento: 1970

Libro ciudadanoSade Título: “Ciudadano Sade”; Autor: gonzaloSuarez; Año de producción: 1999; Editorial: “Plaza&Janés”; Número de páginas: 256

3. Escribir el código necesario para crear el objeto correspondiente a la película "El portero" (Gonzalo Suárez, 2000, Lola Films, interpretada por Carmelo Gómez y Maribel Verdú).

4. Codificar en una sola línea exactamente la siguiente modificación: "la fecha de nacimiento del autor de la película 'El Portero' es 1934". Si a continuación imprimimos por pantalla los datos del libro "Ciudadano Sade", ¿qué fecha de nacimiento se imprimirá en pantalla para el autor?

8.5.3.1 Solución Solución al apartado 1:

Obra

private String titulo; private Artista autor; private int añoEdicion;

String getTitulo()

void setTitulo(String) Artista getAutor() void setAutor(Artista) int getAñoEdicion() void setAñoEdicion(int)

Libro

private String editorial; private int nPaginas;

Libro(String, Artista, int,

String, int) String getEditorial() void setEditorial(String) int getNPaginas() void setNPaginas(int) void imprimir()

Disco

private String discografica; private int nCanciones;

Disco(String, Artista, int,

String, int) String getDiscografica() void setDiscografica(String) int getNCanciones() void setNCanciones(int) void imprimir()

Pelicula

private String productora; private Artista[] interpretes;

Pelicula(String, Artista, int,

String, Artista[]) Artista[] getInterpretes() void setInterpretes(Artista[]) String getProductora() void setProductora(String) void imprimir()

Obra

String getTitulo()

void setTitulo(String) Artista getAutor() void setAutor(Artista) int getAñoEdicion() void setAñoEdicion(int)

int getAñoNacimiento() void setAñoNacimiento(int)

void setNombre(String)

int getAñoNacimiento() void setAñoNacimiento(int)

Artista

private String nombre; private int añoNacimiento;

Artista(String, int)

String getNombre()

Artista

Artista(String, int)

String getNombre() void setNombre(String)

Libro

Libro(String, Artista, int,

String, int) String getEditorial() void setEditorial(String) int getNPaginas() void setNPaginas(int) void imprimir()

Disco

Disco(String, Artista, int,

String, int) String getDiscografica() void setDiscografica(String) int getNCanciones() void setNCanciones(int) void imprimir()

Pelicula

Pelicula(String, Artista, int,

String, Artista[]) Artista[] getInterpretes() void setInterpretes(Artista[]) String getProductora() void setProductora(String) void imprimir()

Page 70: Resumen Java

66 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

Solución al apartado 2:

public class Pelicula extends Obra { private Artista[] interpretes;

private String productora; public Pelicula(String titulo, Artista autor, int año,

String productora, Artista[] interpretes) { this.setTitulo(titulo); this.setAutor(autor);

this.setAñoProducción(año);

this.productora = productora; this.interpretes = interpretes; }

public void imprimir() { System.out.print("OBRA: " + this.getTitulo() + "; AUTOR: " +

this.getAutor() + "; AÑO DE PRODUCCIÓN:" + this.getAñoProducción()

+ "; PRODUCTORA: " + this.productora + "; INTÉRPRETES:"); int i; for (i=0; i<this.interpretes.length; i++ ) { System.out.print(interpretes[i].toString()); } System.out.println(); } }

Esta solución es posible porque no hemos definido ningún constructor para la clase Obra, por lo que sigue disponible su constructor por defecto. En otro caso habría que programar el constructor de la siguiente forma:

public Pelicula(String titulo, Artista autor, int año,

String productora, Artista[] interpretes) { super(titulo, autor, año); this.productora = productora; this.interpretes = interpretes; }

Solución al apartado 3:

Artista[] interpretes_portero = new Artista[2]; interpretes_portero[0] = carmeloGomez; interpretes_portero[1] = maribelVerdu; Pelicula elPortero = new Pelicula("El portero", gonzaloSuarez ,

2000, "Lola Films", interpretes_portero);

Page 71: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 67

Solución al apartado 4:

Si se han declarado los atributos “private” y se han definido para ellos métodos “get” y “set” (opción más correcta):

elPortero.getAutor().setAñoNacimiento(1934);

En caso contrario:

elPortero.autor.añoNacimiento=1934;

Al imprimir datos del libro, la fecha de nacimiento del autor sería 1934, ya que la modificación hecha con la línea anterior afecta permanentemente al objeto “gonzaloSuarez”.

8.5.4 Ejercicio 4 El Estado, a través de los bancos, oferta deuda pública a sus clientes. La deuda pública tiene distintas modalidades que son: letras del tesoro y bonos. Todas ellas se pueden agrupar en lo que se denomina cartera de inversión. Cualquier deuda tiene la fecha de suscripción, el tipo de interés que oferta y su valor. Además necesita de un método que calcule, dada una fecha, la cantidad de intereses que va generando. Para ello se ha de tener en cuenta que en las letras del tesoro los intereses no se actualizan hasta finalizar el plazo de la deuda y en los bonos se actualizan anualmente. El plazo de la deuda es diferente en función de la modalidad de la deuda. Para las letras del tesoro el plazo es de 2 años, mientras que los bonos tendrán una duración de 5 años.

Se pide:

1. Realizar un diagrama de clases. En este diagrama se debe incluir las clases necesarias, sus relaciones (explicando brevemente el por qué de cada una), los atributos de cada clase, el tipo de éstos y su tipo de acceso. También definir sus métodos incluyendo el constructor. (sólo indicarlos, sin escribir su código).

2. Implementar la clase Letra del Tesoro. 3. Suponemos el siguiente ejemplo:

Manuel tiene una cartera de inversión en el banco con las siguientes deudas:

• 2 letras del tesoro, una por valor de 500 euros al 4% de interés a fecha de 01/10/2005 y la otra por valor de 900 al 5% a fecha de 01/06/2004.

• 2 bonos de estado al 7% de interés con fecha de 10/06/2003 con un valor de 3000.

Se pide:

a. Realizar las sentencias concretas para crear cada una de las deudas expuestas anteriormente.

b. Implementar un método y decir en qué clase se encuentra (añadirlo también al diagrama de clases) dónde se pueda calcular dada una fecha qué intereses produce toda la cartera de inversión. Implementar las sentencias necesarias para dada la fecha de hoy, se pueda saber qué intereses ha generado toda la deuda de la cartera.

Page 72: Resumen Java

68 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

8.5.4.1 Solución Diseño de clases

Implementar la clase Letra del tesoro. import java.util.GregorianCalendar; import java.util.Calendar; public class Letra extends Deuda { final private int iañosPlazo = 2; public Letra (GregorianCalendar gcFechaSuscripcion,int dTipoInteres,int iValor) { this.gcFechaSuscripcion = gcFechaSuscripcion; if ((dTipoInteres > 0) &&(dTipoInteres <= 100)) this.dTipoInteres = dTipoInteres; else System.out.println("El interés debe estar entre 0 y 100."); this.iValor = iValor; } public double calcularInteres (GregorianCalendar fecha) { Calendar gcFechaFinPlazo = gcFechaSuscripcion;

// Suma dos años a la fecha de suscripción gcFechaFinPlazo.add(Calendar.DATE,2); if (gcFechaFinPlazo.getTimeInMillis()<= fecha.getTimeInMillis()) return (iValor*(dTipoInteres/100)); else return 0; }

}

DEUDA (Abstract)

protected GregorianCalendar gcFechaSuscripcion;

protected int iTipoInteres;

protected int iValor;

public GregorianCalendar getGcFechaSuscripcion()

public double getDTipoInteres()

public int getIValor()

public setGcFechaSuscripcion(GregorianCalendar gcFechaSuscripcion)

public void setDTipoInteres(double dTipoInteres)

public void setIValor(int iValor)

abstract public double calcularInteres (GregorianCalendar fecha)

BONO

final private int iañosPlazo = 5;

public Bono (GregorianCalendar gcFechaSuscripcion,

int dTipoInteres,int iValor)

public double calcularInteres (GregorianCalendar fecha)

LETRA

final private int iañosPlazo = 2;

public Letra (GregorianCalendar gcFechaSuscripcion,

int dTipoInteres,int iValor)

public double calcularInteres (GregorianCalendar fecha)

CARTERA

static private int identificador = 0;

private Vector deudas;

public Cartera ()

public int getIdentificador ()

public void addDeuda(Deuda deuda)

public double calcularTotalIntereses

(GregorianCalendar fecha)

DEUDA (Abstract)

protected GregorianCalendar gcFechaSuscripcion;

protected int iTipoInteres;

protected int iValor;

public GregorianCalendar getGcFechaSuscripcion()

public double getDTipoInteres()

public int getIValor()

public setGcFechaSuscripcion(GregorianCalendar gcFechaSuscripcion)

public void setDTipoInteres(double dTipoInteres)

public void setIValor(int iValor)

abstract public double calcularInteres (GregorianCalendar fecha)

DEUDA (Abstract)

protected GregorianCalendar gcFechaSuscripcion;

protected int iTipoInteres;

protected int iValor;

public GregorianCalendar getGcFechaSuscripcion()

public double getDTipoInteres()

public int getIValor()

public setGcFechaSuscripcion(GregorianCalendar gcFechaSuscripcion)

public void setDTipoInteres(double dTipoInteres)

public void setIValor(int iValor)

abstract public double calcularInteres (GregorianCalendar fecha)

BONO

final private int iañosPlazo = 5;

public Bono (GregorianCalendar gcFechaSuscripcion,

int dTipoInteres,int iValor)

public double calcularInteres (GregorianCalendar fecha)

BONO

final private int iañosPlazo = 5;

public Bono (GregorianCalendar gcFechaSuscripcion,

int dTipoInteres,int iValor)

public double calcularInteres (GregorianCalendar fecha)

LETRA

final private int iañosPlazo = 2;

public Letra (GregorianCalendar gcFechaSuscripcion,

int dTipoInteres,int iValor)

public double calcularInteres (GregorianCalendar fecha)

LETRA

final private int iañosPlazo = 2;

public Letra (GregorianCalendar gcFechaSuscripcion,

int dTipoInteres,int iValor)

public double calcularInteres (GregorianCalendar fecha)

CARTERA

static private int identificador = 0;

private Vector deudas;

public Cartera ()

public int getIdentificador ()

public void addDeuda(Deuda deuda)

public double calcularTotalIntereses

(GregorianCalendar fecha)

CARTERA

static private int identificador = 0;

private Vector deudas;

public Cartera ()

public int getIdentificador ()

public void addDeuda(Deuda deuda)

public double calcularTotalIntereses

(GregorianCalendar fecha)

Page 73: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 69

Resolviendo el ejemplo de Manuel. Ejemplo: GregorianCalendar fecha1 = new GregorianCalendar(2005,10,1); GregorianCalendar fecha2 = new GregorianCalendar(2004,6,1); Letra letra1 = new Letra(fecha1,4,500); Letra letra2 = new Letra(fecha2,5,900); GregorianCalendar fecha3 = new GregorianCalendar(2003,6,10); Bono bono1 = new Bono(fecha3,7,3000); Bono bono2 = new Bono(fecha3,7,3000);

Cartera cartera1 = new Cartera(); cartera1.addDeuda(letra1); cartera1.addDeuda(letra2); cartera1.addDeuda(bono1); cartera1.addDeuda(bono2);

Implementar el método calcularTotalIntereses, método de la clase Cartera.

public double calcularTotalIntereses (GregorianCalendar fecha) { double totalDeudas = 0; Deuda auxDeuda; for (int i=0;i<deudas.size();i++) { auxDeuda = (Deuda) deudas.elementAt(i); totalDeudas += auxDeuda.calcularInteres(fecha); } return totalDeudas; }

// por defecto al crear un objeto del tipo gregorian calendar se

// crea con la fecha actual GregorianCalendar fecha4 = new GregorianCalendar();

long interesTotales = cartera1.calcularTotalIntereses(fecha4); System.out.println(interesTotales);

8.5.5 Ejercicio 6 Se desea realizar un programa para gestionar ordenadores. De todo ordenador necesitamos saber su tipo de procesador, su velocidad en GHz, y su memoria RAM. Existen dos tipos de ordenadores: portátiles y sobremesa. De los portátiles queremos saber también su peso en Kg y sus horas de autonomía. De los de sobremesa necesitamos saber qué tipo de monitor tienen. Cada ordenador tiene un método llamado “imprimir” que permite escribir sus datos por pantalla. Parte 1 Realizar un esquema de clases indicando gráficamente la herencia. Por cada clase, indicar sus atributos y métodos (incluyendo constructores).

Page 74: Resumen Java

70 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

Parte 2 Supongamos que no definimos ningún constructor para la clase padre y que los atributos de clase son privados: codificar el constructor de la clase que representa a los ordenadores portátiles. Escribir también el código necesario para que desde el método “main” introduzcamos este ordenador portátil:

• Procesador: “Pentium IV” • Velocidad: 2.1 GHz • Memoria RAM: 512 MB • Peso: 2.7 Kg • Horas de autonomía: 2

8.5.5.1 Solución Parte 1

Ordenador

String procesador

double velocidad

int memoria

Ordenador(String, double)

int getMemoria()

void setMemoria(int)

String getProcesador()

void setProcesador(String)

double getVelocidad()

void setVelocidad(double)

Sobremesa

String tipoMonitor;

public Sobremesa(String, double, int, String)

String getTipoMonitor()

void setTipoMonitor(String)

Portatil

double peso

int horasAutonomia

Portatil(String, double, int, double, int)

int getHorasAutonomia()

void setHorasAutonomia(int)

double getPeso()

void setPeso(double)

Ordenador

String procesador

double velocidad

int memoria

Ordenador(String, double)

int getMemoria()

void setMemoria(int)

String getProcesador()

void setProcesador(String)

double getVelocidad()

void setVelocidad(double)

Ordenador

String procesador

double velocidad

int memoria

Ordenador(String, double)

int getMemoria()

void setMemoria(int)

String getProcesador()

void setProcesador(String)

double getVelocidad()

void setVelocidad(double)

Sobremesa

String tipoMonitor;

public Sobremesa(String, double, int, String)

String getTipoMonitor()

void setTipoMonitor(String)

Sobremesa

String tipoMonitor;

public Sobremesa(String, double, int, String)

String getTipoMonitor()

void setTipoMonitor(String)

Portatil

double peso

int horasAutonomia

Portatil(String, double, int, double, int)

int getHorasAutonomia()

void setHorasAutonomia(int)

double getPeso()

void setPeso(double)

Portatil

double peso

int horasAutonomia

Portatil(String, double, int, double, int)

int getHorasAutonomia()

void setHorasAutonomia(int)

double getPeso()

void setPeso(double)

Page 75: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 71

Parte 2

1 package parte2; 2 public class Ordenador { 3 4 private String procesador; 5 private double velocidad; 6 private int memoria; 7 8 public int getMemoria() { 9 return memoria; 10 } 11 public void setMemoria(int memoria) { 12 this.memoria = memoria; 13 } 14 public String getProcesador() { 15 return procesador; 16 } 17 public void setProcesador(String procesador) { 18 this.procesador = procesador; 19 } 20 public double getVelocidad() { 21 return velocidad; 22 } 23 public void setVelocidad(double velocidad) { 24 this.velocidad = velocidad; 25 } 26 27 public static void main(String[] args) { 28 29 Portatil miPortatil = new Portatil("Pentium IV", 2.1, 512, 2.7, 2); 30 31 // Probamos que se ha creado bien: 32 System.out.println("Procesador: " + miPortatil.getProcesador()); 33 System.out.println("Velocidad: " + miPortatil.getVelocidad()); 34 System.out.println("Memoria: " + miPortatil.getProcesador()); 35 System.out.println("Peso: " + miPortatil.getProcesador()); 36 System.out.println("Horas de autonomía: " + miPortatil.getHorasAutonomia()); 37 38 } 39 }

1 package parte2; 2 public class Portatil extends Ordenador {_ 3 double peso; 4 int horasAutonomia; 5 6 public Portatil(String procesador, double velocidad, int memoria, double peso, int horasAutonomia) { 7 super(); 8 //super.setProcesador(procesador); 9 this.setVelocidad(velocidad); 10 this.setMemoria(memoria); 11 this.peso = peso; 12 this.horasAutonomia = horasAutonomia; 13 }

Page 76: Resumen Java

72 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

14 15 // En este caso, implícitamente lo primero que se hace es llamar al constructor de la clase padre, 16 // super(); 17 // (Ver ahora el comentario en la clase Sobremesa) 18 19 public int getHorasAutonomia() { 20 return horasAutonomia; 21 } 22 23 public void setHorasAutonomia(int horasAutonomia) { 24 this.horasAutonomia = horasAutonomia; 25 } 26 27 public double getPeso() { 28 return peso; 29 } 30 31 public void setPeso(double peso) { 32 this.peso = peso; 33 } 34 35 }

1 package parte2; 2 public class Sobremesa extends Ordenador{ 3 String tipoMonitor; 4 5 public Sobremesa(String procesador, double velocidad, int memoria, String tipoMonitor) { 6 super(); 7 this.setProcesador(procesador); 8 this.setVelocidad(velocidad); 9 this.setMemoria(memoria); 10 this.tipoMonitor = tipoMonitor; 11 } 12 13 // (Leer antes el comentario en la clase Portatil) 14 // Aunque no es necesario, podemos llamar nosotros explícitamente a ese constructor por defecto 15 16 public String getTipoMonitor() { 17 return tipoMonitor; 18 } 19 20 public void setTipoMonitor(String tipoMonitor) { 21 this.tipoMonitor = tipoMonitor; 22 } 23 24 }

Page 77: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 73

8.5.6 Ejercicio 7 Una empresa de telecomunicaciones nos encarga realizar la primera versión de un programa para gestionar mensajes de texto en diferentes formatos: e-mail, SMS (mensajes cortos de telefonía móvil) y chat (mensajería instantánea). Todos los mensajes, independientemente del formato, tienen un usuario emisor, un usuario receptor y un texto de mensaje. Además, en particular, un e-mail tiene un Asunto (de tipo texto) y un conjunto de usuarios a los que llegará copia del mensaje; un SMS tiene un número del centro servidor, y un mensaje instantáneo tiene un protocolo de mensajería. De cada usuario podemos necesitar su nombre, su dirección de correo electrónico, su número de teléfono móvil y su dirección IP. Los mensajes pueden enviarse, y al hacerlo se escribe por pantalla el cuerpo del mensaje independientemente de su formato.

1. Dibujar un esquema con las clases necesarias para este programa, indicando los atributos y métodos que tiene cada una (sólo indicarlos, sin escribir su código). No es necesario incluir métodos “get” y “set”. El esquema debe reflejar gráficamente la herencia de clases en caso de que la haya.

La empresa nos explica ahora que al enviar un SMS debe haber un comportamiento especial (el resto de formatos de mensaje mantienen su comportamiento): si el usuario receptor no tiene móvil, debe imprimirse un mensaje de error. Además, si el mensaje SMS ocupa más de 145 caracteres, antes de imprimirlo debemos irlo reduciendo hasta que no sobrepase ese tamaño. La reducción se hace con el método “String reduce(String cadena)”, programado por otra empresa e incluido en el “package” smstools. Cada vez que se ejecuta este método, mediante un diccionario de abreviaturas se reduce levemente la longitud del texto.

2. Explicar, en relación al concepto de herencia, cuál sería la mejor solución para encajar en el diseño anterior este comportamiento particular del método “enviar” para los SMS. Indicar una solución alternativa sin utilizar herencia y comentar sus ventajas o inconvenientes.

3. Codificar el constructor de la clase correspondiente a los SMS. La presencia o ausencia de constructor en una clase padre, ¿afecta de alguna manera a la clase que hereda?

4. Codificar el método que permite enviar mensajes SMS.

8.5.6.1 Solución Solución al Apartado 1:

Mensaje

private Usuario emisor;

private Usuario receptor;

private String texto;

void enviar()

Mensaje

void enviar()

Chat

private String cliente;

Chat(Usuario, Usuario,

String, String)

Chat

Chat(Usuario, Usuario,

String, String)

Sms

private int servidor;

Sms(Usuario, Usuario,

String, int)

Sms

Sms(Usuario, Usuario,

String, int)

Usuario

private String nombre;

private String email;

private String movil;

private String ip;

Usuario(String, String,

movil, ip)

Usuario

Usuario(String, String,

movil, ip)

Usuario

private String nombre;

private String email;

private String movil;

private String ip;

Usuario(String, String,

movil, ip)

Usuario

Usuario(String, String,

movil, ip)

Mensaje

private Usuario emisor;

private Usuario receptor;

private String texto;

void enviar()

Mensaje

void enviar()

Mensaje

private Usuario emisor;

private Usuario receptor;

private String texto;

void enviar()

Mensaje

void enviar()

Chat

private String cliente;

Chat(Usuario, Usuario,

String, String)

Chat

Chat(Usuario, Usuario,

String, String)

Chat

private String cliente;

Chat(Usuario, Usuario,

String, String)

Chat

Chat(Usuario, Usuario,

String, String)

Sms

private int servidor;

Sms(Usuario, Usuario,

String, int)

Sms

Sms(Usuario, Usuario,

String, int)

Sms

private int servidor;

Sms(Usuario, Usuario,

String, int)

Sms

Sms(Usuario, Usuario,

String, int)

Usuario

private String nombre;

private String email;

private String movil;

private String ip;

Usuario(String, String,

movil, ip)

Usuario

Usuario(String, String,

movil, ip)

Usuario

private String nombre;

private String email;

private String movil;

private String ip;

Usuario(String, String,

movil, ip)

Usuario

Usuario(String, String,

movil, ip)

Usuario

private String nombre;

private String email;

private String movil;

private String ip;

Usuario(String, String,

movil, ip)

Usuario

Usuario(String, String,

movil, ip)

Usuario

private String nombre;

private String email;

private String movil;

private String ip;

Usuario(String, String,

movil, ip)

Usuario

Usuario(String, String,

movil, ip)

Page 78: Resumen Java

74 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

Solución al Apartado 2:

Habría que reescribir el método “enviar” en la clase “Sms”, de forma que el método “enviar” original permaneciera en la clase Mensaje. Así, cuando se imprima un email o un mensaje instantáneo, se recurrirá al método heredado de la clase padre, pero cuando se imprima un SMS se ejecutará el método redefinido.

La alternativa sin herencia sería eliminar el método “enviar” de la clase padre y escribirlo individualmente para cada formato de mensaje. Sin embargo, esta solución es peor, porque implica duplicar información al escribir un mismo código varias veces (en este caso dos, pero podrían ser más), con la consiguiente dificultad para mantener la coherencia en caso de un cambio en el código.

Solución al Apartado 3:

Al crear un objeto de la clase que hereda, lo primero que se hace es llamar implícitamente al constructor por defecto de la clase padre, por lo que no es necesario escribir código adicional:

public Sms(Usuario emisor, Usuario receptor, String texto,

boolean multimedia, int servidor) {

this.setEmisor(emisor);

this.setReceptor(receptor);

this.setTexto(texto);

this.servidor = servidor;

}

Sin embargo, si hemos definido un constructor con argumentos para la clase padre, el constructor por defecto deja de estar accesible y por tanto es necesario llamar explícitamente al constructor de la clase padre que hemos creado:

public Sms(Usuario emisor, Usuario receptor, String texto,

boolean multimedia, int servidor) {

super(emisor,receptor,texto);

this.servidor = servidor;

}

Solución al Apartado 4:

public void enviar() {

if (this.getReceptor().getMovil()== null)

System.out.println("ERROR: El receptor carece de móvil.");

else

{

while(this.getTexto().length()>145)

this.setTexto(Smstools.reduce(this.getTexto()));

System.out.println(this.getTexto());

}

}

Page 79: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 75

8.5.7 Ejercicio 8

Se quiere crear un programa que gestione los menús de un establecimiento. Para ello se tiene una clase menú, la cuál está formada por el número del menú, y además tiene el primer plato, el segundo plato y el postre. El primer plato, segundo plato y postre a su vez están formados por el número del plato y l nombre del plato. La diferencia radica en que en el segundo plato se tiene que saber si se añade guarnición y en el postre se aclara si es de tipo fruta o dulce. Una vez creadas las clases necesarias con sus atributos y métodos crear dentro del programa principal unos menús teniendo en cuenta que primero se tienen que crear los platos y postres nombrados a continuación. Después se crearán los menús formados por dichos platos y postres.

Supongamos que tenemos los primeros:

1. Sopa de fideos.

2. Ensalada de trigueros.

3. Endivias con roquefor.

Los segundos:

1. Ternera con patatas.

2. Pescado con ensalada.

3. Fritura.

Los postres:

1. Fruta (manzana).

2. Fruta (Kiwis).

3. Dulce (Flan).

4. Dulce (Tarta).

Con estos platos se elaborar 3 menús compuesto de:

Menú número 1: 2 primero, 1 segundo, 3 postre.

Menú número 2: 1 primero, 3 segundo, 4 postre.

Menú número 3: 3 primero, 2 segundo, 2 postre.

Una vez creados todos los objetos necesarios, tanto para los platos y postres como para los menús, se pide que se lea por pantalla un número correspondiente a un menú y que se imprima según el número dado el menú correspondiente.

8.5.7.1 Solución Para guardar todos las clases comunes vamos a crear un paquete restaurante, para ello creamos una carpeta que se denomine /restaurante y allí vamos guardando todas las clases siguientes:

Page 80: Resumen Java

76 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

1 package restaurante; 2 3 public class Plato 4 5 { 6 private int numeroIdent; 7 private String nombrePlato; 8 9 public Plato(int numeroIdent, String nombrePlato) 10 { 11 this.numeroIdent = numeroIdent; 12 this.nombrePlato = nombrePlato; 13 14 } 15 16 public void setNumIdent(int numeroIdent) 17 { 18 this.numeroIdent = numeroIdent; 19 } 20 21 public void setNombrePlato(String nombrePlato) 22 { 23 this.nombrePlato = nombrePlato; 24 } 25 26 public int getNumIdent () 27 { 28 return this.numeroIdent; 29 } 30 31 public String getNombrePlato() 32 { 33 return this.nombrePlato; 34 } 35 36 }

1 package restaurante; 2 3 public class PlatoSegundo extends Plato 4 { 5 6 private boolean guarnicion; 7 8 public PlatoSegundo(int numeroIdent, String nombrePlato,boolean guarnicion) 9 { 10 super(numeroIdent,nombrePlato); 11 this.guarnicion = guarnicion; 12 13 } 14 15 public void setGuarnicion(boolean guarnicion) 16 { 17 this.guarnicion = guarnicion; 18 } 19 20 public boolean getGuarnicion () 21 {

Page 81: Resumen Java

Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina 77

22 return this.guarnicion; 23 } 24 }

1 package restaurante; 2 3 public class Postre extends Plato 4 { 5 6 private boolean conNata; 7 8 public Postre(int numeroIdent, String nombrePlato,boolean conNata) 9 { 10 super(numeroIdent,nombrePlato); 11 this.conNata = conNata; 12 13 } 14 15 public void setConNata(boolean conNata) 16 { 17 this.conNata = conNata; 18 } 19 public boolean getConNata () 20 { 21 return this.conNata; 22 } 23 }

1 package restaurante; 2 3 public class Menu 4 5 { 6 private int numMenu; 7 private Plato primerPlato; 8 private PlatoSegundo segundoPlato; 9 private Postre postre; 10 11 12 public Menu (int numMenu, Plato primerPlato, PlatoSegundo segundoPlato, Postre postre) 13 { 14 this.numMenu = numMenu; 15 this.primerPlato = primerPlato; 16 this.segundoPlato = segundoPlato; 17 this.postre = postre; 18 19 } 20 21 public void imprimirMenu() 22 { 23 System.out.println("El menu número: " + numMenu); 24 System.out.println("El primer es: " + primerPlato.getNombrePlato());; 25 System.out.print("El segundo es: " + segundoPlato.getNombrePlato());

Page 82: Resumen Java

78 Fundamentos de Programación en Java. Teresa Sastre Toral, Alberto Ruiz Cristina

26 if (segundoPlato.getGuarnicion()) 27 System.out.println(" con guarnición"); 28 else 29 System.out.println(); 30 System.out.print("El postre es: " + postre.getNombrePlato()); 31 if (postre.getConNata()) 32 System.out.println(" con nata"); 33 else 34 System.out.println(); 35 36 } 37 38 }

La clase que contiene el método main la guardaremos en el directorio previo al que denominamos restaurante, de forma que así podremos importar el paquete restaurante.

1 import restaurante.*; 2 3 public class EjecutaMenu 4 { 5 6 public static void main (String[] args) 7 { 8 // Creo los primeros platos _ 9 10 Plato primerPlato1 = new Plato (1,"Sopa de fideos"); 11 Plato primerPlato2 = new Plato (2,"Ensalada de trigueros"); 12 Plato primerPlato3 = new Plato (3,"Endivias con roquefor"); 13 14 15 // Creo los segundos 16 17 PlatoSegundo segundoPlato1 = new PlatoSegundo (4,"Ternera",true); 18 PlatoSegundo segundoPlato2 = new PlatoSegundo (5,"Pescado",true); 19 PlatoSegundo segundoPlato3 = new PlatoSegundo (6,"Fritura",false); 20 21 22 // Creo postre_ 23 24 Postre postre1 = new Postre (4,"Fresas",true); 25 Postre postre2 = new Postre (5,"Flan",true); 26 Postre postre3 = new Postre (6,"Tarta",false); 27 28 29 // menu 30 31 Menu menu1 = new Menu(1,primerPlato2,segundoPlato1, postre3); 32 Menu menu2 = new Menu(2,primerPlato1,segundoPlato3, postre1); 33 Menu menu3 = new Menu(3,primerPlato3,segundoPlato2, postre2); 34 35 menu1.imprimirMenu(); 36 menu2.imprimirMenu(); 37 menu3.imprimirMenu(); 38 } 39 40 }