Clases abstractas e interfaces: ¿Qué son?

Cuando hablamos de programación en lenguajes de alto nivel se suele decir que todo tiene similitud con la vida real. Dicho de otro modo, si algo se puede imaginar es que podemos programarlo. Aunque lo cierto es que habría que matizar que esto es más bien es un tira y afloja entre dos realidades. Por un lado tenemos lo que conocemos como real y por otra la parte lógica y más abstracta que viene siendo nuestra interpretación de cómo deben funcionar las cosas.

Así cuando programamos en JAVA tarde o temprano necesitaremos trabajar con clases abstractas. Qué son y para que las usamos es algo que veremos en este artículo y ya adelanto que no es un concepto especialmente difícil de entender pues si ya entendemos los fundamentos básicos de la programación orientada a objetos como herencia y poliformismo no costará entender éste.

Podemos pensar en las clases abstractas como una anotación y en cierto modo como si de una lista de la compra se tratase. En la vida real solemos hacer breves anotaciones de tareas pendientes sin entrar en descripciones detalladas o en cómo realizar cada una de ellas. Se trata de no olvidarnos de nada y evitar hacer borrón y cuenta nueva o volver sobre nuestros pasos más adelante organizando nuestro tiempo.

Así en programación las clases abstractas funcionan como una clase que declara la existencia de métodos pero no su implementación. Eso es algo que haremos después en las diferentes subclases derivadas de la clase abstracta. Una clase abstracta puede contener métodos no abstractos pero al menos uno de los métodos sí debe serlo.

Para verlo más claro lo mejor es fijarnos en el siguiente ejemplo:

public abstract class Producto  {
   private int precio;

   public Producto(int precio) {
     this.precio = precio;
   }
  public int getPrecio(){
     return this.precio;
  }
   public abstract void getName();
}

public class Banana extends Producto{

   public Banana(){
      super(200);
   }

   @Override 
   public String getName(){
     return "banana";
   }
}

Como puedes ver creamos una clase abstracta “Producto” donde declaramos un método abstracto llamado “getName” pero éste no está implementado en esa clase sino que que es en la clase “Banana” donde definimos el método y su comportamiento.

En otras palabras, lo que hacemos es crear una “anotación” que nos recuerde que debemos definir sí o sí la implementación de dicho método en cada nueva clase que definamos a continuación y que dependa de nuestra clase abstracta.

Qué son los Interfaces

Si este concepto te ha quedado claro ahora damos el paso a otro también muy usado y básico para trabajar en programación orientada a objetos.Los Interfaces son unas clases completamente abstractas que contiene sólo una colección de métodos abstractos y propiedades constantes. Al igual que en las clases abstractas en un Interface se especifica qué se debe hacer pero no su implementación. Serán las clases que implementen estas interfaces las que describen las acciones que puede llevar a cabo un determinado objeto.

Es posible que te preguntes si, ¿eso no eran los métodos que se definen en una clase abstracta hablamos antes? Casi, en una clase abstracta además de aparecer los métodos aparecía el código para dichos métodos, en cambio en un interfaz sólo existe el prototipo de una función, no su código. Aquí la diferencia.

Algunas especificaciones para interfaces:

  • Lo definimos utilizando la palabra clave de la interface.
  • Puede contener solo variables estáticas.
  • No puede contener un constructor porque las interfaces no pueden ser instanciadas.
  • Las interfaces pueden extender otras interfaces.
  • Una clase puede implementar cualquier número de interfaces.
  • Un ejemplo de una interfaz simple:

    interface Animal {
      public void eat();
      public void makeSound();
    }
    
    class Cat implements Animal {
      public void makeSound() {
        System.out.println("Meow");
      }
      public void eat() {
        System.out.println("omnomnom");
      }
    }
    
    

    Las interfaces tienen las siguientes propiedades:

    • Una interfaz es implícitamente abstracta. No es necesario utilizar la palabra clave abstracta al declarar una interfaz.
    • Cada método en una interfaz también es implícitamente abstracto, por lo que la palabra clave abstracta no es necesaria.
    • Los métodos en una interfaz son implícitamente públicos.
    • Una clase puede heredar de una sola superclase, ¡pero puede implementar múltiples interfaces!

    Clase abstracta vs Interface:

    Desde que Java 8 introdujo las implementaciones por defecto en las interfaces, la diferencia a la hora de usarlas se ha diluido mucho, pero principalmente es conceptual. Cuando una clase hereda de otra clase (abstracta o no), estás definiendo qué es, pasar de una idea abstracta a una concreción. Además, estás definiendo una relación entre clases pero cuando implementas una interfaz, estás definiendo cómo se comporta. Es algo como definir y cumplir un contrato.

    Quizá lo mejor, ya a modo conclusión, es ver las clases Abstractas e Interfaces frente a frente en una tabla comparativa. Esto te ayudará a entenderlas mejor aunque mi recomendación es siempre probar con algunos ejemplos y creando tu propio código. Existen muchos ejemplos en Internet y cuanto antes le pilles el truquillo antes podrás sacar provecho de sus ventajas:

    Clase Abstracta Interfaz
    La palabra clave abstract se usa para crear una clase abstracta y se puede usar con métodos. La palabra clave de interface se usa para crear una interfaz, pero no se puede usar con métodos.
    Una clase puede extender solo una clase abstracta. Una clase puede implementar más de una interfaz.
    Las variables no son definitivas por defecto. Puede contener variables no finales. Las variables son finales por defecto en una interfaz.
    Una clase abstracta puede proporcionar la implementación de una interfaz. Una interfaz no puede proporcionar la implementación de una clase abstracta.
    Puede tener métodos con implementaciones. Proporciona una abstracción absoluta y no puede tener implementaciones de métodos.
    Puede tener modificadores de acceso públicos, privados, estáticos y protegidos. Los métodos son implícitamente públicos y abstractos en la interfaz de Java.
    No admite herencias múltiples. Es compatible con herencias múltiples.
    Es ideal para la reutilización del código y la perspectiva de la evolución. Es ideal para la declaración de tipo.

     

    Guía de Posibilidades Profesionales en el Ecosistema de Java