Introducción

En este tema, exploraremos dos conceptos fundamentales de la Programación Orientada a Objetos (POO): la herencia y el polimorfismo. Estos conceptos permiten crear estructuras de código más reutilizables y flexibles, facilitando la extensión y el mantenimiento de las aplicaciones.

Herencia

La herencia es un mecanismo que permite crear una nueva clase a partir de una clase existente. La nueva clase, llamada clase derivada o subclase, hereda los atributos y métodos de la clase base o superclase. Esto permite reutilizar el código y extender la funcionalidad de las clases existentes.

Conceptos Clave

  • Clase Base (Superclase): La clase original de la cual se derivan otras clases.
  • Clase Derivada (Subclase): La nueva clase que hereda de la clase base.
  • Herencia Simple: Una clase derivada hereda de una sola clase base.
  • Herencia Múltiple: No es soportada directamente en Delphi, pero se puede simular usando interfaces.

Ejemplo Práctico

program HerenciaEjemplo;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  // Definición de la clase base
  TAnimal = class
  private
    FNombre: string;
  public
    constructor Create(Nombre: string);
    procedure HacerSonido; virtual;
    property Nombre: string read FNombre write FNombre;
  end;

  // Definición de la clase derivada
  TPerro = class(TAnimal)
  public
    procedure HacerSonido; override;
  end;

constructor TAnimal.Create(Nombre: string);
begin
  FNombre := Nombre;
end;

procedure TAnimal.HacerSonido;
begin
  Writeln('El animal hace un sonido.');
end;

procedure TPerro.HacerSonido;
begin
  Writeln('El perro ladra.');
end;

var
  MiPerro: TPerro;

begin
  MiPerro := TPerro.Create('Fido');
  try
    Writeln('Nombre del perro: ', MiPerro.Nombre);
    MiPerro.HacerSonido;
  finally
    MiPerro.Free;
  end;
end.

Explicación del Código

  1. Definición de la Clase Base TAnimal:

    • Tiene un constructor que inicializa el nombre del animal.
    • Un método HacerSonido que es virtual, lo que permite que las subclases lo sobreescriban.
    • Una propiedad Nombre para acceder al nombre del animal.
  2. Definición de la Clase Derivada TPerro:

    • Hereda de TAnimal.
    • Sobrescribe el método HacerSonido para proporcionar una implementación específica para perros.
  3. Uso de las Clases:

    • Se crea una instancia de TPerro, se establece su nombre y se llama al método HacerSonido.

Polimorfismo

El polimorfismo permite que una clase derivada sea tratada como una instancia de su clase base. Esto permite que el mismo código funcione con diferentes tipos de objetos, proporcionando flexibilidad y extensibilidad.

Conceptos Clave

  • Polimorfismo en Tiempo de Ejecución: Se logra mediante métodos virtuales y sobrescritos.
  • Polimorfismo en Tiempo de Compilación: Se logra mediante sobrecarga de métodos (no cubierto en este tema).

Ejemplo Práctico

program PolimorfismoEjemplo;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TAnimal = class
  public
    procedure HacerSonido; virtual;
  end;

  TPerro = class(TAnimal)
  public
    procedure HacerSonido; override;
  end;

  TGato = class(TAnimal)
  public
    procedure HacerSonido; override;
  end;

procedure TAnimal.HacerSonido;
begin
  Writeln('El animal hace un sonido.');
end;

procedure TPerro.HacerSonido;
begin
  Writeln('El perro ladra.');
end;

procedure TGato.HacerSonido;
begin
  Writeln('El gato maúlla.');
end;

procedure HacerSonidoAnimal(Animal: TAnimal);
begin
  Animal.HacerSonido;
end;

var
  MiPerro: TPerro;
  MiGato: TGato;

begin
  MiPerro := TPerro.Create;
  MiGato := TGato.Create;
  try
    HacerSonidoAnimal(MiPerro);
    HacerSonidoAnimal(MiGato);
  finally
    MiPerro.Free;
    MiGato.Free;
  end;
end.

Explicación del Código

  1. Definición de Clases TAnimal, TPerro y TGato:

    • TAnimal tiene un método virtual HacerSonido.
    • TPerro y TGato sobrescriben HacerSonido para proporcionar implementaciones específicas.
  2. Uso del Polimorfismo:

    • La función HacerSonidoAnimal acepta un parámetro de tipo TAnimal.
    • Se llama a HacerSonido en instancias de TPerro y TGato, demostrando el polimorfismo en tiempo de ejecución.

Ejercicios Prácticos

Ejercicio 1: Crear una Jerarquía de Clases

  1. Objetivo: Crear una jerarquía de clases para diferentes tipos de vehículos.
  2. Instrucciones:
    • Crear una clase base TVehiculo con un método virtual Mover.
    • Crear clases derivadas TCoche y TBicicleta que sobrescriban el método Mover.
    • Crear instancias de TCoche y TBicicleta y demostrar el polimorfismo.

Solución

program VehiculosEjemplo;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TVehiculo = class
  public
    procedure Mover; virtual;
  end;

  TCoche = class(TVehiculo)
  public
    procedure Mover; override;
  end;

  TBicicleta = class(TVehiculo)
  public
    procedure Mover; override;
  end;

procedure TVehiculo.Mover;
begin
  Writeln('El vehículo se mueve.');
end;

procedure TCoche.Mover;
begin
  Writeln('El coche conduce.');
end;

procedure TBicicleta.Mover;
begin
  Writeln('La bicicleta pedalea.');
end;

procedure MoverVehiculo(Vehiculo: TVehiculo);
begin
  Vehiculo.Mover;
end;

var
  MiCoche: TCoche;
  MiBicicleta: TBicicleta;

begin
  MiCoche := TCoche.Create;
  MiBicicleta := TBicicleta.Create;
  try
    MoverVehiculo(MiCoche);
    MoverVehiculo(MiBicicleta);
  finally
    MiCoche.Free;
    MiBicicleta.Free;
  end;
end.

Ejercicio 2: Añadir Nuevas Clases Derivadas

  1. Objetivo: Extender la jerarquía de clases de vehículos.
  2. Instrucciones:
    • Añadir una nueva clase derivada TMotocicleta que sobrescriba el método Mover.
    • Crear una instancia de TMotocicleta y demostrar el polimorfismo.

Solución

program VehiculosExtendidoEjemplo;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TVehiculo = class
  public
    procedure Mover; virtual;
  end;

  TCoche = class(TVehiculo)
  public
    procedure Mover; override;
  end;

  TBicicleta = class(TVehiculo)
  public
    procedure Mover; override;
  end;

  TMotocicleta = class(TVehiculo)
  public
    procedure Mover; override;
  end;

procedure TVehiculo.Mover;
begin
  Writeln('El vehículo se mueve.');
end;

procedure TCoche.Mover;
begin
  Writeln('El coche conduce.');
end;

procedure TBicicleta.Mover;
begin
  Writeln('La bicicleta pedalea.');
end;

procedure TMotocicleta.Mover;
begin
  Writeln('La motocicleta acelera.');
end;

procedure MoverVehiculo(Vehiculo: TVehiculo);
begin
  Vehiculo.Mover;
end;

var
  MiCoche: TCoche;
  MiBicicleta: TBicicleta;
  MiMotocicleta: TMotocicleta;

begin
  MiCoche := TCoche.Create;
  MiBicicleta := TBicicleta.Create;
  MiMotocicleta := TMotocicleta.Create;
  try
    MoverVehiculo(MiCoche);
    MoverVehiculo(MiBicicleta);
    MoverVehiculo(MiMotocicleta);
  finally
    MiCoche.Free;
    MiBicicleta.Free;
    MiMotocicleta.Free;
  end;
end.

Conclusión

En esta sección, hemos aprendido sobre la herencia y el polimorfismo en Delphi/Object Pascal. La herencia nos permite crear nuevas clases basadas en clases existentes, reutilizando y extendiendo el código. El polimorfismo nos permite tratar objetos de diferentes clases derivadas de manera uniforme, proporcionando flexibilidad y extensibilidad en nuestro código.

En el próximo tema, exploraremos las interfaces y las clases abstractas, que son herramientas adicionales para diseñar sistemas orientados a objetos robustos y flexibles.

Curso de Programación en Delphi/Object Pascal

Módulo 1: Introducción a Delphi/Object Pascal

Módulo 2: Estructuras de Control y Procedimientos

Módulo 3: Trabajando con Datos

Módulo 4: Programación Orientada a Objetos

Módulo 5: Características Avanzadas de Delphi

Módulo 6: Desarrollo de GUI con VCL y FMX

Módulo 7: Desarrollo Web y Móvil

Módulo 8: Mejores Prácticas y Patrones de Diseño

Módulo 9: Proyecto Final

© Copyright 2024. Todos los derechos reservados