Programación - 2004/2006

Página Principal

Hoja 4

1 Queremos definir dentro del paquete figuras una clase Cuadrado aprovechando por medio de los mecanismos que proporciona Java que ya disponemoos de la clase Rectángulo.java, ya que un cuadrado puede verse como un rectángulo en el que lx==ly. La clase Cuadrado debe tener una constructora con 3 parámetros enteros, los dos primeros representando las coordenadas de la esquina superior izquierda del cuadrado, y el tercero especificando el ancho del cuadrado. El resto de los métodos deben ser idénticos a los de Rectángulo, y no se permite introducir ningún atributo nuevo. La implementación de la clase debe asegurar que un programa como:
import figuras.*;
public class Principal {
    public static void main(String []args) {
        Cuadrado c = new Cuadrado(20,20,5);
        System.out.println(c.getX()+" "+c.getY()+" "+
                           c.getLx()+" "+c.getLy());
        System.out.println("Área: "+c.área());
        System.out.println(c);      
    }
}
escribirá por pantalla:
20 20 5 5
Área: 25
(20, 20) Lado: 5
Consideramos ahora el siguiente programa:
        Cuadrado c1 = new Rectángulo(10,10,6,6);
        Rectángulo r1 = new Cuadrado(20,20,5);

        Cuadrado c2 = new Cuadrado(20,20,5);
        Rectángulo r2 = new Rectángulo(10,10,6,6);
        c2 = r2;
        r2 = c2;
        
        System.out.println(c2);
        System.out.println(r2);

Indica razonadamente qué líneas darán error al compilar y cuáles son por el contrario correctas. Indica también qué escribirá el programa por pantalla tras quitar las líneas incorrectas.

2 Queremos escribir código para representar los valores de una factura telefónica. La factura contendrá el nombre de la compañía, el total a pagar y el número total de llamadas realizadas.

Sin embargo hay un problema: distintas compañías de teléfonos utilizan diferentes criterios para cobrar las llamadas, por lo que al escribir esta clase no podremos aún escribir todos sus métodos. Escribe, utilizando los recursos de Java, una clase que recoja toda esta información. Los métodos que debe contener son:
  1. Una constructora que reciba como parámetro el nombre de la compañía.
  2. getNúmLlamadas,getCompañía(),getImporte: Métodos que devuelven respectivamente el total de llamadas realizadas, el nombre de la compañía y el importe de la factura, que será un double (para los céntimos de euro).
  3. coste: Recibe dos parámetros, un entero entre 0 y 23 con la hora de inicio de la llamada y otro con su duración en segundos, y devuelve el coste de la llamada (un double). No podremos escribir el cuerpo de este método ya que dependerá de la compañía concreta a la que pertenezca la factura (ver problema siguiente).
  4. llamada: Recibe los mismos dos datos que el método anterior, pero en lugar de devolver el coste lo acumula al total, apuntando además que ha habido una llamada más. No devuelve nada.
  5. toString: Devuelve un String con los datos de la factura. Por ejemplo:
    Compañía: Vozarrón - 3 llamadas - Importe: 127.24 euros.

3 Ahora vamos a utilizar la clase anterior, utilizando los mecanismos de Java, para representar la factura telefónica de la compañía TeLeLe. Esta empresa cobra las llamadas según la hora de inicio h (se considera la parte entera, p.ej. para las 7:54 se tomará h=7) según los siguiente criterios:
  1. Si 0 <= h < 8, el coste es de 0.01 euros por segundo.
  2. Si 8 <= h < 14, el coste es de 0.05 euros por segundo.
  3. Si 14 <= h <=; 23, el coste es de 0.02 euros por segundo.
A este coste hay que añadir 0.25 euros por establecimiento de llamada, independientemente de la hora. Escribir una clase para representar una factura de esta compañía. La clase debe tener una constructora sin parámetros, que inicializará el nombre de la compañía a "TeLeLe". Escribir también un programa principal que declare una factura de la compañía TeLeLe, pida datos de cada llamada al usuario, y utilice el método llamada para ir actualizando la factura. Cuando el usuario no desee introducir más datos, el programa debe mostrar por pantalla la factura resultante. Ejemplo:
Hora de inicio (de 0 a 24): 13
Duración (segundos): 50
Más llamadas? (s/n) s
Hora de inicio (de 0 a 24): 17
Duración (segundos): 1121
Más llamadas? (s/n) s
Hora de inicio (de 0 a 24): 23
Duración (segundos): 170
Más llamadas? (s/n) n
Factura: Compañía: TeLeLe - 3 llamadas - Importe: 29.07 euros

4  Partimos de la siguiente clase Marcador:

 
package deportes;

// marcador de un deporte genérico
public class Marcador {
	// atributos
	private int puntLocal, puntVisitante;   private String nombreLocal, nombreVisitante;
	
	// constructora. Recibe como parámetro el nombre de los equipos. 
    //Las puntuaciones iniciales son 0-0
	public Marcador(String nombreLocal,String nombreVisitante) {
		this.nombreLocal = nombreLocal;
		this.nombreVisitante = nombreVisitante;
		puntLocal = puntVisitante = 0;		
	}	
              
	// métodos de consulta
	public int getPuntLocal() { return puntLocal;}
	public int getPuntVisitante() { return puntVisitante;}
	public String getNombreLocal() { return nombreLocal;}
	public String getNombreVisitante() { return nombreVisitante;}
	
	// incremento de cada equipo
	public Marcador incLocal() {puntLocal++; return this;}
	public Marcador incVisitante() { puntVisitante++; return this;}
    // para deportes que admiten incrementos de más de un punto
	public Marcador incLocal(int inc) {puntLocal += inc; return this;}
	public Marcador incVisitante(int inc) {puntVisitante+=inc; return this;}
	
	// para convertir el objeto a cadena
	public String toString() {
		return nombreLocal + ": "+puntLocal+" - "+
		       nombreVisitante+": "+puntVisitante;
	}		
}

Aprovechando la clase anterior, escribir una nueva clase MarcadorBaloncesto para representar un marcador para dicho juego. Debe formar parte de un paquete juegos.

La clase debe contener los siguientes métodos (además de los atributos que se consideren necesarios):

La clase debe contener únicamente los métodos descritos (por ejemplo no debe tener métodos como incLocal o incVisitante).

5 Queremos representar en Java fórmulas lógicas, formadas por variables combinadas mediantes las operaciones Neg (negación), And (conjunción) y Or (disyunción). Un ejemplo de fórmula: (X And Z) Or (Neg(Y And Z)), donde X, Y, Z son variables. Una valoración de la fórmula será el valor booleano (true o false) obtenido al dar valor booleano a las variables. Por ejemplo si en la fórmula anterior damos a X, Y el valor true y a Z el valor false obtendremos la valoración true, ya que (true And false) Or (Neg(true And false)) = false Or (Neg false) = false Or true = true Para fijar el valor de cada variable se empleará la siguiente clase ValorVar:

package lógica;
// Clase ValorVar: fija el valor (true o false) de una variable
public class ValorVar {
// atributos
private String nombreVar; // nombre de la variable
private boolean valor; // valoración
// constructora.
// - n: Nombre de la variable
// - v: Valoración que le corresponde
public ValorVar(String n, boolean v) {
this.nombreVar = n; this.valor = v;
}
// métodos de consulta
public String nombreVar() {return nombreVar;}
public boolean valor(){return valor;}
}
  1. Escribir un interfaz Fórmula, perteneciente al paquete lógica. El interfaz constará de un único método valoración que tendrá como parámetro un array de valores de tipo ValorVar, devolviendo la valoración de la fórmula (true o false).
  2. Escribir una clase Variable para representar la fórmula que consta de tan sólo una variable. La clase debe formar parte del paquete lógica, tener una constructora que recibirá como parámetro el nombre de la variable, e implementar el interfaz Fórmula. La valoración de la variable será la que le corresponda en el array de valores tipo ValorVar.
    Nota: Suponer que la variable aparece con seguridad en alguna posición del array, y sólo una vez.
  3. Escribir una clase Negación, que implementará el interfaz Fórmula. La clase tendrá una constructora que recibirá como parámetro el valor f de tipo Fórmula que se quiere negar. Dado un array t de valores de tipo ValorVar, la valoración de un objeto de esta clase será true si la valoración de la fórmula f en t es false, y true en caso contrario. La clase pertenecerá al paquete lógica.
  4. Escribir una clase And que implemente el interfaz Fórmula. La constructora de esta clase recibirá como parámetros dos valores f1 y f2 de tipo Fórmula. La valoración de esta fórmula para un cierto array t de valores de tipo ValorVar sera true si las valoraciones de f1 y f2 son ambas true, y false en otro caso. Otra forma de verlo: la valoración es el resultado de hacer la conjución en Java (&&) de las valoraciones en t de ambas fórmulas. La clase debe estar en el paquete lógica.
  5. Escribir una clase Or que implemente el interfaz Fórmula. La constructora de esta clase recibirá como parámetros dos valores f1 y f2 de tipo Fórmula. La valoración de esta fórmula para un cierto array t de valores de tipo ValorVar sera false si las valoraciones de f1 y f2 son ambas false, y true en otro caso. Otra forma de verlo: la valoración es el resultado de hacer la disyunción en Java (||) de las valoraciones en t de ambas fórmulas. La clase debe pertenecer al paquete lógica.

6 Escribir un programa de prueba para las clases del ejercicio anterior en el que:

  1. Se construya un objeto de nombre f representando la fórmula: (X And Z) Or (Neg(Y And Z)) (se pueden definir objetos auxiliares).
  2. Se muestre por pantalla el resultado de valorar f para la asignación de variables X/true, Y/true, Z/false.

7 Consideramos la siguiente clase, que permite calcular raíces de funciones usando el método de Newton:


// halla un raíz de f(x)==0
public abstract class Newton {

  // función de la que se quiere hallar la raíz
  // devuelve un valor 'y' tal que y=f(x)
  public abstract double f (double x);

  // derivada de f. devuelve un valor 'y' tal que y=df(x)
  public abstract double df (double x);
  
  // hay que pasarle el valor inicial desde el que buscará la raíz
  public double raíz (double xIni) {
                   
    final double error =  1e-5; // 
    final int imax = 100; // nº máximo de iteraciones
                      
    double x,aprox=xIni;
    double estimación = xIni; // estimación actual
    
    // en cada vuelta 'aprox' representa la última aproximación
    double iteración = 0;
     do {
        iteración++;
        x = aprox;
        aprox = x - f(x) / df(x); // nueva aproximación
      } while (Math.abs(aprox - x) > error && iteración < imax);
      
      
    return aprox;  
  }
}

Como se puede observar esta clase tiene 3 métodos:

Escribir una clase TercerGrado para representar polinomios de tercer grado. La clase incluirá los atributos que considere necesarios y al menos los siguientes métodos:

a) Una constructora que reciba como parámetros 4 números reales a,b,c,d representando el polinomio ax³ + bx² +cx +d.

b) Un método raíz sin parámetros que devuelva una raíz del polinomio obtenida al aplicar el método de Newton tomando como aproximación inicial el valor 0.0.

La clase puede incluir otros métodos que se consideren necesarios y debe aprovechar, usando los recursos de Java, la clase Newton, que no puede ser modificada.

8 Escribir un programa principal de prueba para la clase anterior en el que se represente el polinomio de tercer grado 4x³ -2x² +3x +1, y se muestre por pantalla la raíz que se obtiene al aplicar el método de Newton-Raphson, con aproximación inicial el valor 0.0. (el resultado debe ser -0.262978.....).

 

Página principal de la asignatura

2004-2006 Rafael Caballero