Mostrando entradas con la etiqueta Herencia. Mostrar todas las entradas
Mostrando entradas con la etiqueta Herencia. Mostrar todas las entradas

viernes, 9 de septiembre de 2011

Ejercicio "Figuras geométricas"

Este ejercicio lo realizamos a lo largo de varias semanas, añadiendo funciones, creando clases nuevas y realizando algunos ejercicios con las figuras que se añadirán en entradas posteriores.

Dada la clase abstracta* "Figura", añadirle varias funciones de desplazamiento, una función que permita consultar su posición y dos funciones que permitan modificar directamente las coordenadas.

public abstract class Figura implements Serializable {
    protected  Point posicion;
    public Figura(int a, int b) {
    posicion= new Point(a,b);}
    public abstract float area();
    public abstract float perimetro();
    public abstract int alto();
    public abstract int ancho();
    public abstract void dibujar(Graphics g);
    public abstract void guardar(OutputStream out) throws IOException;
    public abstract void cargar(InputStream in) throws IOException;
    public void arr(int incremento){
        this.posicion.y -= incremento;
    }
    public void abj(int incremento){
        this.posicion.y += incremento;
    }
    public void izq(int incremento){
        this.posicion.x -= incremento;
    }
    public void der(int incremento){
        this.posicion.x += incremento;
    }
    public Point posicion(){
        Point aux = new Point(posicion);
        return aux;
    }
    public void set_y(int pos_y){
        this.posicion.y = pos_y;
    }
    public void set_x(int pos_x){
        this.posicion.x = pos_x;
    }
}

Crear la clase (excepción) "FiguraFormatException", que hereda de "IllegalArgumentException" y se lanzará si en la función Cargar, se lee del flujo una figura que no es la indicada.

public class FiguraFormatException extends IllegalArgumentException{
    public FiguraFormatException() {
    }
    public FiguraFormatException(String string) {
        super(string);
    }
}

Dadas las clases "Triangulo", "Elipse", "Circulo", "Rectangulo" y "Cuadrado", que heredan de la clase abstracta "Figura", añadir un constructor que reciba un InputStream, que tendrá los datos adecuados para inicializar la figura. Además, se sobreescribirán las funciones abstractas de la clase "Figura".

CLASE Triangulo

public class Triangulo extends Figura {
    protected int lado1, lado2, lado3;
    private int lx, altura;
    public Triangulo(int a, int b, int c, int d, int e) {
        super(a, b);
        int elMayor = (c > d & c > e) ? c : ((d > e) ? d : e);
        if (elMayor >= (c + d + e - elMayor)) {
            throw new IllegalArgumentException("Los lados del triangulo son imposibles");
        }
        lado1 = c;
        lado2 = d;
        lado3 = e;
        lx = (lado2 * lado2 - lado3 * lado3 - lado1 * lado1) / (2 * lado1);
        altura = (int) Math.sqrt(lado3 * lado3 - lx * lx);
    }
    public Triangulo(InputStream in) throws IOException {
        super(0, 0);
        cargar(in);
    }
    public void guardar(OutputStream out) throws IOException {
        DataOutputStream escribir = new DataOutputStream(out);
        escribir.writeUTF("figuras.Triangulo");
        escribir.writeInt(posicion.x);
        escribir.writeInt(posicion.y);
        escribir.writeInt(lado1);
        escribir.writeInt(lado2);
        escribir.writeInt(lado3);
        escribir.flush();
    }
    public void cargar(InputStream in) throws IOException {
        DataInputStream leer = new DataInputStream(in);
        String figura;
        figura = leer.readUTF();
        if (!figura.equals("figuras.Triangulo")) {
            throw new FiguraFormatException();
        }
        posicion.x = leer.readInt();
        posicion.y = leer.readInt();
        lado1 = leer.readInt();
        lado2 = leer.readInt();
        lado3 = leer.readInt();
        lx = (lado2 * lado2 - lado3 * lado3 - lado1 * lado1) / (2 * lado1);
        altura = (int) Math.sqrt(lado3 * lado3 - lx * lx);
    }
    public float area() {
        return (lado1 * altura) / 2;
    }
    public float perimetro() {
        return lado1 + lado2 + lado3;
    }
    public int alto() {
        return altura;
    }
    public int ancho() {
        return lado1;
    }
    public void dibujar(Graphics g) {
        Color cActual = g.getColor();
        int[] xPuntos = {posicion.x,
            posicion.x + lado1,
            posicion.x + lado1 + lx};
        int[] yPuntos = {posicion.y,
            posicion.y,
            posicion.y + altura};
        g.fillPolygon(xPuntos, yPuntos, 3);
        g.setColor(Color.white);
        g.drawPolygon(xPuntos, yPuntos, 3);
        g.setColor(cActual);
    }
}

CLASE Elipse

public class Elipse extends Figura {
    public final static float PI = 3.1415F;
    protected int dMenor, dMayor;
    public Elipse(int a, int b, int c, int d) {
        super(a, b);
        dMenor = c;
        dMayor = d;
    }
    public Elipse(InputStream in) throws IOException {
        super(0, 0);
        this.cargar(in);
    }
    public void guardar(OutputStream out) throws IOException {
        DataOutputStream escribir = new DataOutputStream(out);
        escribir.writeUTF("figuras.Elipse");
        escribir.writeInt(posicion.x);
        escribir.writeInt(posicion.y);
        escribir.writeInt(dMenor);
        escribir.writeInt(dMayor);
        escribir.flush();
    }
    public void cargar(InputStream in) throws IOException {
        DataInputStream leer = new DataInputStream(in);
        if (!leer.readUTF().equals("figuras.Elipse")) {
            throw new FiguraFormatException();
        }
        posicion.x = leer.readInt();
        posicion.y = leer.readInt();
        dMenor = leer.readInt();
        dMayor = leer.readInt();
    }
    public float area() {
        return PI * dMenor * dMayor;
    }
    public float perimetro() {
        return PI * (dMenor + dMayor);
    }
    public int alto() {
        return dMayor;
    }
    public int ancho() {
        return dMenor;
    }
    public void dibujar(Graphics g) {
        Color cActual = g.getColor();
        g.fillOval(posicion.x, posicion.y, dMenor, dMayor);
        g.setColor(Color.white);
        g.drawOval(posicion.x, posicion.y, dMenor, dMayor);
        g.setColor(cActual);
    }
}

CLASE Circulo

public class Circulo extends Elipse {
    public Circulo(int a, int b, int d) {
        super(a, b, d, d);
    }
    public Circulo(InputStream is) throws IOException {
        super(0, 0, 0, 0);
        //Si se produce una IOException, se borrarán los datos del objeto Circulo
        cargar(is);
    }
    @Override
    public void guardar(OutputStream os) throws IOException {
        DataOutputStream dos = new DataOutputStream(os);
        dos.writeUTF("figuras.Circulo");
        dos.writeInt(posicion.x);
        dos.writeInt(posicion.y);
        dos.writeInt(dMayor);
        dos.flush();
    }
    @Override
    public void cargar(InputStream is) throws IOException {
        DataInputStream dis = new DataInputStream(is);

        if (!dis.readUTF().equals("figuras.Circulo")) {
            throw new FiguraFormatException();
        }
        posicion = new Point(dis.readInt(), dis.readInt());
        dMayor = dis.readInt();
        dMenor = dMayor;
    }
}

CLASE Rectangulo

public class Rectangulo extends Figura {
    protected int lado1, lado2;
    public Rectangulo(int a,int b,int c,int d) {
        super(a,b);
        lado1=c;
        lado2=d; }
    public Rectangulo(InputStream in) throws IOException {
        super(0,0);
        this.cargar(in);
    }
    public float area() {
        return lado1*lado2;
    }
    public float perimetro() {
        return lado1*2+lado2*2;
    }
    public int alto() {
        return lado2;
    }
    public int ancho() {
        return lado1;
    }
    public void dibujar(Graphics g) {
        Color cActual=g.getColor();
        g.fillRect(posicion.x,posicion.y,lado1,lado2);
        g.setColor(Color.white);
        g.drawRect(posicion.x,posicion.y,lado1,lado2);
        g.setColor(cActual);
    }
    public void guardar (OutputStream out) throws IOException{
        DataOutputStream dos = new DataOutputStream(out);
        dos.writeUTF("figuras.Rectangulo");
        dos.writeInt((int) super.posicion().getX());
        dos.writeInt((int) super.posicion().getY());
        dos.writeInt(lado1);
        dos.writeInt(lado2);
        dos.flush();
    }
    public void cargar (InputStream in) throws IOException{
        DataInputStream dis = new DataInputStream(in);
        if(!dis.readUTF().equals("figuras.Rectangulo")) {
            throw new FiguraFormatException("La figura no es un rectángulo.");
        }
        super.set_x(dis.readInt());
        super.set_y(dis.readInt());
        lado1=dis.readInt();
        lado2=dis.readInt();
    }
}

CLASE Cuadrado

public class Cuadrado extends Rectangulo {
    public Cuadrado(int a, int b, int c) {
        super(a, b, c, c);
    }
    public Cuadrado(InputStream in) throws IOException {
        super(0, 0, 0, 0);
        cargar(in);
    }
    @Override
    public void guardar(OutputStream out) throws IOException {
        DataOutputStream escribe = new DataOutputStream(out);
        escribe.writeUTF("figuras.Cuadrado");
        escribe.writeInt(posicion.x);
        escribe.writeInt(posicion.y);
        escribe.writeInt(this.alto());
        escribe.flush();
    }
    @Override
    public void cargar(InputStream in) throws IOException {
        DataInputStream lee = new DataInputStream(in);
        if (!lee.readUTF().equals("figuras.Cuadrado")) {
            throw new FiguraFormatException();
        }
        posicion.x = lee.readInt();
        posicion.y = lee.readInt();
        lado1 = lee.readInt();
        lado2 = lado1;
    }
}

Crear las clases "TEquilatero" que hereda de "Triangulo" y "Coche" que hereda de "Figura".

La clase "TEquilatero":
  • Es un triángulo con los tres lados iguales.

La clase "Coche":

  • Estará formada por dos círculos (ruedas) y un rectángulo.
  • Su posición la indicará la esquina superior izquierda.
  • Los círculos tendrán el mismo tamaño que la altura del rectángulo.
    • Si la suma de los dos diámetros es mayor a la longitud del rectángulo, entonces el diámetro será la mitad de la longitud.
CLASE TEquilatero

public class TEquilatero extends Triangulo {
    public TEquilatero(int a, int b, int c) {
        super(a, b, c, c, c);
    }
    public TEquilatero(InputStream in) throws IOException {
        super(0, 0, 0, 0, 0);
        cargar(in);
    }
    @Override
    public void cargar(InputStream into) throws IOException {
        DataInputStream di = new DataInputStream(into);
        if (!di.readUTF().equals("figuras.TEquilatero")) {
            throw new FiguraFormatException();
        }
        posicion.x = di.readInt();
        posicion.y = di.readInt();
        lado1 = di.readInt();
    }
    @Override
    public void guardar(OutputStream o) throws IOException {
        DataOutputStream out = new DataOutputStream(o);
        out.writeUTF("figuras.TEquilatero");
        out.writeInt(posicion.x);
        out.writeInt(posicion.y);
        out.writeInt(lado1);
        out.flush();
    }
}

CLASE Coche

public class Coche extends Figura {
    private Rectangulo chasis;
    private Circulo rueda1, rueda2;
    public Coche(int a, int b, int alto, int ancho) {
        super(a, b);
        if (alto <= ancho) {
            chasis = new Rectangulo(a, b, ancho, alto / 2);
            rueda1 = new Circulo(a, b + chasis.alto(), alto / 2);
            rueda2 = new Circulo(a + ancho - alto / 2, b + chasis.alto(), alto / 2);
        } else {
            chasis = new Rectangulo(a, b, ancho, alto - (ancho / 2));
            rueda1 = new Circulo(a, b + chasis.alto(), ancho / 2);
            rueda2 = new Circulo(a + ancho / 2, b + chasis.alto(), ancho / 2);
        }
    }
    public Coche(InputStream in)throws IOException{
        super(0,0);
        this.cargar(in);
    }
    @Override
    public float area() {
        return chasis.area() + rueda1.area() + rueda2.area();
    }
    @Override
    public float perimetro() {
        return chasis.perimetro() + rueda1.perimetro() + rueda2.perimetro();
    }
    @Override
    public int alto() {
        return chasis.alto() + rueda1.alto();
    }
    @Override
    public int ancho() {
        return chasis.ancho();
    }
    @Override
    public void dibujar(Graphics g) {
        chasis.dibujar(g);
        rueda1.dibujar(g);
        rueda2.dibujar(g);
    }
    @Override
    public void arr(int incremento) {
        super.arr(incremento);
        chasis.arr(incremento);
        rueda1.arr(incremento);
        rueda2.arr(incremento);
    }
    @Override
    public void abj(int incremento) {
        super.abj(incremento);
        chasis.abj(incremento);
        rueda1.abj(incremento);
        rueda2.abj(incremento);
    }
    @Override
    public void izq(int incremento) {
        super.izq(incremento);
        chasis.izq(incremento);
        rueda1.izq(incremento);
        rueda2.izq(incremento);
    }
    @Override
    public void der(int incremento) {
        super.der(incremento);
        chasis.der(incremento);
        rueda1.der(incremento);
        rueda2.der(incremento);
    }
    @Override
    public void set_y(int pos_y) {
        super.set_y(pos_y);
        chasis.set_y(pos_y);
        rueda1.set_y(pos_y + chasis.alto());
        rueda2.set_y(pos_y + chasis.alto());
    }
    @Override
    public void set_x(int pos_x) {
        super.set_x(pos_x);
        chasis.set_x(pos_x);
        rueda1.set_x(pos_x);
        rueda2.set_x(pos_x + chasis.ancho() - rueda2.ancho());
    }
    public void guardar(OutputStream out) throws IOException {
        DataOutputStream escribe = new DataOutputStream(out);
        escribe.writeUTF("figuras.Coche");
        escribe.writeInt(posicion.x);
        escribe.writeInt(posicion.y);
        escribe.flush();
        rueda1.guardar(out);
        rueda2.guardar(out);
        chasis.guardar(out);

    }
    public void cargar(InputStream in) throws IOException {
        DataInputStream leer = new DataInputStream(in);
        String clase;
        if (!(clase=leer.readUTF()).equals("figuras.Coche")) {
            throw new FiguraFormatException("La figura no es un coche. Se ha leído: "+clase);
        }
        posicion.x = (leer.readInt());
        posicion.y = (leer.readInt());
        rueda1 = new Circulo(in);
        rueda2 = new Circulo(in);
        chasis = new Rectangulo(in);
    }
}

* Una clase será abstracta cuando no queremos que se puedan crear objetos de esa clase. Sus funciones pueden ser abstractas, en este caso, las clases que hereden de una abstracta pueden sobreescribir esas funciones o dejarla abstracta (la clase hija será también abstracta). Una clase abstracta también puede tener funciones no abstractas, es decir, que tengan código.

lunes, 29 de agosto de 2011

Ejercicio "Conjunto"

Crear la clase Conjunto<T>, que implementará la interfaz Set<T>. No se pondrá código a todas las funciones de Set<T>, tan sólo aquellas que nos interesan de momento.
Para almacenar todos los objetos que forman parte del conjunto, se empleará un ArrayList. Además, se creará la clase privada ParaRecorrerMiConjunto, alojada dentro de la clase Conjunto<T>, que implementa Iterator<T> y nos permite recorrer todos los elementos que forman parte del conjunto.

public class Conjunto<T> implements Set<T> {
    private ArrayList<T> datos;
    private class ParaRecorrerMiConjunto implements Iterator<T> {
        private int actual = -1;
        public boolean hasNext() {
            return actual < datos.size() - 1;
        }
        public T next() {
            if (!hasNext()) {
                throw new java.util.NoSuchElementException();
            }
            actual++;
            return datos.get(actual);
        }
        public void remove() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    public Conjunto() {
        datos = new ArrayList<T>();
    }
    public void clear() {
        datos.clear();
    }
    @SuppressWarnings("element-type-mismatch")
    public boolean contains(Object o) {
        return datos.contains(o);
    }
    public int size() {
        return datos.size();
    }
    public boolean isEmpty() {
        return datos.isEmpty();
    }
    public boolean add(T e) {
        if (!datos.contains(e)) {
            return datos.add(e);
        }
        return false;
    }
    @SuppressWarnings("element-type-mismatch")
    public boolean remove(Object o) {
        return datos.remove(o);
    }
    @Override
    public String toString() {
        return datos.toString();
    }
    @Override
    public boolean equals(Object o) throws ClassCastException {
        Conjunto<T> aux = (Conjunto<T>) o;
        return this.datos.containsAll(aux.datos) & aux.datos.containsAll(this.datos);
    }
    public Iterator<T> iterator() {
        return new ParaRecorrerMiConjunto();
    }
    public Object[] toArray() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public Object[] toArray(Object[] a) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public boolean containsAll(Collection c) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public boolean addAll(Collection c) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public boolean retainAll(Collection c) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public boolean removeAll(Collection c) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

MODIFICACIÓN
Para que funcione realmente como un conjunto de cosas, modificaremos la clase ParaRecorrerMiConjunto, de manera que cada vez que se instancie un iterador para recorrer los elementos del conjunto, lo haga en orden aleatorio.

public class Conjunto3<T> implements Set<T> {
    private ArrayList<T> datos;
    private class ParaRecorrerMiConjunto implements Iterator<T>{
        private int actual=-1;
        private ArrayList<T> aux;
        ParaRecorrerMiConjunto(){
            aux = new ArrayList<T>(datos);
            Collections.shuffle(aux);
        }
        public boolean hasNext() {
            return !aux.isEmpty();
        }
        public T next() {
            if(!hasNext())
                throw new java.util.NoSuchElementException();
            actual++;
            return aux.get(actual);
        }
        public void remove() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
    public Conjunto3() {
        datos = new ArrayList<T>();
    }
    public void clear() {
        datos.clear();
    }
    @SuppressWarnings("element-type-mismatch")
    public boolean contains(Object o) {
        return datos.contains(o);
    }
    public int size() {
        return datos.size();
    }
    public boolean isEmpty() {
        return datos.isEmpty();
    }
    public boolean add(T e) {
        if (!datos.contains(e)) {
            return datos.add(e);
        }
        return false;
    }
    @SuppressWarnings("element-type-mismatch")
    public boolean remove(Object o) {
        return datos.remove(o);
    }
    @Override
    public String toString() {
        return datos.toString();
    }
    @Override
    public boolean equals(Object o) throws ClassCastException {
        Conjunto3<T> aux = (Conjunto3<T>) o;
        return this.datos.containsAll(aux.datos) & aux.datos.containsAll(this.datos);
    }
    public Iterator<T> iterator() {
        return new ParaRecorrerMiConjunto();
    }
    public Object[] toArray() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public Object[] toArray(Object[] a) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public boolean containsAll(Collection c) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public boolean addAll(Collection c) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public boolean retainAll(Collection c) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    public boolean removeAll(Collection c) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

sábado, 27 de agosto de 2011

Ejercicio "Fracción" (modificación)

Modificar la clase Fraccion, de manera que implemente las interfaces Comparable y Reseteable, es decir, debe poner código a las funciones de esas interfaces. Como las interfaces se encuentran en otro paquete distinto a la clase Fraccion, se deben importar.
Además, se creará la excepción FraccionException, que se lanzará en el constructor de la clase Fraccion cuando el denominador sea 0.

EXCEPCIÓN: FraccionException

public class FraccionException extends ArithmeticException {
    public FraccionException(){
    }
    public FraccionException(String mensaje){
        super(mensaje);
    }
}

Las excepciones se programan normalmente con dos constructores:
  • Uno por defecto, que no recibe nada.
  • Otro que recibe un String, con el texto que queremos que se muestre si se lanza esa excepción.
Las excepciones pueden heredar de las existentes en Java, siempre que tenga sentido que así sea. Si queremos que la excepción no sea marcada, heredará de RuntimeException o de alguna de las que están dentro de ese conjunto.

CLASE: Fraccion

import interfaces.Comparable;
import interfaces.Reseteable;

public class Fraccion implements Comparable, Reseteable {
    private int numerador;
    private int denominador;
    public Fraccion(int num){
        this(num, 1);
    }
    public Fraccion(int num, int den){
        if (den == 0)
            throw new FraccionException();
        numerador = num;
        denominador = den;
    }
    public Fraccion inversa() {
        Fraccion aux;
        aux = new Fraccion(denominador, numerador);
        return aux;
    }
    public Fraccion producto(Fraccion f) {
        Fraccion resultado;
        int numRes, denRes;
        numRes = f.numerador * numerador;
        denRes = f.denominador * denominador;
        resultado = new Fraccion(numRes, denRes);
        return resultado;
    }
    @Override
    public String toString() {
        return numerador+"/"+denominador;
    }
    public Fraccion opuesta() {
        Fraccion aux;
        aux = new Fraccion(-numerador, denominador);

        return aux;
    }
    public static int mcd(int num1, int num2) {
        int aux;
        //Algoritmo de Euclides
        while (num2 != 0){
            aux = num1;
            num1 = num2;
            num2 = aux % num2;
        }
        return num1;
    }
    public static int mcm(int num1, int num2) {
        int mcm;
        int a=num1, b=num2;

        while (num1 != num2){
            if (num1>num2)
                num1 = num1-num2;
            else
                num2 = num2-num1;
        }
        mcm = a*b/num2;
        return mcm;
    }
    public Fraccion suma(Fraccion f2) {
        Fraccion resultado;
        int minimo, num;
        minimo = mcm(denominador, f2.denominador);
        num = (minimo/denominador)*numerador + (minimo/f2.denominador)*f2.numerador;
        resultado = new Fraccion(num, minimo);
        return resultado;
    }
    public boolean equals(Fraccion f2) {
        return numerador==f2.numerador & denominador==f2.denominador;
    }
    public Fraccion simplificar() {
        int divisor;
        divisor = mcd(numerador, denominador);
        numerador = numerador/divisor;
        denominador = denominador/divisor;
        return this;
    }
    public int comparadoCon(Object obj) throws ClassCastException {
        Fraccion f2 = (Fraccion) obj;
        double prim, segun;
        int res;
        prim = numerador/(double)denominador;
        segun = f2.numerador/(double)f2.denominador;
        if (prim < segun)
            res = -1;
        else if (prim > segun)
            res = 1;
        else
            res = 0;
        return res;
    }
    public void reset() {
        numerador = 0;
        denominador = 1;
    }
}

Interfaces

Una interfaz (Java) es una colección de métodos, que no tendrán código, y de atributos, que serán públicos, estáticos y constantes. De esta manera, las clases que hereden de estás interfaces, se verán obligadas a ponerle código a las funciones, a no ser que se trate de clases abstractas.

Es en la documentación de la interfaz donde se especificará de forma concreta qué deben hacer los distintos métodos que la componen. Por ejemplo, la interfaz Comparable, de Java, contiene el método compareTo, que se define detalladamente aquí. Por lo tanto, si alguna clase implementa la interfaz Comparable, debe tener en cuenta la definición de su método para desarrollarlo de acuerdo con su fin.

Las interfaces pueden heredar de otras, en este caso se emplea "extends":

public class NombreInterface1 extends NombreInterface2 {
    //Aquí van los métodos y atributos de NombreInterface1
}

A continuación se muestran dos ejemplos de interfaces, que se utilizarán en algunos ejercicios realizados posteriormente:

public interface Comparable {
    int comparadoCon(Object obj) throws ClassCastException;
}

public interface Reseteable {
    void reset();
}

Cuando una clase hereda de una interfaz, es decir, cuando la implementa, se utiliza la palabra reservada "implements":

public class NombreClase implements NombreInterface {
    //Aquí va el código de NombreClase
}

Una clase puede implementar varias interfaces:

public class NombreClase implements NombreInterface1, NombreInterface2 {
    //Aquí va el código de NombreClase
}

REFERENCIAS:

Ejercicio "Dado" (modificación)

Modificar la clase Dado, añadiéndole varias funciones estáticas que se definen a continuación:
  • String lanzamientos (Dado d, int v). Lanza el dado "d" tantas veces como se le indique y retorna un String con los resultados de las tiradas.
  • int lanzamientos (Dado d1, Dado d2). Lanza los dos dados y devuelve la suma de las tiradas.
  • Dado[] factoria (int d, int c). Construye tantos dados como se le indique en "d" y con las caras indicadas en "c". Devuelve una tabla con los dados creados.
  • String[] lanzamientos (Dado[] t). Lanza cada uno de los dados de la tabla y los guarda en una tabla de String.
  • String[] lanzamientos (Dado[], int v). Lanza cada dado de la tabla el número de veces que se indica y se guardan las tiradas de cada dado en la misma casilla de la tabla de String.
public class Dado {
    protected int caras;
    public Dado(int lados) {
        caras = lados;
    }
    public int tirarDado() {
        int aux;
        aux = (int) (Math.random()*caras+1);
        return aux;
    }
    public static String lanzamientos(Dado d, int veces){
        StringBuffer aux = new StringBuffer("");
        int i;
        for(i=0; i<veces; i++)
            aux.append(d.tirarDado());
        return aux.toString();
    }
    public static int lanzamientos(Dado d1, Dado d2){
        return d1.tirarDado()+d2.tirarDado();
    }
    public static Dado[] factoria(int cuantos, int caras){
        Dado[] caja= new Dado[cuantos];
        int i;
        for (i=0; i<caras; i++)
            caja[i]=new Dado(caras);
        return caja;
    }
    public static String[] lanzamientos(Dado[] caja){
        int i;
        String[] res= new String[caja.length];
        for (i=0; i<caja.length; i++)
            res[i]=Integer.toString(caja[i].tirarDado());
        return res;
    }
    public static String[] lanzamientos(Dado[] caja, int veces){
        int i, j;
        String[] res= new String[caja.length];
        for (i=0; i<caja.length; i++){
            res[i]=Dado.lanzamientos(caja[i], veces);
        }
        return res;
    }
}

Crear ahora la clase DadoConMemoria, que herede de la anterior.

La clase DadoConMemoria funcionará de manera similar a la clase Dado, pero tendrá un historial en el que irá almacenando todas las tiradas realizadas.
Además, esta clase tendrá dos constructores:
  1. Un constructor por defecto, que construirá un dado con 6 caras.
  2. Un constructor que recibe el número de lados que tendrá el dado.
Se añadirán un atributo para guardar el historial de tiradas y las siguientes funciones:
  • void reset(). Borra la memoria.
  • Integer[] historico(). Retorna un listado de todos los valores obtenidos, desde la última tirada a la primera.
  • Integer[] historico(int n). Retorna un listado de los últimos "n" valores obtenidos.
Además, se modificarán las funciones heredadas si se cree necesario, para que funcione como debe, es decir, para almacenar el historial.

public class DadoConMemoria extends Dado {
    private ArrayList<Integer> historico=new ArrayList<Integer>();
    public DadoConMemoria() {
        this(6);
    }
    public DadoConMemoria(int lados) {
        super(lados);
    }
    @Override
    public int tirarDado() {
        int aux;
        aux = (int) (Math.random()*caras+1);
        historico.add(0, aux);
        return aux;
    }
    public void reset() {
        historico = null;
    }
    public Integer[] historico() {
        Integer[] aux = new Integer[0];
        aux=historico.toArray(aux);
        return aux;
    }
    public Integer[] historico(int ult) {
        Integer[] aux = new Integer[0];
        aux=historico.subList(0, ult).toArray(aux);
        return aux;
    }
}

Ejercicio clase "PuntoGordo"

Dada la clase PuntoPoli:

public class PuntoPoli {
    private int x, y;
    public PuntoPoli() {
        y = x = 30;
    }
    public PuntoPoli(int px, int py) {
        x = px;
        y = py;
    }
    public float distancia() {
        System.out.println("EJECUTANDO LA FUNCION DISTANCIA DE PuntoPoli");
        return (float) Math.sqrt(x * x + y * y);
    }
    public void izq(){
        x=x-1;
    }
    public void der(){
        x=x+1;
    }
    public void arr(){
        y=y-1;
    }
    public void aba(){
        y=y+1;
    }
}

Crear la clase PuntoGordo, que heredará de la anterior. Además de las coordenadas, se debe almacenar su diámetro y se modificarán las funciones de movimiento del punto, para que en el caso del PuntoGordo, en vez de moverse de uno en uno, se muevan el tamaño del diámetro.

public class PuntoGordo extends PuntoPoli{
    private int diametro;
    public PuntoGordo(int a, int b, int c) {
        super(a, b);
        diametro = c;
    }
    @Override
    public float distancia() {
        System.out.println("EJECUTANDO LA FUNCION DISTANCIA DE PuntoGordo");
        return super.distancia() - diametro / 2.0f;
    }
    @Override
    public void izq(){
        int i;
        for (i=0; i<diametro; i++)
            super.izq();
    }
    @Override
    public void der(){
        int i;
        for (i=0; i<diametro; i++)
            super.der();
    }
    @Override
    public void arr(){
        int i;
        for (i=0; i<diametro; i++)
            super.arr();
    }
    @Override
    public void aba(){
        int i;
        for (i=0; i<diametro; i++)
            super.aba();
    }
}