miércoles, 23 de octubre de 2013

Herencia y Polimorfismo en Java (Ejemplo 01)

Enunciado: La empresa XYZ requiere una aplicación informática para administrar los datos de su personal.
Del personal se conoce: número de DNI, nombre, apellidos y fecha de ingreso.
Existen dos categorías de personal: el personal contratado y el personal a destajo. Los empleados contratados tienen un sueldo básico y un porcentaje adicional en función al tiempo laborado: de 0 a 3 años: 5%; de 4 a 7 años: 10%; de 8 a 15 años: 15% y más de 15 años: 20%. Los empleados a destajo tienen un número de clientes captados y un monto por cliente captado.

El desarrollo se compone de 3 paquetes: datos, entidades y presentacion.
En el paquete datos se encuentra una clase llamada ListaEmpleados.
Dentro de entidades tenemos la clase padre Empleado de la que heredan las clases EContratado y EDestajo.
Finalmente, el paquete presentacion incluye las clases: Aplication y AplicationRunner.
El video explicativo de este ejercicio (que hace uso de Herencia y Polimorfismo) puede verse desde la siguiente dirección:

Enlace: https://www.youtube.com/watch?v=2tO_v8gYk74

Y el código fuente de cada una de las clases mencionadas se presenta a continuación.

Clase Empleado

package entidades;

public class Empleado {
    private String dni;
    private String nombre;
    private String apellidos;
    protected java.util.GregorianCalendar fechaIngreso;

    public Empleado () {
        dni = "00000000";
        nombre = "NN";
        apellidos = "NA";
        fechaIngreso = new java.util.GregorianCalendar(1800,0,1);
    }

    public Empleado (String dni, String nombre, String apellidos, java.util.GregorianCalendar fechaIngreso) {
        this.dni = dni;
        this.nombre = nombre;
        this.apellidos = apellidos;
        this.fechaIngreso = fechaIngreso;
    }

    public void setDni (String dni) {
        this.dni = dni;
    }

    public String getDni () {
        return dni;
    }

    public void setNombre (String nombre) {
        this.nombre = nombre;
    }

    public String getNombre () {
        return nombre;
    }

    public void setApellidos (String apellidos) {
        this.apellidos = apellidos;
    }

    public String getApellidos () {
        return apellidos;
    }

    public void setFechaIngreso (java.util.GregorianCalendar fechaIngreso) {
        this.fechaIngreso = fechaIngreso;
    }

    public java.util.GregorianCalendar getFechaIngreso () {
        return fechaIngreso;
    }

    @Override
    public String toString () {
        int dia, mes, año;
        dia = getFechaIngreso().get(java.util.Calendar.DAY_OF_MONTH);
        mes = getFechaIngreso().get(java.util.Calendar.MONTH)+1;
        año = getFechaIngreso().get(java.util.Calendar.YEAR);
        return "DNI: " + getDni() + "\nNombre y Apellidos: " + getNombre() + 
               " " + getApellidos() + "\nFecha de ingreso: " + 
               (dia<=9?"0"+dia:dia) + "/" + (mes<=9?"0"+mes:mes) + "/" + año;
    }
}

Clase EContratado
package entidades;

import java.util.Calendar;
import java.util.GregorianCalendar;

public class EContratado extends Empleado {
    private float salarioB;

    public EContratado () {
        super();
        salarioB = 0.0f;
    }

    public EContratado (String dni, String nombre, String apellidos, java.util.GregorianCalendar fechaIngreso, float salarioB) {
        super(dni, nombre, apellidos, fechaIngreso);
        this.salarioB = salarioB;
    }

    public void setSalario (float salarioB) {
        this.salarioB = salarioB;
    }

    public float getSalario () {
        GregorianCalendar Actual = new GregorianCalendar();
        int anios = Actual.get(Calendar.YEAR) - fechaIngreso.get(Calendar.YEAR);
        if(fechaIngreso.get(Calendar.MONTH)>Actual.get(Calendar.MONTH)
           || fechaIngreso.get(Calendar.MONTH)==Actual.get(Calendar.MONTH)
              && fechaIngreso.get(Calendar.DAY_OF_MONTH)>Actual.get(Calendar.DAY_OF_MONTH)
          ) anios--;
        switch(anios)
        {
            case 0: // break;
            case 1:
            case 2:
            case 3: return 1.05f*salarioB;
            case 4: 
            case 5:
            case 6:
            case 7: return 1.10f*salarioB;
            case 8:
            case 9:
            case 10:
            case 11:
            case 12:
            case 13:
            case 14:
            case 15: return 1.15f*salarioB;
            default: return 1.20f*salarioB;
        }
    }

    @Override
    public String toString () {
        return super.toString() + "\nSalario: " + getSalario();
    }
}

Clase EDestajo
package entidades;

public class EDestajo extends Empleado {
    private int clientesCaptados;
    public static final float salarioD = 130.05f;

    public EDestajo () {
        super();
        clientesCaptados = 0;
    }

    public EDestajo (String dni, String nombre, String apellidos, java.util.GregorianCalendar fechaIngreso, int clientesCaptados) {
        super(dni, nombre, apellidos, fechaIngreso);
        this.clientesCaptados = clientesCaptados;
    }

    public void setClientesCaptados (int clientesCaptados) {
        this.clientesCaptados = clientesCaptados;        
    }

    public int getClientesCaptados () {
        return clientesCaptados;
    }
    
    public float getSalario () {
        return salarioD*clientesCaptados;
    }

    @Override
    public String toString () {
        return super.toString() + "\nSalario: " + getSalario();
    }
}

Clase ListaEmpleados
package datos;

import entidades.Empleado; 
import java.util.ArrayList; 

public class ListaEmpleados {
    private ArrayList listaE;
    private int posicion; // Última posición.

    public ListaEmpleados () {
        listaE = new ArrayList();
        posicion = -1;
    }

    public void addEmpleado (Empleado empleado) {
        listaE.add(empleado);
        ++posicion;
    }

    public Empleado getEmpleado (int pos) {
        if(pos>=0 && pos<=posicion)
            return listaE.get(pos);
        return null;
    }

    public int getPosicion () {
        return posicion;
    }

    @Override
    public String toString () {
        String cadena = "";
        for(int i=0; i<=posicion; i++)
            cadena += "\n\tEmpleado " + (i+1) + ":\n" + listaE.get(i);
        return cadena;
    }
}

Clase Aplication
/*
 * Menu de opciones:
 * 1. Registrar empleados contratados
 * 2. Registrar empleados a destajo
 * 3. Mostrar salarios por empleado
 * 4. Salir
 */

package presentacion;

import datos.ListaEmpleados;
import entidades.*;
import java.util.GregorianCalendar;
import java.util.Scanner;

public class Aplication {

    int opt;
    ListaEmpleados ListaContratados = new ListaEmpleados();
    ListaEmpleados ListaDestajos = new ListaEmpleados();
    private static Scanner Lector = new Scanner(System.in);
    public static final short CONTRATADO = 0;
    public static final short POR_DESTAJO = 1;

    private static String Leer(String msje)
    {
        System.out.print(msje+": ");
        return Lector.nextLine();
    }

    private void Leer(int Type)
    {
        String dni = Leer("Ingrese su DNI");
        String nombre = Leer("Ingrese su nombre");
        String apellidos = Leer("Ingrese sus apellidos");
        System.out.println("Ingrese fecha de ingreso:");
        int anio = Integer.parseInt( Leer("Año") );
        int mes = Integer.parseInt( Leer("Mes (1-12)") );
        int dia = Integer.parseInt( Leer("Día") );
        GregorianCalendar fechaIngreso = new GregorianCalendar(anio,mes-1,dia);

        if(Type == CONTRATADO)
        {
            int salarioB = Integer.parseInt( Leer("Ingrese salario base") );
            ListaContratados.addEmpleado( new EContratado(dni, nombre, apellidos, fechaIngreso, salarioB) );
        }else{
            int clientesObtenidos = Integer.parseInt( Leer("Ingrese clientes reclutados") );
            ListaDestajos.addEmpleado( new EDestajo(dni, nombre, apellidos, fechaIngreso, clientesObtenidos) );
        }
    }

    private void MostrarSalarios()
    {
        System.out.println("Salarios de los empleados contratados: ");
        for(int i=0; i<=ListaContratados.getPosicion(); ++i)
            System.out.println( ListaContratados.getEmpleado(i) );
        System.out.println("Salarios de los empleados por destajo: ");
        for(int i=0; i<=ListaDestajos.getPosicion(); ++i)
            System.out.println( ListaDestajos.getEmpleado(i) );
    }


    private int Menu()
    {
        System.out.print(
          "MENU DE OPCIONES\n"
        + "---- -- --------\n"
        + "1. Registrar empleados contratados.\n"
        + "2. Registrar empleados a destajo.\n"
        + "3. Mostrar salarios por empleado.\n"
        + "4. Salir.\n");
        return Integer.parseInt( Leer("Seleccione opción") );
    }

    private void Accionar(int opt)
    {
        switch(opt)
        {
            case 1:
                Leer(CONTRATADO);
                break;
            case 2:
                Leer(POR_DESTAJO);
                break;
            case 3:
                MostrarSalarios();
                break;
            case 4:
                System.out.println("Cerrando programa . . .");
                break;
            default:
                System.err.println("Al menos ingresa una opción válida ._.");
        }
    }

    public void Ejecutar () {

        do{
            opt = Menu();
            Accionar(opt);
        }while(opt!=4);
        
    }
}

Clase AplicationRunner
package presentacion;

public class AplicationRunner {

    public static void main(String[] args) {
        new Aplication().Ejecutar();
    }
    
}
Y ello sería todo. Cualquier duda puede escribirse a modo de comentario.