Autor Tema: CU00687B Ejercicio resuelto ejemplo de herencia simple, extends y super en Java.  (Leído 3887 veces)

Lorenzo31

  • Avanzado
  • ****
  • APR2.COM
  • Mensajes: 381
    • Ver Perfil
Buenas tardes,

Dejo mi solución para el ejercicio, puesto que era una adaptación del anterior y lo importante era tratar la Herencia, he adaptado el del 86, donde ya usaba Calendar.

Comentar que me preparo para los comentarios pues he hecho supuestos que no han aumentado las clases sino disminuido, pero me he ceñido al enunciado del ejercicio.

Primero, debido a que Producto Fresco viene a ser un Producto y no tenia ninguna característica propia (todas comunes) lo eliminé como clase. (Soy consciente que solo que cambiara un nuevo atributo o dos en Producto Fresco ya cambiaria).

Segundo, Congelado por Aire, Agua y Hidrogeno, tenian como propio simplemente una descripción propia del producto que a nivel de programación he simplificado (demasiado pero es una práctica) en un String ya que no daba mas detalles el ejercicio.
Así puse la descripcion en común en la clase PCAireAguaHidrogeno y simplemente unos ENUM con las tres opciones AIRE, AGUA, HIDROGENO.
Les di una clase para los tres. Diferente a congelado aunque podria haber ido dentro porque las descripciones eran distintas en función del enum.

No lo hice por ahorrar tiempo, pues crear una clase son diez minutos, sino porque la información que iba a guardar me parecia... no necesitaba una clase nueva. (en este ejercicio claro)

Sin más, una vez planteadas mis premisas... dejo mi código. Esperando críticas que siempre leo como constructivas y tomo muy en cuenta.

Clase Producto

Código: [Seleccionar]
import java.util.Calendar;
import java.text.SimpleDateFormat;

/**
 * Clase Producto - Consta de los atributos comunes de todo producto y los getters y setters
 * necesarios para establecer las variables de instancia.
 * @author Lorenzo31
 * @version 10.04.2015
 */

public class Producto {

    private Calendar fechaCaducidad;
    private int numeroLote;
    private Calendar fechaEnvasado;
    private String origen;
    private boolean frescoOno;

    //Calendar empieza en Enero = 0 por eso le resto un 1 al mes introducido por el usuario.
 
    public Producto(int yearEnvasado, int monthEnvasado,int dayEnvasado, String origen, int yearCad, int monthCad, int dayCad, int numeroLote, boolean frescoOno){
        fechaCaducidad = Calendar.getInstance();
        fechaCaducidad.set(yearCad, monthCad - 1, dayCad);
        fechaEnvasado = Calendar.getInstance();
        fechaEnvasado.set(yearEnvasado, monthEnvasado - 1,dayEnvasado);
        this.origen = origen;
        this.numeroLote = numeroLote;
        this.frescoOno = frescoOno;
    }

    //Getters
    public String getFechaCaducidad() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
        return dateFormat.format(fechaCaducidad.getTime()); }

    public int getNumeroLote(){ return numeroLote; }
    public boolean getFrescoOno(){return frescoOno; }
    public String getOrigen(){ return origen; }
 
    public String getFechaEnvasado() {
        SimpleDateFormat formato = new SimpleDateFormat("dd-MM-yyyy");
        return formato.format(fechaEnvasado.getTime()); }

    //Setters
    public void setFechaCaducidad(int year, int month, int day) { fechaCaducidad.set(year, month - 1, day); }
    public void setFechaEnvasado(int year, int month, int day) { fechaEnvasado.set(year, month -1, day); }
    public void setOrigen(String origen){ this.origen = origen; }
    public void setNumeroLote(int numeroLote) { this.numeroLote = numeroLote; }

    //Método mostrar atributos

    public void mostrarDatos(){
       
              System.out.println("\n El número de lote es: "+ numeroLote + " su fecha de envasado es: "+ getFechaEnvasado() +
              "\n su fecha de caducidad es: " + getFechaCaducidad() + " su origen es: " + origen);
    }
} //cierre clase


Clase PRefrigerado

Código: [Seleccionar]

/**
 * Clase Productos Refrigerados hereda de Producto
 *
 * @author Lorenzo31
 * @version 10.4.2015
 */

public class PRefrigerado extends Producto{
   
    private String codigoSupervisor;
    private int temperaturaRecomendada;
   
    public PRefrigerado(int yearCad, int monthCad, int dayCad, String codigoSupervisor, int numeroLote, int yearEnvase, int monthEnvase, int dayEnvase, String origen, int temperaturaRecomendada, boolean frescoOno){
        super(yearEnvase,monthEnvase,dayEnvase, origen,yearCad, monthCad, dayCad, numeroLote, frescoOno);
        this.codigoSupervisor = codigoSupervisor;
        this.temperaturaRecomendada = temperaturaRecomendada;
    }
   
    //Getters
    public String getCodigoSupervisor() { return codigoSupervisor; }
    public int getTemperaturaRecomendada(){ return temperaturaRecomendada; }
   
    //Setters
    public void setCodigoSupervisor(String codigoSupervisor){ this.codigoSupervisor = codigoSupervisor; }
    public void setTemperaturaRecomendada() { this.temperaturaRecomendada = temperaturaRecomendada; }
   
    //Metodo mostrarDatos
   
    public void mostrarDatos() {
        super.mostrarDatos();
        System.out.println(" su codigo de supervisor es: " + codigoSupervisor + "su temperatura recomendada es: " + temperaturaRecomendada + "\n");
    }

}


Clase PCongelado

Código: [Seleccionar]

/**
 * Clase Producto Congelado hereda de Producto
 *
 * @author (your name)
 * @version (a version number or a date)
*/

public class PCongelado extends Producto {
   
    private int temperaturaRecomendada;
   
    public PCongelado(int yearEnvase, int monthEnvase, int dayEnvase, String origen, int yearCad, int monthCad, int dayCad, int temperaturaRecomendada, int numeroLote, boolean frescoOno){
        super(yearEnvase, monthEnvase, dayEnvase, origen, yearCad, monthCad, dayCad, numeroLote, frescoOno);
        this.temperaturaRecomendada = temperaturaRecomendada;
    }
   
    public int getTemperatura() { return temperaturaRecomendada; }
   
    public void setTemperatura( int temperaturaRecomendada ){ this.temperaturaRecomendada = temperaturaRecomendada; }

    //Método para Mostrar temperaturaRecomendada
   
    public void mostrarDatos(){
        super.mostrarDatos();
        System.out.println(" su temperatura recomendada es: " + temperaturaRecomendada); }
}


Clase PCAireAguaHidro

Código: [Seleccionar]


/**
 * Clase PCAireAguaHidro describe el tipo de producto congelado extiende de PCongelado
 *
 * @author Lorenzo31
 * @version 13.4.2015
 */
enum TipoCongelado { AIRE, AGUA, HIDROGENO };

public class PCAireAguaHidro extends PCongelado{

   private String informacionAdicional;
   private TipoCongelado tipo;
   
   public PCAireAguaHidro(int yearEnvase, int monthEnvase, int dayEnvase, String origen, int yearCad, int monthCad, int dayCad, int temperaturaRecomendada,
   int numeroLote, boolean frescoOno, String informacionAdicional, TipoCongelado tipo){
       super(yearEnvase, monthEnvase, dayEnvase, origen, yearCad, monthCad, dayCad, temperaturaRecomendada, numeroLote, frescoOno);
       this.informacionAdicional = informacionAdicional;
       this.tipo = tipo;
    }
   
   //Getters
   public String getInformacionAdicional(){ return informacionAdicional; }
   public TipoCongelado getTipoCongelado(){ return tipo; }
   
   //Setters
   public void setInformacionAdicional(String informacionAdicional){ this.informacionAdicional = informacionAdicional; }
   public void setTipoCongelado(TipoCongelado tipo){ this.tipo = tipo; }
   
   //Método para mostrar información
   
   public void mostrarDatos(){
       super.mostrarDatos();
        if (tipo.toString().equals("AIRE") ){System.out.println("Congelado por " + tipo.toString() + " su composición es: \n" + informacionAdicional);
        }else if(tipo.toString().equals("AGUA") ){ System.out.println("Congelado por " + tipo.toString() + " Información sobre su salinidad en agua: \n" + informacionAdicional);
        }else if (tipo.toString().equals("HIDROGENO")) { System.out.println("Congelado por " + tipo.toString() + " Información de su metodo de congelación: \n" + informacionAdicional); }
    }
   
}


Clase EntradaDatos

Código: [Seleccionar]
import java.util.Scanner;
import java.util.InputMismatchException;

public class EntradaDatos{

    public static int recogerEntero(){
        int numero = 1000;
        do{
            try{
                Scanner escaner = new Scanner(System.in);
                numero = escaner.nextInt();
                escaner.close();
            }catch (InputMismatchException e){ System.out.println("Introduce un valor numérico \n"); }
        }while (numero == 1000);
        return numero;
    }

    public static String recogerCadena(){
        String cadena = "";
        do{
            Scanner escaner = new Scanner(System.in);
            cadena = escaner.nextLine();
            escaner.close();
        }while(cadena == "");

        return cadena;   
    }
}


Clase Recoger

Código: [Seleccionar]

/**
 * Clase que agrupa todas las funciones de control de recogida de datos
 * para la introducción por el usuarios.
 *
 * @author Lorenzo31
 * @version 14.04.2015
 */
public class Recoger {

 
public static int menu(){ //método que controla la seleccion del menú
        int numero = 0;   
        do{
            System.out.println(" Elige una opción entre 1 y 5 \n ");
            numero = EntradaDatos.recogerEntero();   
        } while (numero < 1 || numero > 5);
        return numero;
    }

    public static int subMenu(){ //método que controla la seleccion del menú
        int numero = 0;   
        do{
            System.out.println(" Elige una opción entre 1 y 4 \n ");
            numero = EntradaDatos.recogerEntero();   
        } while (numero < 1 || numero > 4);
        return numero;
    }
   
    public static int año(boolean envaseOCaducidad){
        int numero = 0;   

        do{

            if (envaseOCaducidad){ System.out.println(" Introduce el año de envase ");
            }else { System.out.println(" Introduce el año de caducidad:"); }

            numero = EntradaDatos.recogerEntero();   
        } while (numero < 2015 || numero > 2100);
        return numero;
    }

    public static int mes(boolean envaseOCaducidad){
        int numero = 0;   

        do{
            if (envaseOCaducidad){ System.out.println(" Introduce el mes de envase ");
            }else { System.out.println(" Introduce el mes de caducidad:"); }

            numero = EntradaDatos.recogerEntero();   
        } while (numero < 1 || numero > 12);
        return numero;
    }

    public static int dia(boolean envaseOCaducidad){
        int numero = 0;   

        do{
            if (envaseOCaducidad){ System.out.println(" Introduce el dia de envase ");
            }else { System.out.println(" Introduce el dia de caducidad:"); }

            numero = EntradaDatos.recogerEntero();   
        } while (numero < 1 || numero > 31);
        return numero;
    }

    public static int numeroLote(){ System.out.println(" Introduce el número de Lote "); return EntradaDatos.recogerEntero(); }

    public static int temperatura() {
        int numero = 80;
        System.out.println("Introduce la temperatura");
        do{
            numero = EntradaDatos.recogerEntero();
        } while ( numero < -40 || numero > 50 );
        return numero;
    }
    public static String origen(){ System.out.println("Introduce el país de origen del producto "); return EntradaDatos.recogerCadena(); }
   
    public static String informacionAdicional(){ System.out.println("Introduce la composición del producto "); return EntradaDatos.recogerCadena(); }
   
    public static String codigoSupervisor(){ System.out.println("Introduce el código de supervisor del producto "); return EntradaDatos.recogerCadena();}

}

Clase TestHerencia2

Código: [Seleccionar]
import java.util.ArrayList;
/**
 * Main alternativo de productos. Agrega tantos productos como quieras, aunque lo limité a 10 aquí. Y los muestra.
 * @author Lorenzo31
 * @version 12.04.2015
 */
import java.util.Iterator;

public class TestHerencia2{

    public static void main(String[] args){

        int numeroMenu; int numeroSubMenu;
        boolean productoFresco = false;

        ArrayList<Producto> listaProductos = new ArrayList<Producto>();

        do{
            System.out.println(" 1.- Introducir nuevo producto FRESCO \n 2.- Introducir nuevo producto CONGELADO \n 3.- Introducir nuevo producto REFRIGERADO \n 4.- Mostrar productos \n 5.- Salir ");
            numeroMenu = Recoger.menu();

            switch(numeroMenu){
                case 1:
                productoFresco = true;
                System.out.println("Creando nuevo producto fresco... \n ");  //los true, false de los métodos es un boolean para distinguir si es fecha caducidad o fecha envase
                listaProductos.add( new Producto(Recoger.año(true),Recoger.mes(true),Recoger.dia(true),Recoger.origen(),Recoger.año(false),Recoger.mes(false),Recoger.dia(false), Recoger.numeroLote(), productoFresco));
                break;

                case 2:
                productoFresco = false;
                System.out.println("Creando nuevo producto congelado... \n "); 

               
                do{
                    System.out.println(" 1.- Introducir nuevo producto CONGELADO por AIRE \n 2.- Introducir nuevo producto CONGELADO por AGUA \n 3.- Introducir nuevo producto CONGELADO por HIDROGENO \n 4.- Salir de Menu CONGELADO");
                      numeroSubMenu = Recoger.subMenu();
                   
                    switch(numeroSubMenu){
                        case 1:  listaProductos.add( new PCAireAguaHidro(Recoger.año(true),Recoger.mes(true),Recoger.dia(true),Recoger.origen(),Recoger.año(false),Recoger.mes(false),Recoger.dia(false), Recoger.temperatura(), Recoger.numeroLote(), productoFresco, Recoger.informacionAdicional(), TipoCongelado.AIRE ) );
                        break;
                        case 2:  listaProductos.add( new PCAireAguaHidro(Recoger.año(true),Recoger.mes(true),Recoger.dia(true),Recoger.origen(),Recoger.año(false),Recoger.mes(false),Recoger.dia(false), Recoger.temperatura(), Recoger.numeroLote(), productoFresco, Recoger.informacionAdicional(), TipoCongelado.AGUA ) );
                        break;         
                        case 3: listaProductos.add( new PCAireAguaHidro(Recoger.año(true),Recoger.mes(true),Recoger.dia(true),Recoger.origen(),Recoger.año(false),Recoger.mes(false),Recoger.dia(false), Recoger.temperatura(), Recoger.numeroLote(), productoFresco, Recoger.informacionAdicional(), TipoCongelado.HIDROGENO ) );
                        break;
                    }
                }while(numeroSubMenu !=4);
                break;
               
                case 3:
                productoFresco = false;
                System.out.println("Creando nuevo producto refrigerado... \n ");
                listaProductos  .add( new PRefrigerado(Recoger.año(true),Recoger.mes(true),Recoger.dia(true),Recoger.codigoSupervisor(),Recoger.numeroLote(),Recoger.año(false),Recoger.mes(false),Recoger.dia(false),Recoger.origen(), Recoger.temperatura(), productoFresco ));
                break;
               

                case 4: System.out.println("La lista es \n");
                for(int x = 0; x < listaProductos.size(); x++){
                   
                    if (listaProductos.get(x).getFrescoOno() == true) { System.out.println("PRODUCTO FRESCO \n"); Producto temp = listaProductos.get(x); temp.mostrarDatos();
                    }else if (listaProductos.get(x) instanceof PRefrigerado){System.out.println("PRODUCTO REFRIGERADO \n"); PRefrigerado temp = (PRefrigerado)listaProductos.get(x); temp.mostrarDatos();
                    } else if(listaProductos.get(x) instanceof PCAireAguaHidro) {
                                   System.out.println("PRODUCTO CONGELADO");
                                   PCAireAguaHidro temp = (PCAireAguaHidro)listaProductos.get(x);
                                                   if (temp.getTipoCongelado().toString().equals("AIRE")) { temp.mostrarDatos();
                                                    }else if(temp.getTipoCongelado().toString().equals("AGUA")) {  temp.mostrarDatos();
                                                    }else if (temp.getTipoCongelado().toString().equals("HIDROGENO")) { temp.mostrarDatos(); }
                                                }
                                            } //cierre bucle for listado
                 break;   

               
                                               

            }
        }while(numeroMenu != 5);
    }

}





He intentado y no he sabido como;

en lugar de int Año, int mes int dia, que el contructor de Producto pidiera un Calendar, debido a que es una clase abstracta y su forma de creación es distinta,n o he sido capaz de hacerlo.
El control en datos si, con un return de un array pasaba los 3 int (año, mes, dia) pero no he visto como hacer para introducirlos, en fin un lio para el que me faltan recursos o conocimientos :)

P.D. intuyo que más que pedirlo por contructor debia haber cread un Producto no anónimo y despues cambiarle el Calendar con un nuevoProducto.Calendar.set(int,int,int);

P.D.2 He arreglado lo Producto.Calendar.set , lo pondré en el ejercicio 688B :) consigo pasar bien los Calendar.
« Última modificación: 14 de Abril 2015, 17:49 por Lorenzo31 »

toni_apr

  • Avanzado
  • ****
  • Mensajes: 497
  • Curiosidad, es uno de los pilares del Conocimiento
    • Ver Perfil
Hola Lorenzo

Como veo que estás preparado. Voy al ataqueeee.

Todo el código que has enviado, lo he visto siempre muy bien.
Has usado control de excepciones, has creado clases con métodos estáticos que se usan sin instanciar.
Y tu código por decirlo de alguna manera, es ligero, no resulta empalagoso. Es fácil de leer y de seguir. Esto último seguramente gracias a tu experiencia codificando y codificando.

En este ejercicio también aportas cosas nuevas.
Con dos clases (Recoger y EntradaDatos) tienes solucionada la 'recogida' de datos.

Todo esto era para ver si te pillo desprevenido.


Mis comentarios:
Hacer una adaptación del ejercicio anterior, está bien, pero hay que seguir las nuevas condiciones.

Si a tu clase Producto le cambias el nombre y le pones ProductoFresco, tu estructura de clases se mantiene y además el atributo (boolean frescoOno) no parece ser necesario -yo por lo menos no se la veo-.

En el ejercicio anterior no me di cuenta, pero la clase PRefrigerado tiene un atributo igual que el de la clase PCongelado. Para evitar esa duplicidad, hacemos que PRefrigerado herede de PCongelado.

La idea de gestinonar los tres tipos de congelados con la misma clase, es buena. Dices que has simplificado la información de esos productos.
En una de las clases simplificas tres atributos numéricos, en otra dos un String y un valor numérico y en la tercera otro numérico.
Eso es una buena simplificación y una buena abstracción.

Si, esto es una práctica. Pero con los productos congelados en clases individuales y con todos sus atributos este ejercicio sería un buen ejemplo de herencia de clases.

Eso es todo. Se que en otro momento, a este ejercicio o a otro como este le meterás caña y harás una virguería.

Hasta entonces, mis saludos.

PD: Adjunto clase de mi cosecha.
Código: [Seleccionar]
import java.util.Calendar;
/**
 * Detalles de la clase.
 * @author (Toni)
 * @version (0)<br>
 * La clase devuelve con el metodo <b>in</b> una fecha de tipo Calendar aportando dicha fecha en formato String<br>
 * Y con el metodo <b>out</b> devuelve una fecha en formato String aportando la fecha de tipo Calendar
 */
public class Fecha {   
/**
 * @param ddmmaa <br>Este String debe recibir una fecha valida en los formatos: <br>
 * <b>dia/mes/anno</b>, o <b>dia mes anno</b>, o <b>dia-mes</b>, o <b>dia</b>, o una cadena vacia <br>
 * con cualquier caracter separador no numerico entre dia mes y anno
 * @return Y devuelve una fecha de tipo Calendar
 */
    public static Calendar in(String ddmmaa) { //dd-mm-aa  dd/mm/aa
        Calendar fecha1 = Calendar.getInstance();
        String dd="",mm="",aa="";
        int d=0,m=0,a=0;
        char c = ' ';
        ddmmaa = ddmmaa.trim() + " ";
        if (ddmmaa.equals(" ")) {
            // se tomara la fecha de hoy
        } else {
            for (int i = 0; i < ddmmaa.length(); i++) {
                c = ddmmaa.charAt(i);
                if (c==48 || c==49 || c==50 || c==51 || c==52 || c==53 || c==54 || c==55 || c==56 || c==57) {  // solo dígitos del 0 al 9
                    if (d == 0) {        // tomar día
                        dd = dd + c;
                    } else if (m == 0) { // tomar mes
                        mm = mm + c;
                    } else {             // tomar año
                        aa = aa + c;
                    }
                } else    {  // ha aparecido un caracter no dígito
                    if (d == 0) { // tomar día
                        if (!dd.isEmpty()) d = Integer.valueOf(dd);
                    } else if (m == 0) { // tomar mes
                        if (!mm.isEmpty()) m = Integer.valueOf(mm);
                    } else { // tomar año
                        if (!aa.isEmpty()) a = Integer.valueOf(aa);
                    }
                }
            }
        }
//        System.out.println("dd -" + dd + "- mm -" + mm + "- aa -" + aa + "-");
        Calendar fechaHoy = Calendar.getInstance();
        if (a == 0) { // si no hay año se tomam el actual
            a = fechaHoy.get(Calendar.YEAR);
        } else if(a < 1000) { // si el año tiene dos cifras, se le suma 2000
            a = (a % 100) + 2000;
        }
        if (m == 0) { // si no hay mes se toma el actual
            m = fechaHoy.get(Calendar.MONTH);
        } else {
            m = m - 1;
        }
        if (d == 0) { // si tampoco hay dia, se toma el de hoy
            d = fechaHoy.get(Calendar.DATE);
        }
        fecha1.set (a,m,d);
        return fecha1;
    }
/**
 * @return
 * El String devuelto tiene el formato <b>dia/mes/anno</b> tras recibir una fecha de tipo Calendar
 */
    public static String out(Calendar fecha1) {
        int d=0,m=0,a=0;
        d = fecha1.get(Calendar.DATE);
        m = fecha1.get(Calendar.MONTH);
        a = fecha1.get(Calendar.YEAR);
        return d + "/" + (m+1) + "/" + a;
    }
} // Fin de la clase Fecha
« Última modificación: 14 de Abril 2015, 23:42 por toni_apr »

Lorenzo31

  • Avanzado
  • ****
  • APR2.COM
  • Mensajes: 381
    • Ver Perfil
Buenas toni! gracias por el interés que siempre le pones y el tiempo que empleas en la revisión y ayuda (que no es poca y muy valiosa).

Bueno si, en general mi codigo está bien, lo he mejorado bastante y corregido sugerencias en el 688B.

Mi concepción de clases, aunque arriesgada, creo que cumplía lo pedido (salvando la excepción de temperatura común de dos clases). Me alegra que te parezcan simples o funcionales mis códigos, es lo que pretendo siempre.
Seguiré mejorando :)

Gracias por tus ánimos y me pongo a mirar detenidamente la clase de tu cosecha sobre Calendar. ;)
« Última modificación: 15 de Abril 2015, 10:40 por Lorenzo31 »

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".