Programación Orientada a Objetos 10 - Abstracción

La abstracción (clase abstracta es uno de sus representantes) es un principio fundamental en la programación orientada a objetos, que permite a los desarrolladores enfocarse en lo que hace un objeto sin tener que lidiar con los detalles de cómo lo hace.

En este capítulo, veremos el concepto de abstracción, cómo se implementa a través de clases y métodos abstractos, y proporcionaremos orientación sobre por qué y cuándo usarla.

¿Qué es la Abstracción?

La abstracción es el proceso de ocultar los detalles de implementación complejos y mostrar solo las funcionalidades esenciales al usuario.

Se centra en lo que hace un objeto, no en cómo lo hace, permitiendo a los desarrolladores trabajar con conceptos a un nivel más general e intuitivo.

Métodos Abstractos

Un método abstracto es un método que se declara sin cuerpo.

Sirve como un “contrato” que garantiza que las subclases tendrán que implementar este método, una implementación específica de cada subclase.

UML

En UML un método abstracto se escribe en itálica, indicando que se debe redefinir. También el nombre de la clase. Como en este caso el método dibujar() y el nombre de la clase Figura.

abstracción y clases abstractas

Clases Abstractas

Una clase abstracta es una que no se puede instanciar, debe ser extendida por otra clase que implemente sus métodos abstractos.

Clase abstracta es toda clase que tiene al menos un método abstracto.

Puede tener atributos y métodos concretos (implementados), pero si tiene uno o más abstractos, es abstracta.

Características

  • No Instanciables: No se puede crear un objeto directamente de una clase abstracta.
  • Puede Contener Métodos Abstractos: Un método abstracto es un método que se declara sin una implementación. Las subclases deben proporcionar una implementación concreta para estos métodos.
  • Pueden Contener Métodos Concretos: Las clases abstractas también pueden tener métodos con implementación completa, lo que permite cierto grado de reutilización de código.

    public abstract class Vehiculo {
      public abstract void moverse();
    }                
                

En este ejemplo Vehiculo es una clase abstracta, tiene al menos un método abstracto.

Cualquier clase que extienda Vehiculo deberá proporcionar su propia versión del método moverse.

¿Por Qué Usar Abstracción?

  • Simplicidad: La abstracción permite a los desarrolladores trabajar con operaciones a un alto nivel, sin preocuparse por los detalles complejos de su implementación.
  • Reutilización de Código: Las clases abstractas pueden contener una implementación parcial que será compartida por todas sus subclases, reduciendo la duplicación de código.
  • Extensibilidad: Al definir un “contrato” a través de métodos abstractos, las clases abstractas hacen que el código sea más fácil de extender y mantener.

¿Cuándo Usar Abstracción?

  • Cuando se tienen clases relacionadas que deben compartir código común, pero también tienen sus propios comportamientos.
  • Cuando se desea ocultar detalles de implementación complejos, que lo usuarios de la clase se concentren en qué hace un método y no en cómo lo hace.

Ejemplo Práctico: Sistema de Figuras Geométricas

Como ejemplo de abstracción consideremos un sistema de figuras geométricas.

Podemos definir una clase abstracta Figura que contiene métodos abstractos para calcular el área y el perímetro. Crearemos implementaciones específicas para diferentes tipos de figuras.


    public abstract class Figura {
      public abstract double area();
      public abstract double perimetro();
    }                
                

Clases concretas:


    public class Circulo extends Figura {
        private double radio;
    
        public Circulo(double radio) {
            this.radio = radio;
        }
    
        @Override
        public double area() {
            return Math.PI * radio * radio;
        }
    
        @Override
        public double perimetro() {
            return 2 * Math.PI * radio;
        }
    }
    
    public class Rectangulo extends Figura {
        private double largo;
        private double ancho;
    
        public Rectangulo(double largo, double ancho) {
            this.largo = largo;
            this.ancho = ancho;
        }
    
        @Override
        public double area() {
            return largo * ancho;
        }
    
        @Override
        public double perimetro() {
            return 2 * (largo + ancho);
        }
    }
                

Conclusiones

La abstracción es una técnica poderosa que ayuda a simplificar el diseño de software al permitir a los desarrolladores concentrarse en las operaciones de alto nivel.

Al usar clases abstractas y métodos abstractos, se puede crear una jerarquía clara y flexible que promueva la reutilización de código y facilite la extensibilidad y el mantenimiento.

Entender y aplicar la abstracción te permitirá construir sistemas más robustos y escalables, las buenas prácticas y los patrones de diseño se basan en abstracciones.