martes, 24 de septiembre de 2024

■ Java ► Polimorfismo

Continuando con el ejemplo de herencia donde se tenían las clases "Persona" y "Empleado" (ver aquí), donde "Empleado" heredaba de "Persona", continuaré este ejemplo agregando la clase "Cliente" que también heredará de "Persona".


■ Sub clase Cliente

En el ejemplo anterior se habló de la herencia y se tenían solo dos clases, la super clase "Persona" y la sub clase "Empleado" que heredaba de "Persona", en este ejemplo y para poder explicar el Polimorfismo se agregará una nueva clase llamada "Cliente" que también heredará de "Persona" quedando la estructura así:


■ Polimorfismo

El polimorfismo es la capacidad de un método de responder de diferentes formas, esto es que podemos tener métodos que compartan el mismo nombre pero que se comporten de forma diferente.

Es decir, pensando en el diagrama anterior, la clase "Persona" puede tener un método llamado "mostrarDatos" que lo único que hará es mostrar los datos de la persona en pantalla, esto es su nombre, su teléfono y su dirección, ¿por qué solo esos tres datos?, porque son los propios atributos de la clase, es lo único que tiene.

Como "Empleado" y "Cliente" heredan de "Persona", significa que también pueden acceder al método "mostrarDatos" aunque estas subclases no lo tengan definido lo acceden por herencia, pero, aunque las subclases tengan sus propios atributos, el método de heredado de "Persona" "mostrarDatos" solo mostrará el nombre, la dirección y el teléfono ya que es lo que la clase tiene.


■ Sobreescritura de métodos

Ahora, si definimos el método "mostrarDatos" en las subclases, este se va comportar diferente, en cada subclase se puede acceder por herencia a los atributos de "Persona" y además a los atributos propios, por lo que si desde una instancia de Empleado, es decir, un objeto del tipo Empleado, llamamos al método "mostrarDatos", aunque haya dos métodos con el mismo nombre, es decir el método "mostrarDatos" de "Persona" y el método "mostrarDatos" de "Empleado", se tomará el método de la propia clase, si el objeto se creó a partir de "Empleado" se invocará el método de dicha clase y no se mostrarán solo los atributos de "Persona" sino que se mostrarán tanto los de "Persona" como los de "Empleado", lo mismo sucedería con "Cliente".

Lo anterior visto en código es así:

class Persona {
     // atributos

    public void mostrarDatos() {
        System.out.println(this.nombre);
        System.out.println(this.teléfono);
        System.out.println(this.dirección);
    }
}

class Empleado {
    // atributos

    public void mostrarDatos() {
        super.mostrarDatos();
        System.out.println(this.idEmpleado);
        System.out.println(this.departamento);
        System.out.println(this.turno);
    }
}

class Cliente {
    // atributos

    public void mostrarDatos() {
        super.mostrarDatos();
        System.out.println(this.idCliente);
        System.out.println(this.limitecredito);
    }
}

Si las subclases (Empleado y Cliente) no tuvieran un método propio "mostrarDatos", al invocarlo desde una de ellas se ejecutaría el método "mostrarDatos" de "Persona" ya que lo tienen por herencia y solo mostraría los atributos de persona.

Pero si las subclases tuvieran su método propio "mostrarDatos", en lugar de ejecutarse el de "Persona" se ejecutaría el de la propia clase, esto es el polimorfismo por sobreescrituda de métodos, ya que se le da prioridad al de la propia clase del objeto que lo invoca, y se mostrarían tanto los atributos de persona como los de la subclase.


■ Ejemplo completo

En el ejemplo pasado cuando se habló de la herencia se vio como funcionan los métodos set y get por lo que en este código los omitiré para no hacerlo tan extenso y centrarse en el polimosrfismo.

class Persona {
    String nombre;
    String telefono;
    String direccion;
    public Persona(String _nombre, String _telefono, String _direccion) {
        this.nombre = _nombre;
        this.telefono = _telefono;
        this.direccion = _direccion;
    }
    // Setters
    // Getters
    // Métodos
    public void mostrarDatos() {
        System.out.println("Nombre: " + this.nombre);
        System.out.println("Teléfono: " + this.telefono);
        System.out.println("Dirección: " + this.direccion);
    }
}

class Empleado extends Persona {
    int idEmpleado;
    String departamento;
    String turno;
    public Empleado(
        String _nombre, String _telefono, String _direccion,
        int _idEmpleado, String _departamento, String _turno
    ) {
        super(_nombre, _telefono, _direccion);
        this.idEmpleado = _idEmpleado;
        this.departamento = _departamento;
        this.turno = _turno;
    }
    // Setters
    // Getters
    // Métodos
    public void mostrarDatos() {
        super.mostrarDatos(); // Método de la superclase
        System.out.println("Id. Empleado: " + this.idEmpleado);
        System.out.println("Departamento: " + this.departamento);
        System.out.println("Turno: " + this.turno);
        System.out.println();
    }
}

class Cliente extends Persona {
    int idCliente;
    double limiteCredito;
    public Cliente(
        String _nombre, String _telefono, String _direccion,
        int _idCliente, double _limiteCredito
    ) {
        super(_nombre, _telefono, _direccion);
        this.idCliente = _idCliente;
        this.limiteCredito = _limiteCredito;
    }
    // Setters
    // Getters
    // Métodos
    public void mostrarDatos() {
        super.mostrarDatos(); // Método de la superclase
        System.out.println("Id. Cliente: " + this.idCliente);
        System.out.println("Límite de crédito: " + this.limiteCredito);
        System.out.println();
    }
}

public class Main {
    public static void main (String args[]) {
        Empleado empleado = new Empleado(
            "John Smith",
            "(555) 123 456 7890",
            "Main Street",
            1001,
            "Gerencia",
            "Matutino"
        );
        Cliente cliente = new Cliente(
            "Mackenzie Anderson",
            "(666) 999 333 1234",
            "Fifth Avenue",
            2001,
            1000.90
        );
        empleado.mostrarDatos();
        cliente.mostrarDatos();
    }
}


En este ejemplo se tienen tres clases: Persona, Empleado y Cliente, donde las últimas dos heredan de Persona, cada clase tiene sus atributos propios y un método del mismo nombre en las tres.

Como los objetos creados son a partir de las subclases "Empleado" y "Persona", al invocar al método "mostrarDatos", se ejecuta el método de las subclases mostrando no solo los datos de "Persona" sino todos los datos de cada sublase.

No hay comentarios:

Publicar un comentario