La abstracción es uno de los cuatro pilares fundamentales de la Programación Orientada a Objetos (POO), junto con la encapsulación, la herencia y el polimorfismo. La abstracción permite a los desarrolladores manejar la complejidad del software ocultando los detalles de implementación y mostrando solo la funcionalidad esencial.

Conceptos Clave

  1. Definición de Abstracción:

    • La abstracción es el proceso de ocultar los detalles de implementación y mostrar solo la funcionalidad necesaria.
    • Permite a los desarrolladores centrarse en lo que hace un objeto en lugar de cómo lo hace.
  2. Clases Abstractas:

    • Una clase abstracta no puede ser instanciada directamente.
    • Puede contener métodos abstractos (sin implementación) y métodos concretos (con implementación).
    • Se utiliza para definir una interfaz común para todas sus subclases.
  3. 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 para todos los métodos abstractos de la clase base.

Ejemplo Práctico

Vamos a crear un ejemplo práctico para ilustrar la abstracción en C#. Imaginemos que estamos desarrollando una aplicación para gestionar diferentes tipos de cuentas bancarias.

Paso 1: Definir una Clase Abstracta

// Definición de la clase abstracta CuentaBancaria
public abstract class CuentaBancaria
{
    public string NumeroCuenta { get; set; }
    public double Saldo { get; protected set; }

    public CuentaBancaria(string numeroCuenta, double saldoInicial)
    {
        NumeroCuenta = numeroCuenta;
        Saldo = saldoInicial;
    }

    // Método abstracto para depositar dinero
    public abstract void Depositar(double cantidad);

    // Método abstracto para retirar dinero
    public abstract void Retirar(double cantidad);

    // Método concreto para mostrar el saldo
    public void MostrarSaldo()
    {
        Console.WriteLine($"El saldo de la cuenta {NumeroCuenta} es: {Saldo}");
    }
}

Paso 2: Crear Subclases que Heredan de la Clase Abstracta

// Definición de la clase CuentaCorriente
public class CuentaCorriente : CuentaBancaria
{
    public CuentaCorriente(string numeroCuenta, double saldoInicial) 
        : base(numeroCuenta, saldoInicial) { }

    public override void Depositar(double cantidad)
    {
        Saldo += cantidad;
        Console.WriteLine($"Se han depositado {cantidad} en la cuenta {NumeroCuenta}");
    }

    public override void Retirar(double cantidad)
    {
        if (Saldo >= cantidad)
        {
            Saldo -= cantidad;
            Console.WriteLine($"Se han retirado {cantidad} de la cuenta {NumeroCuenta}");
        }
        else
        {
            Console.WriteLine("Fondos insuficientes");
        }
    }
}

// Definición de la clase CuentaAhorro
public class CuentaAhorro : CuentaBancaria
{
    public double TasaInteres { get; set; }

    public CuentaAhorro(string numeroCuenta, double saldoInicial, double tasaInteres) 
        : base(numeroCuenta, saldoInicial)
    {
        TasaInteres = tasaInteres;
    }

    public override void Depositar(double cantidad)
    {
        Saldo += cantidad;
        Console.WriteLine($"Se han depositado {cantidad} en la cuenta {NumeroCuenta}");
    }

    public override void Retirar(double cantidad)
    {
        if (Saldo >= cantidad)
        {
            Saldo -= cantidad;
            Console.WriteLine($"Se han retirado {cantidad} de la cuenta {NumeroCuenta}");
        }
        else
        {
            Console.WriteLine("Fondos insuficientes");
        }
    }

    public void AplicarInteres()
    {
        Saldo += Saldo * TasaInteres;
        Console.WriteLine($"Se ha aplicado un interés del {TasaInteres * 100}% a la cuenta {NumeroCuenta}");
    }
}

Paso 3: Uso de las Clases Abstractas y Concretas

class Program
{
    static void Main(string[] args)
    {
        // Crear una cuenta corriente
        CuentaBancaria cuentaCorriente = new CuentaCorriente("123456", 1000);
        cuentaCorriente.Depositar(500);
        cuentaCorriente.Retirar(200);
        cuentaCorriente.MostrarSaldo();

        // Crear una cuenta de ahorro
        CuentaAhorro cuentaAhorro = new CuentaAhorro("789012", 2000, 0.05);
        cuentaAhorro.Depositar(1000);
        cuentaAhorro.Retirar(500);
        cuentaAhorro.AplicarInteres();
        cuentaAhorro.MostrarSaldo();
    }
}

Ejercicio Práctico

Ejercicio 1: Implementar una Clase Abstracta

  1. Crea una clase abstracta llamada Vehiculo con las siguientes propiedades y métodos:

    • Propiedades: Marca, Modelo, Año.
    • Métodos abstractos: Arrancar(), Detener().
    • Método concreto: MostrarDetalles() que muestra la marca, modelo y año del vehículo.
  2. Crea dos subclases que hereden de Vehiculo:

    • Coche: Implementa los métodos Arrancar() y Detener().
    • Motocicleta: Implementa los métodos Arrancar() y Detener().
  3. En el método Main, crea instancias de Coche y Motocicleta, y llama a sus métodos.

Solución

// Definición de la clase abstracta Vehiculo
public abstract class Vehiculo
{
    public string Marca { get; set; }
    public string Modelo { get; set; }
    public int Año { get; set; }

    public Vehiculo(string marca, string modelo, int año)
    {
        Marca = marca;
        Modelo = modelo;
        Año = año;
    }

    public abstract void Arrancar();
    public abstract void Detener();

    public void MostrarDetalles()
    {
        Console.WriteLine($"Marca: {Marca}, Modelo: {Modelo}, Año: {Año}");
    }
}

// Definición de la clase Coche
public class Coche : Vehiculo
{
    public Coche(string marca, string modelo, int año) 
        : base(marca, modelo, año) { }

    public override void Arrancar()
    {
        Console.WriteLine($"El coche {Marca} {Modelo} ha arrancado.");
    }

    public override void Detener()
    {
        Console.WriteLine($"El coche {Marca} {Modelo} se ha detenido.");
    }
}

// Definición de la clase Motocicleta
public class Motocicleta : Vehiculo
{
    public Motocicleta(string marca, string modelo, int año) 
        : base(marca, modelo, año) { }

    public override void Arrancar()
    {
        Console.WriteLine($"La motocicleta {Marca} {Modelo} ha arrancado.");
    }

    public override void Detener()
    {
        Console.WriteLine($"La motocicleta {Marca} {Modelo} se ha detenido.");
    }
}

// Uso de las clases Vehiculo, Coche y Motocicleta
class Program
{
    static void Main(string[] args)
    {
        // Crear una instancia de Coche
        Vehiculo miCoche = new Coche("Toyota", "Corolla", 2020);
        miCoche.MostrarDetalles();
        miCoche.Arrancar();
        miCoche.Detener();

        // Crear una instancia de Motocicleta
        Vehiculo miMoto = new Motocicleta("Honda", "CBR", 2019);
        miMoto.MostrarDetalles();
        miMoto.Arrancar();
        miMoto.Detener();
    }
}

Conclusión

En esta sección, hemos aprendido sobre la abstracción en C# y cómo utilizar clases y métodos abstractos para definir una interfaz común para diferentes tipos de objetos. La abstracción nos permite manejar la complejidad del software ocultando los detalles de implementación y mostrando solo la funcionalidad esencial. En el próximo módulo, exploraremos otros conceptos fundamentales de la Programación Orientada a Objetos, como la herencia y el polimorfismo.

© Copyright 2024. Todos los derechos reservados