Clases Abstractas E Interfaces En Java Ejemplos

En Java, las clases abstractas e interfaces son mecanismos fundamentales para lograr la abstracción y el polimorfismo. Ambas herramientas te permiten definir comportamientos comunes para múltiples clases, promoviendo la reutilización de código y la flexibilidad en el diseño de software.
Clases Abstractas
Una clase abstracta es una clase que no se puede instanciar directamente. Su propósito principal es servir como una plantilla o un modelo para otras clases. Las clases abstractas pueden contener métodos abstractos (sin implementación) y métodos concretos (con implementación).
Un método abstracto se declara utilizando la palabra clave `abstract` y no tiene cuerpo (implementación). Las clases hijas (subclases) de una clase abstracta deben proporcionar una implementación para todos los métodos abstractos definidos en la clase padre, a menos que la subclase también se declare como abstracta.
Must Read
Ejemplo:
abstract class Figura {
protected double area;
public abstract double calcularArea();
public double getArea() {
return area;
}
}
class Circulo extends Figura {
private double radio;
public Circulo(double radio) {
this.radio = radio;
}
@Override
public double calcularArea() {
area = Math.PI * radio * radio;
return area;
}
}
class Rectangulo extends Figura {
private double base;
private double altura;
public Rectangulo(double base, double altura) {
this.base = base;
this.altura = altura;
}
@Override
public double calcularArea() {
area = base * altura;
return area;
}
}
En este ejemplo, `Figura` es una clase abstracta con un método abstracto `calcularArea()`. Las clases `Circulo` y `Rectangulo` extienden `Figura` e implementan el método `calcularArea()` proporcionando su propia lógica específica para calcular el área de cada figura.

Interfaces
Una interfaz es un contrato que define un conjunto de métodos que una clase debe implementar. A diferencia de las clases abstractas, las interfaces no pueden tener variables de instancia (campos) ni métodos con implementación (excepto en las versiones más recientes de Java, que permiten métodos `default` y `static`).
Una clase puede implementar múltiples interfaces, lo que le permite adoptar múltiples comportamientos o "tipos". Esto es una diferencia clave con las clases abstractas, ya que Java no permite la herencia múltiple de clases.
Ejemplo:

interface Sonido {
void hacerSonido();
}
interface Movible {
void mover();
}
class Perro implements Sonido, Movible {
@Override
public void hacerSonido() {
System.out.println("Guau!");
}
@Override
public void mover() {
System.out.println("El perro corre.");
}
}
class Coche implements Sonido, Movible {
@Override
public void hacerSonido() {
System.out.println("¡Brum!");
}
@Override
public void mover() {
System.out.println("El coche avanza.");
}
}
Aquí, `Sonido` y `Movible` son interfaces. Las clases `Perro` y `Coche` implementan ambas interfaces, proporcionando implementaciones específicas para los métodos `hacerSonido()` y `mover()`. Esto demuestra cómo una clase puede adoptar comportamientos de múltiples interfaces.
Diferencias Clave
La principal diferencia entre las clases abstractas y las interfaces radica en su propósito y en las capacidades que ofrecen:

- Herencia vs. Implementación: Una clase hereda de una clase abstracta, mientras que una clase implementa una interfaz.
- Herencia Múltiple: Java no soporta la herencia múltiple de clases, pero una clase puede implementar múltiples interfaces.
- Estado: Las clases abstractas pueden contener estado (variables de instancia), mientras que las interfaces tradicionalmente no lo hacían (hasta la introducción de campos `static final`).
- Implementación: Las clases abstractas pueden contener métodos con implementación, mientras que las interfaces originalmente solo contenían declaraciones de métodos abstractos (esto ha cambiado con las versiones más recientes de Java).
Cuándo Usar Cada Uno
Utiliza una clase abstracta cuando quieras definir una jerarquía de clases con un comportamiento común y compartir un estado. También, cuando algunas partes de la implementación ya están definidas y quieres forzar a las subclases a implementar ciertas funcionalidades específicas.
Utiliza una interfaz cuando quieras definir un contrato que múltiples clases, posiblemente no relacionadas, deben cumplir. Es ideal cuando quieres lograr un acoplamiento bajo y permitir que diferentes clases implementen el mismo comportamiento de manera independiente.
En resumen, las clases abstractas e interfaces son herramientas poderosas para lograr abstracción y polimorfismo en Java. Comprender sus diferencias y cuándo usar cada una te permitirá diseñar un código más flexible, reutilizable y mantenible.
