Interacción de Objetos en Programación
Interacción de Objetos en Programación
Esta unidad de trabajo nos enseñará cómo construir pequeñas aplicaciones formadas por un
conjunto de objetos de diferentes clases que cooperan e interactúan entre ellos. Los objetos se
envían mensajes entre ellos para conseguir un objetivo común.
Por último, veremos qué es lo que debe incluir una aplicación Java para que pueda ejecutarse
fuera del entorno BlueJ, tal como lo hacen las aplicaciones profesionales y empezaremos a
utilizar algunas clases de la librería Java para dotar de mayor funcionalidad a nuestros
programas.
Para explicar los conceptos que surjan utilizaremos el proyecto Reloj Digital que implementa un
visor (un display) para un reloj digital de estilo europeo: un reloj que va desde las 00:00 hasta
las 23:59 horas (11:59 p.m.).
/**
* La clase VisorReloj implementa un panel de un reloj digital para un reloj
* estilo 24 horas europeo. El reloj muestra horas y minutos. El rango del reloj es
* 00:00 (medianoche) a 23:59 (un minuto antes de medianoche)
*
* El reloj recibe "ticks" (vía el método emitirTic) cada minuto y reacciona
* incrementando el visor. Esto se hace de la manera habitual: la hora se incrementa
* cuando los minutos alcanzan de nuevo el valor cero.
*/
/**
* Constructor de objetos VisorReloj. Este constructor crea un nuevo
* reloj puesto en hora a las 00:00
*/
public VisorReloj()
{
horas = new VisorNumero(24);
minutos = new VisorNumero(60);
actualizarReloj();
}
/**
* Constructor de objetos VisorReloj. Este constructor crea un nuevo
* reloj puesto en hora a partir de los parámetros pasados
* al constructor
*/
/**
* Este método debería llamarse una vez cada minuto -
* permite que el reloj avance un minuto
*/
- Pág. 2 de 50 -
/**
* Pone la hora en el visor a un determinado valor de hora y minuto
*/
/**
* Devuelve la hora actual en el formato HH:MM.
*/
public String getHora()
{
return visorString;
}
/**
* Actualiza la cadena interna que representa el visor
*/
private void actualizarReloj()
{
visorString = horas.getValorVisor() + ":" +
minutos.getValorVisor();
}
}
/**
* La clase VisorNumero representa un visor – panel - digital que permite almacenar
* valores entre 0 y un límite. El límite puede ser especificado cuando se crea
* el visor. El rango de valores va de 0 a límite-1. Si se usa, por ejemplo, para
* los segundos un reloj digital, el límite sería 60, resultando en este caso que
* el visor mostraría valores entre 0 y 59. Al incrementarse, el visor da la vuelta
* automáticamente y se pone a 0 al alcanzar el límite.
*/
/**
* Constructor para objetos de la clase VisorNumero
*/
public VisorNumero(int limiteMaximo)
{
limite = limiteMaximo;
valor = 0;
}
/**
* Devuelve el valor actual
*/
public int getValor()
{
return valor;
}
/**
* Pone el valor del visor al nuevo valor especificado. Si el
* nuevo valor es menor que 0 o supera el límite no hace nada
*/
/**
* Incrementa el valor del display en 1, dando la vuelta a cero
* si se alcanza el límite
*/
En la sentencia, private VisorNumero horas; vemos que el atributo horas tiene como tipo la
clase VisorNumero. Una clase puede ser utilizada para definir el tipo de una variable. Cuando
ocurre esto la variable puede almacenar objetos (referencias a objetos) de esa clase.
- Pág. 4 de 50 -
4.3.- Diagramas de clases y diagramas de objetos
La estructura de la clase VisorReloj que utiliza otra clase, la clase VisorNumero, puede ser
descrita utilizando un diagrama de clases. Este diagrama muestra las clases de la aplicación
y las relaciones entre ellas. Muestra una vista estática del programa. Es lo que nos interesa
cuando escribimos el código.
Diagrama de objetos – en
nuestro ejemplo, al iniciar el
programa se creará un objeto de
la clase VisorReloj y este objeto
(su constructor) creará en
tiempo de ejecución dos objetos
de la clase VisorNumero (horas
y minutos)
BlueJ visualiza únicamente la vista estática, el diagrama de clases, además es un diagrama muy
simplificado (no se refleja toda la variedad de relaciones entre clases que puede haber y que se
pueden representar a través de UML).
Ya sabemos que las clases pueden ser usadas como tipos y, por tanto, podemos definir una
variables de una determinada clase. A estos tipos se les denomina tipos objeto (o tipos
referencia).
Java posee:
a) tipos primitivos – byte, short, int, float, double, long, char, boolean. Son los tipos
predefinidos por el lenguaje.
b) tipos objeto o tipos referencia – aquellos definidos por las clases. Algunas clases son
clases predefinidas de Java, como la clase String, otras las define el usuario.
Ambos tipos pueden utilizarse para indicar el tipo de una variable pero hay diferencias entre
ellos:
- las variables de un tipo objeto (aquellas cuyo tipo es una clase) almacenan una
referencia al objeto, no el objeto en sí.
Ejer.4.3.
Abre el proyecto Reloj Digital
Crea un objeto VisorReloj y prueba su comportamiento
Analiza el código de la clase VisorNumero. ¿Cuál es la función del argumento en su
constructor?
¿Qué hace el método incrementar()? Analiza la sentencia valor = (valor + 1) %
limite; Expresa esta misma sentencia con un if
Analiza el código del método public String getValorVisor(). ¿Es un accesor o un
mutador?
¿Qué ocurriría si el código de ese método fuese el siguiente? Haz los cambios y
pruébalo. Luego restablece el método a su código inicial.
- Pág. 6 de 50 -
return valor ;
/**
* Constructor de objetos VisorReloj. Este constructor crea un nuevo
* reloj puesto en hora a las 00:00
*/
public VisorReloj()
{
horas = new VisorNumero(24);
minutos = new VisorNumero(60);
actualizarReloj();
}
……………………………..
}
La clase define dos atributos, horas y minutos, ambos tienen como tipo una clase, la clase
VisorNumero. Estos atributos almacenarán una referencia a un objeto de esa clase.
Cuando un atributo (en general, una variable) de un tipo objeto se declara, el objeto todavía no
existe. Por analogía, cuando una variable de tipo int se declara la variable no tiene ningún valor
todavía. Hay que crear los nuevos objetos con el operador new. En nuestro ejemplo, cuando
desde BlueJ se crea un objeto de la clase VisorReloj se ejecutará el constructor de esa clase.
Dentro del constructor se crean los objetos horas y minutos de la clase VisorNumero.
- crea un nuevo objeto de la clase especificada detrás de new y asigna una referencia a
ese objeto a la variable especificada a la izquierda de la asignación
- ejecuta el constructor de esa clase (el código incluido en el constructor)
Lo que distinguirá a unos de otros será el nº y/o tipo de sus argumentos (no puede haber más de
un constructor con igual nº de parámetros y mismo tipo).
- Pág. 8 de 50 -
public VisorReloj()
public VisorReloj(int hora, int minuto)
La razón para incluir varios constructores en una misma clase es proporcionar alternativas a la
hora de construir e inicializar los objetos.
4.7.-Llamadas a métodos
4.7.1.-Llamadas internas a métodos
Los métodos pueden llamar a otros métodos de la misma clase como parte de su
implementación. Es lo que se denomina llamada interna a un método (desde dentro de la
clase). Nuestra clase VisorReloj define un método, private void actualizarReloj(), al cual se le
invoca desde dentro del constructor de la clase:
/**
* Constructor de objetos VisorReloj. Este constructor crea un nuevo
* reloj puesto en hora a las 00:00
*/
public VisorReloj()
{
horas = new VisorNumero(24);
minutos = new VisorNumero(60);
actualizarReloj();
}
llamada interna
Para efectuar una llamada interna a un método de la misma clase (enviarse un mensaje a sí
mismo el objeto) se especifica:
nombre_método(lista de parámetros);
Cuando se invoca a un método interno se localiza en la clase un método con el mismo nombre y
parámetros (nº y tipo) especificados en la llamada y se ejecuta el método. Cuando acaba la
ejecución se retorna al punto donde se produjo la llamada y continúa la ejecución en la siguiente
sentencia después de la llamada.
Otro ejemplo:
/**
* Constructor de objetos VisorReloj. Este constructor crea un nuevo
* reloj puesto en hora a partir de los parámetros pasados
* al constructor
*/
Los métodos pueden llamar a métodos de otros objetos (pueden enviar mensajes a otros
objetos). Enviar un mensaje a un objeto obj significa querer ejecutar un método definido
dentro de la clase a la que pertenece obj. Es lo que se denomina efectuar una llamada externa
a un método.
- Pág. 10 de 50 -
La sintaxis a utilizar para llamar a un método externo es la siguiente:
objeto.nombre_método(lista de parámetros);
referencia al objeto
Otro ejemplo:
/**
* Este método debería llamarse una vez cada minuto -
* permite que el reloj avance un minuto
*/
public void emitirTic()
{
minutos.incrementar();
if (minutos.getValor() == 0)
{ // se da la vuelta
horas.incrementar();
}
actualizarReloj();
}
llamadas externas
Cuando se define un método en una clase se especifica su visibilidad con las palabras
reservadas public/private:
a) public – significa que el método es público, por lo tanto, es visible desde fuera de
la clase. Esto quiere decir que puede ser invocado desde otros objetos
minutos.incrementar();
b) private – si un método se define con esta visibilidad significa que sólo podrá ser
llamado desde dentro de la propia clase (sólo llamadas internas)
actualizarReloj();
La visibilidad se aplica también a los atributos. En los ejemplos utilizados hasta ahora todos los
atributos definidos en las clases son private. Únicamente son accesibles desde dentro de la
propia clase. Esto debe ser siempre así ya que garantiza la encapsulación.
La clase Impresora tiene definidos dos métodos con las siguientes signaturas:
tenga 2 atributos, delantera y trasera que representan las 2 ruedas de una bici
el constructor cree las ruedas con una presión inicial de 0.0
incluya un método público verificar() sin parámetros y que no devuelve nada.
Este método verifica cada una de las ruedas de la bici. Si están desinfladas las
infla quedando las ruedas con una presión de 1.5.
}
……………………
}
En principio Java no genera ningún error ante la siguiente situación. Estamos ante lo que se
llama sobrecarga de nombres. Hay un atributo en la clase, presion, con el mismo nombre que el
parámetro local en el constructor. Esto no genera errores, sin embargo, la asignación en el
constructor no es correcta porque lo que queremos es dejar en el atributo presion el valor del
parámetro presion que se pasa al constructor. Pero lo que ocurre es que se asigna al argumento
local su propio valor. La forma de solucionar esto es haciendo uso de this para referirnos al
objeto actual (el objeto receptor del método) .
- Pág. 12 de 50 -
private double presion;
Completa la clase:
Otro uso de la palabra this es para pasar el objeto actual como parámetro a otro método.
Cuando una variable objeto no apunta a nada no es posible llamar a ningún método de ese
objeto ya que se generaría un error (una excepción NullPointerException). Para evitar esto se
puede verificar si la variable es null o no.
Java tiene un mecanismo, el Garbage Collector, para destruir aquellos objetos que no son
referenciados por ninguna variable.
Ejer.4.13. Repasa el código completo del proyecto Reloj Digital. Vamos a modificarlo para que
en lugar de ser un reloj de 24 horas sea un reloj de 12 horas y muestre la hora de la forma 4:23
a.m. o 4:23 p.m. Las 00:30 se mostrarán como 12:30. Los minutos se mostrarán de 0 a 59 pero
las horas son ahora de 1 a 12. Modificaremos únicamente el método actualizarReloj(). El resto
quedará igual.
Un paquete BlueJ se almacena en varios ficheros Algunos contienen código fuente, otros código
compilado y otros información adicional. BlueJ utiliza el formato standard Java para algunos
ficheros y añade otros ficheros con información adicional extra.
bluej.pkg Hay uno por paquete. Contiene información sobre las clases en el paquete
bluej.pkh
Fichero backup del paquete
- Pág. 14 de 50 -
*.java Un fichero fuente java por cada clase del proyecto
*.class Fichero de código standard java compilado. Hay uno por clase
*.ctxt Fichero BlueJ con información adicional. Hay uno por clase
Recordemos que los ficheros *.java son los ficheros fuente. Contienen el código fuente que
escribe el programador. Hay uno por clase. Los ficheros *.class contienen el código compilado,
el que más tarde interpretará la máquina virtual. Hay uno por clase y los genera el compilador
Java a partir del código fuente.
El método main:
Para cada proyecto incluiremos una clase adicional, en nuestro ejemplo, la clase
TestCirculo (o PruebaCirculo) en la que incluiremos el método main. Dentro de este
método incluiremos las sentencias que nos permiten probar (testear) la aplicación. Desde
BlueJ llamaremos al método main sin crear ningún objeto de la clase TestCirculo.
Los métodos representan el comportamiento que tienen los objetos de una clase. Un método
consta de una serie de sentencias que se ejecutan en orden secuencial, unas detrás de otras.
- Pág. 16 de 50 -
int tiradas = 1; int ncaras = 0; //es una variable contador
while (tiradas <= 10) int ncruz = 0; //es una variable contador
{ int tiradas = 1; //es una variable contador
moneda.tirar(); while (tiradas <= 30)
tiradas++; {
} moneda.tirar();
if (moneda.esCara())
ncaras++;
else
ncruz++;
tiradas++;
}
boolean salioCara = false; // es una variable que actúa como un switch o conmutador
int tiradas = 1; //es una variable contador
while (tiradas <= 30 && ! salioCara)
{
moneda.tirar();
if (moneda.esCara())
salioCara = true;
else
tiradas++;
}
System.out.println(“Salió cara en la tirada “ + tiradas);
Un contador es una variable cuyo valor se incrementa en una cantidad fija, positiva o negativa. Se
utiliza en los siguientes casos:
a) Para contabilizar el número de veces que es necesario realizar una acción (variable de
control de un bucle). Ej. tiradas++; contador--;
Un acumulador es una variable cuyo valor se incrementa sucesivas veces en cantidades variables.
Se utiliza:
Un switch o conmutador es una variable que toma dos valores exclusivos, 0 / 1, true / false,
-1 / 1, y que se utiliza para:
a) public void escribirNumero(int desde, int hasta) – escribe los números que están
comprendidos entre el parámetro desde y el parámetro hasta. Si desde = 10 y hasta =30,
escribe 10, 11, 12, ….. ,30
b) public void mostrarPares() - Visualiza en la ventana de terminal los números pares entre
2 y 50.
c) public int generarAleatorios() - genera y escribe nos aleatorios entre 1 y 100 parando el
proceso cuando se generan 30 o bien cuando salga un 99. El método cuenta también las
veces que sale el 12 y devuelve este valor.
Para generar un nº aleatorio entre 1 y 100: numero = (int) (Math.random() * 100) + 1;
Ejer.4.15. (Para trabajar con bucles anidados) Escribe los siguientes métodos:
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
4 4 4 4 4 4
5 5 5 5 5 5
6 6 6 6 6 6
- Pág. 18 de 50 -
1
2 2
3 3 3
4 4 4 4
5 5 5 5 5
6 6 6 6 6 6
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
e) public void calcularSumatorios(int cuantos, int limite) - genera cuantos nos aleatorios
entre 1 y limite y por cada nº generado calcula su sumatorio (suma consecutiva desde el
propio numero hasta uno decrementando de uno en uno, por ejemplo:
sumatorio(5)=5+4+3+2+1=15).
int ncaras = 0;
int ncruz = 0;
for (int tiradas = 1; tiradas <= 30; tiradas++)
{
moneda.tirar();
if (moneda.esCara())
ncaras++;
else
ncruz++;
}
Ejer.4.16. Escribe los siguientes métodos utilizando para las repeticiones la sentencia for:
El bucle do .. while es una variación del bucle while con la diferencia de que las sentencias del
cuerpo del bucle se ejecutan al menos una vez.
- Pág. 20 de 50 -
4.12.- La clase Random. La clase Scanner
Esta clase es una de las contenidas en la librería de clases de Java. Permite generar n ºs
aleatorios. Para ello:
Ej. ……………………………….
Random generador = new Random();
int valor = generador.nextInt(10) + 1 ;
import java.util.Random;
public class Dado
{
private int cara;
private Random generador;
public Dado( )
{
generador = new Random();
cara = 1;
}
}
La clase Scanner es una clase de la librería Java incorporada a partir de la versión 1.5. Permite
leer valores desde el dispositivo de entrada standard, el teclado. Para ello:
Ej. El siguiente ejemplo muestra una clase prueba que testea una clase Persona. En esta clase
se utiliza la clase Scanner para leer del teclado los valores que se pasan como parámetros
actuales a los métodos de la clase Persona (lo que en BlueJ hacemos desde el propio entorno):
import java.util.Scanner;
public class TestPersona
{
public static void main(String[] args)
{
Persona p = new Persona();
Scanner teclado = new Scanner(System.in);
String nombre;
System.out.print(“ Nombre de la persona =”);
nombre = teclado.next() ;
p.setNombre(nombre) ;
System.out.print(“ Edad de la persona =”);
p.setEdad(teclado.nextInt());
p.printDatosPersona();
}
}
Los miembros de las clases definidas hasta el momento han sido miembros de instancia, los
atributos (variables de instancias), las constantes y los métodos (métodos de instancia),
miembros que se asocian a los objetos individuales, a las instancias de la clase. Cada objeto tiene
sus propios valores para sus atributos (constantes y variables) y los métodos se invocan sobre
los objetos.
- Pág. 22 de 50 -
Las clases pueden contener también miembros de clase, tanto constantes, como variables y
métodos de clase. Se denominan miembros static y pertenecen a la clase, no a las instancias
(los objetos).
private static final double PI = 3.1416; // constante de clase con un valor inicial no modificable
Es habitual el uso de constantes static y además es muy común definirlas con visibilidad public
para que sean accesibles por todas las clases (nosotros, salvo excepciones las definiremos
private). Un ejemplo de este tipo de constantes lo encontramos en el propio lenguaje Java y la
clase Math:
Para declarar una variable de clase se especifica static después de la visibilidad y antes del tipo
de la variable.
Imaginemos que en la clase Circulo anterior queremos incluir un nuevo atributo entero numero
de forma que cada vez que creemos un nuevo objeto Circulo este atributo guarde el nº de círculo
creado (1 para el 1º, 2 para el 2º, 3 para el 3º, ...). ¿Cómo conseguimos esto? Se necesita un
contador que no esté asociado a ninguna instancia (si lo estuviera el constructor asignaría
siempre el mismo valor inicial) y que se incremente cada vez que se crea un nuevo objeto
Circulo. La solución es utilizar una variable de clase y asignar el valor de esta variable al atributo
numero dentro del constructor.
public Circulo()
{
contadorCirculos++;
numero = contadorCirculos;
}
…………………..
}
- Pág. 24 de 50 -
Cada vez que se llama al constructor de la clase Circulo la variable static contadorCirculos se
incrementa en 1 y su nuevo valor se asigna al atributo numero.
Las variables de clase mantienen el estado de la clase compartido por las instancias.
Java asigna un valor por defecto (igual que con las variables de instancia) a este tipo de variables
: 0 para las de tipo int, 0.0 para double, null para las de tipo String, .... Las variables de clase se
inicializan por 1ª vez cuando se carga la clase.
Dentro de una clase se definen antes que las variables de instancia y después de las constantes.
Los métodos de instancia pueden acceder a las variables static de la misma forma que lo hacen
con las variables de instancia.
Ejer.4.18. Crea un proyecto que incluya una clase Empleado con la siguiente estructura:
public Empleado()
{
// a completar
}
…………………..
}
La clase Math incorpora varios métodos static. Esta clase funciona como una librería de
utilidades donde los métodos static devuelven un valor de retorno a partir de los parámetros
que se les pasa.
Es habitual cuando se define una variable de clase definir también un método de clase para
obtener su valor: public static int getContadorCirculos()
La recursión es una técnica utilizada en programación que proporciona una solución elegante
y sencilla a cierta clase de problemas.
una lista es un nº o
una lista es un nº y una , junto con una lista
nº , lista
24 , 38, 40, 37
nº , lista
38 , 40, 37
nº , lista
40 , 37
nº
37
Todas las definiciones recursivas tienen una parte que no lo es (sino la recursión sería infinita),
esta parte no recursiva es lo que se denomina caso base o caso trivial.
- Pág. 26 de 50 -
Detrás de la recursión se esconde el principio del “divide y vencerás”, el problema inicial se
plantea en términos de problemas más pequeños pero de las mismas características, similar al
original.
5! = 5 * 4 * 3 * 2 * 1 El factorial de 5! = 5 * 4! =
4! = 4 * 3 * 2 * 1 5 * 4 * 3! =
3! = 3 * 2 * 1 5 * 4 * 3 * 2! =
2! = 2 * 1 5 * 4 * 3 * 2 * 1! = .....
1! = 1
0! = 0
En Java quedaría:
Cada nueva llamada al método supone un nuevo entorno de ejecución para él con nuevos
parámetros y variables locales que no son visibles de una llamada a otra.
- Pág. 28 de 50 -
Ejer.4.19.
Crea un proyecto Librería recursiva e incluye una clase Librería. Esta clase
únicamente va a contener métodos static y no tendrá atributos (será uno de los
pocos ejemplos en los que trabajaremos con métodos de clase). Los métodos van a
ser utilidades y serán métodos recursivos. Todos los métodos son public.
Incluye el método int factorial(int num) y pruébalo.
Añade un método int sumatorio (int num) que devuelve el sumatorio del parámetro
proporcionado al método. Si num = 5 devolverá 1 + 2 + 3 + 4 + 5 = 15
Define el método int maximoComunDivisor(int a, int b) que calcula y devuelve el
máximo común divisor de a y b utilizando el algoritmo de Euclides
Construye el método int contarDigitos(int num) que devuelve el nº de cifras de num
Método int potencia(int base, int expon) que calcula baseexpon
Método int fibonnaci(int n) que calcula y devuelve el n-simo término de la serie de
Fibonacci. La serie de Fibonnacci es: 0 1 1 2 3 5 8 13 ..... Cada término es la
suma de los dos anteriores. Si el nº de término a calcular es el 7º el método
devolverá 8.
La clase RelojAlarma tiene dos atributos de tipo referencia, reloj de tipo VisorReloj y alarma de
tipo Alarma. Esta clase incluye:
- Pág. 30 de 50 -
comparar dos cadenas haremos: cadena1.equals(cadena2)
Ejercicio 2.
Abre el proyecto Circulo y Punto. Analiza el código de la clase Punto. Esta clase no
hay que modificarla. Prueba la clase creando varios objetos Punto y llamando al
método toString().
La clase Circulo modela círculos de un centro y un radio determinados. Se trata de
completar el código de esta clase. El diagrama UML muestra los atributos y métodos
que incluye la clase.
Ejercicio 3.
Añade a la clase Punto un método public void desplaza(int distanciaX, int distanciaY)
que permite deslazar el punto en el plano la distancia indicada por los parámetros.
Prueba la clase modificada.
Crea ahora la clase Linea que incluye dos atributos , punto1 y punto2 de la clase Punto
Incorpora dos constructores, el primero sin parámetros (el constructor predeterminado)
que crea los dos puntos que forman la línea con valores iniciales (0,0) ambos. El
segundo constructor recibe como parámetros dos objetos de la clase Punto que son
utilizados para inicializar los atributos
Punto 1 - Valor de x = 3
Valor de y = 2
Punto 2 - Valor de x = 12
Valor de y = 10
Prueba la clase Linea.
Ejercicio 4.
La última clase es Sistema. Es la que simula un sistema que tiene tres usuarios que
intentan acceder. Los miembros de esta clase son:
- Pág. 32 de 50 -
o atributos - los tres usuarios
o Métodos –
i. La clase tiene un constructor sin parámetros que crea los tres usuarios
con nombre “Uno”, “Dos” y “Tres” respectivamente.
ii. public void entrarEnSistema() – simula que los usuarios intentan
acceder al sistema
iii. public void printEstadisticaSistema() – muestra en pantalla la
información de todos los usuarios del sistema
Ejercicio 5. Crea una clase Fraccion que representa fracciones. La clase tiene dos atributos
enteros, numerador y denominador y los siguientes constructores y métodos:
Ejercicio 6. Abre el proyecto Circulo y Punto del ejercicio 2 y guárdalo con otro nombre.
Modifica la clase Punto añadiendo los siguientes métodos:
La clase incluye dos constructores. El primero tiene un parámetro, el nombre del pasajero, e
inicializa la edad a –1. El segundo constructor tiene dos parámetros, el nombre y la edad.
Hay un accesor getNombre() que devuelve el nombre del pasajero y otro para la edad
getEdad().
Hay otro accesor printDetalles() sin parámetros y sin valor de retorno que escribe el nombre del
pasajero y su edad. Si hay un valor negativo en la edad se escribirá “edad sin especificar”.
La clase Ferry tiene cuatro atributos: asiento1, asiento2, asiento3 que referencian objetos de la
clase Pasajero y numPasajeros de tipo entero que almacena el nº actual de pasajeros en el ferry.
Nombre: XXXXX
Edad: 34
Nombre: XXXXX
Edad: sin especificar
La clase tiene un mutador añadirPasajero() que toma un objeto de la clase Pasajero como
parámetro y devuelve un valor booleano. Si no hay pasajeros todavía el método asigna el nuevo
pasajero a asiento1. Si solo hay un pasajero el nuevo se asigna a asiento2 y si hay dos pasajeros
el nuevo se asigna a asiento3. Si el nuevo pasajero tiene asiento se devuelve true. Si no lo tiene
devuelve false. El método debe actualizar el atributo numPasajeros adecuadamente.
La clase Ferry tiene por último el método getPasajeroMasJoven() que devuelve un pasajero.
Compara las edades de los pasajeros que están en el momento en el ferry y devuelve el más
joven. Si no hay ningún pasajero devuelve null. No se consideran las edades no especificadas
(con valor = -1). Si por ejemplo, hay tres pasajeros y los tres tienen una edad = -1 se devuelve
también null. Para ayudarte en el diseño de este último método construye el método privado
masJovenDeDos(). La signatura de este método es:
y devuelve el pasajero más joven de entre dos que se le pasan como parámetros.
Ejercicio 8. Añade una clase TestReloj dentro del proyecto RelojDigital del ejercicio 1 en la
que definas:
- Pág. 34 de 50 -
en el constructor de la clase TestReloj (que no tendrá parámetros) crea miReloj con las
18:32 horas y tuReloj con la hora 23:58
define un método test1() en el que:
- se establece la alarma de miReloj a las 18:35
- visualiza la hora actual de miReloj y la hora de alarma
- se avance el reloj tres minutos
Analiza detalladamente los servicios que proporciona la clase RelojAlarma. Verás que no hay
ningún método que nos permita cambiar la hora actual del reloj. Añade un nuevo método a esta
clase, el método ponerEnHora() con dos parámetros hora y minutos que permita el cambio de
hora de nuestro reloj. Este método delegará esta tarea en la clase VisorReloj.
Ejercicio 9. Añade al proyecto del ejercicio 5 una clase DemoFraccion que incluye:
Ejercicio 10. Añade al proyecto del ejercicio 6 una clase TestPunto que nos va a permitir
testear la clase Punto. La clase TestPunto no va a tener atributos y en el constructor no vamos a
incluir ninguna sentencia. Únicamente añadiremos a la clase un método test() y dentro de él
haremos:
A partir del JDK 1.5 se ha incorporado un nuevo método, printf(), que permite
formatear la salida en pantalla (algo que no hacen los métodos print() ni println()):
donde:
Especificador Salida
%d valor enter0
%f valor real
%s valor String
%c valor de tipo carácter
%b valor booleano
Se puede indicar en los especificadores de formato el ancho y la precisión, por ej, %10.2f,
significa un ancho para un valor real de 10 posiciones incluido el punto decimal y dos dígitos
para los decimales después del punto, con lo que quedan 7 posiciones antes del punto decimal.
- prueba el método printf() para visualizar la distancia entre los dos puntos
Ejercicio 11. Añade al proyecto Embarque del ejercicio 7 dos clases que nos permitan probar
las otras dos que existen, Pasajero y Ferry.
La clase PruebaPasajero tiene dos atributos que representan dos pasajeros, pasajero1 y
pasajero2. El constructor crea los dos pasajeros, el primero con un nombre pero sin determinar
la edad y el segundo con nombre y edad determinados (los que quieras). El método
testPasajeros() incluye llamadas a todos los métodos de la clase Pasajero sobre el objeto
pasajero1 y sobre el objeto pasajero2.
La clase PruebaFerry incluye un atributo ferry y un constructor que crea el ferry. Añade un
método testFerry() que:
- Pág. 36 de 50 -
Ejercicio 12. Modela una clase Cuenta que representa una cuenta corriente. De una cuenta se
conoce el nº de cuenta, el saldo y el nombre de su único titular. Sobre una cuenta se puede
realizar el ingreso y el reintegro de una determinada cantidad. Además es posible consultar el
saldo y obtener una representación textual del estado de la cuenta. Las cuentas se crean con un
nº de cuenta y un titular determinado pero con saldo inicial 0. Estudia los atributos y métodos
de esta clase. Dibuja el diagrama UML de la clase (con ayuda de UmlPad) y define la clase
dentro de un proyecto CuentaCorriente de BlueJ.
Añade al proyecto una nueva clase InterfazUsuario. Un objeto de esta clase va a permitir al
usuario interactuar con una cuenta corriente de manera que pueda seleccionar la operación a
realizar sobre la cuenta.
1.- Ingreso
2.- Reintegro
3 .- Consulta
4.- Imprimir datos cuenta
5.- Salir
Elija opcion:
El método menu() presenta el menú anterior en pantalla e indica al usuario que elija una opción,
la opción se lee desde teclado y se devuelve.
Añade al proyecto la clase AplicacionCuentaBancaria. Esta clase va a ser la clase que contenga el
método main() y por tanto la clase necesaria para ejecutar de forma autónoma la aplicación.
Esta clase solo contiene a este método y lo único que hace es:
Ejercicio 14. Crea un proyecto BlueJ que incluya la clase Dado y una nueva clase DemoDado
que tenga:
- un atributo dado
- un método test1() que simule el lanzamiento de un dado TOTAL veces (TOTAL es
una constante) y cuente y visualice las apariciones del 1 y del 6 en esos
lanzamientos
- un método test2() que lance el dado hasta que salga el 4 o el 5 contando las veces
que se ha tirado el dado
- un método test3() que tire el dado mientras la suma de las tiradas no supere el
valor 42.
- en los tres métodos anteriores los resultados se visualizan con ayuda de un método
“helper” privado: private void escribir(String mensaje, int contador)
- Pág. 38 de 50 -
Ejercicio 15. Modifica el método iniciar() de la clase InterfazUsuario del ejercicio 12 de
manera que ahora el método implemente un bucle, así mientras el usuario no pulse la opción
SALIR se le está mostrando continuamente el menú para que elija opción.
Ejercicio 16. Añade a la clase Fraccion del ejercicio 5 un método privado simplificar() que
simplifica la fracción (el numerador y denominador del objeto actual). Para simplificar se
utilizará otro método privado mcd() cuya signatura es:
y que devuelve el máximo común divisor de dos números. Para calcular el máximo común
divisor de dos valores se utilizará el algoritmo de Euclides: se dividen ambos n0s (el dividendo
es el mayor de los dos) calculando el resto. Si el resto es 0 entonces el mcd es el último divisor.
Si el resto no es 0 se repite el proceso, pero ahora el dividendo es el divisor y el divisor es el
resto.
Ejercicio 17. Crea una aplicación que permite hacer operaciones con números exponenciales.
El número exponencial ab significa que la base a se está multiplicando por sí misma tantas veces
como indique el exponente b. (a y n son nºs enteros).
a(-n) = 1 / an
a0 = 1
an = a*a*a*.... (n veces)
La clase Exponencial modela un nº exponencial. Tiene dos atributos enteros, base y exponente.
La clase incluye:
Añade una clase DemoExponencial (no incluye main()) que incluya métodos que prueben la
clase anterior.
Ejercicio 18. Define una clase Numero en un proyecto. La clase incluye un atributo entero,
numero. Tiene tres constructores sobrecargados, uno sin parámetros que inicializa el nº a 0,
otro con un parámetro entero y el último recibe un objeto Numero. Incluye accesor y mutador
para el atributo.
La clase tiene los siguientes métodos privados, private int ultimaCifra(int numero), que
devuelve la última cifra de un nº, la de las unidades y , private int inverso(int numero) que dado
un nº lo devuelve invertido.
Añade al proyecto una clase InterfazTexto cuyos objetos permitan al usuario interactuar con los
objetos de la clase Numero. El interfaz permitirá al usuario seleccionar una de esta opciones:
Diseña esta clase de forma análoga a la realizada en el ejercicio 12 con las modificaciones
introducidas en el ejercicio 15.
Completa el proyecto con la clase AplicacionNumero que incluye el main() y crea un objeto
miInterfaz y llama al método iniciar().
Ejercicio 19. El juego del Crasp es un juego de azar cuyas reglas son:
- Pág. 40 de 50 -
Diseña la clase ParDados tal como muestra el diagrama. El método
tirarDados() devuelve la suma de los dos dados . Prueba la clase.
Añade al proyecto una clase InterfazCrasp para interactuar con el usuario. Esta clase incluye:
Para completar la aplicación añade la clase AppJuegoDelCraps que incluye el método main().
Crea un objeto de tipo InterfazCrasp y llama al método iniciar(). Prueba la aplicación completa.
La clase define los atributos cantidadInicial y tipoInteres, ambos de tipo double, y representan
la inversión inicial y el interés anual. El interés representa un porcentaje, por ejemplo, 5 (5%).
Define un constructor con dos parámetros para inicializar los objetos de la clase y accesores para
la cantidad y el interés.
- public double despuesDe(int años) - devuelve el valor de la inversión inicial con los
intereses acumulados al cabo de los años indicados en el parámetro. No modifiques
al hacer este método el atributo que representa la cantidad inicial.
Año Balance
1 3150,00 €
2 3307,50 €
3 3472,88 €
4 3646,52 €
5 3828,84 €
Crea una clase SimulacionInversion para probar los métodos anteriores. Define dentro de la
clase tres constantes, INICIAL, INTERES y AÑOS y asígnales los valores que quieras. Añade un
atributo miInversion de tipo Inversion. En el constructor crea el objeto miInversion. Añade los
siguientes métodos:
- Pág. 42 de 50 -
Ejercicio 21. Modifica la clase Inversión añadiendo los atributos y métodos necesarios para
hacer una simulación como la presentada en la figura. En ella se muestra una tabla con los
diferentes futuros valores de una inversión inicial (en este caso de 1000 €) desde un interés
mínimo (4%) hasta un interés máximo (8%) con incrementos del interés de 0.5. Para cada tipo
de interés se muestra la inversión desde un mínimo nº de años (5) hasta un máximo de años
(30) con incrementos de 5 años. Las filas corresponden al tipo de interés y las columnas al nº de
años.
Incluye un nuevo constructor en la clase con 7 parámetros, la cantidad inicial y seis nuevos
valores más para inicializar los atributos anteriores.
Define dentro de la clase tres constantes de tipo char, ASTERISCO, ESPACIO y ASPA.
dibujarBicolor()
dibujarContorno() dibujarEnAspa()
Ejercicio 23. Define una clase GeneradorSeries sin atributos y con los siguientes métodos que
generan diferentes series:
A B C D E F G H I J
- Pág. 44 de 50 -
K L M N O P Q R S T
U V W X Y Z A B C D
E F G H I J K L M N
O P Q R S T U V W X
Y Z A B C D E F G H
I J K L M N O P Q R
S T U V W X Y Z A B
C D E F G H I J K L
M N O P Q R S T U V
public void serieLetras() – 10 filas y 10 columnas de la serie de la figura (utiliza como índice
para recorrer las filas una variable carácter)
A A A A A A A A A A
B B B B B B B B B B
C C C C C C C C C C
D D D D D D D D D D
E E E E E E E E E E
F F F F F F F F F F
G G G G G G G G G G
H H H H H H H H H H
I I I I I I I I I I
J J J J J J J J J J
K K K K K K K K K K
L L L L L L L L L L
M M M M M M M M M M
public void serieAlterna(int numFilas, int numColumnas) – genera la serie mostrada de tantas
filas como indique numFilas y tantas columnas como indique numColumnas. Utiliza para
generar esta serie el método private void escribirFila(char car, int cuantas) que escribe una fila
de cuantas columnas con el carácter car
****************************
====================
***************************
====================
***************************
====================
***************************
====================
***************************
====================
***************************
Ejercicio 24. Queremos diseñar un programa Java que permita a un usuario adivinar un nº
secreto del 1 al 100 , que previamente ha generado el ordenador, en un máximo nº de intentos.
El usuario intenta adivinar el nº y el ordenador contesta “Más bajo”, “Más alto”, “Enhorabuena
has adivinado el nº”, o “Lo siento has agotado los intentos”.
La clase Contador modela un contador. Los objetos de esta clase nos permitan simular el
funcionamiento de un contador, imcrementan, decrementan, ..... (podéis importar esta clase del
ejercicio 4).
Ejercicio 25. Crea una clase CalculadoraFibonacci como la indicada en el diagrama UML. La
clase no tiene atributos. El método generarFibonacci() devuelve un String con la representación
textual de la serie de Fibonacci para el nº de términos que se indican en el parámetro. Se
ayudará del método generarTerminoFibonacci().
0 1 1 2 3 5 8 13
Cada término en la serie de Fibonacci es la suma de los dos anteriores a excepción del 1º y 2º.
El método generarTerminoFibonacci() recibe un parámetro que representa una posición (el 3º,
el 5º, el 8º, ...) y devuelve el valor del término de esa posición.
- Pág. 46 de 50 -
La clase DemoFibonacci prueba la calculadora de términos a través de código.
Ejercicio 26. Crea una clase PintorFiguras sin atributos, con dos constantes de tipo char
privadas BLANCO y NEGRO con valores asociados ‘ ‘ y ‘*’. El constructor está vacío y solo hay
un método dibujarTableroAjedrez() que dibuja un tablero de ajedrez como el mostrado en la
figura.
1
232
34543
4567654
567898765
67890109876
7890123210987
890123454321098
90123456765432109
000
000
Con el método intentarJugada() se simula una jugada del Master Mind, es decir, hay que ver,
cuantos muertos y heridos hay en el nº intentado por el usuario. Para calcular los muertos y
heridos se utilizará el método calcularMuertosHeridos()
- Pág. 48 de 50 -
La clase IUMasterMind modela la interacción con el usuario. El
método iniciar() presenta el juego y permite jugar una vez al
juego del MasterMind.
Ejercicio 28.
0 1
1 1 1
2 1 2 1
3 1 3 3 1
4 1 4 6 4 1
5 1 5 10 10 5 1
6 1 6 15 20 15 6 1
7 1 7 21 35 35 21 7 1
Cada elemento de este triángulo es la suma de los dos que están por encima de él.
Ej – C5,2 = 5! / 2! ( 5 – 2 )! = 10
- Pág. 50 de 50 -