domingo, 10 de septiembre de 2017

23-Las Clases Abstractas

Seguimos avanzando en el curso de Java para principiantes, hoy vamos a ver las clases abstractas. ¿Qué son las clases abstractas? Las clases abstractas en Java, son un tipo de clase especial que no permite ser instanciada. ¿Qué quiere decir que las clases abstractas no pueden ser instanciadas? Quiere decir que de las clases abstractas no podemos crear objetos.
Entonces, si no puedo crear objetos de las clases abstractas, ¿Para qué sirven? Las clases abstractas sirven para ser utilizadas como super clases. Por ejemplo, supongamos que tenemos una clase abstracta llamada Persona. A partir de esta clase abstracta Persona podemos crear subclases de dicha clase, como por ejemplo la clase Profesor y la clase Alumno.
La clase Persona será la clase abstracta, no se podrá instanciar.
Cuando creemos un proyecto que tengamos que crear una clase que sea una Persona, pues crearemos una clase que herede de la clase Persona. Otro ejemplo de subclases de Persona podrían ser la clase Hombre y/o la clase Mujer. Ambas clases serán subclases de Persona.

Pero todo esto lo vimos cuando estudiamos la herencia ¿verdad? Entonces, ¿Qué diferencia hay en crear una super clase y crear una super clase que sea clase abstracta?
Bueno, algunas diferencias son las siguientes:
  • Las clases abstractas no son instanciables, no podemos crear objetos de dichas clases
  • Las clases abstractas, si tienen métodos abstractos nos obligan a sobreescribir dichos métodos en las clases hijas.

Una clase abstracta puede contener, o no, métodos abstractos. Si una clase tiene al menos un método abstracto, dicha clase deberá ser abstracta obligatoriamente, en caso contrario nos dará error.
Para declarar una clase abstracta lo hacemos con la siguiente sintaxis:
public abstract class NombreClase {

}

Como hemos dicho ya, las clases abstractas no pueden ser instanciadas, y que las podemos utilizar para que hagan de super clases. Pero también podemos crear métodos abstractos.
Si una clase tiene al menos un método abstracto, la clase deberá ser obligatoriamente abstracta.
Los métodos abstractos tienen una particularidad, y es que no tienen cuerpo, solamente se declaran y se termina con punto y coma ';' El cuerpo de estos métodos se sobreescribirán en las clases hijas. La sintaxis de los métodos abstractos son de la siguiente manera:

public abstract tipoDevuelto nombreMetodo();

Como vemos, no lleva las llaves de apertura ni de cierre '{}'.

¿Para qué sirven los métodos abstractos?A parte ser super clases, los métodos abstractos lo que hacen son obligarnos a sobreescribirlos en las clases hijas los métodos que sean abstractos. Cuando sobreescribamos los métodos abstractos en la clase hija correspondiente, lo haremos para esa clase en particular.
Puede darse el caso de que una clase abstracta no contenga ningún método abstracto.

Las clase abstractas pueden contener métodos que no sean abstractos igualmente, pero en caso de que tenga algún método abstracto, la clase deberá pasar a ser abstracta.

Bueno, la teoría está muy bien aprenderla y todo eso, pero vamos a pasar a la acción que seguro que lo veis más facilmente. Vamos a crear una clase Persona que será una clase abstracta, tendrá metodos normales y un método abstracto, que veremos que tendremos que sobreescribir en las clases hijas.
Las clases hijas que crearemos serán la clase Profesor y la clase Alumno.
Clase abstracta Persona:

package clasesAbstractas;

public abstract class Persona {
    
    //Podemos crear atributos igualmente que con las clases no abstractas
    private String nombre;
    private int edad;
    
    //Creamos el constructor
    public Persona(String nombre, int edad) {
        
        this.nombre = nombre;
        this.edad = edad;
        
    }
    
    //Creamos un método abstracto
    //Este método lo sobreescribiremos en las clases hijas.
    public abstract void accionPersona();
    
    //Creamos métodos setter y getter
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
    
    public String getNombre() {
        
        return nombre;
    }
    
    public void setEdad(int edad) {
        
        this.edad = edad;
    }
    
    public int getEdad() {
        
        return edad;
    }
    
    
}

Clase Profesor que hereda de la clase Persona:

package clasesAbstractas;

public class Profesor extends Persona {
    
    //Atributos propios de un profesor
    private double sueldo;
    private String colegio;
    
    //Constructor
    public Profesor() {
        super();
        
    }
    
    //Al heredar de una clase abstracta, nos obliga a sobreescribir
    //los métodos abstractos de la clase abstracta

    @Override
    public void accionPersona() {
        System.out.println("El profesor enseña a los Alumnos.");
    }
    
    
    /*
    No creamos los setter y getter de Profesor para no aumentar el código
    */
    
    
}

Por último creamos la clase Alumno, subclase también de Persona:

package clasesAbstractas;

public class Alumno extends Persona {
    
    //Atributos del alumno
    private int curso;
    private String colegio;
    
    //Constructor
    public Alumno() {
        super();
    }
    
    //Sobreescribimos el método abstracto de la clase abstracta Persona

    @Override
    public void accionPersona() {
        System.out.println("El alumno aprende del profesor");
    }
    
    /*
    Tampoco creamos los métodos setter ni getter para no aumentar la legibilidad
    del código
    */
    
}

Ahora creamos una nueva clase, que será nuestro programa principal para ver el resultado de nuestros programas:

package clasesAbstractas;

public class Programa {
    
    public static void main(String[] args) {
        
        //Creamos dos instancias, una de la clase Profesor
        //y otra de la clase Alumno.
        
        Profesor p = new Profesor();
        Alumno a = new Alumno();
        
        //Ahora llamamos a su método accionPersona() que sobreescribimos
        //en cada una de las subclases de Persona
        
        p.accionPersona();
        a.accionPersona();
        
    }
    
}

Si ejecutamso el programa nos saldrá la siguiente salida por consola:


También podríamos hacer uso de la propiedad es un de las subclases, puesto que un Profesor es una Persona y un Alumno también es una Persona, podríamos hacer lo siguiente:

package clasesAbstractas;

public class Programa {
    
    public static void main(String[] args) {
        
        //Utilización de la propiedad es un de la herencia
        Persona p1 = new Profesor();
        Persona p2 = new Alumno();
        
        p1.accionPersona();
        p2.accionPersona();
        
    }
    
}

Si volvemos a ejecutar podemos ver el funcionamiento de la propiedad es un de la herencia:



Pues eso es todo referente a las clases abstractas en Java. Ahora como siempre digo, os toca a vosotros, jugad con el código, probad cosas..... y si algo no entendéis o tenéis dudas, do dudéis en dejar vuestro comentario debajo.
Gracias por seguir mis tutoriales y en el siguiente veremos las interfaces y las clases internas.
Recordad también que me podéis seguir en Facebook.

No hay comentarios:

Publicar un comentario

Related Posts Plugin for WordPress, Blogger...