Lesson 4 · 4 of 20
Virtual methods and polymorphism · Pascal
Use virtual and override in Object Pascal so each class answers the same call in its own way: polymorphism with shipping rates.

A `virtual` method can be replaced by child classes. TShipping.Cost works out the standard rate (4.95 EUR plus 0.80 per kilo), and TExpress and TPickup redefine it with `override`: same signature, different calculation.
Inside an override you can reuse the original: TExpress.Cost returns inherited Cost(kg) * 2, twice the standard rate, without copying the formula. TPickup.Cost returns 0, since the customer collects the parcel at the shop.
The loop is where polymorphism shows up: option is declared as TShipping, yet each pass it holds an object of a different class. Because Cost is virtual, option.Cost(3.5) decides at run time which version to call based on the real object, and three different prices come out.
Without virtual, the compiler would pick by the variable's type and all three lines would cost 7.75. The loop walks straight over the list [TShipping.Create, TExpress.Create, TPickup.Create] and frees each object as soon as it has been used.
This is the mechanism Lazarus runs on: a form calls Paint or Resize on every control without knowing its class. In DMarlon Studio you can run this example with the Console target and F9.
Code · main.pas
program main;type TShipping = class function Cost(kg: Double): Double; virtual; end; TExpress = class(TShipping) function Cost(kg: Double): Double; override; end; TPickup = class(TShipping) function Cost(kg: Double): Double; override; end;function TShipping.Cost(kg: Double): Double;begin Result := 4.95 + 0.80 * kg; // standard rateend;function TExpress.Cost(kg: Double): Double;begin Result := inherited Cost(kg) * 2; // twice the standard rateend;function TPickup.Cost(kg: Double): Double;begin Result := 0; // collected at the shopend;var option: TShipping;begin for option in [TShipping.Create, TExpress.Create, TPickup.Create] do begin WriteLn(option.ClassName:10, ': ', option.Cost(3.5):5:2, ' EUR for 3.5 kg'); option.Free; end;end.Output · fpc main.pas && ./main
TShipping: 7.75 EUR for 3.5 kg TExpress: 15.50 EUR for 3.5 kg TPickup: 0.00 EUR for 3.5 kg
Key points
virtuallets children change a method;overridechanges it.- The version that runs depends on the object, not the variable.
inheritedinside anoverridereuses the original.- A parent-class variable can hold any child.
- No
virtual, no polymorphism.
Exercise
Add TInternational = class(TShipping) whose Cost is the standard rate plus 12 EUR in customs, and put it in the loop's list.