Interfaces en Java: Abstracción y Bases de Datos

¿Qué es una interfaz en Java y por qué es tan importante?

Cuando comienzas a desarrollar en Java, rápidamente te topas con el concepto de interfaces. Puede sonar abstracto (y lo es), pero entender bien qué son y cómo usarlas marca una gran diferencia en cómo estructuras tu código.

¿Qué es una interfaz?

Una interfaz en Java es un contrato: define un conjunto de métodos que una clase debe implementar. No dice cómo deben funcionar esos métodos, solo que deben existir.

En otras palabras, una interfaz define el comportamiento esperado de una clase, sin preocuparse de la implementación.

¿Por qué usar interfaces?

  • Desacoplamiento: separas la definición de comportamiento de la implementación concreta.
  • Flexibilidad: puedes cambiar la implementación sin afectar el resto del sistema.
  • Testeo más fácil: puedes usar objetos simulados (mocks) para pruebas.
  • Polimorfismo: puedes tratar objetos diferentes como si fueran del mismo tipo (la interfaz).

Ejemplo simple

public interface Animal {
    void hacerSonido();
}

public class Perro implements Animal {
    public void hacerSonido() {
        System.out.println("Guau");
    }
}

public class Gato implements Animal {
    public void hacerSonido() {
        System.out.println("Miau");
    }
}

List<Animal> animales = List.of(new Perro(), new Gato());
for (Animal a : animales) {
    a.hacerSonido();
}

Apliquemos lo mismo para las bases de datos

El mismo principio de abstracción con interfaces también se aplica al acceso a datos. En lugar de acoplar tu código a una base de datos específica, defines una interfaz con las operaciones necesarias:

public interface UsuarioDAO {
    Usuario buscarPorId(int id);
    void guardar(Usuario usuario);
    void eliminar(int id);
}

Y luego implementas esa interfaz con una clase concreta:

public class UsuarioDAOMySQL implements UsuarioDAO {
    @Override
    public Usuario buscarPorId(int id) {
        // Conexión, query, mapeo...
    }

    @Override
    public void guardar(Usuario usuario) {
        // Inserta en la tabla correspondiente
    }

    @Override
    public void eliminar(int id) {
        // Ejecuta DELETE
    }
}

¿Y cómo llamamos a la implementación?

Como estás trabajando contra la interfaz, el código que utiliza esta lógica no necesita saber qué implementación hay debajo. Solo necesita un objeto que implemente UsuarioDAO:

public class UsuarioService {
    private UsuarioDAO usuarioDAO;

    public UsuarioService(UsuarioDAO usuarioDAO) {
        this.usuarioDAO = usuarioDAO;
    }

    public void registrarUsuario(Usuario usuario) {
        usuarioDAO.guardar(usuario);
    }
}

Y cuando creas el UsuarioService, le inyectas la implementación concreta:

UsuarioDAO dao = new UsuarioDAOMySQL(); // Aquí decides la implementación
UsuarioService servicio = new UsuarioService(dao);

Esto se llama inyección de dependencias: usas la interfaz como contrato y decides en tiempo de ejecución (o por configuración) qué implementación usar.

Ventaja clave

Gracias a esto, puedes:

  • Cambiar fácilmente a otra base de datos (ej: UsuarioDAOPostgreSQL)
  • Usar una versión de prueba (UsuarioDAOMock) para test unitarios
  • Reutilizar UsuarioService sin tocarlo

Interfaz vs Clase Abstracta

Característica Interfaz Clase Abstracta
Métodos con implementación Sí, con default
Puede tener atributos Solo constantes (static final) Sí, variables normales
Herencia múltiple No

Conclusión

Las interfaces no solo son una herramienta del lenguaje. Son una forma de pensar el diseño de tus aplicaciones. Al abstraer el "qué" del "cómo", te permiten construir sistemas más mantenibles, extensibles y robustos.

Así que la próxima vez que escribas una interfaz, recuerda: estás diseñando un contrato elegante para algo que aún no existe, pero que sabrás cómo tratar, incluso si es una base de datos.

Comentarios

Entradas populares de este blog

Configurando Servlets y JSP en Jetty

Firma de un Documento XML con Certificado Digital en Java para Uso Tributario en Chile

RESOLUCION SET BASICO DE FACTURA ELECTRÓNICA SII