DMarlon Studio

Lección 5 · 5 de 20

Clases abstractas · Pascal

Declare métodos abstract en Object Pascal para definir un esquema común que cada clase hija completa, con métodos de pago y sus comisiones.

Pascal · Clases abstractas en DMarlon Studio: el código del ejemplo y su salida en la terminal

Un método `abstract` se declara pero no se implementa: TPayment.Fee dice que todo pago tiene una comisión, pero no cuál. Debe ser también virtual, porque su única razón de ser es que las clases hijas lo completen con override.

TPayment es una clase abstracta: sirve de molde, no para crear objetos. Si hiciera TPayment.Create, Free Pascal lo compilaría con un aviso, y al llamar a Fee saltaría un error EAbstractError. Los objetos reales son TCard (1,5 % del importe) y TTransfer (0,35 EUR fijos).

Lo interesante es Charge: es un método normal de la clase abstracta que usa el método abstracto. Todos los pagos se cobran con los mismos pasos y solo cambia la comisión. Este patrón se llama *método plantilla*: la madre pone el esquema y las hijas, el detalle.

Copy(ClassName, 2, 9) quita la T inicial del nombre de la clase para escribir Card o Transfer. El bucle crea cada método de pago, le cobra 20 y 250 EUR y lo libera con Free.

Código · main.pas

program main;type  TPayment = class    function Fee(amount: Double): Double; virtual; abstract;  // no body here    procedure Charge(amount: Double);  end;  TCard = class(TPayment)    function Fee(amount: Double): Double; override;  end;  TTransfer = class(TPayment)    function Fee(amount: Double): Double; override;  end;procedure TPayment.Charge(amount: Double);begin  // the same steps for every method; only Fee changes  WriteLn(Copy(ClassName, 2, 9):8, amount:8:2, ' + fee', Fee(amount):5:2, ' =', amount + Fee(amount):7:2);end;function TCard.Fee(amount: Double): Double;begin  Result := amount * 0.015;  // 1.5 % of the amountend;function TTransfer.Fee(amount: Double): Double;begin  Result := 0.35;  // flat feeend;var method: TPayment;begin  for method in [TCard.Create, TTransfer.Create] do  begin    method.Charge(20);    method.Charge(250);    method.Free;  end;end.

Salida · fpc main.pas && ./main

    Card   20.00 + fee 0.30 =  20.30
    Card  250.00 + fee 3.75 = 253.75
Transfer   20.00 + fee 0.35 =  20.35
Transfer  250.00 + fee 0.35 = 250.35

Para recordar

  • virtual; abstract; declara un método sin cuerpo.
  • Una clase abstracta es un molde; se usan sus hijas.
  • Llamar a un método abstracto lanza EAbstractError.
  • Los métodos normales de la madre pueden usar los abstractos.
  • Método plantilla: pasos comunes, detalle en cada hija.

Ejercicio

Añada TBizum = class(TPayment) sin comisión para importes de hasta 50 EUR y con 0,20 EUR para importes mayores, y cóbrele los mismos dos importes.