0% encontró este documento útil (0 votos)
119 vistas50 páginas

Interacción de Objetos en Programación

Este documento introduce la interacción entre objetos y la estructura de control iterativa. Enseña cómo construir aplicaciones formadas por objetos de diferentes clases que cooperan e interactúan para lograr un objetivo común. También enseña cómo diseñar métodos para realizar tareas repetitivas usando la estructura iterativa. Finalmente, explica cómo hacer que las aplicaciones Java se ejecuten fuera de BlueJ como aplicaciones profesionales usando clases de la librería Java.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOC, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
119 vistas50 páginas

Interacción de Objetos en Programación

Este documento introduce la interacción entre objetos y la estructura de control iterativa. Enseña cómo construir aplicaciones formadas por objetos de diferentes clases que cooperan e interactúan para lograr un objetivo común. También enseña cómo diseñar métodos para realizar tareas repetitivas usando la estructura iterativa. Finalmente, explica cómo hacer que las aplicaciones Java se ejecuten fuera de BlueJ como aplicaciones profesionales usando clases de la librería Java.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOC, PDF, TXT o lee en línea desde Scribd

UT4 Interacción de objetos.

La estructura de control iterativa.

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.

Aprenderemos además una nueva estructura de control de la programación, la iteración. Con


esta estructura podremos diseñar métodos que realicen tareas repetitivas.

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.

4.1.- Abstracción y modularización


Cuando un problema es simple, por ej, el proyecto MaquinaExpendedora del tema anterior, es
posible encontrar una solución utilizando una única clase (la clase MaquinaExpendedora en ese
caso). Sin embargo, a medida que crece la complejidad crece la dificultad para mantener la pista
de todos los detalles del problema y dar una solución.

Para manejar la complejidad de un problema hay que utilizar:

a) la abstracción - la abstracción es la habilidad para ignorar los detalles del


problema centrando la atención en un nivel más alto del mismo.
b) la modularización – se trata de dividir un problema en subproblemas, éstos a su
vez en problemas más pequeños y dar una solución a cada uno de ellos
individualmente. Es la técnica del “divide y vencerás” . Cada una de estas partes se
construye y experimenta separadamente e interactúa con las demás a través de
mecanismos bien definidos. Además cada uno de los subproblemas puede ser
resuelto por personas diferentes.
En una compañía de coches, para diseñar un coche los ingenieros utilizan también la
abstracción y la modularización. Ellos imaginan el coche como un conjunto de componentes.
Cada ingeniero se centra en cómo construir uno de esos componentes (motor, ruedas, asiento,
…). Cuando un componente se construye se utiliza la abstracción, cada componente se considera
una pieza más a ser utilizada para construir otros componentes más complejos.
Los mismos principios de abstracción y modularización se utilizan en el desarrollo del software.
A la hora de diseñar un programa se trata de identificar subproblemas que se puedan programar
como entidades separadas.
En la POO estos subcomponentes son objetos. Si intentásemos construir un coche a través de
software, en lugar de implementar el coche como un único objeto, lo diseñaríamos como un
conjunto de objetos separados, un objeto para el motor, otros para las ruedas, otros para los
asientos, y después construiríamos un objeto coche a partir de estos objetos, ensamblándolos.

4.2.- Las clases como tipos

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.).

UT1 Introducción a la programación


- Pág. 1 de 50 -
Si utilizamos la abstracción podemos considerar el display del reloj como dos
paneles, uno para representar la hora (de 00 a 23) y otro para representar los
11:03 minutos (de 00 a 59). Ambos tienen las mismas características, visualizan un
valor que va de 0 hasta un límite determinado y se incrementan de uno en
uno. Cuando alcanzan el límite se ponen otra vez a 0.

El código completo del proyecto es el siguiente:

/**
* 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.
*/

public class VisorReloj


{
private VisorNumero horas;
private VisorNumero minutos;
private String visorString; // simula el visor actual

/**
* 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
*/

public VisorReloj(int hora, int minuto)


{
horas = new VisorNumero(24);
minutos = new VisorNumero(60);
ponerEnHora(hora, minuto);
}

/**
* 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();
}

- Pág. 2 de 50 -
/**
* Pone la hora en el visor a un determinado valor de hora y minuto
*/

public void ponerEnHora(int hora, int minuto)


{
horas.setValor(hora);
minutos.setValor(minuto);
actualizarReloj();
}

/**
* 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.
*/

public class VisorNumero


{
private int limite;
private int valor;

/**
* Constructor para objetos de la clase VisorNumero
*/
public VisorNumero(int limiteMaximo)
{
limite = limiteMaximo;
valor = 0;
}

/**
* Devuelve el valor actual
*/
public int getValor()
{
return valor;
}

UT1 Introducción a la programación


- Pág. 3 de 50 -
/**
* Devuelve el valor del visor como una cadena de dos dígitos
* Si el valor es menor que 10 se le añade a la izquierda un 0
*/

public String getValorVisor()


{
if (valor < 10)
return "0" + valor;
else
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
*/

public void setValor(int nuevoValor)


{
if ((nuevoValor >= 0) && (nuevoValor < limite))
valor = nuevoValor;
}

/**
* Incrementa el valor del display en 1, dando la vuelta a cero
* si se alcanza el límite
*/

public void incrementar()


{
valor = (valor + 1) % limite;
}
}

Nuestro reloj puede representarse a través de la clase VisorReloj:

public class VisorReloj


{
private VisorNumero horas;
private VisorNumero minutos;
……………………
}

donde VisorNumero es una clase tal que:

public class VisorNumero


{
private int limite; // cuando se alcanza este límite el valor de pone a 0
private int valor; // valor actual
…………………..
}

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 clases – La clase VisorReloj


utiliza (depende) de la clase VisorNumero

Relación de composición en UML (un objeto


VisorReloj se compone de 2 objetos
VisorNumero)

El diagrama de objetos muestra los objetos y sus relaciones en un determinado momento de


la ejecución del programa. Proporciona información de los objetos en tiempo de ejecución.
Presenta una vista dinámica del programa.

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).

Ejer.4.1. Dadas las siguientes clases:

public class Cuenta public class Persona


{ {
private String identificador; private String nombre;
private Persona titular;
private double balance; ……………………
…………………… }
}

 Dibuja el diagrama de clases


 Dibuja el diagrama de objetos en tiempo de ejecución para la cuenta unaCuenta con
identificador = “14345BA” cuyo propietario es “Ana López” y el balance actual es
1800€.

Ejer.4.2. Haz lo mismo con las siguientes clases:

public class Circulo public class Punto


{ {
private Punto centro; private int x;
private double radio; private int y;
…………………… ……………………
} }

UT1 Introducción a la programación


- Pág. 5 de 50 -
 Dibuja el diagrama de clases
 Dibuja el diagrama de objetos en tiempo de ejecución para el círculo miCirculo de
radio 5.4 y centro las coordenadas (13, 19) .

4.4.- Tipos primitivos y tipos objeto (tipos referencia)

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).

private VisorNumero horas; private Bola unaBola;


private Persona titular; private Profesor tutor;

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 primitivo almacenan directamente el valor

int numero = 34 34;

- 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.

if (valor < 10)


return "0" + valor;
else

- Pág. 6 de 50 -
return valor ;

 Testea la clase VisorNumero creando varios objetos y llamando a sus métodos

4.5.- Creación de nuevos objetos

Centrémonos en la clase VisorReloj, en concreto en el primero de sus constructores:

public class VisorReloj


{
private VisorNumero horas;
private VisorNumero minutos;
private String visorString; // simula el visor actual

/**
* 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.

horas = new VisorNumero(24);


minutos = new VisorNumero(60);

El operador new realiza dos cosas:

- 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)

UT1 Introducción a la programación


- Pág. 7 de 50 -
Después de ejecutar
el constructor de la
clase VisorReloj

Ya que el constructor de la clase VisorNumero tiene un argumento,

public VisorNumero(int limiteMaximo),


parámetro formal

al crear un objeto de esta clase habrá que pasar un parámetro al constructor,

horas = new VisorNumero(24);


parámetro actual

Ejer.4.4. Sea la siguiente declaración:

public class Tren


{
private int velocidadMaxima;
private String nombre;
/**
* Constructor de objetos Tren.
*/
public Tren(int v, String n)
{
velocidadMaxima = v;
nombre = n;
}
……………………………..
}

 ¿Qué hacemos cuando escribimos, Tren unTren;?


 ¿Es correcto, unTren = new Tren() ?
 Crea correctamente un objeto Tren de nombre “ave” y velocidad 250.
 Dibuja el diagrama de objetos para el apartado anterior

Ejer.4.5. Escribe la signatura de un constructor que se ajuste a la siguiente creación de un


objeto:
miEditor = new Editor(“readme.txt”, -1);

4.6.-Múltiples constructores. Constructores sobrecargados


En Java es posible definir varios constructores en la misma clase. Todos tendrán el mismo
nombre, el nombre de la clase. Ninguno devolverá un valor de retorno (ni siquiera void).

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.

El hecho de definir con el mismo nombre varios constructores se denomina sobrecarga y de


los constructores se dice que están sobrecargados. La sobrecarga se puede aplicar no solo a los
constructores sino a cualquier método. Los argumentos que se pasan en la llamada
determinarán qué constructor o método se ejecutará.

Ejer.4.6. Analiza los dos constructores de la clase VisorReloj examinando similitudes y


diferencias. ¿Por qué no se llama a actualizarReloj() en el segundo constructor?

Ejer.4.7. Dada la siguiente clase:

public class Pasajero


{
private String nombre;
private int peso;
private double altura;

public Pasajero( String n)


{
nombre = n;
peso = 78;
altura = 1.80;
}

public Pasajero( String n, int p)


{
nombre = n;
peso = p;
altura = 1.80;
}

public Pasajero( String n, double a)


{
nombre = n;
peso = 73;
altura = a;
}

public Pasajero( String n, int p, double a)


{
nombre = n;
peso = p;
altura = a;
}
}

 Indica qué sentencias son correctas:

Pasajero p = new Pasajero(“pepe”);


Pasajero p = new Pasajero(“pepe”, 1.83);
Pasajero p = new Pasajero(“pepe”, 65.8, 1.83);
Pasajero p = new Pasajero(“pepe”, 69, 1.83);

Ejer.4.8. Siguiendo con la definición anterior,

 ¿qué ocurre si hacemos?

Pasajero pasa1, pasa2;


pasa1 = new Pasajero(“Jose Luis”);
pasa1 = pasa2;

UT1 Introducción a la programación


- Pág. 9 de 50 -
 Dibuja el diagrama de objetos.
 Declara y crea en la misma sentencia un pasajero pasa3 de nombre “Alejandro”
y altura 1.75. ¿Qué peso tendrá este pasajero?

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
*/

public VisorReloj(int hora, int minuto)


{
horas = new VisorNumero(24);
minutos = new VisorNumero(60);
ponerEnHora(hora, minuto);
}
llamada interna

4.7.2.-Llamadas externas a métodos

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

4.8.- Visibilidad public / private

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.

Ejer.4.9. Dada la siguiente definición de atributo en una determinada clase:

private Impresora impre;

La clase Impresora tiene definidos dos métodos con las siguientes signaturas:

public void imprimir(String nombreFichero, boolean dobleCara)


public int getEstado()

Supongamos que en algún punto se ha construido ya un objeto de la clase


Impresora (impre = new Impresora();).

Realiza dos posibles llamadas a cada uno de los métodos anteriores.

UT1 Introducción a la programación


- Pág. 11 de 50 -
Ejer.4.10. Dada la siguiente definición:

public class Rueda


{
private double presion;

public Rueda( double p)


{
presion = p;
}

public void inflar( )


{
presion += 0.5;
}

public void desinflar( )


{
presion -= 0.5;
}

public boolean estaDesinflada ( )


{
return ( presion == 0.0 );
}
}

Define una clase Bicicleta tal que:

 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.

4.9.- La palabra clave this. La palabra clave null


4.9.1.-Uso de this

Imaginemos la siguiente situación:

public class Rueda


{
private double presion;

public Rueda( double presion)


{
presion = presion;

}
……………………
}
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) .

public class Rueda


{

- Pág. 12 de 50 -
private double presion;

public Rueda( double presion)


{
this.presion = presion;

} asignar al atributo presion del objeto actual el


…………………… valor del parámetro formal presion
}

Ejer.4.11. Dada la siguiente definición:

public class Articulo


{
private String nombre;
private double precio;

Completa la clase:

 escribe el constructor parametrizado que inicialice los dos atributos


 escribe los accesores para el nombre y el precio
 escribe el método, public boolean masBaratoQue(Articulo a), que devuelve
true si el precio del objeto actual es menor que el del objeto que se pasa como
parámetro (no utilices if)

Otro uso de la palabra this es para pasar el objeto actual como parámetro a otro método.

Ej. public class Coche


{
……………………
public void aparcar(Parking p)
{
p.aparcarCoche(this); // paso el objeto actual como parámetro
}
………….
}

public class Parking


{
private Coche c;
…………………………
public void aparcarCoche(Coche c)
{
this.c = c;
}
………….
}

4.9.2.- La palabra clave null


Cuando se declara una variable de tipo objeto la variable no apunta a nada, a ningún objeto, por
defecto, tiene como valor inicial null. Si definimos, private Articulo unArticulo; , hasta que no se
invoque al constructor (o se asigne con el valor de otro objeto Articulo) la variable unArticulo
contiene null.

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.

UT1 Introducción a la programación


- Pág. 13 de 50 -
Ej. public boolean masBaratoQue(Articulo a)
{
if (a != null) // este test permite verificar si la variable apunta o no a un objeto
return (a.getPrecio() > this.precio);
return false;
}

Ejer.4.12. Siguiendo con la clase Articulo:

 añade un mutador para el precio


 representa gráficamente, con un diagrama de objetos, las siguientes situaciones,

Articulo uno, otro;


uno = new Articulo(“Tornillo”, 2.67);
uno.setPrecio(3.4);

 ¿Es posible esta sentencia: uno.setNombre(“Tornillo – B2”); ?


 otro = uno;
uno.setPrecio(3.7);
uno = null;
otro = null;

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.

4.10.- Estructura de un proyecto BlueJ


Un proyecto BlueJ se almacena en un directorio del disco, por ej, C:\...........\Ejercicios Java\
Circulo y Punto.

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.

La estructura de ficheros que genera BlueJ para un proyecto es la siguiente:

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.

4.10.1.- Ejecutando sin BlueJ


El sistema Java siempre inicia la ejecución de una aplicación buscando un método llamadao
main. Este método debe existir y debe tener la siguiente signatura:

public static void main(String[] args)

El método main:

- debe existir en alguna clase del proyecto


- ha de ser público (para que pueda ser invocado desde fuera de la clase)
- debe ser static (método de clase – quiere decir que no se necesitan
instancias de la clase que contiene a main para invocarlo)
- debe tener un array de parámetros String (esto permitirá pasar argumentos
a la aplicación en el momento de su inicio)
- sólo se puede invocar a main() para ejecutar una aplicación

◦ ¿Dónde incluir el main? - Normalmente este


método incluye sentencias que inician la aplicación (crear objetos, llamar a algún método
que inicie la aplicación, ….). Puede incluir cualquier sentencia .

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.

public class TestCirculo


{
public static void main(String[] args)
{
Circulo miCirculo ;
Punto unPunto ;
double x, y, area ;
unPunto = new Punto(3,6) ;
miCirculo = new Circulo(unPunto, 6) ;
x = unPunto.getX() ;
y = unPunto.getY() ;
area = miCirculo.calcularArea() ;
System.out.println(“ Area =” + area + “\n”);
}
}

UT1 Introducción a la programación


- Pág. 15 de 50 -
4.11.- Añadiendo comportamiento iterativo: la estructura
de control iterativa

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.

Hasta ahora las sentencias que hemos utilizado han sido:

- sentencias para escribir valores en la Terminal de texto (System.out.println())


- sentencia de asignación ( variable = valor)
- llamadas a métodos (minutos.incrementar())
- la sentencia if para ejecutar unas u otras instrucciones dependiendo del valor de
una condición

Muchas veces en programación es necesario repetir una o varias instrucciones un nº


determinado o indeterminado de veces. Los lenguajes incluyen estructuras de control para
expresar las iteraciones o bucles.

Java proporciona tres instrucciones de control repetitivas: while, for, do … while.

4.11.1.- La sentencia while

- la condición (expresión booleana) se evalúa. Si es cierta se ejecutan las instrucciones


incluidas en el cuerpo del while y se vuelve a evaluar la condición. Este proceso se repite
hasta que la condición es falsa. En este caso el bucle termina.
- la condición se evalúa siempre en primer lugar. Esto quiere decir que el bucle puede que
no se ejecute nunca si la condición se evalúa a false la primera vez.
- el conjunto de acciones (sentencias) se repiten un nº determinado o indeterminado de
veces.
- siempre tiene que haber alguna sentencia dentro del cuerpo del while que modifique la
condición para que el bucle pueda terminar ( y no se generen bucles infinitos).

Ej. int nveces = 1;


while (nveces <= 10)
{
System.out.println(“Saludo “ + nveces);
nveces = nveces + 1;
}

- 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);

int suma = 0; //es una variable acumulador


int producto = 1; //es una variable acumulador
int contador = 20; //es una variable contador
while (contador >= 1)
{
suma = suma + contador;
producto = producto * contador;
contador--;
}

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--;

b) Para contar un suceso particular (asociado o no a un bucle). Ej. ncaras++; ncruz++;

Un acumulador es una variable cuyo valor se incrementa sucesivas veces en cantidades variables.
Se utiliza:

a) Para obtener un total acumulado de un conjunto de cantidades siendo preciso, en este


caso inicializar el acumulador a 0. Ej. suma = suma + contador;

b) Para obtener un total como producto de distintas cantidades, inicializándose entonces


a 1. Ej. producto = producto * contador;

Un switch o conmutador es una variable que toma dos valores exclusivos, 0 / 1, true / false,
-1 / 1, y que se utiliza para:

a) hacer que se ejecuten alternativamente dos grupos de sentencias dentro de un bucle


b) recordar la ocurrencia o no de un determinado suceso o para salir de un bucle

UT1 Introducción a la programación


- Pág. 17 de 50 -
Ej.
/* Suma de pares entre 1 y 100
y producto de impares entre 1 y 100 */

int sumaPar = 0; // es un acumulador


int productoImpar = 1; //es un acumulador
boolean tocaImpar = true; // es un switch
int numero = 1; //es un contador
while (numero <= 100)
{
if (tocaImpar)
{
productoImpar *= numero;
tocaImpar = false;
}
else
{
sumaPar += numero;
tocaImpar = true;
}
numero++;
}

Ejer.4.14. Codifica en Java los siguientes métodos:

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;

d) public double sumarSerie(int n) - Calcula y devuelve la suma de la serie

e) public double sumarSerie(int n) - Calcula y devuelve la suma de la serie

f) public int sumarDivisores(int numero) - Calcula y devuelve la suma de los divisores de


numero
g) public int sumarDigitos(int numero) - Calcula y devuelve la suma de los dígitos de
numero

Ejer.4.15. (Para trabajar con bucles anidados) Escribe los siguientes métodos:

a) public void escribirFigura(int n) - escribe la siguiente figura, si n = 6 (por ej.)

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

b) public void escribirFigura(int n) - escribe la siguiente figura, si n = 6 (por ej.)

- 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

c) public void escribirFigura(int n) - escribe la siguiente figura, si n = 6 (por ej.)

1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6

d) public void escribirTablaMultiplicar(int numero) - escribe la tabla de multiplicar de l 1,


del 2, del 3, .... hasta la tabla de numero

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).

4.11.2.- La sentencia for

Esta sentencia permite ejecutar un nº determinado de veces una o varias sentencias.

- inicialización – establece la situación inicial para empezar a iterar. Generalmente


consiste en asignar un valor inicial a la variable de control del bucle (la que lleva la
cuenta del nº de veces que se han de repetir las sentencias)
- condición – si se evalúa a true se ejecuta el bucle, si es false termina
- incremento (o decremento) – incrementa (decrementa) la variable de control para
continuar la iteración

Ej. for (int nveces = 1; nveces <= 10; nveces++)


{
System.out.println(“Saludo “ + nveces);
}

UT1 Introducción a la programación


- Pág. 19 de 50 -
for (int tiradas = 1; tiradas <= 30; tiradas++)
{
moneda.tirar();
}

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:

a) public void contarParesImpares() - genera 20 nºs aleatorios comprendidos entre 1 y 50 y


cuenta los pares e impares generados escribiendo al final esta cuenta
b) public int maximo() - calcula y devuelve el máximo de una secuencia de valores aleatorios
comprendidos entre 1 y 100
c) public void escribirEstadisticas() - genera MAX notas aleatorias (comprendidas entre 1 y
10) y escribe la siguiente estadística: media de las notas, nota máxima, nota mínima,
cuántas veces ha aparecido la nota máxima y cuántas la nota mínima. MAX es una
constante de valor 30.

4.11.3.- La sentencia do .. while

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.

Ej. int nveces = 1;


do
{
System.out.println(“Saludo “ + nveces);
nveces++;
}
while (nveces <= 10);

- Pág. 20 de 50 -
4.12.- La clase Random. La clase Scanner

Aunque en temas posteriores veremos en profundidad la API (librerías) de Java, vamos a


introducir ahora las clases Random y Scanner.

4.12.1.- La clase Random

Esta clase es una de las contenidas en la librería de clases de Java. Permite generar n ºs
aleatorios. Para ello:

a) hay que crear una instancia de la clase Random


b) hay que llamar a un método de esa instancia para obtener el nº aleatorio, por ej,
nextInt()
c) para poder utilizar la clase hay que importarla incluyendo la sentencia
import.java.Random al comienzo de la declaración de la clase que utilizará a
Random.

Ej. ……………………………….
Random generador = new Random();
int valor = generador.nextInt(10) + 1 ;

genera un nº aleatorio entre 0 y 9

Ejer.4.17. Completa la siguiente clase que modela un dado de 6 caras:

import java.util.Random;
public class Dado
{
private int cara;
private Random generador;

public Dado( )
{
generador = new Random();
cara = 1;

public int getCara( )


{
return cara;
}

public void tirarDado( )


{
// a completar

}
}

4.12.2.- La clase Scanner

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:

a) se crea una instancia de la clase Scanner

UT1 Introducción a la programación


- Pág. 21 de 50 -
Scanner teclado = new Scanner(System.in);

System.in se refiere a la entrada standard (System.out es la salida standard)

b) se llama a un método de la clase para leer un entero, o un real, o un String, …

 nextInt() – lee un entero del teclado


 nextDouble() – lee un real
 next() – lee un String
 nextBoolean() – lee un valor booleano
 nextLine() – lee un String completo hasta el fin de línea incluyendo los
separadores (espacios, tabuladores, ....). (Lee los tokens que quedan hasta
el fin de línea).

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();
}
}

4.13.- Miembros de clase (miembros static)

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.

Ej. public class Circulo


{
private final double PI = 3.1416;
private double radio;
……………………

public double getPerimetro()


{
return 2 * PI * radio;
}
…………………..
}

- 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).

4.13.1.- Constantes de clase (constantes static)


Se declaran como las constantes habituales pero anteponiendo la palabra reservada static.

private static final double PI = 3.1416; // constante de clase con un valor inicial no modificable

Las constantes static no pertenecen a los objetos sino a la clase.

public class Circulo


{
private static final double PI = 3.1416;
private double radio;
……………………

public double getPerimetro()


{
return 2 * PI * radio;
}
…………………..
}

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:

public class Math


{
...................
public static final double PI = 3.1415192....;
public static final double E = 2.718281;

UT1 Introducción a la programación


- Pág. 23 de 50 -
………………………
}

Para utilizar la constante de la clase Math: perimetro = 2 * Math.PI * radio; , se antepone el


nombre de la clase (no hay que crear instancias de la clase Math).

4.13.2.- Variable de clase (variables static)


Una clase puede declarar variables de clase o variables static, es decir, variables que pertenecen
a la clase y no a las instancias.

Para declarar una variable de clase se especifica static después de la visibilidad y antes del tipo
de la variable.

Ej. private static int contador;

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 class Circulo


{
private static final double PI = 3.1416;
private static int contadorCirculos;
private double radio;
private int numero;
……………………

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.

No utilizaremos este tipo de variables habitualmente.

Ejer.4.18. Crea un proyecto que incluya una clase Empleado con la siguiente estructura:

public class Empleado


{

private int numeroEmpleado;


……………………

public Empleado()
{
// a completar
}
…………………..
}

 Completa la definición de la clase y el constructor de forma que el atributo


numeroEmpleado guarde un valor consecutivo 1, 2, 3, ... por cada nuevo empleado
creado.
 Prueba la clase desde BlueJ creando varios empleados e inspeccionando su estado.
Observa como BlueJ muestra también los miembros static de una clase.

4.13.3.- Métodos de clase (métodos static)


Los métodos también pueden definirse como static en una clase. Como el resto de miembros de
clase, los métodos static se asocian a la clase y no a las instancias por lo que para ser invocados
no se necesita crear ningún objeto (instancia) de la clase.

Un método se declara de clase anteponiendo la palabra static después de su visibilidad.

Ej. public static int máximo(int numero1, int numero2)


public static double factorial(double numero)

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.

public class Math


{
........................
public static double sqrt(double n)
public static double random()
}

UT1 Introducción a la programación


- Pág. 25 de 50 -
Los métodos de clase no pueden acceder a las variables de instancia sólo a las variables de clase.
Estos métodos no operan sobre objetos, se invocan con el nombre de la clase. Tampoco pueden
llamar a los métodos de instancia (al revés sí, los métodos de instancia pueden llamar a los
métodos de clase). double resultado = Math.sqrt(89);
public class Libreria
{
........................
public static int maximo(int numero1, int numero 2)
{
………………….
}
public static double factorial(double numero)
{
………………….
}
}

int valorMaximo = Libreria.maximo(7,89);


double ipso = Librería.factorial(6);

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()

No utilizaremos métodos static (salvo que se pida explícitamente).

4.14.- Recursión. Métodos recursivos

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 definición es recursiva si el concepto o palabra que se define aparece en la propia


definición. Por ejemplo, imaginemos la lista de n os: 24, 38, 40, 37 podríamos definir la
lista así,

 una lista es un nº o
 una lista es un nº y una , junto con una lista

Aquí el concepto de lista aparece en la propia definición.

nº , lista
24 , 38, 40, 37
nº , lista
38 , 40, 37
nº , lista
40 , 37

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.

Aplicado a la programación el uso de la recursión es idóneo en problemas cuyos cálculos o


estructuras de datos pueden definirse en términos recursivos y es una alternativa a la iteración.
Cualquier problema que se resuelva de forma recursiva puede resolverse también sin recursión,
con una solución iterativa, sólo que muchas veces esta última es más compleja.

- 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.

Veamos un ejemplos de método recursivo teniendo en cuenta que el método manejará


únicamente tipos primitivos (por sencillez, no aplicaremos la recursión a los objetos).

Un método es recursivo si puede “llamarse” (invocarse) a sí mismo.

Planteemos el cálculo del factorial de un nº en términos recursivos.

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 general, el problema n! expresado recursivamente queda:

1 si n = 1 o n = 0 es el caso base o caso trivial, el que se resuelve sin recursión


n * (n – 1)! si n > 1 caso general

En todo problema recursivo hay que encontrar primero el caso


base y luego el caso general en el que se incluirá la llamada al
método recursivo.

En Java quedaría:

public int factorial(int n) public int factorial(int n)


{ {
if (n == 1 || n == 0) int resul;
return 1; if (n == 1 || n == 0)
return n * factorial (n – 1); resul = 1;
} else
resul = n * factorial(n – 1);

UT1 Introducción a la programación


- Pág. 27 de 50 -
return resul;
}

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.

UT1 Introducción a la programación


- Pág. 29 de 50 -
Ejercicios adicionales UT4
Ejercicio 1. A partir de las clases que forman el proyecto Reloj Digital vamos a crear un nuevo
proyecto que incluya estas dos clases y otras dos más, RelojAlarma y Alarma. La clase
RelojAlarma va a modelar un reloj como el que hemos estudiado pero que incorpora una
alarma ,así cada vez que el reloj avanza si la nueva hora es la misma que la establecida en la
alarma se hará sonar un RINGGGGGGGG.

El diagrama de clases es el siguiente:

Las clases VisorReloj y VisorNumero no cambian, son las


mismas que en el proyecto anterior.

La clase Alarma guarda la hora de alarma, permite modificar


esta hora con el método setHoraAlarma() y obtiene la hora de
alarma como un String de la forma “XX:XX”. El constructor de
esta clase establece la alarma, por defecto, a la hora 7:00

La clase RelojAlarma tiene dos atributos de tipo referencia, reloj de tipo VisorReloj y alarma de
tipo Alarma. Esta clase incluye:

 un constructor sin parámetros que crea tanto el reloj como la alarma


 un constructor con dos parámetros, la hora y minutos del reloj, que crea el reloj a
partir de estos dos parámetros y la alarma
 el método emitirTic() que avanza el reloj. Después de que la hora del reloj avanza se
comprueba utilizando el método esHoraAlarma() si la hora actual y la de alarma
coinciden. Si es así se hace sonar la alarma emitiendo un
“RRRRIIIIINNNNNGGGGG” en la pantalla
 el método setAlarma() permite al reloj cambiar la hora de la alarma
 los métodos getHora() y getAlarma() devuelven la hora actual y la de alarma en
formato String
 el método esHoraAlarma() es un método privado. Este método compara dos
cadenas, la que representa la hora actual y la que representa la hora de alarma. Para

- 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.

Relación de composición en UML (un círculo consta


de un centro que es de tipo Punto)

 Añade a la clase Circulo el atributo centro


 Crea los dos constructores de la clase. Son constructores sobrecargados. El primero
tiene dos parámetros, el valor del radio y un parámetro de tipo Punto ( se pasa un
objeto Punto que ya está creado) que será el valor del centro que hay que asignar. El
segundo constructor solo tiene un parámetro, el valor del radio. Dentro de este
constructor se crea el objeto centro con valores iniciales (0,0).
 Prueba ambos constructores creando varios objetos Circulo. Inspecciona cada
círculo creado con Inspect de BlueJ y observa como se nuestra el atributo centro.
 Incluye al accesor getCentro() que devuelve el centro del círculo
 Incluye los mutadores setCentroX() y setCentroY(). Estos valores modifican las
coordenadas x e y del centro del círculo. Tendrás que llamar dentro de estos
métodos a los mutadores setX() y setY() de la clase Punto
 Incluye el método toString() para devolver una cadena con una representación del
círculo. Para hacer este método tendrás que llamara a toString() de la clase Punto.
 Incluye el método printCirculo() para visualizar en la pantalla la representación del
círculo (llama desde este método al método toString() – es una llamada interna)

Ejercicio 3.

El proyecto consta de dos clases Linea y Punto. La


clase Punto del ejercicio anterior nos puede servir
por eso la añadiremos a nuestro proyecto nuevo
haciendo Edit / Add class from File y la
seleccionaremos desde el proyecto Circulo y Punto. La relación del diagrama de clases muestra
una composición, una línea consta de dos puntos.

 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

UT1 Introducción a la programación


- Pág. 31 de 50 -
 Añade a la clase los métodos:

public void moverDerecha(int distancia)


public void moverIzquierda(int distancia)
public void moverArriba(int distancia)
public void moverAbajo(int distancia)

que desplazan la línea a la derecha, izquierda, arriba y abajo, respectivamente, la


distancia que se indica como parámetro
 Añade accesores y mutadores para los dos puntos que forman la línea
 Incluye un método printLinea() que muestre en pantalla la información de la línea:

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.

Nuestro proyecto constará de tres clases, las que


muestra el diagrama, que modelan un sistema
que consta de tres usuarios que utilizan cada uno
de ello un par de contadores para registrar los
intentos de acceso al sistema y contar los
intentos fallidos e intentos con éxito.

 La clase Contador es similar a la utilizada en la UT3 , puedes añadirla al nuevo proyecto


y hacer sobre ella las modificaciones necesarios. Añade un nuevo constructor ,
Contador(int nuevoValor), que inicia el contador con el valor indicado en el parámetro.
Si el valor es negativo el contador se inicializa a 0.
 Ahora añade otro constructor pero que tome como parámetro un objeto Contador y se
inicialice con el valor de ese contador, public Contador(Contador otroContador)
 Prueba la clase Contador.
 Crea una nueva clase Usuario que incluya:
o atributos – nombre del usuario, accesos y fallos ambos de tipo Contador
o métodos -
i. un solo constructor public Usuario(String queNombre) . Dentro del
constructor se crean los dos contadores asociados al usuario
ii. un método public void acceder() que simula el intento del usuario
para acceder al sistema. Para simular esto generaremos un valor
aleatorio (1 o 2). Si sale 1 significa que el acceso ha sido fallido y si
sale 2 el acceso ha sido correcto.

int intento = (int)(Math.random()* 2) + 1;

Consulta en la documentación la clase Math y el método random() de


esta clase

iii. incluye un accesor para el nombre del usuario y un método


printDatosUsuario() que muestre en pantalla la información del
usuario en cuestión, su nombre y el nº de accesos fallidos y con éxito

 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:

 constructor sin parámetros que inicializa el numerador a 0 y el denominador a 1


 constructor con dos parámetros, numerador y denominador
 accesores y mutadores para los dos atributos
 public Fraccion sumar(Fraccion otra) – suma la fracción actual con la recibida
como parámetro
 public Fraccion restar(Fraccion otra) – ídem calculando la resta
 public Fraccion multiplicar(Fraccion otra) – multiplica dos fracciones
 public Fraccion dividir(Fraccion otra) – divide dos fracciones
 public boolean igualQue(Fraccion otra) – devuelve true si las fracciones son
iguales, false en otro caso
 public boolean menorQue(Fraccion otra) – devuelve true si la fracción actual es
menor que la recibida como parámetro.
 public Fraccion clonar() – devuelve una fracción idéntica a la actual
 public String toString() – devuelve una representación de la fracción de la forma
“ xx / yy “

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:

- getDistanciaDesdeOrigen() – devuelve la distancia desde el origen al punto. Se


calcula con la fórmula:
- getDistanciaDesde(Punto p) – calcula la distancia desde el punto recibido como
parámetro con la fórmula: donde (x1, y1) son las
coordenadas del objeto actual y (x2, y2) las del objeto recibido como parámetro.

Ejercicio 7. Crea un proyecto Embarque que incluya dos clases:

- clase Pasajero – los objetos de esta clase almacenan el nombre y edad de un


pasajero, además escriben detalles sobre los pasajeros y se comparan unos con otros
- clase Ferry – contiene hasta tres pasajeros que van en el ferry

La clase Pasajero tiene dos atributos: el nombre de un pasajero y la edad.

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”.

Nombre: Pedro Reyes


Edad: “Sin especificar”
El método esMasJovenQue() devuelve un valor booleano y toma como parámetro un objeto de
la clase Pasajero. Devuelve true si el pasajero actual (el receptor del mensaje) es más joven que
el pasajero que se recibe como parámetro. Hay que comprobar que este parámetro (el pasajero
recibido) contiene algo, no es una referencia null. Si es así se devolverá false. La comprobación

UT1 Introducción a la programación


- Pág. 33 de 50 -
también tiene en cuenta que la edad se haya especificado en los dos objetos que se comparan. Si
no es así también se devuelve false.

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.

La clase tiene un constructor sin parámetros que inicializa el nº de pasajeros a 0 y el resto de


atributos a null.

Hay un accesor, getNumeroPasajeros(), que devuelve el nº de pasajeros actualmente en el ferry.

Otro accesor es printDetallesPasajeros(), sin parámetros, que escribe información detallada de


los pasajeros que hay en el ferry. Este método utilizará el método printDetalles() de la clase
Pasajero. Si no hay ningún pasajero en el ferry se escribirá “No hay pasajeros”. Si hay uno o más
se escribirá, “Los pasajeros son” y a continuación los detalles de cada pasajero. No deberá fallar
si hay menos de tres pasajeros. Por ejemplo si hay dos pasajeros aparecerá:

Los pasajeros son:

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.

Otro mutador añadirPasajeroPorNombre() toma un String como parámetro y devuelve un


bolean. Si el ferry está lleno devuelve false. En otro caso, crea un nuevo objeto de la clase
Pasajero a partir del nombre y lo añade utilizando para ello el método añadirPasajero().

El mutador borrarPasajero() no tiene parámetros y devuelve un objeto de tipo Pasajero.


“Borra” el pasajero que está en asiento1 devolviendo su referencia asegurando además que el
pasajero de asiento2 pasa ahora a asiento1 y el que está en asiento3 pasa a asiento2 quedando
en asiento3 una referencia null. Si no hay ningún pasajero en el ferry el método no hace nada y
devuelve null. El método actualizará adecuadamente el nº de pasajeros.

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:

private Pasajero masJovenDeDos(Pasajero uno, Pasajero dos)

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:

 dos atributos, miReloj, tuReloj de tipo RelojAlarma

- 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

 define un método test2() en el que:


- se establece la alarma de tuReloj a las 7:00
- visualiza la hora actual de tuReloj y la hora de alarma
- se avance el reloj cinco minutos
- visualiza la hora actual de tuReloj

 Crea un objeto de la clase TestReloj y ejecuta los métodos test1 ytest2.

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:

 dos atributos fraccion1 y fraccion2 de tipo Fraccion


 un constructor sin parámetros que inicializa los dos atributos a null
 un método público demo1(). Este método no tiene parámetros ni devuelve nada. Dentro
del método:
- se crea fraccion1 llamando al constructor sin parámetros
- se establece numerador y denominador para que la fracción sea –4 / 7
- se crea fraccion2 con el constructor parametrizado siendo el numerador y
denominador respectivamente 13 / 2
- se calcula la suma, resta, producto y división de las dos fracciones
- se escribe el resultado. Para ello se hará uso del método privado,
private void escribirFraccion(String mensaje, Fraccion fraccion)
que muestra una sola fracción en la pantalla precedida de un mensaje
aclaratorio, por ejemplo, “Fracción 1” o “La suma es “, ....
 un método público demo2() en el que:
- se modifica fraccion1 para que ahora sea la fracción 17 / 25 y fraccion2 para
que sea 16 / 11 (no hay que llamar a ningún constructor)
- se compara fraccion1 en relación a fraccion2 escribiendo en pantalla si es
menor o si son iguales
- se realiza una copia de fraccion1 visualizando en pantalla el valor de la
copia. Utiliza en este último caso el método privado anterior
escribirFraccion()
 crea un objeto de la clase DemoFraccion y llama primero e demo1() y luego a demo2().
Crea otro objeto de la misma clase pero ahora invoca primero a demo2(). ¿Qué ocurre y
por qué?

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:

- declarar y crear dos puntos con coordenadas (3, 8) y (12, 9)


respectivamente
- visualizar cada uno de los dos puntos en pantalla
- visualizar la distancia del primer punto al origen
- visualizar la distancia que hay entre ambos puntos

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()):

UT1 Introducción a la programación


- Pág. 35 de 50 -
System.out.printf(cadena_de_formato, expresiones_a_escribir);

donde:

cadena_de_formato: es un string en el que se incluyen especificadores de formato. Un


especificador de formato indica cómo una expresión ha de ser visualizada.
expresiones_a_escribir: puede ser una (o varias) expresiones (s) numérica(s) , o carácter, o
booleana (s) o de tipo String

Algunos especificadores usados frecuentemente:

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.

Ej. double total = 45.6789;


int contador = 6;
System.out.printf(“El valor del total es %6.2f y el de contador es %d \n”,
total, contador);

- 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:

- cree un nuevo Pasajero, “Luisa” de 34 años, y lo añada al ferry


- visualice el nº de pasajeros del ferry
- cree un nuevo Pasajero, “Enrique” de 19 años, y lo añada al ferry
- visualice el nº de pasajeros del ferry
- cree un nuevo Pasajero, “Alberto” sin especificar edad , y lo añada al ferry
- visualice el nº de pasajeros del ferry
- cree un nuevo Pasajero, “Raquel” sin especificar edad , y lo añada al ferry
- visualice el nº de pasajeros del ferry
- borre un pasajero
- visualice el nº de pasajeros del ferry
- borre dos pasajeros
- visualice el nº de pasajeros del ferry
- borra otro pasajero (el programa no deberá fallar en este caso)
- añade tres pasajeros, uno por su nombre (utilizando el método
addPasajeroPorNombre()) y los otros dos creando previamente los objetos
Pasajero con un nombre y una edad concreta
- visualice el nombre del pasajero más joven

- 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.

La clase define cinco constantes con valores de 1 a 5 que


representan las diferentes opciones que el usuario puede elegir
para trabajar con la cuenta.

Los atributos de esta clase son la cuenta sobre la que


trabajaremos y el teclado que nos permitirá aceptar datos desde la
consola.

El constructor crea el teclado.

El método público iniciar() es el método principal que controla la


lógica de funcionamiento de un objeto de esta clase. Primero
solicita el nº de cuenta y el nombre del titular y con estos datos se
crea la cuenta con la que se va a trabajar.

A continuación presenta al usuario un menú en la pantalla del


estilo:

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.

Dependiendo de la opción elegida por el usuario se ejecuta el método adecuado:


realizarIngreso(), realizarReintegro(), ...... Cuando se realiza un reintegro o ingreso dentro del
método encargado de esta acción se solicita al usuario la cantidad a ingresar o sacar.

El método borrarPantalla() borra la pantalla.

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:

- crear un objeto InterfazUsuario


- llamar al método iniciar()

Recuerda que no es necesario que exista ningún objeto de la clase AplicacionCuentaBancaria


para ejecutar el método main(), es un método de clase y no necesita instancias para su
ejecución.

UT1 Introducción a la programación


- Pág. 37 de 50 -
Ejercicio 13 . Añade al proyecto Embarque una clase AplicacionEmbarque que contenga el
método main() y que:

a) solicite al usuario el nº de pasajeros que van a embarcar (supondremos que el usuario


teclea 1, 2 o 3, no hay que comprobar esto)
b) pida los datos de los pasajeros que embarcan (nombre completo y edad)
c) cree y añada los pasajeros al ferry
d) visualice los datos de los pasajeros embarcados

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:

private int mcd(int num1, int num2),

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).

El producto de dos nos exponenciales de igual base se define: ab * am = a (n+m)


La potencia de un nº exponencial es: (an)m = a(n*m)
El cociente de números exponenciales de igual base se define: an / am = a(n-m)
El valor de un nº exponencial es:

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:

 dos constructores sobrecargados, uno tiene dos parámetros, base y exponente. El


otro recibe un objeto Exponencial .
 accesores y mutadores para base y exponente
 el método public double valorExponencial() que calcula el valor de un nº
exponencial. Para ello se ayuda del método privado,
private int potencia(int a , int b), que calcula ab
 el método public Exponencial multiplicar(Exponencial otro) que multiplica dos nos
exponenciales
 el método public Exponencial dividir(Exponencial otro)
 el método public Exponencial elevar(int n) que calcula la potencia de un nº
exponencial
 el método toString() devuelve una representación textual del nº exponencial que
incluya la base, el exponente y el valor exponencial del nº

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 ofrece los siguientes servicios:

UT1 Introducción a la programación


- Pág. 39 de 50 -
- devuelve el factorial del nº guardado en el objeto (haz dos versiones, una con while
y otra con for)
- detecta si el nº es primo o no (un nº es primo si tiene como únicos divisores a él
mismo y a la unidad)
- calcula cuántas cifras tiene el nº
- detecta si el nº es o no capicúa
- escribe un cuadrado en pantalla de * con tantas filas y columnas como indique el
nº guardado en el objeto (implementa este método con ayuda de una sentencia for)

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.

Testea la clase desde BlueJ.

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:

1.- Solicitar número


2.- Factorial
3.- Primo
4.- Contar cifras
5.-Capicúa
6.- Dibujar
7.- Salir

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().

Prueba toda la aplicación.

Ejercicio 19. El juego del Crasp es un juego de azar cuyas reglas son:

- un jugador lanza dos dados (de 6 caras cada dado)


- si la suma de los dados es 7 u 11 en el primer lanzamiento el jugador gana
- si la suma es 2, 3 0 12 en el primer lanzamiento el jugador pierde (este resultado es
el que se denomina “Crasp”, la “casa” gana en este caso)
- si la suma es 4, 5, 6, 8, 9 0 10 en el primer lanzamiento esta suma se convierte en el
“punto” del jugador. Para ganar debe seguir tirando los dados hasta lograr su punto,
es decir, obtener otra vez esa suma en una tirada
- el jugador pierde si saca un 7 antes de lograr su punto

Diseña la clase Dado tal como muestra el diagrama. Puedes añadir la


clase Dado que hiciste con anterioridad al proyecto.

- 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.

La clase JuegoCraps simula un juego del Craps . El constructor,


además de crear los dados, inicializa el juego llamando al método
reset(). Este método prepara el juego para empezar a jugar
poniendo el atributo ganado a false y el numeroTiradas a 0.

El método jugar() simula una vez completa del juego (una


secuencia de tiradas hasta ganar o perder el juego) . Dentro de este
método utiliza un sentencia switch para analizar el resultado
obtenido cuando se tiran los dados. El atributo numeroTiradas
contiene al final el nº de tiradas que se han hecho hasta ganar o
perder.

Prueba la clase desde BlueJ.

Añade al proyecto una clase InterfazCrasp para interactuar con el usuario. Esta clase incluye:

- una constante CONTINUAR de tipo char y con valor asociado ‘S’


- un objeto juego que representa un juego del Crasp y un objeto teclado de tipo
Scanner para interactuar con el usuario a través del terminal
- el constructor crea el juego y el teclado
- un método iniciar() dentro del cual se indica al usuario la posibilidad de jugar al
Crasp mientras él quiera, es decir, mientras pulse CONTINUAR. Si quiere jugar se
prepara el juego llamando al método reset() y se juega. Después de cada jugada se
muestran los resultados en pantalla, es decir, se indica al usuario si ha ganado o
perdido y en cuantas tiradas lo ha hecho
- la clase incluye dos métodos privados que ayudan al método iniciar() anterior:

 private void jugarAlCrasp() – aquí se llama al método jugar() y se


muestran los resulatados
 private char seguirJugando() - indica con un mensaje al usuario si
quiere jugar y devuelve un char que es la tecla pulsada por el usuario

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.

UT1 Introducción a la programación


- Pág. 41 de 50 -
Ejercicio 20. Define una clase Inversión cuyos objetos nos permiten monitorizar el
crecimiento de una cantidad invertida que acumula un determinado tipo fijo de interés anual .

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.

Añade los siguientes métodos:

- 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.

- public int añosHastaObjetivo(double importeObjetivo) – calcula y devuelve el nº


de años que han de pasar para que el importe inicial se convierte en
importeObjetivo

- public String tablaDespuesDe(int años) – devuelve una cadena con la información


mostrada en la figura. Para hacer este método ayúdate del método anterior. Los
resultados están formateados. Utiliza el método estático format() de la clase String
(consulta la API).

Ej. String cadena = String.format(“%8.2f €”, cantidad);

Cantidad inicial 3000.0 €

Interés anual 5.0 %

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:

- public void simularDespuesDe() - prueba el método despuesDe() de la


clase Inversión
- public void simularTablaDespuesDe() – prueba el método
tablaDespuesDe() de la clase Inversión
- public void simularHastaObjetivo() – prueba el método
añosHastaObjetivo() de la clase Inversión

- 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.

Añade a la clase Inversión los siguiente atributos:

- minInteres, maxInteres, increInteres de tipo double


- minAños, maxAños, increAños de tipo int

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 el método public void tablaInversionLargoPlazo() que permite visualizar en pantalla la


tabla de la figura. Los valores double están formateados. Utiliza ahora el método printf().

Incluye en la clase SimulacionInversion un nuevo método public void simulacionLargoPlazo()


que pruebe el método tablaInversionLargoPlazo().

UT1 Introducción a la programación


- Pág. 43 de 50 -
Ejercicio 22. Define una clase Cuadrado con un atributo de tipo entero, lado. Incluye un
constructor con un parámetro, un accesor y un mutador. Añade a la clase los siguientes métodos
para dibujar en pantalla el cuadrado de diferentes formas:

 public void dibujarBicolor()


 public void dibujarContorno()
 public void dibujarEnAspa()

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:

public void serieAlfabeto() – genera la serie de la figura para 10 filas y 10 columnas

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”.

UT1 Introducción a la programación


- Pág. 45 de 50 -
Las clases que implementarán el juego serán tres: Contador, JuegoNumeroSecreto e
InterfazJuego.

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).

La clase JuegoNumeroSecreto modela las reglas de


funcionamiento del juego. El diagrama UML muestra los atributos
y métodos de la clase.

- terminado vale true cuando acaba el juego, false en


otro caso
- resultado guarda el resultado de cada jugada (cada
intento de adivinar por parte del usuario)

El constructor inicializa adecuadamente los atributos. Dentro del


constructor se llama al método resetJuego() que genera un
nºaletorio entre 1 y 100, restablece el nº de intentos, ....... (analiza
qué otras inicializaciones e hacen dentro de este método)

El método realizarJugada() simula una única jugada por parte


del usuario. Al método se le pasa como parámetro el nº intentado
que se comparará con el nº secreto. El método indicará a través de
los atributos terminado y resultado cuál ha sido el resultado de la
jugada (el usuario ha acertado, el nº intentado es más alto o más
bajo, ya se han agotado los intentos, ...)

La clase InterfazJuego es la responsable de interactuar con el


usuario.

El constructor crea los dos atributos.

El método jugar() implementa un bucle (hazlo con un do ....while)


que le permite al usuario estar jugando al juego del nº secreto
hasta que se canse. Cada vez que quiere jugar se le hace una
presentación del juego con el método privado
presentacionJuego(), se prepara un nuevo juego y se juega al
número secreto hasta que termine.

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().

Por ejemplo si el parámetro que se le pasa al método generarFibonacci() es 8 se devuelve:

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.

Testea la clase desde BlueJ.

- 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.

Añade el método dibujarArbolNavidad() que dibuja en pantalla:

1
232
34543
4567654
567898765
67890109876
7890123210987
890123454321098
90123456765432109
000
000

UT1 Introducción a la programación


- Pág. 47 de 50 -
Ejercicio 27. Vamos a diseñar una clase que modele el juego del MasterMind para números
de 5 cifras en los que las cifras no se repiten. Un objeto de esta clase piensa un nº de cifras y el
usuario a través de un objeto IUMasterMind interactuará con el juego para intentar adivinarlo.
Cada vez que lo intenta el juego le dice al usuario cuántos muertos y heridos hay en el nº que él
ha proporcionado. Un muerto es una cifra que coincide en valor posición con otra que hay en el
número secreto, un herido coincide en valor pero no en posición.

Un ejemplo del juego:

------------------ Juego del MasterMind ---------------


Introduce números de 5 cifras sin repetir
Debes adivinarlo en un máximo de 3 intentos
--------------------------------------------------------------
Teclea número 12345
Intentos 1
Nº muertos 2 Heridos 1
Teclea número 56789
Intentos 2
Nº muertos 0 Heridos 3
Teclea número 23456
Intentos 3
Nº muertos 2 Heridos 1
Lo siento has agotado los intentos
El número secreto era 18356

MAX_INTENTOS es una constante de clase (observa que se ha


hecho pública, por tanto, podrá ser accesible desde el código de
la otra clase IUMasterMind). Indica el máximo nº de intentos
que se permiten al usuario.

CIFRAS es una constante de valor 5.

numeroSecreto es el nº que se genera cada vez que se hace un


reset al juego. El nº es de 5 cifras y ninguna se puede repetir.
Para generar este nº se obtiene una a una cada una de las
cifras de forma aleatoria. Cada vez que se tiene una cifra antes
de que pueda formar parte del nº secreto habrá que comprobar
que no está ya dentro de él. Esto lo hace el método privado de
ayuda estaDigito() que tomando como parámetros una cifra y
un número devuelve la posición de la cifra dentro del nº o 0 si
no está.

intentos, muertos y heridos son del tipo Contador (importa


esta clase de ejercicios anteriores).

El constructor inicializa los atributos adecuadamente. LLama


al método reset().

El método reset() prepara el juego para poder empezar a jugar


(pone los intentos a 0, los muertos y heridos 0, ....)

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()

El método juegoTerminado() determina si ha acabado el juego. Esto ocurre cuando se adivina el


nº secreto o se han agotado los intentos

- 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.

La siguiente figura muestra un Triángulo de Pascal (o Triángulo de Tartaglia):

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

Este triángulo debe su nombre al matemático Blaise Pascal .

Cada elemento de este triángulo es la suma de los dos que están por encima de él.

Para construir este triángulo tendremos en cuenta:

- las filas se numeran comenzando por 0


- la fila n contiene n+1 elementos
- cada número del triángulo es un nº combinatorio. En la fila 3 hay cuatro nºs
combinatorios: 1 3 3 1.
- para calcular un nº determinado del triángulo haremos: Cn,m = n! / m! (n – m)!
(donde n es el nº de fila en que se encuentra el término y m el nº que hace en la
columna, en ambos casos empezando desde 0)

Ej – C5,2 = 5! / 2! ( 5 – 2 )! = 10

UT1 Introducción a la programación


- Pág. 49 de 50 -
Diseña una clase Tartaglia cuyos objetos generen este triángulo. La clase guarda como atributo
el nº de filas que tendrá el triángulo. Incluye accesor y mutador y los siguientes métodos:

 void dibujarTriangulo() – genera y dibuja el triángulo en pantalla


 void dibujarFila(int fila) - es un método privado de ayuda que escribe la
fila indicada en el parámetro
 int obtenerTermino(int fila, int columna) – método privado de ayuda que
devuelve el término de la fila y columna indicadas como parámetros
 int factorial(int numero) - método privado de ayuda que devuelve el
factorial de un número de forma recursiva

- Pág. 50 de 50 -

También podría gustarte